aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@ezchip.com>2015-12-23 17:13:04 -0500
committerChris Metcalf <cmetcalf@ezchip.com>2016-01-18 14:49:30 -0500
commit1bb50cad45f4a3fb9a339006d76efc50f70eed5b (patch)
tree91e00be5d5852acdb7c5c9ba9707b9f7926e6bc6
parent9ce815ed50bbc518526106071f395deacaf94ad7 (diff)
arch/tile: move user_exit() to early kernel entry sequence
This ensures that we always notify context tracking that we have exited from user space no matter how we enter the kernel. It is similar to how arm64 handles context tracking, for example. This allows the removal of all the exception_enter() calls that were added in commit 49e4e15619cd ("tile: support CONTEXT_TRACKING and thus NOHZ_FULL"). Signed-off-by: Chris Metcalf <cmetcalf@ezchip.com>
-rw-r--r--arch/tile/kernel/intvec_32.S5
-rw-r--r--arch/tile/kernel/intvec_64.S5
-rw-r--r--arch/tile/kernel/ptrace.c15
-rw-r--r--arch/tile/kernel/single_step.c3
-rw-r--r--arch/tile/kernel/traps.c13
-rw-r--r--arch/tile/kernel/unaligned.c13
-rw-r--r--arch/tile/mm/fault.c3
7 files changed, 16 insertions, 41 deletions
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S
index 33d48812872a..9ff75e3a318a 100644
--- a/arch/tile/kernel/intvec_32.S
+++ b/arch/tile/kernel/intvec_32.S
@@ -572,7 +572,7 @@ intvec_\vecname:
572 } 572 }
573 wh64 r52 573 wh64 r52
574 574
575#ifdef CONFIG_TRACE_IRQFLAGS 575#if defined(CONFIG_TRACE_IRQFLAGS) || defined(CONFIG_CONTEXT_TRACKING)
576 .ifnc \function,handle_nmi 576 .ifnc \function,handle_nmi
577 /* 577 /*
578 * We finally have enough state set up to notify the irq 578 * We finally have enough state set up to notify the irq
@@ -588,6 +588,9 @@ intvec_\vecname:
588 { move r32, r2; move r33, r3 } 588 { move r32, r2; move r33, r3 }
589 .endif 589 .endif
590 TRACE_IRQS_OFF 590 TRACE_IRQS_OFF
591#ifdef CONFIG_CONTEXT_TRACKING
592 jal context_tracking_user_exit
593#endif
591 .ifnc \function,handle_syscall 594 .ifnc \function,handle_syscall
592 { move r0, r30; move r1, r31 } 595 { move r0, r30; move r1, r31 }
593 { move r2, r32; move r3, r33 } 596 { move r2, r32; move r3, r33 }
diff --git a/arch/tile/kernel/intvec_64.S b/arch/tile/kernel/intvec_64.S
index 080b77269ccd..3b51bdf37d11 100644
--- a/arch/tile/kernel/intvec_64.S
+++ b/arch/tile/kernel/intvec_64.S
@@ -753,7 +753,7 @@ intvec_\vecname:
753 } 753 }
754 wh64 r52 754 wh64 r52
755 755
756#ifdef CONFIG_TRACE_IRQFLAGS 756#if defined(CONFIG_TRACE_IRQFLAGS) || defined(CONFIG_CONTEXT_TRACKING)
757 .ifnc \function,handle_nmi 757 .ifnc \function,handle_nmi
758 /* 758 /*
759 * We finally have enough state set up to notify the irq 759 * We finally have enough state set up to notify the irq
@@ -769,6 +769,9 @@ intvec_\vecname:
769 { move r32, r2; move r33, r3 } 769 { move r32, r2; move r33, r3 }
770 .endif 770 .endif
771 TRACE_IRQS_OFF 771 TRACE_IRQS_OFF
772#ifdef CONFIG_CONTEXT_TRACKING
773 jal context_tracking_user_exit
774#endif
772 .ifnc \function,handle_syscall 775 .ifnc \function,handle_syscall
773 { move r0, r30; move r1, r31 } 776 { move r0, r30; move r1, r31 }
774 { move r2, r32; move r3, r33 } 777 { move r2, r32; move r3, r33 }
diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c
index bdc126faf741..54e7b723db99 100644
--- a/arch/tile/kernel/ptrace.c
+++ b/arch/tile/kernel/ptrace.c
@@ -255,13 +255,6 @@ int do_syscall_trace_enter(struct pt_regs *regs)
255{ 255{
256 u32 work = ACCESS_ONCE(current_thread_info()->flags); 256 u32 work = ACCESS_ONCE(current_thread_info()->flags);
257 257
258 /*
259 * If TIF_NOHZ is set, we are required to call user_exit() before
260 * doing anything that could touch RCU.
261 */
262 if (work & _TIF_NOHZ)
263 user_exit();
264
265 if (secure_computing() == -1) 258 if (secure_computing() == -1)
266 return -1; 259 return -1;
267 260
@@ -281,12 +274,6 @@ void do_syscall_trace_exit(struct pt_regs *regs)
281 long errno; 274 long errno;
282 275
283 /* 276 /*
284 * We may come here right after calling schedule_user()
285 * in which case we can be in RCU user mode.
286 */
287 user_exit();
288
289 /*
290 * The standard tile calling convention returns the value (or negative 277 * The standard tile calling convention returns the value (or negative
291 * errno) in r0, and zero (or positive errno) in r1. 278 * errno) in r0, and zero (or positive errno) in r1.
292 * It saves a couple of cycles on the hot path to do this work in 279 * It saves a couple of cycles on the hot path to do this work in
@@ -322,7 +309,5 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs)
322/* Handle synthetic interrupt delivered only by the simulator. */ 309/* Handle synthetic interrupt delivered only by the simulator. */
323void __kprobes do_breakpoint(struct pt_regs* regs, int fault_num) 310void __kprobes do_breakpoint(struct pt_regs* regs, int fault_num)
324{ 311{
325 enum ctx_state prev_state = exception_enter();
326 send_sigtrap(current, regs); 312 send_sigtrap(current, regs);
327 exception_exit(prev_state);
328} 313}
diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c
index 53f7b9def07b..862973074bf9 100644
--- a/arch/tile/kernel/single_step.c
+++ b/arch/tile/kernel/single_step.c
@@ -23,7 +23,6 @@
23#include <linux/types.h> 23#include <linux/types.h>
24#include <linux/err.h> 24#include <linux/err.h>
25#include <linux/prctl.h> 25#include <linux/prctl.h>
26#include <linux/context_tracking.h>
27#include <asm/cacheflush.h> 26#include <asm/cacheflush.h>
28#include <asm/traps.h> 27#include <asm/traps.h>
29#include <asm/uaccess.h> 28#include <asm/uaccess.h>
@@ -739,7 +738,6 @@ static DEFINE_PER_CPU(unsigned long, ss_saved_pc);
739 738
740void gx_singlestep_handle(struct pt_regs *regs, int fault_num) 739void gx_singlestep_handle(struct pt_regs *regs, int fault_num)
741{ 740{
742 enum ctx_state prev_state = exception_enter();
743 unsigned long *ss_pc = this_cpu_ptr(&ss_saved_pc); 741 unsigned long *ss_pc = this_cpu_ptr(&ss_saved_pc);
744 struct thread_info *info = (void *)current_thread_info(); 742 struct thread_info *info = (void *)current_thread_info();
745 int is_single_step = test_ti_thread_flag(info, TIF_SINGLESTEP); 743 int is_single_step = test_ti_thread_flag(info, TIF_SINGLESTEP);
@@ -756,7 +754,6 @@ void gx_singlestep_handle(struct pt_regs *regs, int fault_num)
756 __insn_mtspr(SPR_SINGLE_STEP_CONTROL_K, control); 754 __insn_mtspr(SPR_SINGLE_STEP_CONTROL_K, control);
757 send_sigtrap(current, regs); 755 send_sigtrap(current, regs);
758 } 756 }
759 exception_exit(prev_state);
760} 757}
761 758
762 759
diff --git a/arch/tile/kernel/traps.c b/arch/tile/kernel/traps.c
index 0011a9ff0525..4d9651c5b1ad 100644
--- a/arch/tile/kernel/traps.c
+++ b/arch/tile/kernel/traps.c
@@ -20,7 +20,6 @@
20#include <linux/reboot.h> 20#include <linux/reboot.h>
21#include <linux/uaccess.h> 21#include <linux/uaccess.h>
22#include <linux/ptrace.h> 22#include <linux/ptrace.h>
23#include <linux/context_tracking.h>
24#include <asm/stack.h> 23#include <asm/stack.h>
25#include <asm/traps.h> 24#include <asm/traps.h>
26#include <asm/setup.h> 25#include <asm/setup.h>
@@ -254,7 +253,6 @@ static int do_bpt(struct pt_regs *regs)
254void __kprobes do_trap(struct pt_regs *regs, int fault_num, 253void __kprobes do_trap(struct pt_regs *regs, int fault_num,
255 unsigned long reason) 254 unsigned long reason)
256{ 255{
257 enum ctx_state prev_state = exception_enter();
258 siginfo_t info = { 0 }; 256 siginfo_t info = { 0 };
259 int signo, code; 257 int signo, code;
260 unsigned long address = 0; 258 unsigned long address = 0;
@@ -263,7 +261,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
263 261
264 /* Handle breakpoints, etc. */ 262 /* Handle breakpoints, etc. */
265 if (is_kernel && fault_num == INT_ILL && do_bpt(regs)) 263 if (is_kernel && fault_num == INT_ILL && do_bpt(regs))
266 goto done; 264 return;
267 265
268 /* Re-enable interrupts, if they were previously enabled. */ 266 /* Re-enable interrupts, if they were previously enabled. */
269 if (!(regs->flags & PT_FLAGS_DISABLE_IRQ)) 267 if (!(regs->flags & PT_FLAGS_DISABLE_IRQ))
@@ -277,7 +275,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
277 const char *name; 275 const char *name;
278 char buf[100]; 276 char buf[100];
279 if (fixup_exception(regs)) /* ILL_TRANS or UNALIGN_DATA */ 277 if (fixup_exception(regs)) /* ILL_TRANS or UNALIGN_DATA */
280 goto done; 278 return;
281 if (fault_num >= 0 && 279 if (fault_num >= 0 &&
282 fault_num < ARRAY_SIZE(int_name) && 280 fault_num < ARRAY_SIZE(int_name) &&
283 int_name[fault_num] != NULL) 281 int_name[fault_num] != NULL)
@@ -319,7 +317,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
319 case INT_GPV: 317 case INT_GPV:
320#if CHIP_HAS_TILE_DMA() 318#if CHIP_HAS_TILE_DMA()
321 if (retry_gpv(reason)) 319 if (retry_gpv(reason))
322 goto done; 320 return;
323#endif 321#endif
324 /*FALLTHROUGH*/ 322 /*FALLTHROUGH*/
325 case INT_UDN_ACCESS: 323 case INT_UDN_ACCESS:
@@ -346,7 +344,7 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
346 if (!state || 344 if (!state ||
347 (void __user *)(regs->pc) != state->buffer) { 345 (void __user *)(regs->pc) != state->buffer) {
348 single_step_once(regs); 346 single_step_once(regs);
349 goto done; 347 return;
350 } 348 }
351 } 349 }
352#endif 350#endif
@@ -390,9 +388,6 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num,
390 if (signo != SIGTRAP) 388 if (signo != SIGTRAP)
391 trace_unhandled_signal("trap", regs, address, signo); 389 trace_unhandled_signal("trap", regs, address, signo);
392 force_sig_info(signo, &info, current); 390 force_sig_info(signo, &info, current);
393
394done:
395 exception_exit(prev_state);
396} 391}
397 392
398void do_nmi(struct pt_regs *regs, int fault_num, unsigned long reason) 393void do_nmi(struct pt_regs *regs, int fault_num, unsigned long reason)
diff --git a/arch/tile/kernel/unaligned.c b/arch/tile/kernel/unaligned.c
index d075f92ccee0..0db5f7c9d9e5 100644
--- a/arch/tile/kernel/unaligned.c
+++ b/arch/tile/kernel/unaligned.c
@@ -25,7 +25,6 @@
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/compat.h> 26#include <linux/compat.h>
27#include <linux/prctl.h> 27#include <linux/prctl.h>
28#include <linux/context_tracking.h>
29#include <asm/cacheflush.h> 28#include <asm/cacheflush.h>
30#include <asm/traps.h> 29#include <asm/traps.h>
31#include <asm/uaccess.h> 30#include <asm/uaccess.h>
@@ -1449,7 +1448,6 @@ void jit_bundle_gen(struct pt_regs *regs, tilegx_bundle_bits bundle,
1449 1448
1450void do_unaligned(struct pt_regs *regs, int vecnum) 1449void do_unaligned(struct pt_regs *regs, int vecnum)
1451{ 1450{
1452 enum ctx_state prev_state = exception_enter();
1453 tilegx_bundle_bits __user *pc; 1451 tilegx_bundle_bits __user *pc;
1454 tilegx_bundle_bits bundle; 1452 tilegx_bundle_bits bundle;
1455 struct thread_info *info = current_thread_info(); 1453 struct thread_info *info = current_thread_info();
@@ -1503,7 +1501,7 @@ void do_unaligned(struct pt_regs *regs, int vecnum)
1503 *((tilegx_bundle_bits *)(regs->pc))); 1501 *((tilegx_bundle_bits *)(regs->pc)));
1504 jit_bundle_gen(regs, bundle, align_ctl); 1502 jit_bundle_gen(regs, bundle, align_ctl);
1505 } 1503 }
1506 goto done; 1504 return;
1507 } 1505 }
1508 1506
1509 /* 1507 /*
@@ -1527,7 +1525,7 @@ void do_unaligned(struct pt_regs *regs, int vecnum)
1527 1525
1528 trace_unhandled_signal("unaligned fixup trap", regs, 0, SIGBUS); 1526 trace_unhandled_signal("unaligned fixup trap", regs, 0, SIGBUS);
1529 force_sig_info(info.si_signo, &info, current); 1527 force_sig_info(info.si_signo, &info, current);
1530 goto done; 1528 return;
1531 } 1529 }
1532 1530
1533 1531
@@ -1544,7 +1542,7 @@ void do_unaligned(struct pt_regs *regs, int vecnum)
1544 trace_unhandled_signal("segfault in unalign fixup", regs, 1542 trace_unhandled_signal("segfault in unalign fixup", regs,
1545 (unsigned long)info.si_addr, SIGSEGV); 1543 (unsigned long)info.si_addr, SIGSEGV);
1546 force_sig_info(info.si_signo, &info, current); 1544 force_sig_info(info.si_signo, &info, current);
1547 goto done; 1545 return;
1548 } 1546 }
1549 1547
1550 if (!info->unalign_jit_base) { 1548 if (!info->unalign_jit_base) {
@@ -1579,7 +1577,7 @@ void do_unaligned(struct pt_regs *regs, int vecnum)
1579 1577
1580 if (IS_ERR((void __force *)user_page)) { 1578 if (IS_ERR((void __force *)user_page)) {
1581 pr_err("Out of kernel pages trying do_mmap\n"); 1579 pr_err("Out of kernel pages trying do_mmap\n");
1582 goto done; 1580 return;
1583 } 1581 }
1584 1582
1585 /* Save the address in the thread_info struct */ 1583 /* Save the address in the thread_info struct */
@@ -1592,9 +1590,6 @@ void do_unaligned(struct pt_regs *regs, int vecnum)
1592 1590
1593 /* Generate unalign JIT */ 1591 /* Generate unalign JIT */
1594 jit_bundle_gen(regs, GX_INSN_BSWAP(bundle), align_ctl); 1592 jit_bundle_gen(regs, GX_INSN_BSWAP(bundle), align_ctl);
1595
1596done:
1597 exception_exit(prev_state);
1598} 1593}
1599 1594
1600#endif /* __tilegx__ */ 1595#endif /* __tilegx__ */
diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c
index 13eac59bf16a..26734214818c 100644
--- a/arch/tile/mm/fault.c
+++ b/arch/tile/mm/fault.c
@@ -35,7 +35,6 @@
35#include <linux/syscalls.h> 35#include <linux/syscalls.h>
36#include <linux/uaccess.h> 36#include <linux/uaccess.h>
37#include <linux/kdebug.h> 37#include <linux/kdebug.h>
38#include <linux/context_tracking.h>
39 38
40#include <asm/pgalloc.h> 39#include <asm/pgalloc.h>
41#include <asm/sections.h> 40#include <asm/sections.h>
@@ -845,9 +844,7 @@ static inline void __do_page_fault(struct pt_regs *regs, int fault_num,
845void do_page_fault(struct pt_regs *regs, int fault_num, 844void do_page_fault(struct pt_regs *regs, int fault_num,
846 unsigned long address, unsigned long write) 845 unsigned long address, unsigned long write)
847{ 846{
848 enum ctx_state prev_state = exception_enter();
849 __do_page_fault(regs, fault_num, address, write); 847 __do_page_fault(regs, fault_num, address, write);
850 exception_exit(prev_state);
851} 848}
852 849
853#if CHIP_HAS_TILE_DMA() 850#if CHIP_HAS_TILE_DMA()