diff options
author | Chris Metcalf <cmetcalf@ezchip.com> | 2015-03-23 21:23:58 +0300 |
---|---|---|
committer | Chris Metcalf <cmetcalf@ezchip.com> | 2015-04-17 21:01:10 +0300 |
commit | 49e4e15619cd7cd9fc275d460fae2a95c1337fcc (patch) | |
tree | 700e24bb8f72a7662e7d4ae26d847e908d08de92 /arch/tile/kernel/unaligned.c | |
parent | b340c656af6317e28b466996a72cca019d97b42d (diff) | |
download | linux-49e4e15619cd7cd9fc275d460fae2a95c1337fcc.tar.xz |
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>
Diffstat (limited to 'arch/tile/kernel/unaligned.c')
-rw-r--r-- | arch/tile/kernel/unaligned.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/arch/tile/kernel/unaligned.c b/arch/tile/kernel/unaligned.c index 7d9a83be0aca..d075f92ccee0 100644 --- a/arch/tile/kernel/unaligned.c +++ b/arch/tile/kernel/unaligned.c @@ -25,6 +25,7 @@ #include <linux/module.h> #include <linux/compat.h> #include <linux/prctl.h> +#include <linux/context_tracking.h> #include <asm/cacheflush.h> #include <asm/traps.h> #include <asm/uaccess.h> @@ -1448,6 +1449,7 @@ void jit_bundle_gen(struct pt_regs *regs, tilegx_bundle_bits bundle, void do_unaligned(struct pt_regs *regs, int vecnum) { + enum ctx_state prev_state = exception_enter(); tilegx_bundle_bits __user *pc; tilegx_bundle_bits bundle; struct thread_info *info = current_thread_info(); @@ -1487,12 +1489,11 @@ void do_unaligned(struct pt_regs *regs, int vecnum) (int)unaligned_fixup, (unsigned long long)regs->ex1, (unsigned long long)regs->pc); - return; + } else { + /* Not fixable. Go panic. */ + panic("Unalign exception in Kernel. pc=%lx", + regs->pc); } - /* Not fixable. Go panic. */ - panic("Unalign exception in Kernel. pc=%lx", - regs->pc); - return; } else { /* * Try to fix the exception. If we can't, panic the @@ -1501,8 +1502,8 @@ void do_unaligned(struct pt_regs *regs, int vecnum) bundle = GX_INSN_BSWAP( *((tilegx_bundle_bits *)(regs->pc))); jit_bundle_gen(regs, bundle, align_ctl); - return; } + goto done; } /* @@ -1526,7 +1527,7 @@ void do_unaligned(struct pt_regs *regs, int vecnum) trace_unhandled_signal("unaligned fixup trap", regs, 0, SIGBUS); force_sig_info(info.si_signo, &info, current); - return; + goto done; } @@ -1543,7 +1544,7 @@ void do_unaligned(struct pt_regs *regs, int vecnum) trace_unhandled_signal("segfault in unalign fixup", regs, (unsigned long)info.si_addr, SIGSEGV); force_sig_info(info.si_signo, &info, current); - return; + goto done; } if (!info->unalign_jit_base) { @@ -1578,7 +1579,7 @@ void do_unaligned(struct pt_regs *regs, int vecnum) if (IS_ERR((void __force *)user_page)) { pr_err("Out of kernel pages trying do_mmap\n"); - return; + goto done; } /* Save the address in the thread_info struct */ @@ -1591,6 +1592,9 @@ void do_unaligned(struct pt_regs *regs, int vecnum) /* Generate unalign JIT */ jit_bundle_gen(regs, GX_INSN_BSWAP(bundle), align_ctl); + +done: + exception_exit(prev_state); } #endif /* __tilegx__ */ |