some binary, for example the output of golang, may be mark as FPXX, while in fact they are still FP32.
Since FPXX binary can work with both FR=1 and FR=0, we force it to use FR=0 here.
https://go-review.googlesource.com/c/go/+/239217 https://go-review.googlesource.com/c/go/+/237058
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
Signed-off-by: YunQiang Su yunqiang.su@cipunited.com Cc: stable@vger.kernel.org # 4.19+ --- arch/mips/kernel/elf.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c index 7b045d2a0b51..bf798ce0ec0e 100644 --- a/arch/mips/kernel/elf.c +++ b/arch/mips/kernel/elf.c @@ -234,9 +234,10 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr, * 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 + * handle both FR=1 and FR=0. Here, we use FR=0, because some + * binaries may be mark as FPXX by mistake (ie, output of golang). + * - 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 +249,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 = 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) ?
On Sat, 20 Feb 2021, YunQiang Su wrote:
some binary, for example the output of golang, may be mark as FPXX, while in fact they are still FP32.
Since FPXX binary can work with both FR=1 and FR=0, we force it to use FR=0 here.
This defeats the purpose of FPXX of working with what hardware provides; R6 has the value of FR hardwired according to the FPU configuration[1][2].
https://go-review.googlesource.com/c/go/+/239217 https://go-review.googlesource.com/c/go/+/237058
You need to fix the compiler. In the interim you may be able to use `objcopy', `elfedit' or a similar tool to fix up the broken existing binaries if required.
NB I suspect there is something wrong with the linker as well, because I would expect the FP mode of an input legacy object (that is one without GNU attributes or MIPS abiflags) to be interpreted according to the legacy ABI requirements, i.e. o32 => FR=0, n32/n64 => FR=1, and the output GNU attributes or MIPS abiflags set accordingly. You need to investigate further what is going on here.
References:
[1] "MIPS Architecture For Programmers, Volume I-A: Introduction to the MIPS64 Architecture", Imagination Technologies Ltd., Document Number: MD00083, Revision 6.01, August 20, 2014, Table 6.4 "FPU Register Models Availability and Compliance", p. 87
[2] "MIPSAR Architecture For Programmers Volume III: MIPS64 / microMIPS64 Privileged Resource Architecture", Imagination Technologies Ltd., Document Number: MD00091, Revision 6.03, December 22, 2015, Table 9.49 "Status Register Field Descriptions", p. 215
Maciej
Maciej W. Rozycki macro@orcam.me.uk 于2021年2月20日周六 下午10:55写道:
On Sat, 20 Feb 2021, YunQiang Su wrote:
some binary, for example the output of golang, may be mark as FPXX, while in fact they are still FP32.
Since FPXX binary can work with both FR=1 and FR=0, we force it to use FR=0 here.
This defeats the purpose of FPXX of working with what hardware provides;
Yes. It is some like a workaround. Should we add a new CONFIG option?
R6 has the value of FR hardwired according to the FPU configuration[1][2].
https://go-review.googlesource.com/c/go/+/239217 https://go-review.googlesource.com/c/go/+/237058
You need to fix the compiler. In the interim you may be able to use `objcopy', `elfedit' or a similar tool to fix up the broken existing binaries if required.
The above 2 merge request of golang are just for it. This patch for kernel is to support the current exists binary that we cannot modify. For example, use the kernel of Debian 11 with the userland of Debian 10.
Without this workaround, then, we cannot switch on O32_FP64 support. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=962485
NB I suspect there is something wrong with the linker as well, because I would expect the FP mode of an input legacy object (that is one without GNU attributes or MIPS abiflags) to be interpreted according to the legacy ABI requirements, i.e. o32 => FR=0, n32/n64 => FR=1, and the output GNU attributes or MIPS abiflags set accordingly. You need to investigate further what is going on here.
Yes. This is a problem that I will inveset.
References:
[1] "MIPS Architecture For Programmers, Volume I-A: Introduction to the MIPS64 Architecture", Imagination Technologies Ltd., Document Number: MD00083, Revision 6.01, August 20, 2014, Table 6.4 "FPU Register Models Availability and Compliance", p. 87
[2] "MIPSAR Architecture For Programmers Volume III: MIPS64 / microMIPS64 Privileged Resource Architecture", Imagination Technologies Ltd., Document Number: MD00091, Revision 6.03, December 22, 2015, Table 9.49 "Status Register Field Descriptions", p. 215
Maciej
-- YunQiang Su
linux-stable-mirror@lists.linaro.org