Update ARM alignment patch to upstream
This commit is contained in:
parent
a0a8db50e5
commit
39c7bf392f
127
arm-alignment-faults.patch
Normal file
127
arm-alignment-faults.patch
Normal file
@ -0,0 +1,127 @@
|
||||
arch/arm/kernel/traps.c | 34 +++++++---------------------------
|
||||
arch/arm/mm/alignment.c | 11 ++++-------
|
||||
2 files changed, 11 insertions(+), 34 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
|
||||
index b0179b8..62f429e 100644
|
||||
--- a/arch/arm/kernel/traps.c
|
||||
+++ b/arch/arm/kernel/traps.c
|
||||
@@ -89,17 +89,8 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
|
||||
unsigned long top)
|
||||
{
|
||||
unsigned long first;
|
||||
- mm_segment_t fs;
|
||||
int i;
|
||||
|
||||
- /*
|
||||
- * We need to switch to kernel mode so that we can use __get_user
|
||||
- * to safely read from kernel space. Note that we now dump the
|
||||
- * code first, just in case the backtrace kills us.
|
||||
- */
|
||||
- fs = get_fs();
|
||||
- set_fs(KERNEL_DS);
|
||||
-
|
||||
printk("%s%s(0x%08lx to 0x%08lx)\n", lvl, str, bottom, top);
|
||||
|
||||
for (first = bottom & ~31; first < top; first += 32) {
|
||||
@@ -112,7 +103,7 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
|
||||
for (p = first, i = 0; i < 8 && p < top; i++, p += 4) {
|
||||
if (p >= bottom && p < top) {
|
||||
unsigned long val;
|
||||
- if (__get_user(val, (unsigned long *)p) == 0)
|
||||
+ if (probe_kernel_address(p, val) == 0)
|
||||
sprintf(str + i * 9, " %08lx", val);
|
||||
else
|
||||
sprintf(str + i * 9, " ????????");
|
||||
@@ -120,8 +111,6 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
|
||||
}
|
||||
printk("%s%04lx:%s\n", lvl, first & 0xffff, str);
|
||||
}
|
||||
-
|
||||
- set_fs(fs);
|
||||
}
|
||||
|
||||
static void dump_instr(const char *lvl, struct pt_regs *regs)
|
||||
@@ -129,25 +118,18 @@ static void dump_instr(const char *lvl, struct pt_regs *regs)
|
||||
unsigned long addr = instruction_pointer(regs);
|
||||
const int thumb = thumb_mode(regs);
|
||||
const int width = thumb ? 4 : 8;
|
||||
- mm_segment_t fs;
|
||||
char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
|
||||
int i;
|
||||
|
||||
- /*
|
||||
- * We need to switch to kernel mode so that we can use __get_user
|
||||
- * to safely read from kernel space. Note that we now dump the
|
||||
- * code first, just in case the backtrace kills us.
|
||||
- */
|
||||
- fs = get_fs();
|
||||
- set_fs(KERNEL_DS);
|
||||
-
|
||||
for (i = -4; i < 1 + !!thumb; i++) {
|
||||
unsigned int val, bad;
|
||||
|
||||
- if (thumb)
|
||||
- bad = __get_user(val, &((u16 *)addr)[i]);
|
||||
- else
|
||||
- bad = __get_user(val, &((u32 *)addr)[i]);
|
||||
+ if (thumb) {
|
||||
+ u16 instr;
|
||||
+ bad = probe_kernel_address(addr, instr);
|
||||
+ val = instr;
|
||||
+ } else
|
||||
+ bad = probe_kernel_address(addr, val);
|
||||
|
||||
if (!bad)
|
||||
p += sprintf(p, i == 0 ? "(%0*x) " : "%0*x ",
|
||||
@@ -158,8 +140,6 @@ static void dump_instr(const char *lvl, struct pt_regs *regs)
|
||||
}
|
||||
}
|
||||
printk("%sCode: %s\n", lvl, str);
|
||||
-
|
||||
- set_fs(fs);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARM_UNWIND
|
||||
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
|
||||
index b9f60eb..f8f14fc 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)
|
||||
unsigned long instr = 0, instrptr;
|
||||
int (*handler)(unsigned long addr, unsigned long instr, struct pt_regs *regs);
|
||||
unsigned int type;
|
||||
- mm_segment_t fs;
|
||||
unsigned int fault;
|
||||
u16 tinstr = 0;
|
||||
int isize = 4;
|
||||
@@ -760,16 +759,15 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
|
||||
|
||||
instrptr = instruction_pointer(regs);
|
||||
|
||||
- fs = get_fs();
|
||||
- set_fs(KERNEL_DS);
|
||||
if (thumb_mode(regs)) {
|
||||
- fault = __get_user(tinstr, (u16 *)(instrptr & ~1));
|
||||
+ unsigned long ptr = instrptr;
|
||||
+ fault = probe_kernel_address(ptr, tinstr);
|
||||
if (!fault) {
|
||||
if (cpu_architecture() >= CPU_ARCH_ARMv7 &&
|
||||
IS_T32(tinstr)) {
|
||||
/* Thumb-2 32-bit */
|
||||
u16 tinst2 = 0;
|
||||
- fault = __get_user(tinst2, (u16 *)(instrptr+2));
|
||||
+ fault = probe_kernel_address(ptr + 2, tinst2);
|
||||
instr = (tinstr << 16) | tinst2;
|
||||
thumb2_32b = 1;
|
||||
} else {
|
||||
@@ -778,8 +776,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
|
||||
}
|
||||
}
|
||||
} else
|
||||
- fault = __get_user(instr, (u32 *)instrptr);
|
||||
- set_fs(fs);
|
||||
+ fault = probe_kernel_address(instrptr, instr);
|
||||
|
||||
if (fault) {
|
||||
type = TYPE_FAULT;
|
@ -1,83 +0,0 @@
|
||||
commit dd945918f747f61eff384f5cb8889e524f60615a
|
||||
Author: Jon Masters <jcm@jonmasters.org>
|
||||
Date: Fri Oct 5 22:32:29 2012 -0400
|
||||
|
||||
Revert "ARM: 7528/1: uaccess: annotate [__]{get,put}_user functions with might_fault()"
|
||||
|
||||
This reverts commit ad72907acd2943304c292ae36960bb66e6dc23c9.
|
||||
|
||||
Technically, the original commit is totally correct, however it exposes
|
||||
a deep-rooted problem with missaligned accesses in e.g. the networking
|
||||
stack and we need to revert this (sweep under rug) until we can get
|
||||
a good solution in place upstream. The problem is that the compiler
|
||||
believes the structs concerned are aligned (they are in the code),
|
||||
however at runtime the IP structs are actually not aligned within
|
||||
received network packets, and the fault handler is not guaranteed
|
||||
to be entirely atomic and free of calls to the scheduler.
|
||||
|
||||
Signed-off-by: Jon Masters <jcm@jonmasters.org>
|
||||
|
||||
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
|
||||
index 77bd79f..6f83ad6 100644
|
||||
--- a/arch/arm/include/asm/uaccess.h
|
||||
+++ b/arch/arm/include/asm/uaccess.h
|
||||
@@ -118,7 +118,7 @@ extern int __get_user_4(void *);
|
||||
: "0" (__p), "r" (__l) \
|
||||
: __GUP_CLOBBER_##__s)
|
||||
|
||||
-#define __get_user_check(x,p) \
|
||||
+#define get_user(x,p) \
|
||||
({ \
|
||||
unsigned long __limit = current_thread_info()->addr_limit - 1; \
|
||||
register const typeof(*(p)) __user *__p asm("r0") = (p);\
|
||||
@@ -141,12 +141,6 @@ extern int __get_user_4(void *);
|
||||
__e; \
|
||||
})
|
||||
|
||||
-#define get_user(x,p) \
|
||||
- ({ \
|
||||
- might_fault(); \
|
||||
- __get_user_check(x,p); \
|
||||
- })
|
||||
-
|
||||
extern int __put_user_1(void *, unsigned int);
|
||||
extern int __put_user_2(void *, unsigned int);
|
||||
extern int __put_user_4(void *, unsigned int);
|
||||
@@ -161,7 +155,7 @@ extern int __put_user_8(void *, unsigned long long);
|
||||
: "0" (__p), "r" (__r2), "r" (__l) \
|
||||
: "ip", "lr", "cc")
|
||||
|
||||
-#define __put_user_check(x,p) \
|
||||
+#define put_user(x,p) \
|
||||
({ \
|
||||
unsigned long __limit = current_thread_info()->addr_limit - 1; \
|
||||
register const typeof(*(p)) __r2 asm("r2") = (x); \
|
||||
@@ -186,12 +180,6 @@ extern int __put_user_8(void *, unsigned long long);
|
||||
__e; \
|
||||
})
|
||||
|
||||
-#define put_user(x,p) \
|
||||
- ({ \
|
||||
- might_fault(); \
|
||||
- __put_user_check(x,p); \
|
||||
- })
|
||||
-
|
||||
#else /* CONFIG_MMU */
|
||||
|
||||
/*
|
||||
@@ -245,7 +233,6 @@ do { \
|
||||
unsigned long __gu_addr = (unsigned long)(ptr); \
|
||||
unsigned long __gu_val; \
|
||||
__chk_user_ptr(ptr); \
|
||||
- might_fault(); \
|
||||
switch (sizeof(*(ptr))) { \
|
||||
case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \
|
||||
case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \
|
||||
@@ -327,7 +314,6 @@ do { \
|
||||
unsigned long __pu_addr = (unsigned long)(ptr); \
|
||||
__typeof__(*(ptr)) __pu_val = (x); \
|
||||
__chk_user_ptr(ptr); \
|
||||
- might_fault(); \
|
||||
switch (sizeof(*(ptr))) { \
|
||||
case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \
|
||||
case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \
|
@ -88,9 +88,6 @@ CONFIG_STRICT_DEVMEM=y
|
||||
|
||||
CONFIG_SPARSE_IRQ=y
|
||||
|
||||
CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
|
||||
CONFIG_LSM_MMAP_MIN_ADDR=32768
|
||||
|
||||
# Generic HW for all ARM platforms
|
||||
CONFIG_LEDS=y
|
||||
CONFIG_LEDS_CPU=y
|
||||
|
@ -733,7 +733,7 @@ Patch19001: i82975x-edac-fix.patch
|
||||
Patch21000: arm-read_current_timer.patch
|
||||
Patch21001: arm-fix-omapdrm.patch
|
||||
Patch21002: arm-fix_radio_shark.patch
|
||||
Patch21003: arm-linux-3.6-revert-missaligned-access-check-on-put_user.patch
|
||||
Patch21003: arm-alignment-faults.patch
|
||||
# OMAP
|
||||
|
||||
# ARM tegra
|
||||
@ -1368,7 +1368,7 @@ ApplyPatch arm-tegra-nvec-kconfig.patch
|
||||
ApplyPatch arm-tegra-usb-no-reset-linux33.patch
|
||||
ApplyPatch arm-tegra-sdhci-module-fix.patch
|
||||
ApplyPatch arm-highbank-sata-fix.patch
|
||||
ApplyPatch arm-linux-3.6-revert-missaligned-access-check-on-put_user.patch
|
||||
ApplyPatch arm-alignment-faults.patch
|
||||
ApplyPatch arm-smdk310-regulator-fix.patch
|
||||
ApplyPatch arm-origen-regulator-fix.patch
|
||||
|
||||
@ -2376,6 +2376,9 @@ fi
|
||||
# ||----w |
|
||||
# || ||
|
||||
%changelog
|
||||
* Mon Oct 29 2012 Peter Robinson <pbrobinson@fedoraproject.org>
|
||||
- Update ARM alignment patch to upstream
|
||||
|
||||
* Mon Oct 29 2012 Justin M. Forbes <jforbes@redhat.com> 3.6.4-1
|
||||
- Linux 3.6.4
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user