summaryrefslogtreecommitdiffstats
path: root/target/linux/generic/patches-3.9/001-mips_fix_code_non_dsp_cpu.patch
diff options
context:
space:
mode:
authorflorian <florian@3c298f89-4303-0410-b956-a3cf2f4a3e73>2013-03-14 14:45:56 +0000
committerflorian <florian@3c298f89-4303-0410-b956-a3cf2f4a3e73>2013-03-14 14:45:56 +0000
commit05ea13b746e715f03c70e29068b650a62e5e5d79 (patch)
tree08d6be7813310be182259388518215a17afcc18c /target/linux/generic/patches-3.9/001-mips_fix_code_non_dsp_cpu.patch
parent54d0b82f17bde2e67b8a2b58c1cb3e9ba294e9b7 (diff)
kernel: add support for 3.9-rc2
Signed-off-by: Florian Fainelli <florian@openwrt.org> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@36008 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/generic/patches-3.9/001-mips_fix_code_non_dsp_cpu.patch')
-rw-r--r--target/linux/generic/patches-3.9/001-mips_fix_code_non_dsp_cpu.patch375
1 files changed, 375 insertions, 0 deletions
diff --git a/target/linux/generic/patches-3.9/001-mips_fix_code_non_dsp_cpu.patch b/target/linux/generic/patches-3.9/001-mips_fix_code_non_dsp_cpu.patch
new file mode 100644
index 000000000..be8d74e95
--- /dev/null
+++ b/target/linux/generic/patches-3.9/001-mips_fix_code_non_dsp_cpu.patch
@@ -0,0 +1,375 @@
+From f9b4e05597e636a550af8392e80b15f79d9f9e11 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <florian@openwrt.org>
+Date: Thu, 14 Mar 2013 14:07:20 +0100
+Subject: [PATCH] MIPS: fix code generation for non-DSP capable CPUs
+
+Commit 32a7ede (MIPS: dsp: Add assembler support for DSP ASEs) has
+enabled the use of DSP ASE specific instructions such as rddsp and wrdsp
+under the idea that all code path that will make use of these two
+instructions are properly checking for cpu_has_dsp to ensure that the
+particular CPU we are running on *actually* supports DSP ASE.
+
+This commit actually causes the following oops on QEMU Malta emulating a
+MIPS 24Kc without the DSP ASE implemented:
+
+[ 7.960000] Reserved instruction in kernel
+[ 7.960000] Cpu 0
+[ 7.960000] $ 0 : 00000000 00000000 00000014 00000005
+[ 7.960000] $ 4 : 8fc2de48 00000001 00000000 8f59ddb0
+[ 7.960000] $ 8 : 8f5ceec4 00000018 00000c00 00800000
+[ 7.960000] $12 : 00000100 00000200 00000000 00457b84
+[ 7.960000] $16 : 00000000 8fc2ba78 8f4ec980 00000001
+[ 7.960000] $20 : 80418f90 00000000 00000000 000002dd
+[ 7.960000] $24 : 0000009c 7730d7b8
+[ 7.960000] $28 : 8f59c000 8f59dd38 00000001 80104248
+[ 7.960000] Hi : 0000001d
+[ 7.960000] Lo : 0000000b
+[ 7.960000] epc : 801041ec thread_saved_pc+0x2c/0x38
+[ 7.960000] Not tainted
+[ 7.960000] ra : 80104248 get_wchan+0x48/0xac
+[ 7.960000] Status: 1000b703 KERNEL EXL IE
+[ 7.960000] Cause : 10800028
+[ 7.960000] PrId : 00019300 (MIPS 24Kc)
+[ 7.960000] Modules linked in:
+[ 7.960000] Process killall (pid: 1574, threadinfo=8f59c000,
+task=8fd14558, tls=773aa440)
+[ 7.960000] Stack : 8fc2ba78 8012b008 0000000c 0000001d 00000000
+00000000 8f58a380
+ 8f58a380 8fc2ba78 80202668 8f59de78 8f468600 8f59de28
+801b2a3c 8f59df00 8f98ba20 74696e69
+ 8f468600 8f59de28 801b7308 0081c007 00000000 00000000
+00000000 00000000 00000000 00000000
+ 00000000 8fc2bbb4 00000001 0000001d 0000000b 77f038cc
+7fe80648 ffffffff ffffffff 00000000
+ 00000001 0016e000 00000000 ...
+[ 7.960000] Call Trace:
+[ 7.960000] [<801041ec>] thread_saved_pc+0x2c/0x38
+[ 7.960000] [<80104248>] get_wchan+0x48/0xac
+
+The disassembly of thread_saved_pc points to the following:
+000006d0 <thread_saved_pc>:
+ 6d0: 8c820208 lw v0,520(a0)
+ 6d4: 3c030000 lui v1,0x0
+ 6d8: 24630000 addiu v1,v1,0
+ 6dc: 10430008 beq v0,v1,700 <thread_saved_pc+0x30>
+ 6e0: 00000000 nop
+ 6e4: 3c020000 lui v0,0x0
+ 6e8: 8c43000c lw v1,12(v0)
+ 6ec: 04620004 bltzl v1,700 <thread_saved_pc+0x30>
+ 6f0: 00001021 move v0,zero
+ 6f4: 8c840200 lw a0,512(a0)
+ 6f8: 00031080 sll v0,v1,0x2
+ 6fc: 7c44100a lwx v0,a0(v0) <------------
+ 700: 03e00008 jr ra
+ 704: 00000000 nop
+
+If we specifically disable -mdsp/-mdspr2 for arch/mips/kernel/process.o,
+we get the following (non-crashing) assembly:
+
+00000708 <thread_saved_pc>:
+ 708: 8c820208 lw v0,520(a0)
+ 70c: 3c030000 lui v1,0x0
+ 710: 24630000 addiu v1,v1,0
+ 714: 10430009 beq v0,v1,73c <thread_saved_pc+0x34>
+ 718: 00000000 nop
+ 71c: 3c020000 lui v0,0x0
+ 720: 8c42000c lw v0,12(v0)
+ 724: 04420005 bltzl v0,73c <thread_saved_pc+0x34>
+ 728: 00001021 move v0,zero
+ 72c: 8c830200 lw v1,512(a0)
+ 730: 00021080 sll v0,v0,0x2
+ 734: 00431021 addu v0,v0,v1
+ 738: 8c420000 lw v0,0(v0)
+ 73c: 03e00008 jr ra
+ 740: 00000000 nop
+
+The specific line that leads a different assembly being produced is:
+
+unsigned long thread_saved_pc(struct task_struct *tsk)
+...
+ return ((unsigned long *)t->reg29)[schedule_mfi.pc_offset]; <---
+
+The problem here is that the compiler was given the right to use DSP
+instructions with the -mdsp / -mdspr2 command-line switches and
+performed some optimization for us and used DSP ASE instructions where
+we are not checking that the running CPU actually supports DSP ASE.
+
+This patch fixes the issue by partially reverting commit 32a7ede for
+arch/mips/kernel/Makefile in order to remove the -mdsp / -mdspr2
+compiler command-line switches such that we are now guaranteed that the
+compiler will not optimize using DSP ASE reserved instructions. We also
+need to fixup the rddsp/wrdsp and m{t,h}{hi,lo}{0,1,2,3} macros in
+arch/mips/include/asm/mipsregs.h to tell the assembler that we are going
+to explicitely use DSP ASE reserved instructions.
+
+Signed-off-by: Florian Fainelli <florian@openwrt.org>
+---
+Ralf, John,
+
+This should be part of your 3.9-rc3 pull request if I may ;)
+
+ arch/mips/include/asm/mipsregs.h | 209 ++++++++++++++++++++++++++++++++++----
+ arch/mips/kernel/Makefile | 14 ---
+ 2 files changed, 190 insertions(+), 33 deletions(-)
+
+diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
+index 12b70c2..0da44d4 100644
+--- a/arch/mips/include/asm/mipsregs.h
++++ b/arch/mips/include/asm/mipsregs.h
+@@ -1166,7 +1166,10 @@ do { \
+ unsigned int __dspctl; \
+ \
+ __asm__ __volatile__( \
++ " .set push \n" \
++ " .set dsp \n" \
+ " rddsp %0, %x1 \n" \
++ " .set pop \n" \
+ : "=r" (__dspctl) \
+ : "i" (mask)); \
+ __dspctl; \
+@@ -1175,30 +1178,198 @@ do { \
+ #define wrdsp(val, mask) \
+ do { \
+ __asm__ __volatile__( \
++ " .set push \n" \
++ " .set dsp \n" \
+ " wrdsp %0, %x1 \n" \
++ " .set pop \n" \
+ : \
+ : "r" (val), "i" (mask)); \
+ } while (0)
+
+-#define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;})
+-#define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;})
+-#define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;})
+-#define mflo3() ({ long mflo3; __asm__("mflo %0, $ac3" : "=r" (mflo3)); mflo3;})
+-
+-#define mfhi0() ({ long mfhi0; __asm__("mfhi %0, $ac0" : "=r" (mfhi0)); mfhi0;})
+-#define mfhi1() ({ long mfhi1; __asm__("mfhi %0, $ac1" : "=r" (mfhi1)); mfhi1;})
+-#define mfhi2() ({ long mfhi2; __asm__("mfhi %0, $ac2" : "=r" (mfhi2)); mfhi2;})
+-#define mfhi3() ({ long mfhi3; __asm__("mfhi %0, $ac3" : "=r" (mfhi3)); mfhi3;})
+-
+-#define mtlo0(x) __asm__("mtlo %0, $ac0" ::"r" (x))
+-#define mtlo1(x) __asm__("mtlo %0, $ac1" ::"r" (x))
+-#define mtlo2(x) __asm__("mtlo %0, $ac2" ::"r" (x))
+-#define mtlo3(x) __asm__("mtlo %0, $ac3" ::"r" (x))
+-
+-#define mthi0(x) __asm__("mthi %0, $ac0" ::"r" (x))
+-#define mthi1(x) __asm__("mthi %0, $ac1" ::"r" (x))
+-#define mthi2(x) __asm__("mthi %0, $ac2" ::"r" (x))
+-#define mthi3(x) __asm__("mthi %0, $ac3" ::"r" (x))
++#define mflo0() \
++({ \
++ long mflo0; \
++ __asm__( \
++ " .set push \n" \
++ " .set dsp \n" \
++ " mflo %0, $ac0 \n" \
++ " .set pop \n" \
++ : "=r" (mflo0)); \
++ mflo0; \
++})
++
++#define mflo1() \
++({ \
++ long mflo1; \
++ __asm__( \
++ " .set push \n" \
++ " .set dsp \n" \
++ " mflo %0, $ac1 \n" \
++ " .set pop \n" \
++ : "=r" (mflo1)); \
++ mflo1; \
++})
++
++#define mflo2() \
++({ \
++ long mflo2; \
++ __asm__( \
++ " .set push \n" \
++ " .set dsp \n" \
++ " mflo %0, $ac2 \n" \
++ " .set pop \n" \
++ : "=r" (mflo2)); \
++ mflo2; \
++})
++
++#define mflo3() \
++({ \
++ long mflo3; \
++ __asm__( \
++ " .set push \n" \
++ " .set dsp \n" \
++ " mflo %0, $ac3 \n" \
++ " .set pop \n" \
++ : "=r" (mflo3)); \
++ mflo3; \
++})
++
++#define mfhi0() \
++({ \
++ long mfhi0; \
++ __asm__( \
++ " .set push \n" \
++ " .set dsp \n" \
++ " mfhi %0, $ac0 \n" \
++ " .set pop \n" \
++ : "=r" (mfhi0)); \
++ mfhi0; \
++})
++
++#define mfhi1() \
++({ \
++ long mfhi1; \
++ __asm__( \
++ " .set push \n" \
++ " .set dsp \n" \
++ " mfhi %0, $ac1 \n" \
++ " .set pop \n" \
++ : "=r" (mfhi1)); \
++ mfhi1; \
++})
++
++#define mfhi2() \
++({ \
++ long mfhi2; \
++ __asm__( \
++ " .set push \n" \
++ " .set dsp \n" \
++ " mfhi %0, $ac2 \n" \
++ " .set pop \n" \
++ : "=r" (mfhi2)); \
++ mfhi2; \
++})
++
++#define mfhi3() \
++({ \
++ long mfhi3; \
++ __asm__( \
++ " .set push \n" \
++ " .set dsp \n" \
++ " mfhi %0, $ac3 \n" \
++ " .set pop \n" \
++ : "=r" (mfhi3)); \
++ mfhi3; \
++})
++
++
++#define mtlo0(x) \
++({ \
++ __asm__( \
++ " .set push \n" \
++ " .set dsp \n" \
++ " mtlo %0, $ac0 \n" \
++ " .set pop \n" \
++ : \
++ : "r" (x)); \
++})
++
++#define mtlo1(x) \
++({ \
++ __asm__( \
++ " .set push \n" \
++ " .set dsp \n" \
++ " mtlo %0, $ac1 \n" \
++ " .set pop \n" \
++ : \
++ : "r" (x)); \
++})
++
++#define mtlo2(x) \
++({ \
++ __asm__( \
++ " .set push \n" \
++ " .set dsp \n" \
++ " mtlo %0, $ac2 \n" \
++ " .set pop \n" \
++ : \
++ : "r" (x)); \
++})
++
++#define mtlo3(x) \
++({ \
++ __asm__( \
++ " .set push \n" \
++ " .set dsp \n" \
++ " mtlo %0, $ac3 \n" \
++ " .set pop \n" \
++ : \
++ : "r" (x)); \
++})
++
++#define mthi0(x) \
++({ \
++ __asm__( \
++ " .set push \n" \
++ " .set dsp \n" \
++ " mthi %0, $ac0 \n" \
++ " .set pop \n" \
++ : \
++ : "r" (x)); \
++})
++
++#define mthi1(x) \
++({ \
++ __asm__( \
++ " .set push \n" \
++ " .set dsp \n" \
++ " mthi %0, $ac1 \n" \
++ " .set pop \n" \
++ : \
++ : "r" (x)); \
++})
++
++#define mthi2(x) \
++({ \
++ __asm__( \
++ " .set push \n" \
++ " .set dsp \n" \
++ " mthi %0, $ac2 \n" \
++ " .set pop \n" \
++ : \
++ : "r" (x)); \
++})
++
++#define mthi3(x) \
++({ \
++ __asm__( \
++ " .set push \n" \
++ " .set dsp \n" \
++ " mthi %0, $ac3 \n" \
++ " .set pop \n" \
++ : \
++ : "r" (x)); \
++})
+
+ #else
+
+diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
+index f81d98f..2e8a9c1 100644
+--- a/arch/mips/kernel/Makefile
++++ b/arch/mips/kernel/Makefile
+@@ -109,20 +109,6 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o
+ ifeq ($(CONFIG_CPU_MIPSR2), y)
+ CFLAGS_DSP = -DHAVE_AS_DSP
+
+-#
+-# Check if assembler supports DSP ASE
+-#
+-ifeq ($(call cc-option-yn,-mdsp), y)
+-CFLAGS_DSP += -mdsp
+-endif
+-
+-#
+-# Check if assembler supports DSP ASE Rev2
+-#
+-ifeq ($(call cc-option-yn,-mdspr2), y)
+-CFLAGS_DSP += -mdspr2
+-endif
+-
+ CFLAGS_signal.o = $(CFLAGS_DSP)
+ CFLAGS_signal32.o = $(CFLAGS_DSP)
+ CFLAGS_process.o = $(CFLAGS_DSP)
+--
+1.7.10.4
+