aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/alignment.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/alignment.c')
-rw-r--r--arch/arm/mm/alignment.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index b820edaf3184..6f4585b89078 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -749,7 +749,6 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
749 unsigned long instr = 0, instrptr; 749 unsigned long instr = 0, instrptr;
750 int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs); 750 int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs);
751 unsigned int type; 751 unsigned int type;
752 mm_segment_t fs;
753 unsigned int fault; 752 unsigned int fault;
754 u16 tinstr = 0; 753 u16 tinstr = 0;
755 int isize = 4; 754 int isize = 4;
@@ -760,16 +759,15 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
760 759
761 instrptr = instruction_pointer(regs); 760 instrptr = instruction_pointer(regs);
762 761
763 fs = get_fs();
764 set_fs(KERNEL_DS);
765 if (thumb_mode(regs)) { 762 if (thumb_mode(regs)) {
766 fault = __get_user(tinstr, (u16 *)(instrptr & ~1)); 763 u16 *ptr = (u16 *)(instrptr & ~1);
764 fault = probe_kernel_address(ptr, tinstr);
767 if (!fault) { 765 if (!fault) {
768 if (cpu_architecture() >= CPU_ARCH_ARMv7 && 766 if (cpu_architecture() >= CPU_ARCH_ARMv7 &&
769 IS_T32(tinstr)) { 767 IS_T32(tinstr)) {
770 /* Thumb-2 32-bit */ 768 /* Thumb-2 32-bit */
771 u16 tinst2 = 0; 769 u16 tinst2 = 0;
772 fault = __get_user(tinst2, (u16 *)(instrptr+2)); 770 fault = probe_kernel_address(ptr + 1, tinst2);
773 instr = (tinstr << 16) | tinst2; 771 instr = (tinstr << 16) | tinst2;
774 thumb2_32b = 1; 772 thumb2_32b = 1;
775 } else { 773 } else {
@@ -778,8 +776,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
778 } 776 }
779 } 777 }
780 } else 778 } else
781 fault = __get_user(instr, (u32 *)instrptr); 779 fault = probe_kernel_address(instrptr, instr);
782 set_fs(fs);
783 780
784 if (fault) { 781 if (fault) {
785 type = TYPE_FAULT; 782 type = TYPE_FAULT;
@@ -964,12 +961,14 @@ static int __init alignment_init(void)
964 return -ENOMEM; 961 return -ENOMEM;
965#endif 962#endif
966 963
964#ifdef CONFIG_CPU_CP15
967 if (cpu_is_v6_unaligned()) { 965 if (cpu_is_v6_unaligned()) {
968 cr_alignment &= ~CR_A; 966 cr_alignment &= ~CR_A;
969 cr_no_alignment &= ~CR_A; 967 cr_no_alignment &= ~CR_A;
970 set_cr(cr_alignment); 968 set_cr(cr_alignment);
971 ai_usermode = safe_usermode(ai_usermode, false); 969 ai_usermode = safe_usermode(ai_usermode, false);
972 } 970 }
971#endif
973 972
974 hook_fault_code(FAULT_CODE_ALIGNMENT, do_alignment, SIGBUS, BUS_ADRALN, 973 hook_fault_code(FAULT_CODE_ALIGNMENT, do_alignment, SIGBUS, BUS_ADRALN,
975 "alignment exception"); 974 "alignment exception");