diff options
Diffstat (limited to 'arch/sh/kernel/traps_32.c')
-rw-r--r-- | arch/sh/kernel/traps_32.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index 6aba9af79eaf..f9760c5c234a 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; |