diff options
Diffstat (limited to 'arch/sh/kernel/traps_32.c')
-rw-r--r-- | arch/sh/kernel/traps_32.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index 6aba9af79ea..69bb1652ecc 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c | |||
@@ -452,6 +452,12 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs, | |||
452 | u_int rm; | 452 | u_int rm; |
453 | int ret, index; | 453 | int ret, index; |
454 | 454 | ||
455 | /* | ||
456 | * XXX: We can't handle mixed 16/32-bit instructions yet | ||
457 | */ | ||
458 | if (instruction_size(instruction) != 2) | ||
459 | return -EINVAL; | ||
460 | |||
455 | index = (instruction>>8)&15; /* 0x0F00 */ | 461 | index = (instruction>>8)&15; /* 0x0F00 */ |
456 | rm = regs->regs[index]; | 462 | rm = regs->regs[index]; |
457 | 463 | ||
@@ -619,9 +625,9 @@ asmlinkage void do_address_error(struct pt_regs *regs, | |||
619 | 625 | ||
620 | se_user += 1; | 626 | se_user += 1; |
621 | 627 | ||
622 | #ifndef CONFIG_CPU_SH2A | ||
623 | set_fs(USER_DS); | 628 | set_fs(USER_DS); |
624 | if (copy_from_user(&instruction, (u16 *)(regs->pc & ~1), 2)) { | 629 | if (copy_from_user(&instruction, (insn_size_t *)(regs->pc & ~1), |
630 | sizeof(instruction))) { | ||
625 | set_fs(oldfs); | 631 | set_fs(oldfs); |
626 | goto uspace_segv; | 632 | goto uspace_segv; |
627 | } | 633 | } |
@@ -633,7 +639,6 @@ asmlinkage void do_address_error(struct pt_regs *regs, | |||
633 | "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", | 639 | "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", |
634 | current->comm, current->pid, (void *)regs->pc, | 640 | current->comm, current->pid, (void *)regs->pc, |
635 | instruction); | 641 | instruction); |
636 | #endif | ||
637 | 642 | ||
638 | if (se_usermode & 2) | 643 | if (se_usermode & 2) |
639 | goto fixup; | 644 | goto fixup; |
@@ -673,12 +678,6 @@ uspace_segv: | |||
673 | } else { | 678 | } else { |
674 | se_sys += 1; | 679 | se_sys += 1; |
675 | 680 | ||
676 | if (se_kernmode_warn) | ||
677 | printk(KERN_NOTICE "Unaligned kernel access " | ||
678 | "on behalf of \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", | ||
679 | current->comm, current->pid, (void *)regs->pc, | ||
680 | instruction); | ||
681 | |||
682 | if (regs->pc & 1) | 681 | if (regs->pc & 1) |
683 | die("unaligned program counter", regs, error_code); | 682 | die("unaligned program counter", regs, error_code); |
684 | 683 | ||
@@ -692,6 +691,12 @@ uspace_segv: | |||
692 | die("insn faulting in do_address_error", regs, 0); | 691 | die("insn faulting in do_address_error", regs, 0); |
693 | } | 692 | } |
694 | 693 | ||
694 | if (se_kernmode_warn) | ||
695 | printk(KERN_NOTICE "Unaligned kernel access " | ||
696 | "on behalf of \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", | ||
697 | current->comm, current->pid, (void *)regs->pc, | ||
698 | instruction); | ||
699 | |||
695 | handle_unaligned_access(instruction, regs, | 700 | handle_unaligned_access(instruction, regs, |
696 | &user_mem_access, 0); | 701 | &user_mem_access, 0); |
697 | set_fs(oldfs); | 702 | set_fs(oldfs); |