@@ -14,5 +14,9 @@ void irqentry_enter_from_user_mode(struct pt_regs *regs);
void irqentry_exit_to_user_mode(struct pt_regs *regs);
void irqentry_enter_from_kernel_mode(struct pt_regs *regs);
void irqentry_exit_to_kernel_mode(struct pt_regs *regs);
+void irqentry_nmi_enter_from_user_mode(struct pt_regs *regs);
+void irqentry_nmi_exit_to_user_mode(struct pt_regs *regs);
+void irqentry_nmi_enter_from_kernel_mode(struct pt_regs *regs);
+void irqentry_nmi_exit_to_kernel_mode(struct pt_regs *regs);
#endif /* __ASM_ENTRY_H__ */
@@ -157,7 +157,7 @@ ENDPROC(__und_invalid)
#define SPFIX(code...)
#endif
- .macro svc_entry, stack_hole=0 uaccess=1, overflow_check=1
+ .macro svc_entry, stack_hole=0 uaccess=1, overflow_check=1, nmi=0
UNWIND(.fnstart )
sub sp, sp, #(SVC_REGS_SIZE + \stack_hole)
THUMB( add sp, r1 ) @ get SP in a GPR without
@@ -205,7 +205,11 @@ ENDPROC(__und_invalid)
uaccess_entry tsk, r0, r1, r2, \uaccess
mov r0, sp @ 'regs'
+ .if \nmi
+ bl irqentry_nmi_enter_from_kernel_mode
+ .else
bl irqentry_enter_from_kernel_mode
+ .endif
.endm
@@ -297,7 +301,7 @@ ENDPROC(__pabt_svc)
.align 5
__fiq_svc:
- svc_entry
+ svc_entry nmi=1
mov r0, sp @ struct pt_regs *regs
bl handle_fiq_as_nmi
svc_exit_via_fiq
@@ -315,7 +319,7 @@ ENDPROC(__fiq_svc)
@
.align 5
__fiq_abt:
- svc_entry
+ svc_entry nmi=1
ARM( msr cpsr_c, #ABT_MODE | PSR_I_BIT | PSR_F_BIT )
THUMB( mov r0, #ABT_MODE | PSR_I_BIT | PSR_F_BIT )
@@ -490,9 +494,13 @@ ENDPROC(ret_from_exception)
.align 5
__fiq_usr:
usr_entry
+ mov r0, sp
+ bl irqentry_nmi_enter_from_user_mode
kuser_cmpxchg_check
mov r0, sp @ struct pt_regs *regs
bl handle_fiq_as_nmi
+ mov r0, sp
+ bl irqentry_nmi_exit_to_user_mode
get_thread_info tsk
restore_user_regs
UNWIND(.fnend )
@@ -252,6 +252,8 @@
@
.macro svc_exit_via_fiq
uaccess_exit tsk, r0, r1
+ mov r0, sp
+ bl irqentry_nmi_exit_to_kernel_mode
#ifndef CONFIG_THUMB2_KERNEL
@ ARM mode restore
mov r0, sp
@@ -69,3 +69,19 @@ noinstr void irqentry_exit_to_kernel_mode(struct pt_regs *regs)
else
trace_hardirqs_off();
}
+
+noinstr void irqentry_nmi_enter_from_user_mode(struct pt_regs *regs)
+{
+}
+
+noinstr void irqentry_nmi_exit_to_user_mode(struct pt_regs *regs)
+{
+}
+
+noinstr void irqentry_nmi_enter_from_kernel_mode(struct pt_regs *regs)
+{
+}
+
+noinstr void irqentry_nmi_exit_to_kernel_mode(struct pt_regs *regs)
+{
+}
These NMI (FIQ) callbacks are added to complete the calls expected by the generic entry. They are perfectly fine to add code to but are left empty for now. Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- arch/arm/include/asm/entry.h | 4 ++++ arch/arm/kernel/entry-armv.S | 14 +++++++++++--- arch/arm/kernel/entry-header.S | 2 ++ arch/arm/kernel/entry.c | 16 ++++++++++++++++ 4 files changed, 33 insertions(+), 3 deletions(-)