diff options
Diffstat (limited to 'arch/parisc/kernel')
-rw-r--r-- | arch/parisc/kernel/sys_parisc.c | 6 | ||||
-rw-r--r-- | arch/parisc/kernel/syscall.S | 12 | ||||
-rw-r--r-- | arch/parisc/kernel/syscall_table.S | 1 | ||||
-rw-r--r-- | arch/parisc/kernel/traps.c | 54 |
4 files changed, 38 insertions, 35 deletions
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 31ffa9b55322..e1ffea2f9a0b 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c | |||
@@ -72,10 +72,10 @@ static unsigned long mmap_upper_limit(void) | |||
72 | { | 72 | { |
73 | unsigned long stack_base; | 73 | unsigned long stack_base; |
74 | 74 | ||
75 | /* Limit stack size to 1GB - see setup_arg_pages() in fs/exec.c */ | 75 | /* Limit stack size - see setup_arg_pages() in fs/exec.c */ |
76 | stack_base = rlimit_max(RLIMIT_STACK); | 76 | stack_base = rlimit_max(RLIMIT_STACK); |
77 | if (stack_base > (1 << 30)) | 77 | if (stack_base > STACK_SIZE_MAX) |
78 | stack_base = 1 << 30; | 78 | stack_base = STACK_SIZE_MAX; |
79 | 79 | ||
80 | return PAGE_ALIGN(STACK_TOP - stack_base); | 80 | return PAGE_ALIGN(STACK_TOP - stack_base); |
81 | } | 81 | } |
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index a63bb179f79a..838786011037 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S | |||
@@ -589,10 +589,13 @@ cas_nocontend: | |||
589 | # endif | 589 | # endif |
590 | /* ENABLE_LWS_DEBUG */ | 590 | /* ENABLE_LWS_DEBUG */ |
591 | 591 | ||
592 | rsm PSW_SM_I, %r0 /* Disable interrupts */ | ||
593 | /* COW breaks can cause contention on UP systems */ | ||
592 | LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */ | 594 | LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */ |
593 | cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */ | 595 | cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */ |
594 | cas_wouldblock: | 596 | cas_wouldblock: |
595 | ldo 2(%r0), %r28 /* 2nd case */ | 597 | ldo 2(%r0), %r28 /* 2nd case */ |
598 | ssm PSW_SM_I, %r0 | ||
596 | b lws_exit /* Contended... */ | 599 | b lws_exit /* Contended... */ |
597 | ldo -EAGAIN(%r0), %r21 /* Spin in userspace */ | 600 | ldo -EAGAIN(%r0), %r21 /* Spin in userspace */ |
598 | 601 | ||
@@ -619,15 +622,17 @@ cas_action: | |||
619 | stw %r1, 4(%sr2,%r20) | 622 | stw %r1, 4(%sr2,%r20) |
620 | #endif | 623 | #endif |
621 | /* The load and store could fail */ | 624 | /* The load and store could fail */ |
622 | 1: ldw 0(%sr3,%r26), %r28 | 625 | 1: ldw,ma 0(%sr3,%r26), %r28 |
623 | sub,<> %r28, %r25, %r0 | 626 | sub,<> %r28, %r25, %r0 |
624 | 2: stw %r24, 0(%sr3,%r26) | 627 | 2: stw,ma %r24, 0(%sr3,%r26) |
625 | /* Free lock */ | 628 | /* Free lock */ |
626 | stw %r20, 0(%sr2,%r20) | 629 | stw,ma %r20, 0(%sr2,%r20) |
627 | #if ENABLE_LWS_DEBUG | 630 | #if ENABLE_LWS_DEBUG |
628 | /* Clear thread register indicator */ | 631 | /* Clear thread register indicator */ |
629 | stw %r0, 4(%sr2,%r20) | 632 | stw %r0, 4(%sr2,%r20) |
630 | #endif | 633 | #endif |
634 | /* Enable interrupts */ | ||
635 | ssm PSW_SM_I, %r0 | ||
631 | /* Return to userspace, set no error */ | 636 | /* Return to userspace, set no error */ |
632 | b lws_exit | 637 | b lws_exit |
633 | copy %r0, %r21 | 638 | copy %r0, %r21 |
@@ -639,6 +644,7 @@ cas_action: | |||
639 | #if ENABLE_LWS_DEBUG | 644 | #if ENABLE_LWS_DEBUG |
640 | stw %r0, 4(%sr2,%r20) | 645 | stw %r0, 4(%sr2,%r20) |
641 | #endif | 646 | #endif |
647 | ssm PSW_SM_I, %r0 | ||
642 | b lws_exit | 648 | b lws_exit |
643 | ldo -EFAULT(%r0),%r21 /* set errno */ | 649 | ldo -EFAULT(%r0),%r21 /* set errno */ |
644 | nop | 650 | nop |
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 83ead0ea127d..f1432da7b4c0 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S | |||
@@ -432,6 +432,7 @@ | |||
432 | ENTRY_SAME(sched_setattr) | 432 | ENTRY_SAME(sched_setattr) |
433 | ENTRY_SAME(sched_getattr) /* 335 */ | 433 | ENTRY_SAME(sched_getattr) /* 335 */ |
434 | ENTRY_COMP(utimes) | 434 | ENTRY_COMP(utimes) |
435 | ENTRY_COMP(renameat2) | ||
435 | 436 | ||
436 | /* Nothing yet */ | 437 | /* Nothing yet */ |
437 | 438 | ||
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 1cd1d0c83b6d..47ee620d15d2 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/console.h> | 26 | #include <linux/console.h> |
27 | #include <linux/bug.h> | 27 | #include <linux/bug.h> |
28 | #include <linux/ratelimit.h> | ||
28 | 29 | ||
29 | #include <asm/assembly.h> | 30 | #include <asm/assembly.h> |
30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
@@ -42,9 +43,6 @@ | |||
42 | 43 | ||
43 | #include "../math-emu/math-emu.h" /* for handle_fpe() */ | 44 | #include "../math-emu/math-emu.h" /* for handle_fpe() */ |
44 | 45 | ||
45 | #define PRINT_USER_FAULTS /* (turn this on if you want user faults to be */ | ||
46 | /* dumped to the console via printk) */ | ||
47 | |||
48 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) | 46 | #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) |
49 | DEFINE_SPINLOCK(pa_dbit_lock); | 47 | DEFINE_SPINLOCK(pa_dbit_lock); |
50 | #endif | 48 | #endif |
@@ -160,6 +158,17 @@ void show_regs(struct pt_regs *regs) | |||
160 | } | 158 | } |
161 | } | 159 | } |
162 | 160 | ||
161 | static DEFINE_RATELIMIT_STATE(_hppa_rs, | ||
162 | DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST); | ||
163 | |||
164 | #define parisc_printk_ratelimited(critical, regs, fmt, ...) { \ | ||
165 | if ((critical || show_unhandled_signals) && __ratelimit(&_hppa_rs)) { \ | ||
166 | printk(fmt, ##__VA_ARGS__); \ | ||
167 | show_regs(regs); \ | ||
168 | } \ | ||
169 | } | ||
170 | |||
171 | |||
163 | static void do_show_stack(struct unwind_frame_info *info) | 172 | static void do_show_stack(struct unwind_frame_info *info) |
164 | { | 173 | { |
165 | int i = 1; | 174 | int i = 1; |
@@ -229,12 +238,10 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err) | |||
229 | if (err == 0) | 238 | if (err == 0) |
230 | return; /* STFU */ | 239 | return; /* STFU */ |
231 | 240 | ||
232 | printk(KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n", | 241 | parisc_printk_ratelimited(1, regs, |
242 | KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n", | ||
233 | current->comm, task_pid_nr(current), str, err, regs->iaoq[0]); | 243 | current->comm, task_pid_nr(current), str, err, regs->iaoq[0]); |
234 | #ifdef PRINT_USER_FAULTS | 244 | |
235 | /* XXX for debugging only */ | ||
236 | show_regs(regs); | ||
237 | #endif | ||
238 | return; | 245 | return; |
239 | } | 246 | } |
240 | 247 | ||
@@ -321,14 +328,11 @@ static void handle_break(struct pt_regs *regs) | |||
321 | (tt == BUG_TRAP_TYPE_NONE) ? 9 : 0); | 328 | (tt == BUG_TRAP_TYPE_NONE) ? 9 : 0); |
322 | } | 329 | } |
323 | 330 | ||
324 | #ifdef PRINT_USER_FAULTS | 331 | if (unlikely(iir != GDB_BREAK_INSN)) |
325 | if (unlikely(iir != GDB_BREAK_INSN)) { | 332 | parisc_printk_ratelimited(0, regs, |
326 | printk(KERN_DEBUG "break %d,%d: pid=%d command='%s'\n", | 333 | KERN_DEBUG "break %d,%d: pid=%d command='%s'\n", |
327 | iir & 31, (iir>>13) & ((1<<13)-1), | 334 | iir & 31, (iir>>13) & ((1<<13)-1), |
328 | task_pid_nr(current), current->comm); | 335 | task_pid_nr(current), current->comm); |
329 | show_regs(regs); | ||
330 | } | ||
331 | #endif | ||
332 | 336 | ||
333 | /* send standard GDB signal */ | 337 | /* send standard GDB signal */ |
334 | handle_gdb_break(regs, TRAP_BRKPT); | 338 | handle_gdb_break(regs, TRAP_BRKPT); |
@@ -758,11 +762,9 @@ void notrace handle_interruption(int code, struct pt_regs *regs) | |||
758 | 762 | ||
759 | default: | 763 | default: |
760 | if (user_mode(regs)) { | 764 | if (user_mode(regs)) { |
761 | #ifdef PRINT_USER_FAULTS | 765 | parisc_printk_ratelimited(0, regs, KERN_DEBUG |
762 | printk(KERN_DEBUG "\nhandle_interruption() pid=%d command='%s'\n", | 766 | "handle_interruption() pid=%d command='%s'\n", |
763 | task_pid_nr(current), current->comm); | 767 | task_pid_nr(current), current->comm); |
764 | show_regs(regs); | ||
765 | #endif | ||
766 | /* SIGBUS, for lack of a better one. */ | 768 | /* SIGBUS, for lack of a better one. */ |
767 | si.si_signo = SIGBUS; | 769 | si.si_signo = SIGBUS; |
768 | si.si_code = BUS_OBJERR; | 770 | si.si_code = BUS_OBJERR; |
@@ -779,16 +781,10 @@ void notrace handle_interruption(int code, struct pt_regs *regs) | |||
779 | 781 | ||
780 | if (user_mode(regs)) { | 782 | if (user_mode(regs)) { |
781 | if ((fault_space >> SPACEID_SHIFT) != (regs->sr[7] >> SPACEID_SHIFT)) { | 783 | if ((fault_space >> SPACEID_SHIFT) != (regs->sr[7] >> SPACEID_SHIFT)) { |
782 | #ifdef PRINT_USER_FAULTS | 784 | parisc_printk_ratelimited(0, regs, KERN_DEBUG |
783 | if (fault_space == 0) | 785 | "User fault %d on space 0x%08lx, pid=%d command='%s'\n", |
784 | printk(KERN_DEBUG "User Fault on Kernel Space "); | 786 | code, fault_space, |
785 | else | 787 | task_pid_nr(current), current->comm); |
786 | printk(KERN_DEBUG "User Fault (long pointer) (fault %d) ", | ||
787 | code); | ||
788 | printk(KERN_CONT "pid=%d command='%s'\n", | ||
789 | task_pid_nr(current), current->comm); | ||
790 | show_regs(regs); | ||
791 | #endif | ||
792 | si.si_signo = SIGSEGV; | 788 | si.si_signo = SIGSEGV; |
793 | si.si_errno = 0; | 789 | si.si_errno = 0; |
794 | si.si_code = SEGV_MAPERR; | 790 | si.si_code = SEGV_MAPERR; |