diff --git a/debian/changelog b/debian/changelog index 6dc4f0d5f..b2bd2047f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -118,6 +118,7 @@ linux (4.0.7-1) UNRELEASED; urgency=medium * Revert "tcp: fix child sockets to use system default congestion control if not set" to avoid ABI change * [ppc64el] Disable HIBERNATION (Closes: #789070) + * [mips*] Correct FP ISA requirements (Closes: #781892) -- Ben Hutchings Sun, 21 Jun 2015 03:30:39 +0100 diff --git a/debian/patches/bugfix/mips/mips-correct-fp-isa-requirements.patch b/debian/patches/bugfix/mips/mips-correct-fp-isa-requirements.patch new file mode 100644 index 000000000..ab4bbc6e6 --- /dev/null +++ b/debian/patches/bugfix/mips/mips-correct-fp-isa-requirements.patch @@ -0,0 +1,275 @@ +From: "Maciej W. Rozycki" +Date: Fri, 3 Apr 2015 23:26:49 +0100 +Subject: MIPS: Correct FP ISA requirements +Origin: https://git.kernel.org/linus/2d83fea786d7aeb5b3b76bd492d9b3bccc0f823c +Bug-Debian: https://bugs.debian.org/781892 + +Correct ISA requirements for floating-point instructions: + +* the CU3 exception signifies a real COP3 instruction in MIPS I & II, + +* the BC1FL and BC1TL instructions are not supported in MIPS I, + +* the SQRT.fmt instructions are indeed supported in MIPS II, + +* the LDC1 and SDC1 instructions are indeed supported in MIPS32r1, + +* the CEIL.W.fmt, FLOOR.W.fmt, ROUND.W.fmt and TRUNC.W.fmt instructions + are indeed supported in MIPS32, + +* the CVT.L.fmt and CVT.fmt.L instructions are indeed supported in + MIPS32r2 and MIPS32r6, + +* the CEIL.L.fmt, FLOOR.L.fmt, ROUND.L.fmt and TRUNC.L.fmt instructions + are indeed supported in MIPS32r2 and MIPS32r6, + +* the RSQRT.fmt and RECIP.fmt instructions are indeed supported in + MIPS64r1, + +Also simplify conditionals for MIPS III and MIPS IV FPU instructions and +the handling of the MOVCI minor opcode. + +Signed-off-by: Maciej W. Rozycki +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/9700/ +Signed-off-by: Ralf Baechle +--- + arch/mips/include/asm/cpu-features.h | 7 +++-- + arch/mips/kernel/traps.c | 23 ++++++++------- + arch/mips/math-emu/cp1emu.c | 55 ++++++++++++++++++------------------ + 3 files changed, 43 insertions(+), 42 deletions(-) + +--- a/arch/mips/include/asm/cpu-features.h ++++ b/arch/mips/include/asm/cpu-features.h +@@ -220,8 +220,11 @@ + #define cpu_has_mips_4_5_r (cpu_has_mips_4 | cpu_has_mips_5_r) + #define cpu_has_mips_5_r (cpu_has_mips_5 | cpu_has_mips_r) + +-#define cpu_has_mips_4_5_r2_r6 (cpu_has_mips_4_5 | cpu_has_mips_r2 | \ +- cpu_has_mips_r6) ++#define cpu_has_mips_3_4_5_64_r2_r6 \ ++ (cpu_has_mips_3 | cpu_has_mips_4_5_64_r2_r6) ++#define cpu_has_mips_4_5_64_r2_r6 \ ++ (cpu_has_mips_4_5 | cpu_has_mips64r1 | \ ++ cpu_has_mips_r2 | cpu_has_mips_r6) + + #define cpu_has_mips32 (cpu_has_mips32r1 | cpu_has_mips32r2 | cpu_has_mips32r6) + #define cpu_has_mips64 (cpu_has_mips64r1 | cpu_has_mips64r2 | cpu_has_mips64r6) +--- a/arch/mips/kernel/traps.c ++++ b/arch/mips/kernel/traps.c +@@ -1350,19 +1350,18 @@ asmlinkage void do_cpu(struct pt_regs *r + + case 3: + /* +- * Old (MIPS I and MIPS II) processors will set this code +- * for COP1X opcode instructions that replaced the original +- * COP3 space. We don't limit COP1 space instructions in +- * the emulator according to the CPU ISA, so we want to +- * treat COP1X instructions consistently regardless of which +- * code the CPU chose. Therefore we redirect this trap to +- * the FP emulator too. +- * +- * Then some newer FPU-less processors use this code +- * erroneously too, so they are covered by this choice +- * as well. ++ * The COP3 opcode space and consequently the CP0.Status.CU3 ++ * bit and the CP0.Cause.CE=3 encoding have been removed as ++ * of the MIPS III ISA. From the MIPS IV and MIPS32r2 ISAs ++ * up the space has been reused for COP1X instructions, that ++ * are enabled by the CP0.Status.CU1 bit and consequently ++ * use the CP0.Cause.CE=1 encoding for Coprocessor Unusable ++ * exceptions. Some FPU-less processors that implement one ++ * of these ISAs however use this code erroneously for COP1X ++ * instructions. Therefore we redirect this trap to the FP ++ * emulator too. + */ +- if (raw_cpu_has_fpu) { ++ if (raw_cpu_has_fpu || !cpu_has_mips_4_5_64_r2_r6) { + force_sig(SIGILL, current); + break; + } +--- a/arch/mips/math-emu/cp1emu.c ++++ b/arch/mips/math-emu/cp1emu.c +@@ -1103,17 +1103,18 @@ emul: + likely = 0; + switch (MIPSInst_RT(ir) & 3) { + case bcfl_op: +- likely = 1; ++ if (cpu_has_mips_2_3_4_5_r) ++ likely = 1; ++ /* Fall through */ + case bcf_op: + cond = !cond; + break; + case bctl_op: +- likely = 1; ++ if (cpu_has_mips_2_3_4_5_r) ++ likely = 1; ++ /* Fall through */ + case bct_op: + break; +- default: +- /* thats an illegal instruction */ +- return SIGILL; + } + + set_delay_slot(xcp); +@@ -1153,36 +1154,34 @@ emul: + + switch (MIPSInst_OPCODE(ir)) { + case lwc1_op: +- goto emul; +- + case swc1_op: + goto emul; + + case ldc1_op: + case sdc1_op: +- if (cpu_has_mips_2_3_4_5 || +- cpu_has_mips64) ++ if (cpu_has_mips_2_3_4_5_r) + goto emul; + + return SIGILL; +- goto emul; + + case cop1_op: + goto emul; + + case cop1x_op: +- if (cpu_has_mips_4_5 || cpu_has_mips64 || cpu_has_mips32r2) ++ if (cpu_has_mips_4_5_64_r2_r6) + /* its one of ours */ + goto emul; + + return SIGILL; + + case spec_op: +- if (!cpu_has_mips_4_5_r) +- return SIGILL; ++ switch (MIPSInst_FUNC(ir)) { ++ case movc_op: ++ if (cpu_has_mips_4_5_r) ++ goto emul; + +- if (MIPSInst_FUNC(ir) == movc_op) +- goto emul; ++ return SIGILL; ++ } + break; + } + +@@ -1216,7 +1215,7 @@ emul: + break; + + case cop1x_op: +- if (!cpu_has_mips_4_5 && !cpu_has_mips64 && !cpu_has_mips32r2) ++ if (!cpu_has_mips_4_5_64_r2_r6) + return SIGILL; + + sig = fpux_emu(xcp, ctx, ir, fault_addr); +@@ -1549,7 +1548,7 @@ static int fpu_emu(struct pt_regs *xcp, + + /* unary ops */ + case fsqrt_op: +- if (!cpu_has_mips_4_5_r) ++ if (!cpu_has_mips_2_3_4_5_r) + return SIGILL; + + handler.u = ieee754sp_sqrt; +@@ -1561,14 +1560,14 @@ static int fpu_emu(struct pt_regs *xcp, + * achieve full IEEE-754 accuracy - however this emulator does. + */ + case frsqrt_op: +- if (!cpu_has_mips_4_5_r2_r6) ++ if (!cpu_has_mips_4_5_64_r2_r6) + return SIGILL; + + handler.u = fpemu_sp_rsqrt; + goto scopuop; + + case frecip_op: +- if (!cpu_has_mips_4_5_r2_r6) ++ if (!cpu_has_mips_4_5_64_r2_r6) + return SIGILL; + + handler.u = fpemu_sp_recip; +@@ -1670,7 +1669,7 @@ copcsr: + case ftrunc_op: + case fceil_op: + case ffloor_op: +- if (!cpu_has_mips_2_3_4_5 && !cpu_has_mips64) ++ if (!cpu_has_mips_2_3_4_5_r) + return SIGILL; + + oldrm = ieee754_csr.rm; +@@ -1682,7 +1681,7 @@ copcsr: + goto copcsr; + + case fcvtl_op: +- if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) ++ if (!cpu_has_mips_3_4_5_64_r2_r6) + return SIGILL; + + SPFROMREG(fs, MIPSInst_FS(ir)); +@@ -1694,7 +1693,7 @@ copcsr: + case ftruncl_op: + case fceill_op: + case ffloorl_op: +- if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) ++ if (!cpu_has_mips_3_4_5_64_r2_r6) + return SIGILL; + + oldrm = ieee754_csr.rm; +@@ -1763,13 +1762,13 @@ copcsr: + * achieve full IEEE-754 accuracy - however this emulator does. + */ + case frsqrt_op: +- if (!cpu_has_mips_4_5_r2_r6) ++ if (!cpu_has_mips_4_5_64_r2_r6) + return SIGILL; + + handler.u = fpemu_dp_rsqrt; + goto dcopuop; + case frecip_op: +- if (!cpu_has_mips_4_5_r2_r6) ++ if (!cpu_has_mips_4_5_64_r2_r6) + return SIGILL; + + handler.u = fpemu_dp_recip; +@@ -1859,7 +1858,7 @@ dcopuop: + goto copcsr; + + case fcvtl_op: +- if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) ++ if (!cpu_has_mips_3_4_5_64_r2_r6) + return SIGILL; + + DPFROMREG(fs, MIPSInst_FS(ir)); +@@ -1871,7 +1870,7 @@ dcopuop: + case ftruncl_op: + case fceill_op: + case ffloorl_op: +- if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) ++ if (!cpu_has_mips_3_4_5_64_r2_r6) + return SIGILL; + + oldrm = ieee754_csr.rm; +@@ -1930,7 +1929,7 @@ dcopuop: + + case l_fmt: + +- if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) ++ if (!cpu_has_mips_3_4_5_64_r2_r6) + return SIGILL; + + DIFROMREG(bits, MIPSInst_FS(ir)); +@@ -1994,7 +1993,7 @@ dcopuop: + SITOREG(rv.w, MIPSInst_FD(ir)); + break; + case l_fmt: +- if (!cpu_has_mips_3_4_5 && !cpu_has_mips64) ++ if (!cpu_has_mips_3_4_5_64_r2_r6) + return SIGILL; + + DITOREG(rv.l, MIPSInst_FD(ir)); diff --git a/debian/patches/bugfix/mips/mips-normalise-code-flow-in-the-cpu-exception-handle.patch b/debian/patches/bugfix/mips/mips-normalise-code-flow-in-the-cpu-exception-handle.patch new file mode 100644 index 000000000..5a6153ede --- /dev/null +++ b/debian/patches/bugfix/mips/mips-normalise-code-flow-in-the-cpu-exception-handle.patch @@ -0,0 +1,71 @@ +From: "Maciej W. Rozycki" +Date: Fri, 3 Apr 2015 23:25:08 +0100 +Subject: MIPS: Normalise code flow in the CpU exception handler +Origin: https://git.kernel.org/linus/27e28e8ec47a5ce335ebf25d34ca356c80635908 +Bug-Debian: https://bugs.debian.org/781892 + +Changes applied to `do_cpu' over time reduced the use of the SIGILL +issued with `force_sig' at the end to a single CU3 case only in the +switch statement there. Move that `force_sig' call over to right where +required then and toss out the pile of gotos now not needed to skip over +the call, replacing them with regular breaks out of the switch. + +Signed-off-by: Maciej W. Rozycki +Cc: linux-mips@linux-mips.org +Patchwork: https://patchwork.linux-mips.org/patch/9683/ +Signed-off-by: Ralf Baechle +--- + arch/mips/kernel/traps.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +--- a/arch/mips/kernel/traps.c ++++ b/arch/mips/kernel/traps.c +@@ -1313,7 +1313,7 @@ asmlinkage void do_cpu(struct pt_regs *r + status = -1; + + if (unlikely(compute_return_epc(regs) < 0)) +- goto out; ++ break; + + if (get_isa16_mode(regs->cp0_epc)) { + unsigned short mmop[2] = { 0 }; +@@ -1346,7 +1346,7 @@ asmlinkage void do_cpu(struct pt_regs *r + force_sig(status, current); + } + +- goto out; ++ break; + + case 3: + /* +@@ -1362,8 +1362,10 @@ asmlinkage void do_cpu(struct pt_regs *r + * erroneously too, so they are covered by this choice + * as well. + */ +- if (raw_cpu_has_fpu) ++ if (raw_cpu_has_fpu) { ++ force_sig(SIGILL, current); + break; ++ } + /* Fall through. */ + + case 1: +@@ -1379,16 +1381,13 @@ asmlinkage void do_cpu(struct pt_regs *r + mt_ase_fp_affinity(); + } + +- goto out; ++ break; + + case 2: + raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs); +- goto out; ++ break; + } + +- force_sig(SIGILL, current); +- +-out: + exception_exit(prev_state); + } + diff --git a/debian/patches/series b/debian/patches/series index da3830fca..eea885c8f 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -80,3 +80,5 @@ debian/revert-libata-ignore-spurious-phy-event-on-lpm-polic.patch debian/ktime-fix-abi-change-in-4.0.5.patch debian/revert-tcp-fix-child-sockets-to-use-system-default-c.patch debian/udp-fix-abi-change-in-4.0.6.patch +bugfix/mips/mips-normalise-code-flow-in-the-cpu-exception-handle.patch +bugfix/mips/mips-correct-fp-isa-requirements.patch