diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-05-08 07:32:56 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-05-08 07:32:56 -0400 |
commit | c29418c2ae15ee9171bc136ad261c497b95a46fc (patch) | |
tree | 909d43d394baa1f2a01bf79b747a10ad57732789 /arch/sh/kernel/traps_64.c | |
parent | 30d88cf52f229c3e0c90b8d71036960ccc2db4e2 (diff) |
sh: Always fixup unaligned userspace accesses on sh64.
sh64 has traditionally had this configurable via a Kconfig option
(CONFIG_SH64_USER_MISALIGNED_FIXUP). In practice it has never really been
terribly useful to turn this off, so just get rid of the option entirely.
We leave the sysctl around so we don't end up breaking existing root
file systems, and to allow folks that really want this off to do so at
their own risk.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/kernel/traps_64.c')
-rw-r--r-- | arch/sh/kernel/traps_64.c | 35 |
1 files changed, 5 insertions, 30 deletions
diff --git a/arch/sh/kernel/traps_64.c b/arch/sh/kernel/traps_64.c index a85831cbf18b..267e5ebbb475 100644 --- a/arch/sh/kernel/traps_64.c +++ b/arch/sh/kernel/traps_64.c | |||
@@ -370,7 +370,6 @@ static int generate_and_check_address(struct pt_regs *regs, | |||
370 | return -1; | 370 | return -1; |
371 | } | 371 | } |
372 | 372 | ||
373 | #if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP) | ||
374 | /* Check accessible. For misaligned access in the kernel, assume the | 373 | /* Check accessible. For misaligned access in the kernel, assume the |
375 | address is always accessible (and if not, just fault when the | 374 | address is always accessible (and if not, just fault when the |
376 | load/store gets done.) */ | 375 | load/store gets done.) */ |
@@ -380,18 +379,13 @@ static int generate_and_check_address(struct pt_regs *regs, | |||
380 | } | 379 | } |
381 | /* Do access_ok check later - it depends on whether it's a load or a store. */ | 380 | /* Do access_ok check later - it depends on whether it's a load or a store. */ |
382 | } | 381 | } |
383 | #endif | ||
384 | 382 | ||
385 | *address = addr; | 383 | *address = addr; |
386 | return 0; | 384 | return 0; |
387 | } | 385 | } |
388 | 386 | ||
389 | /* Default value as for sh */ | ||
390 | #if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP) | ||
391 | static int user_mode_unaligned_fixup_count = 10; | 387 | static int user_mode_unaligned_fixup_count = 10; |
392 | static int user_mode_unaligned_fixup_enable = 1; | 388 | static int user_mode_unaligned_fixup_enable = 1; |
393 | #endif | ||
394 | |||
395 | static int kernel_mode_unaligned_fixup_count = 32; | 389 | static int kernel_mode_unaligned_fixup_count = 32; |
396 | 390 | ||
397 | static void misaligned_kernel_word_load(__u64 address, int do_sign_extend, __u64 *result) | 391 | static void misaligned_kernel_word_load(__u64 address, int do_sign_extend, __u64 *result) |
@@ -440,7 +434,6 @@ static int misaligned_load(struct pt_regs *regs, | |||
440 | } | 434 | } |
441 | 435 | ||
442 | destreg = (opcode >> 4) & 0x3f; | 436 | destreg = (opcode >> 4) & 0x3f; |
443 | #if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP) | ||
444 | if (user_mode(regs)) { | 437 | if (user_mode(regs)) { |
445 | __u64 buffer; | 438 | __u64 buffer; |
446 | 439 | ||
@@ -470,9 +463,7 @@ static int misaligned_load(struct pt_regs *regs, | |||
470 | width_shift, (unsigned long) regs->pc); | 463 | width_shift, (unsigned long) regs->pc); |
471 | break; | 464 | break; |
472 | } | 465 | } |
473 | } else | 466 | } else { |
474 | #endif | ||
475 | { | ||
476 | /* kernel mode - we can take short cuts since if we fault, it's a genuine bug */ | 467 | /* kernel mode - we can take short cuts since if we fault, it's a genuine bug */ |
477 | __u64 lo, hi; | 468 | __u64 lo, hi; |
478 | 469 | ||
@@ -519,7 +510,6 @@ static int misaligned_store(struct pt_regs *regs, | |||
519 | } | 510 | } |
520 | 511 | ||
521 | srcreg = (opcode >> 4) & 0x3f; | 512 | srcreg = (opcode >> 4) & 0x3f; |
522 | #if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP) | ||
523 | if (user_mode(regs)) { | 513 | if (user_mode(regs)) { |
524 | __u64 buffer; | 514 | __u64 buffer; |
525 | 515 | ||
@@ -546,9 +536,7 @@ static int misaligned_store(struct pt_regs *regs, | |||
546 | if (__copy_user((void *)(int)address, &buffer, (1 << width_shift)) > 0) { | 536 | if (__copy_user((void *)(int)address, &buffer, (1 << width_shift)) > 0) { |
547 | return -1; /* fault */ | 537 | return -1; /* fault */ |
548 | } | 538 | } |
549 | } else | 539 | } else { |
550 | #endif | ||
551 | { | ||
552 | /* kernel mode - we can take short cuts since if we fault, it's a genuine bug */ | 540 | /* kernel mode - we can take short cuts since if we fault, it's a genuine bug */ |
553 | __u64 val = regs->regs[srcreg]; | 541 | __u64 val = regs->regs[srcreg]; |
554 | 542 | ||
@@ -576,7 +564,6 @@ static int misaligned_store(struct pt_regs *regs, | |||
576 | 564 | ||
577 | } | 565 | } |
578 | 566 | ||
579 | #if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP) | ||
580 | /* Never need to fix up misaligned FPU accesses within the kernel since that's a real | 567 | /* Never need to fix up misaligned FPU accesses within the kernel since that's a real |
581 | error. */ | 568 | error. */ |
582 | static int misaligned_fpu_load(struct pt_regs *regs, | 569 | static int misaligned_fpu_load(struct pt_regs *regs, |
@@ -727,7 +714,6 @@ static int misaligned_fpu_store(struct pt_regs *regs, | |||
727 | return -1; | 714 | return -1; |
728 | } | 715 | } |
729 | } | 716 | } |
730 | #endif | ||
731 | 717 | ||
732 | static int misaligned_fixup(struct pt_regs *regs) | 718 | static int misaligned_fixup(struct pt_regs *regs) |
733 | { | 719 | { |
@@ -735,12 +721,8 @@ static int misaligned_fixup(struct pt_regs *regs) | |||
735 | int error; | 721 | int error; |
736 | int major, minor; | 722 | int major, minor; |
737 | 723 | ||
738 | #if !defined(CONFIG_SH64_USER_MISALIGNED_FIXUP) | 724 | if (!user_mode_unaligned_fixup_enable) |
739 | /* Never fixup user mode misaligned accesses without this option enabled. */ | 725 | return -1; |
740 | return -1; | ||
741 | #else | ||
742 | if (!user_mode_unaligned_fixup_enable) return -1; | ||
743 | #endif | ||
744 | 726 | ||
745 | error = read_opcode(regs->pc, &opcode, user_mode(regs)); | 727 | error = read_opcode(regs->pc, &opcode, user_mode(regs)); |
746 | if (error < 0) { | 728 | if (error < 0) { |
@@ -749,15 +731,12 @@ static int misaligned_fixup(struct pt_regs *regs) | |||
749 | major = (opcode >> 26) & 0x3f; | 731 | major = (opcode >> 26) & 0x3f; |
750 | minor = (opcode >> 16) & 0xf; | 732 | minor = (opcode >> 16) & 0xf; |
751 | 733 | ||
752 | #if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP) | ||
753 | if (user_mode(regs) && (user_mode_unaligned_fixup_count > 0)) { | 734 | if (user_mode(regs) && (user_mode_unaligned_fixup_count > 0)) { |
754 | --user_mode_unaligned_fixup_count; | 735 | --user_mode_unaligned_fixup_count; |
755 | /* Only do 'count' worth of these reports, to remove a potential DoS against syslog */ | 736 | /* Only do 'count' worth of these reports, to remove a potential DoS against syslog */ |
756 | printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%08x ins=0x%08lx\n", | 737 | printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%08x ins=0x%08lx\n", |
757 | current->comm, task_pid_nr(current), (__u32)regs->pc, opcode); | 738 | current->comm, task_pid_nr(current), (__u32)regs->pc, opcode); |
758 | } else | 739 | } else if (!user_mode(regs) && (kernel_mode_unaligned_fixup_count > 0)) { |
759 | #endif | ||
760 | if (!user_mode(regs) && (kernel_mode_unaligned_fixup_count > 0)) { | ||
761 | --kernel_mode_unaligned_fixup_count; | 740 | --kernel_mode_unaligned_fixup_count; |
762 | if (in_interrupt()) { | 741 | if (in_interrupt()) { |
763 | printk("Fixing up unaligned kernelspace access in interrupt pc=0x%08x ins=0x%08lx\n", | 742 | printk("Fixing up unaligned kernelspace access in interrupt pc=0x%08x ins=0x%08lx\n", |
@@ -830,7 +809,6 @@ static int misaligned_fixup(struct pt_regs *regs) | |||
830 | } | 809 | } |
831 | break; | 810 | break; |
832 | 811 | ||
833 | #if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP) | ||
834 | case (0x94>>2): /* FLD.S */ | 812 | case (0x94>>2): /* FLD.S */ |
835 | error = misaligned_fpu_load(regs, opcode, 1, 2, 0); | 813 | error = misaligned_fpu_load(regs, opcode, 1, 2, 0); |
836 | break; | 814 | break; |
@@ -881,7 +859,6 @@ static int misaligned_fixup(struct pt_regs *regs) | |||
881 | break; | 859 | break; |
882 | } | 860 | } |
883 | break; | 861 | break; |
884 | #endif | ||
885 | 862 | ||
886 | default: | 863 | default: |
887 | /* Fault */ | 864 | /* Fault */ |
@@ -907,7 +884,6 @@ static ctl_table unaligned_table[] = { | |||
907 | .mode = 0644, | 884 | .mode = 0644, |
908 | .proc_handler = &proc_dointvec | 885 | .proc_handler = &proc_dointvec |
909 | }, | 886 | }, |
910 | #if defined(CONFIG_SH64_USER_MISALIGNED_FIXUP) | ||
911 | { | 887 | { |
912 | .ctl_name = CTL_UNNUMBERED, | 888 | .ctl_name = CTL_UNNUMBERED, |
913 | .procname = "user_reports", | 889 | .procname = "user_reports", |
@@ -923,7 +899,6 @@ static ctl_table unaligned_table[] = { | |||
923 | .maxlen = sizeof(int), | 899 | .maxlen = sizeof(int), |
924 | .mode = 0644, | 900 | .mode = 0644, |
925 | .proc_handler = &proc_dointvec}, | 901 | .proc_handler = &proc_dointvec}, |
926 | #endif | ||
927 | {} | 902 | {} |
928 | }; | 903 | }; |
929 | 904 | ||