diff options
| -rw-r--r-- | arch/parisc/kernel/unaligned.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c index d7c0acb35ec2..8d49614d600d 100644 --- a/arch/parisc/kernel/unaligned.c +++ b/arch/parisc/kernel/unaligned.c | |||
| @@ -666,7 +666,7 @@ void handle_unaligned(struct pt_regs *regs) | |||
| 666 | break; | 666 | break; |
| 667 | } | 667 | } |
| 668 | 668 | ||
| 669 | if (modify && R1(regs->iir)) | 669 | if (ret == 0 && modify && R1(regs->iir)) |
| 670 | regs->gr[R1(regs->iir)] = newbase; | 670 | regs->gr[R1(regs->iir)] = newbase; |
| 671 | 671 | ||
| 672 | 672 | ||
| @@ -677,6 +677,14 @@ void handle_unaligned(struct pt_regs *regs) | |||
| 677 | 677 | ||
| 678 | if (ret) | 678 | if (ret) |
| 679 | { | 679 | { |
| 680 | /* | ||
| 681 | * The unaligned handler failed. | ||
| 682 | * If we were called by __get_user() or __put_user() jump | ||
| 683 | * to it's exception fixup handler instead of crashing. | ||
| 684 | */ | ||
| 685 | if (!user_mode(regs) && fixup_exception(regs)) | ||
| 686 | return; | ||
| 687 | |||
| 680 | printk(KERN_CRIT "Unaligned handler failed, ret = %d\n", ret); | 688 | printk(KERN_CRIT "Unaligned handler failed, ret = %d\n", ret); |
| 681 | die_if_kernel("Unaligned data reference", regs, 28); | 689 | die_if_kernel("Unaligned data reference", regs, 28); |
| 682 | 690 | ||
