diff options
Diffstat (limited to 'arch/sparc/mm/fault_32.c')
-rw-r--r-- | arch/sparc/mm/fault_32.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/arch/sparc/mm/fault_32.c b/arch/sparc/mm/fault_32.c index bd8601601afa..7543ddbdadb2 100644 --- a/arch/sparc/mm/fault_32.c +++ b/arch/sparc/mm/fault_32.c | |||
@@ -135,7 +135,7 @@ asmlinkage int lookup_fault(unsigned long pc, unsigned long ret_pc, | |||
135 | 135 | ||
136 | default: | 136 | default: |
137 | break; | 137 | break; |
138 | }; | 138 | } |
139 | 139 | ||
140 | memset(®s, 0, sizeof (regs)); | 140 | memset(®s, 0, sizeof (regs)); |
141 | regs.pc = pc; | 141 | regs.pc = pc; |
@@ -240,11 +240,10 @@ asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, | |||
240 | * only copy the information from the master page table, | 240 | * only copy the information from the master page table, |
241 | * nothing more. | 241 | * nothing more. |
242 | */ | 242 | */ |
243 | code = SEGV_MAPERR; | ||
243 | if (!ARCH_SUN4C && address >= TASK_SIZE) | 244 | if (!ARCH_SUN4C && address >= TASK_SIZE) |
244 | goto vmalloc_fault; | 245 | goto vmalloc_fault; |
245 | 246 | ||
246 | code = SEGV_MAPERR; | ||
247 | |||
248 | /* | 247 | /* |
249 | * If we're in an interrupt or have no user | 248 | * If we're in an interrupt or have no user |
250 | * context, we must not take the fault.. | 249 | * context, we must not take the fault.. |
@@ -539,6 +538,12 @@ do_sigbus: | |||
539 | __do_fault_siginfo(BUS_ADRERR, SIGBUS, tsk->thread.kregs, address); | 538 | __do_fault_siginfo(BUS_ADRERR, SIGBUS, tsk->thread.kregs, address); |
540 | } | 539 | } |
541 | 540 | ||
541 | static void check_stack_aligned(unsigned long sp) | ||
542 | { | ||
543 | if (sp & 0x7UL) | ||
544 | force_sig(SIGILL, current); | ||
545 | } | ||
546 | |||
542 | void window_overflow_fault(void) | 547 | void window_overflow_fault(void) |
543 | { | 548 | { |
544 | unsigned long sp; | 549 | unsigned long sp; |
@@ -547,6 +552,8 @@ void window_overflow_fault(void) | |||
547 | if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) | 552 | if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) |
548 | force_user_fault(sp + 0x38, 1); | 553 | force_user_fault(sp + 0x38, 1); |
549 | force_user_fault(sp, 1); | 554 | force_user_fault(sp, 1); |
555 | |||
556 | check_stack_aligned(sp); | ||
550 | } | 557 | } |
551 | 558 | ||
552 | void window_underflow_fault(unsigned long sp) | 559 | void window_underflow_fault(unsigned long sp) |
@@ -554,6 +561,8 @@ void window_underflow_fault(unsigned long sp) | |||
554 | if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) | 561 | if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) |
555 | force_user_fault(sp + 0x38, 0); | 562 | force_user_fault(sp + 0x38, 0); |
556 | force_user_fault(sp, 0); | 563 | force_user_fault(sp, 0); |
564 | |||
565 | check_stack_aligned(sp); | ||
557 | } | 566 | } |
558 | 567 | ||
559 | void window_ret_fault(struct pt_regs *regs) | 568 | void window_ret_fault(struct pt_regs *regs) |
@@ -564,4 +573,6 @@ void window_ret_fault(struct pt_regs *regs) | |||
564 | if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) | 573 | if(((sp + 0x38) & PAGE_MASK) != (sp & PAGE_MASK)) |
565 | force_user_fault(sp + 0x38, 0); | 574 | force_user_fault(sp + 0x38, 0); |
566 | force_user_fault(sp, 0); | 575 | force_user_fault(sp, 0); |
576 | |||
577 | check_stack_aligned(sp); | ||
567 | } | 578 | } |