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 <cmetcalf@ezchip.com> Acked-by: Frederic Weisbecker <fweisbec@gmail.com>
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/context_tracking.h>
|
||||
#include <asm/stack.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/setup.h>
|
||||
@@ -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)
|
||||
|
Reference in New Issue
Block a user