From 49e4e15619cd7cd9fc275d460fae2a95c1337fcc Mon Sep 17 00:00:00 2001 From: Chris Metcalf Date: Mon, 23 Mar 2015 14:23:58 -0400 Subject: tile: support CONTEXT_TRACKING and thus NOHZ_FULL Add the TIF_NOHZ flag appropriately. Add call to user_exit() on entry to do_work_pending() and on entry to syscalls via do_syscall_trace_enter(), and also the top of do_syscall_trace_exit() just because it's done in x86. Add call to user_enter() at the bottom of do_work_pending() once we have no more work to do before returning to userspace. Wrap all the trap code in exception_enter() / exception_exit(). Signed-off-by: Chris Metcalf Acked-by: Frederic Weisbecker --- arch/tile/kernel/traps.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'arch/tile/kernel/traps.c') diff --git a/arch/tile/kernel/traps.c b/arch/tile/kernel/traps.c index bf841ca517bb..312fc134c1cb 100644 --- a/arch/tile/kernel/traps.c +++ b/arch/tile/kernel/traps.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -253,6 +254,7 @@ static int do_bpt(struct pt_regs *regs) void __kprobes do_trap(struct pt_regs *regs, int fault_num, unsigned long reason) { + enum ctx_state prev_state = exception_enter(); siginfo_t info = { 0 }; int signo, code; unsigned long address = 0; @@ -261,7 +263,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, /* Handle breakpoints, etc. */ if (is_kernel && fault_num == INT_ILL && do_bpt(regs)) - return; + goto done; /* Re-enable interrupts, if they were previously enabled. */ if (!(regs->flags & PT_FLAGS_DISABLE_IRQ)) @@ -275,7 +277,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, const char *name; char buf[100]; if (fixup_exception(regs)) /* ILL_TRANS or UNALIGN_DATA */ - return; + goto done; if (fault_num >= 0 && fault_num < ARRAY_SIZE(int_name) && int_name[fault_num] != NULL) @@ -294,7 +296,6 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, fault_num, name, regs->pc, buf); show_regs(regs); do_exit(SIGKILL); /* FIXME: implement i386 die() */ - return; } switch (fault_num) { @@ -308,7 +309,6 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, pr_err("Unreadable instruction for INT_ILL: %#lx\n", regs->pc); do_exit(SIGKILL); - return; } if (!special_ill(instr, &signo, &code)) { signo = SIGILL; @@ -319,7 +319,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, case INT_GPV: #if CHIP_HAS_TILE_DMA() if (retry_gpv(reason)) - return; + goto done; #endif /*FALLTHROUGH*/ case INT_UDN_ACCESS: @@ -346,7 +346,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, if (!state || (void __user *)(regs->pc) != state->buffer) { single_step_once(regs); - return; + goto done; } } #endif @@ -380,7 +380,6 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, #endif default: panic("Unexpected do_trap interrupt number %d", fault_num); - return; } info.si_signo = signo; @@ -391,6 +390,9 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, if (signo != SIGTRAP) trace_unhandled_signal("trap", regs, address, signo); force_sig_info(signo, &info, current); + +done: + exception_exit(prev_state); } void kernel_double_fault(int dummy, ulong pc, ulong lr, ulong sp, ulong r52) -- cgit v1.2.3