diff --git a/core/arch/arm/kernel/thread_a32.S b/core/arch/arm/kernel/thread_a32.S index 7851935c98c..f5c59d312e1 100644 --- a/core/arch/arm/kernel/thread_a32.S +++ b/core/arch/arm/kernel/thread_a32.S @@ -443,6 +443,16 @@ END_FUNC thread_rpc /* The handler of native interrupt. */ .macro native_intr_handler mode:req + .ifc \mode\(),irq + /* + * Foreign interrupts should be masked. + * For GICv2, IRQ is for foreign interrupt and already masked by + * hardware in FIQ mode which is used for native interrupt. + * For GICv3, FIQ is for foreign interrupt. It's not masked by hardware + * in IRQ mode which is used for natvie interrupt. + */ + cpsid f + .endif /* * FIQ and IRQ have a +4 offset for lr compared to preferred return * address @@ -662,6 +672,12 @@ LOCAL_FUNC thread_abort_handler , : thread_und_handler: UNWIND( .fnstart) UNWIND( .cantunwind) + /* + * Disable both foreign and native interrupts in the thread handlers. + * The tee handlers can decide when the native interrupts should + * be enabled. + */ + cpsid f /* IRQ is already masked by the hardware */ strd r0, r1, [sp, #THREAD_CORE_LOCAL_R0] mrs r1, spsr tst r1, #CPSR_T @@ -671,12 +687,24 @@ UNWIND( .cantunwind) b .thread_abort_generic thread_dabort_handler: + /* + * Disable both foreign and native interrupts in the thread handlers. + * The tee handlers can decide when the native interrupts should + * be enabled. + */ + cpsid f /* IRQ is already masked by the hardware */ strd r0, r1, [sp, #THREAD_CORE_LOCAL_R0] sub lr, lr, #8 mov r0, #ABORT_TYPE_DATA b .thread_abort_generic thread_pabort_handler: + /* + * Disable both foreign and native interrupts in the thread handlers. + * The tee handlers can decide when the native interrupts should + * be enabled. + */ + cpsid f /* IRQ is already masked by the hardware */ strd r0, r1, [sp, #THREAD_CORE_LOCAL_R0] sub lr, lr, #4 mov r0, #ABORT_TYPE_PREFETCH @@ -771,6 +799,12 @@ END_FUNC thread_abort_handler LOCAL_FUNC thread_svc_handler , : UNWIND( .fnstart) UNWIND( .cantunwind) + /* + * Disable both foreign and native interrupts in the thread handlers. + * The tee handlers can decide when the native interrupts should + * be enabled. + */ + cpsid f /* IRQ is already masked by the hardware */ push {r0-r7, lr} mrs r0, spsr push {r0} diff --git a/core/arch/arm/tee/arch_svc.c b/core/arch/arm/tee/arch_svc.c index a0e78745478..f74bee30044 100644 --- a/core/arch/arm/tee/arch_svc.c +++ b/core/arch/arm/tee/arch_svc.c @@ -196,10 +196,15 @@ void __weak tee_svc_handler(struct thread_svc_regs *regs) size_t scn; size_t max_args; syscall_t scf; + uint32_t state; COMPILE_TIME_ASSERT(ARRAY_SIZE(tee_svc_syscall_table) == (TEE_SCN_MAX + 1)); + /* Enable native interupts */ + state = thread_get_exceptions(); + thread_unmask_exceptions(state & ~THREAD_EXCP_NATIVE_INTR); + thread_user_save_vfp(); /* TA has just entered kernel mode */