diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-26 20:15:49 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-26 20:15:49 -0400 |
commit | a45dcff7489f7cb21a3a8e967a90ea41b31c1559 (patch) | |
tree | a84c7891cdea55d7f1058059fd8882f3545f73be /arch/sparc | |
parent | cc10ad25bbca3d2925adc32d51cb7a10b837d32c (diff) | |
parent | 6c2fc9cddc1ffdef8ada1dc8404e5affae849953 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Pull sparc fixes from David Miller:
"Some more sparc fixups, mostly aimed at getting the allmodconfig build
up and clean again"
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc:
sparc64: Rework xchg() definition to avoid warnings.
sparc64: Export __node_distance.
sparc64: Make corrupted user stacks more debuggable.
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/include/asm/cmpxchg_64.h | 7 | ||||
-rw-r--r-- | arch/sparc/include/asm/switch_to_64.h | 3 | ||||
-rw-r--r-- | arch/sparc/kernel/process_64.c | 25 | ||||
-rw-r--r-- | arch/sparc/kernel/rtrap_64.S | 1 | ||||
-rw-r--r-- | arch/sparc/kernel/signal32.c | 12 | ||||
-rw-r--r-- | arch/sparc/kernel/signal_64.c | 6 | ||||
-rw-r--r-- | arch/sparc/mm/init_64.c | 1 |
7 files changed, 44 insertions, 11 deletions
diff --git a/arch/sparc/include/asm/cmpxchg_64.h b/arch/sparc/include/asm/cmpxchg_64.h index f71ef3729888..316faa0130ba 100644 --- a/arch/sparc/include/asm/cmpxchg_64.h +++ b/arch/sparc/include/asm/cmpxchg_64.h | |||
@@ -52,7 +52,12 @@ static inline unsigned long xchg64(__volatile__ unsigned long *m, unsigned long | |||
52 | return val; | 52 | return val; |
53 | } | 53 | } |
54 | 54 | ||
55 | #define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) | 55 | #define xchg(ptr,x) \ |
56 | ({ __typeof__(*(ptr)) __ret; \ | ||
57 | __ret = (__typeof__(*(ptr))) \ | ||
58 | __xchg((unsigned long)(x), (ptr), sizeof(*(ptr))); \ | ||
59 | __ret; \ | ||
60 | }) | ||
56 | 61 | ||
57 | void __xchg_called_with_bad_pointer(void); | 62 | void __xchg_called_with_bad_pointer(void); |
58 | 63 | ||
diff --git a/arch/sparc/include/asm/switch_to_64.h b/arch/sparc/include/asm/switch_to_64.h index 4ff29b1406a9..b1d4e2e3210f 100644 --- a/arch/sparc/include/asm/switch_to_64.h +++ b/arch/sparc/include/asm/switch_to_64.h | |||
@@ -67,6 +67,7 @@ do { save_and_clear_fpu(); \ | |||
67 | } while(0) | 67 | } while(0) |
68 | 68 | ||
69 | void synchronize_user_stack(void); | 69 | void synchronize_user_stack(void); |
70 | void fault_in_user_windows(void); | 70 | struct pt_regs; |
71 | void fault_in_user_windows(struct pt_regs *); | ||
71 | 72 | ||
72 | #endif /* __SPARC64_SWITCH_TO_64_H */ | 73 | #endif /* __SPARC64_SWITCH_TO_64_H */ |
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index 6c086086ca8f..59eaf6227af1 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/sysrq.h> | 36 | #include <linux/sysrq.h> |
37 | #include <linux/nmi.h> | 37 | #include <linux/nmi.h> |
38 | #include <linux/context_tracking.h> | 38 | #include <linux/context_tracking.h> |
39 | #include <linux/signal.h> | ||
39 | 40 | ||
40 | #include <linux/uaccess.h> | 41 | #include <linux/uaccess.h> |
41 | #include <asm/page.h> | 42 | #include <asm/page.h> |
@@ -521,7 +522,12 @@ static void stack_unaligned(unsigned long sp) | |||
521 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *) sp, 0, current); | 522 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *) sp, 0, current); |
522 | } | 523 | } |
523 | 524 | ||
524 | void fault_in_user_windows(void) | 525 | static const char uwfault32[] = KERN_INFO \ |
526 | "%s[%d]: bad register window fault: SP %08lx (orig_sp %08lx) TPC %08lx O7 %08lx\n"; | ||
527 | static const char uwfault64[] = KERN_INFO \ | ||
528 | "%s[%d]: bad register window fault: SP %016lx (orig_sp %016lx) TPC %08lx O7 %016lx\n"; | ||
529 | |||
530 | void fault_in_user_windows(struct pt_regs *regs) | ||
525 | { | 531 | { |
526 | struct thread_info *t = current_thread_info(); | 532 | struct thread_info *t = current_thread_info(); |
527 | unsigned long window; | 533 | unsigned long window; |
@@ -534,9 +540,9 @@ void fault_in_user_windows(void) | |||
534 | do { | 540 | do { |
535 | struct reg_window *rwin = &t->reg_window[window]; | 541 | struct reg_window *rwin = &t->reg_window[window]; |
536 | int winsize = sizeof(struct reg_window); | 542 | int winsize = sizeof(struct reg_window); |
537 | unsigned long sp; | 543 | unsigned long sp, orig_sp; |
538 | 544 | ||
539 | sp = t->rwbuf_stkptrs[window]; | 545 | orig_sp = sp = t->rwbuf_stkptrs[window]; |
540 | 546 | ||
541 | if (test_thread_64bit_stack(sp)) | 547 | if (test_thread_64bit_stack(sp)) |
542 | sp += STACK_BIAS; | 548 | sp += STACK_BIAS; |
@@ -547,8 +553,16 @@ void fault_in_user_windows(void) | |||
547 | stack_unaligned(sp); | 553 | stack_unaligned(sp); |
548 | 554 | ||
549 | if (unlikely(copy_to_user((char __user *)sp, | 555 | if (unlikely(copy_to_user((char __user *)sp, |
550 | rwin, winsize))) | 556 | rwin, winsize))) { |
557 | if (show_unhandled_signals) | ||
558 | printk_ratelimited(is_compat_task() ? | ||
559 | uwfault32 : uwfault64, | ||
560 | current->comm, current->pid, | ||
561 | sp, orig_sp, | ||
562 | regs->tpc, | ||
563 | regs->u_regs[UREG_I7]); | ||
551 | goto barf; | 564 | goto barf; |
565 | } | ||
552 | } while (window--); | 566 | } while (window--); |
553 | } | 567 | } |
554 | set_thread_wsaved(0); | 568 | set_thread_wsaved(0); |
@@ -556,8 +570,7 @@ void fault_in_user_windows(void) | |||
556 | 570 | ||
557 | barf: | 571 | barf: |
558 | set_thread_wsaved(window + 1); | 572 | set_thread_wsaved(window + 1); |
559 | user_exit(); | 573 | force_sig(SIGSEGV, current); |
560 | do_exit(SIGILL); | ||
561 | } | 574 | } |
562 | 575 | ||
563 | asmlinkage long sparc_do_fork(unsigned long clone_flags, | 576 | asmlinkage long sparc_do_fork(unsigned long clone_flags, |
diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S index 4073e2b87dd0..29aa34f11720 100644 --- a/arch/sparc/kernel/rtrap_64.S +++ b/arch/sparc/kernel/rtrap_64.S | |||
@@ -39,6 +39,7 @@ __handle_preemption: | |||
39 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate | 39 | wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate |
40 | 40 | ||
41 | __handle_user_windows: | 41 | __handle_user_windows: |
42 | add %sp, PTREGS_OFF, %o0 | ||
42 | call fault_in_user_windows | 43 | call fault_in_user_windows |
43 | 661: wrpr %g0, RTRAP_PSTATE, %pstate | 44 | 661: wrpr %g0, RTRAP_PSTATE, %pstate |
44 | /* If userspace is using ADI, it could potentially pass | 45 | /* If userspace is using ADI, it could potentially pass |
diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index 44d379db3f64..4c5b3fcbed94 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c | |||
@@ -371,7 +371,11 @@ static int setup_frame32(struct ksignal *ksig, struct pt_regs *regs, | |||
371 | get_sigframe(ksig, regs, sigframe_size); | 371 | get_sigframe(ksig, regs, sigframe_size); |
372 | 372 | ||
373 | if (invalid_frame_pointer(sf, sigframe_size)) { | 373 | if (invalid_frame_pointer(sf, sigframe_size)) { |
374 | do_exit(SIGILL); | 374 | if (show_unhandled_signals) |
375 | pr_info("%s[%d] bad frame in setup_frame32: %08lx TPC %08lx O7 %08lx\n", | ||
376 | current->comm, current->pid, (unsigned long)sf, | ||
377 | regs->tpc, regs->u_regs[UREG_I7]); | ||
378 | force_sigsegv(ksig->sig, current); | ||
375 | return -EINVAL; | 379 | return -EINVAL; |
376 | } | 380 | } |
377 | 381 | ||
@@ -501,7 +505,11 @@ static int setup_rt_frame32(struct ksignal *ksig, struct pt_regs *regs, | |||
501 | get_sigframe(ksig, regs, sigframe_size); | 505 | get_sigframe(ksig, regs, sigframe_size); |
502 | 506 | ||
503 | if (invalid_frame_pointer(sf, sigframe_size)) { | 507 | if (invalid_frame_pointer(sf, sigframe_size)) { |
504 | do_exit(SIGILL); | 508 | if (show_unhandled_signals) |
509 | pr_info("%s[%d] bad frame in setup_rt_frame32: %08lx TPC %08lx O7 %08lx\n", | ||
510 | current->comm, current->pid, (unsigned long)sf, | ||
511 | regs->tpc, regs->u_regs[UREG_I7]); | ||
512 | force_sigsegv(ksig->sig, current); | ||
505 | return -EINVAL; | 513 | return -EINVAL; |
506 | } | 514 | } |
507 | 515 | ||
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index 48366e5eb5b2..e9de1803a22e 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c | |||
@@ -370,7 +370,11 @@ setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs) | |||
370 | get_sigframe(ksig, regs, sf_size); | 370 | get_sigframe(ksig, regs, sf_size); |
371 | 371 | ||
372 | if (invalid_frame_pointer (sf)) { | 372 | if (invalid_frame_pointer (sf)) { |
373 | do_exit(SIGILL); /* won't return, actually */ | 373 | if (show_unhandled_signals) |
374 | pr_info("%s[%d] bad frame in setup_rt_frame: %016lx TPC %016lx O7 %016lx\n", | ||
375 | current->comm, current->pid, (unsigned long)sf, | ||
376 | regs->tpc, regs->u_regs[UREG_I7]); | ||
377 | force_sigsegv(ksig->sig, current); | ||
374 | return -EINVAL; | 378 | return -EINVAL; |
375 | } | 379 | } |
376 | 380 | ||
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index f396048a0d68..39822f611c01 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c | |||
@@ -1383,6 +1383,7 @@ int __node_distance(int from, int to) | |||
1383 | } | 1383 | } |
1384 | return numa_latency[from][to]; | 1384 | return numa_latency[from][to]; |
1385 | } | 1385 | } |
1386 | EXPORT_SYMBOL(__node_distance); | ||
1386 | 1387 | ||
1387 | static int __init find_best_numa_node_for_mlgroup(struct mdesc_mlgroup *grp) | 1388 | static int __init find_best_numa_node_for_mlgroup(struct mdesc_mlgroup *grp) |
1388 | { | 1389 | { |