diff options
author | Hauke Mehrtens <hauke@hauke-m.de> | 2020-07-03 00:54:38 +0200 |
---|---|---|
committer | Hauke Mehrtens <hauke@hauke-m.de> | 2020-07-04 16:04:21 +0200 |
commit | 4bb5e331a781c2d4f3040c70df328b1ef90f1871 (patch) | |
tree | 905f699a5d39534033b40d3cf28cad0f0e79f57f | |
parent | 3b0f698760ae3a62173a28f18e9e1e3adef9c492 (diff) | |
download | upstream-4bb5e331a781c2d4f3040c70df328b1ef90f1871.tar.gz upstream-4bb5e331a781c2d4f3040c70df328b1ef90f1871.tar.bz2 upstream-4bb5e331a781c2d4f3040c70df328b1ef90f1871.zip |
kernel: Fix ath79 DSP exception at bootup
This resolves a hazard between a mtc0 and a mfc0 instruction after
activating the DSP support. Without this fix the CPU could use the old
value again and the DSP support would not be active.
Fixes: FS#2928, FS#2899
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Tested-by: Stefan Lippers-Hollmann <s.l-h@gmx.de> [ath79/tl-wdr3600; ath79/tl-wdr4300]
Tested-by: David Bauer <mail@david-bauer.net> [ocedo_koala/ocedo_raccoon]
2 files changed, 122 insertions, 0 deletions
diff --git a/target/linux/generic/pending-4.19/350-MIPS-Add-missing-EHB-in-mtc0-mfc0-sequence-for-DSPen.patch b/target/linux/generic/pending-4.19/350-MIPS-Add-missing-EHB-in-mtc0-mfc0-sequence-for-DSPen.patch new file mode 100644 index 0000000000..92a22bc655 --- /dev/null +++ b/target/linux/generic/pending-4.19/350-MIPS-Add-missing-EHB-in-mtc0-mfc0-sequence-for-DSPen.patch @@ -0,0 +1,61 @@ +From db4603e30effd74d4adb6bcdf73072b2c06fafcd Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Fri, 3 Jul 2020 00:07:15 +0200 +Subject: [PATCH] MIPS: Add missing EHB in mtc0 -> mfc0 sequence for DSPen + +This resolves the hazard between the mtc0 in the change_c0_status() and +the mfc0 in configure_exception_vector(). Without resolving this hazard +configure_exception_vector() could read an old value and would restore +this old value again. This would revert the changes change_c0_status() +did. I checked this by printing out the read_c0_status() at the end of +per_cpu_trap_init() and the ST0_MX is not set without this patch. + +The hazard is documented in the MIPS Architecture Reference Manual Vol. +III: MIPS32/microMIPS32 Privileged Resource Architecture (MD00088), rev +6.03 table 8.1 which includes: + + Producer | Consumer | Hazard + ----------|----------|---------------------------- + mtc0 | mfc0 | any coprocessor 0 register + +I saw this hazard on an Atheros AR9344 rev 2 SoC with a MIPS 74Kc CPU. +There the change_c0_status() function would activate the DSPen by +setting ST0_MX in the c0_status register. This was reverted and then the +system got a DSP exception when the DSP registers were saved in +save_dsp() in the first process switch. The crash looks like this: + +[ 0.089999] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear) +[ 0.097796] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear) +[ 0.107070] Kernel panic - not syncing: Unexpected DSP exception +[ 0.113470] Rebooting in 1 seconds.. + +We saw this problem in OpenWrt only on the MIPS 74Kc based Atheros SoCs, +not on the 24Kc based SoCs. We only saw it with kernel 5.4 not with +kernel 4.19, in addition we had to use GCC 8.4 or 9.X, with GCC 8.3 it +did not happen. + +In the kernel I bisected this problem to commit 9012d011660e ("compiler: +allow all arches to enable CONFIG_OPTIMIZE_INLINING"), but when this was +reverted it also happened after commit 172dcd935c34b ("MIPS: Always +allocate exception vector for MIPSr2+"). + +Commit 0b24cae4d535 ("MIPS: Add missing EHB in mtc0 -> mfc0 sequence.") +does similar changes to a different file. I am not sure if there are +more places affected by this problem. + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +Cc: <stable@vger.kernel.org> +--- + arch/mips/kernel/traps.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/mips/kernel/traps.c ++++ b/arch/mips/kernel/traps.c +@@ -2096,6 +2096,7 @@ static void configure_status(void) + + change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX, + status_set); ++ back_to_back_c0_hazard(); + } + + unsigned int hwrena; diff --git a/target/linux/generic/pending-5.4/350-MIPS-Add-missing-EHB-in-mtc0-mfc0-sequence-for-DSPen.patch b/target/linux/generic/pending-5.4/350-MIPS-Add-missing-EHB-in-mtc0-mfc0-sequence-for-DSPen.patch new file mode 100644 index 0000000000..063ec0e9fb --- /dev/null +++ b/target/linux/generic/pending-5.4/350-MIPS-Add-missing-EHB-in-mtc0-mfc0-sequence-for-DSPen.patch @@ -0,0 +1,61 @@ +From db4603e30effd74d4adb6bcdf73072b2c06fafcd Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens <hauke@hauke-m.de> +Date: Fri, 3 Jul 2020 00:07:15 +0200 +Subject: [PATCH] MIPS: Add missing EHB in mtc0 -> mfc0 sequence for DSPen + +This resolves the hazard between the mtc0 in the change_c0_status() and +the mfc0 in configure_exception_vector(). Without resolving this hazard +configure_exception_vector() could read an old value and would restore +this old value again. This would revert the changes change_c0_status() +did. I checked this by printing out the read_c0_status() at the end of +per_cpu_trap_init() and the ST0_MX is not set without this patch. + +The hazard is documented in the MIPS Architecture Reference Manual Vol. +III: MIPS32/microMIPS32 Privileged Resource Architecture (MD00088), rev +6.03 table 8.1 which includes: + + Producer | Consumer | Hazard + ----------|----------|---------------------------- + mtc0 | mfc0 | any coprocessor 0 register + +I saw this hazard on an Atheros AR9344 rev 2 SoC with a MIPS 74Kc CPU. +There the change_c0_status() function would activate the DSPen by +setting ST0_MX in the c0_status register. This was reverted and then the +system got a DSP exception when the DSP registers were saved in +save_dsp() in the first process switch. The crash looks like this: + +[ 0.089999] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear) +[ 0.097796] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes, linear) +[ 0.107070] Kernel panic - not syncing: Unexpected DSP exception +[ 0.113470] Rebooting in 1 seconds.. + +We saw this problem in OpenWrt only on the MIPS 74Kc based Atheros SoCs, +not on the 24Kc based SoCs. We only saw it with kernel 5.4 not with +kernel 4.19, in addition we had to use GCC 8.4 or 9.X, with GCC 8.3 it +did not happen. + +In the kernel I bisected this problem to commit 9012d011660e ("compiler: +allow all arches to enable CONFIG_OPTIMIZE_INLINING"), but when this was +reverted it also happened after commit 172dcd935c34b ("MIPS: Always +allocate exception vector for MIPSr2+"). + +Commit 0b24cae4d535 ("MIPS: Add missing EHB in mtc0 -> mfc0 sequence.") +does similar changes to a different file. I am not sure if there are +more places affected by this problem. + +Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> +Cc: <stable@vger.kernel.org> +--- + arch/mips/kernel/traps.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/mips/kernel/traps.c ++++ b/arch/mips/kernel/traps.c +@@ -2126,6 +2126,7 @@ static void configure_status(void) + + change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX, + status_set); ++ back_to_back_c0_hazard(); + } + + unsigned int hwrena; |