From: YunQiang Su <yunqiang.su(a)cipunited.com>
The MIPS FPU may have 3 mode:
FR=0: MIPS I style, all of the FPR are single.
FR=1: all 32 FPR can be double.
FRE: redirecting the rw of odd-FPR to the upper 32bit of even-double FPR.
The binary may have 3 mode:
FP32: can only work with FR=0 and FRE mode
FPXX: can work with all of FR=0/FR=1/FRE mode.
FP64: can only work with FR=1 mode
Some binary, for example the output of golang, may be mark as FPXX,
while in fact they are FP32. It is caused by the bug of design and linker:
Object produced by pure Go has no FP annotation while in fact they are FP32;
if we link them with the C module which marked as FPXX,
the result will be marked as FPXX. If these fake-FPXX binaries is executed
in FR=1 mode, some problem will happen.
In Golang, now we add the FP32 annotation, so the future golang programs
won't have this problem. While for the existing binaries, we need a
kernel workaround.
Currently, FR=1 mode is used for all FPXX binary, it makes some wrong
behivour of the binaries. Since FPXX binary can work with both FR=1 and FR=0,
we force it to use FR=0 or FRE (for R6 CPU).
Reference:
https://web.archive.org/web/20180828210612/https://dmz-portal.mips.com/wiki…https://go-review.googlesource.com/c/go/+/239217https://go-review.googlesource.com/c/go/+/237058
Signed-off-by: YunQiang Su <yunqiang.su(a)cipunited.com>
Cc: stable(a)vger.kernel.org # 4.19+
v6->v7:
Use FRE mode for pre-R6 binaries on R6 CPU.
v5->v6:
Rollback to V3, aka remove config option.
v4->v5:
Fix CONFIG_MIPS_O32_FPXX_USE_FR0 usage: if -> ifdef
v3->v4:
introduce a config option: CONFIG_MIPS_O32_FPXX_USE_FR0
v2->v3:
commit message: add Signed-off-by and Cc to stable.
v1->v2:
Fix bad commit message: in fact, we are switching to FR=0
---
arch/mips/kernel/elf.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c
index 7b045d2a0b51..4d4db619544b 100644
--- a/arch/mips/kernel/elf.c
+++ b/arch/mips/kernel/elf.c
@@ -232,11 +232,16 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr,
* that inherently require the hybrid FP mode.
* - If FR1 and FRDEFAULT is true, that means we hit the any-abi or
* fpxx case. This is because, in any-ABI (or no-ABI) we have no FPU
- * instructions so we don't care about the mode. We will simply use
- * the one preferred by the hardware. In fpxx case, that ABI can
- * handle both FR=1 and FR=0, so, again, we simply choose the one
- * preferred by the hardware. Next, if we only use single-precision
- * FPU instructions, and the default ABI FPU mode is not good
+ * instructions so we don't care about the mode.
+ * In fpxx case, that ABI can handle all of FR=1/FR=0/FRE mode.
+ * Here, we need to use FR=0/FRE mode instead of FR=1, because some binaries
+ * may be mark as FPXX by mistake due to bugs of design and linker:
+ * The object produced by pure Go has no FP annotation,
+ * then is treated as any-ABI by linker, although in fact they are FP32;
+ * if any-ABI object is linked with FPXX object, the result will be mark as FPXX.
+ * Then the problem happens: run FP32 binaries in FR=1 mode.
+ * - If we only use single-precision FPU instructions,
+ * and the default ABI FPU mode is not good
* (ie single + any ABI combination), we set again the FPU mode to the
* one is preferred by the hardware. Next, if we know that the code
* will only use single-precision instructions, shown by single being
@@ -248,8 +253,9 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr,
*/
if (prog_req.fre && !prog_req.frdefault && !prog_req.fr1)
state->overall_fp_mode = FP_FRE;
- else if ((prog_req.fr1 && prog_req.frdefault) ||
- (prog_req.single && !prog_req.frdefault))
+ else if (prog_req.fr1 && prog_req.frdefault)
+ state->overall_fp_mode = cpu_has_mips_r6 ? FP_FRE : FP_FR0;
+ else if (prog_req.single && !prog_req.frdefault)
/* Make sure 64-bit MIPS III/IV/64R1 will not pick FR1 */
state->overall_fp_mode = ((raw_current_cpu_data.fpu_id & MIPS_FPIR_F64) &&
cpu_has_mips_r2_r6) ?
--
2.20.1
The patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable(a)vger.kernel.org>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
>From 6d5e7af1f6f5924de5dd1ebe97675c2363100878 Mon Sep 17 00:00:00 2001
From: Srinivas Kandagatla <srinivas.kandagatla(a)linaro.org>
Date: Fri, 15 Jan 2021 16:25:59 +0000
Subject: [PATCH] soundwire: debugfs: use controller id instead of link_id
link_id can be zero and if we have multiple controller instances
in a system like Qualcomm debugfs will end-up with duplicate namespace
resulting in incorrect debugfs entries.
Using id should give a unique debugfs directory entry and should fix below
warning too.
"debugfs: Directory 'master-0' with parent 'soundwire' already present!"
Fixes: bf03473d5bcc ("soundwire: add debugfs support")
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla(a)linaro.org>
Link: https://lore.kernel.org/r/20210115162559.20869-1-srinivas.kandagatla@linaro…
Signed-off-by: Vinod Koul <vkoul(a)kernel.org>
diff --git a/drivers/soundwire/debugfs.c b/drivers/soundwire/debugfs.c
index b6cad0d59b7b..5f9efa42bb25 100644
--- a/drivers/soundwire/debugfs.c
+++ b/drivers/soundwire/debugfs.c
@@ -19,7 +19,7 @@ void sdw_bus_debugfs_init(struct sdw_bus *bus)
return;
/* create the debugfs master-N */
- snprintf(name, sizeof(name), "master-%d", bus->link_id);
+ snprintf(name, sizeof(name), "master-%d", bus->id);
bus->debugfs = debugfs_create_dir(name, sdw_debugfs_root);
}