Message ID | 20200528231628.120171-1-syq@debian.org (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | mips: add o32_fp64 boot param to disable FP64 support | expand |
On Fri, May 29, 2020 at 07:16:28AM +0800, YunQiang Su wrote: > When build with CONFIG_O32_FP64_SUPPORTS, even all of the userland > is FPXX, we cannot run any FP32 binary. I don't understand what this means. Can you explain what the problem is ? > Then we need to disable FP64 support temporarily with a boot param: > o32_fp64=no/disable A boot parameter should IMHO be last resort. But I need to understand the problem first to think about different ways to solve this. Thomas.
Thomas Bogendoerfer <tsbogend@alpha.franken.de> 于2020年5月29日周五 下午7:09写道: > > On Fri, May 29, 2020 at 07:16:28AM +0800, YunQiang Su wrote: > > When build with CONFIG_O32_FP64_SUPPORTS, even all of the userland > > is FPXX, we cannot run any FP32 binary. > > I don't understand what this means. Can you explain what the problem > is ? > Some or most CPU cannot run FP32 application if CONFIG_O32_FP64_SUPPORTS is enabled. So we switch the whole Debian archive to FPXX. But the golang cannot support FP32 now. So I wish provides a way to support FP32 and FP64 with a single kernel image. > > Then we need to disable FP64 support temporarily with a boot param: > > o32_fp64=no/disable > > A boot parameter should IMHO be last resort. But I need to understand > the problem first to think about different ways to solve this. > Yes, I guess that we have a better solution, but I have no idea how to: 1. switch by /sys or /proc ? 2. support per-process mode switch. I think that the 2) should be better. https://web.archive.org/web/20180828210612/https://dmz- portal.mips.com/wiki/MIPS_O32_ABI_-_FR0_and_FR1_Interlinking > Thomas. > > -- > Crap can work. Given enough thrust pigs will fly, but it's not necessarily a > good idea. [ RFC1925, 2.3 ]
On Fri, 29 May 2020, YunQiang Su wrote: > > > When build with CONFIG_O32_FP64_SUPPORTS, even all of the userland > > > is FPXX, we cannot run any FP32 binary. > > > > I don't understand what this means. Can you explain what the problem > > is ? > > > > Some or most CPU cannot run FP32 application if > CONFIG_O32_FP64_SUPPORTS is enabled. > So we switch the whole Debian archive to FPXX. But the golang cannot > support FP32 now. > > So I wish provides a way to support FP32 and FP64 with a single kernel image. Well, FP32 and FP64 (and FPXX) are per-program attributes set in the ELF headers of o32 binaries and CP0.Status.FR is a per-process property. At program execution an FP64-enabled kernel will set CP0.Status.FR in the program's user context according to the FP32/FP64 setting in the program's ELF structures, or fail if hardware does not support the requested mode. The FPXX hybrid mode is there to permit running with either CP0.Status.FR setting, by tightening the FP ABI and forbidding the use of some code that is allowed with both FP32 and FP64. This mode also permits the use of either FP32 or FP64 modules (but not both at a time) in dynamic loading, by switching CP0.Status.FR accordingly as long as supported by the piece of hardware being run on. If you have software that only supports a certain FPxx setting, then build it accordingly and the kernel will do the rest. If the setting required is not compatible with what hardware supports, then you can't run your software on your hardware, and if you override the checks by patching the kernel, then you'll get incorrect results. So what problem are you trying to solve? Why do you need FP32 support if all your software is FPXX (which will run with any CP0.Status.FR setting), and why does Go have issues (what kind of issues?) with any particular FPxx setting given that it uses the same MIPS backend as all the other language frontends do? Maciej
Maciej W. Rozycki <macro@wdc.com> 于2020年6月4日周四 上午8:19写道: > > On Fri, 29 May 2020, YunQiang Su wrote: > > > > > When build with CONFIG_O32_FP64_SUPPORTS, even all of the userland > > > > is FPXX, we cannot run any FP32 binary. > > > > > > I don't understand what this means. Can you explain what the problem > > > is ? > > > > > > > Some or most CPU cannot run FP32 application if > > CONFIG_O32_FP64_SUPPORTS is enabled. > > So we switch the whole Debian archive to FPXX. But the golang cannot > > support FP32 now. > > > > So I wish provides a way to support FP32 and FP64 with a single kernel image. > > Well, FP32 and FP64 (and FPXX) are per-program attributes set in the ELF > headers of o32 binaries and CP0.Status.FR is a per-process property. At > program execution an FP64-enabled kernel will set CP0.Status.FR in the > program's user context according to the FP32/FP64 setting in the program's > ELF structures, or fail if hardware does not support the requested mode. Yes. It is a bug of golang. It is FP32 while claims that it is FPXX, due to it use gcc, while doesn't pass -mfp32 to it. https://go-review.googlesource.com/c/go/+/237058 > > The FPXX hybrid mode is there to permit running with either CP0.Status.FR > setting, by tightening the FP ABI and forbidding the use of some code that > is allowed with both FP32 and FP64. This mode also permits the use of > either FP32 or FP64 modules (but not both at a time) in dynamic loading, > by switching CP0.Status.FR accordingly as long as supported by the piece > of hardware being run on. > > If you have software that only supports a certain FPxx setting, then > build it accordingly and the kernel will do the rest. If the setting > required is not compatible with what hardware supports, then you can't run > your software on your hardware, and if you override the checks by patching > the kernel, then you'll get incorrect results. > > So what problem are you trying to solve? Why do you need FP32 support if The problem is that I enabled CONFIG_O32_FP64_SUPPORT for Debian buster while now golang cannot work with it. I don't want to switch it off again, by instead, I *was* preferring to provides a boot-time option for sysadmin. So I can keep this option open, and the kernel of DSA (debian official sysadmin) can turn it off on boot-time. > all your software is FPXX (which will run with any CP0.Status.FR setting), > and why does Go have issues (what kind of issues?) with any particular > FPxx setting given that it uses the same MIPS backend as all the other > language frontends do? > > Maciej
diff --git a/arch/mips/include/asm/abi.h b/arch/mips/include/asm/abi.h index dba7f4b6bebf..c5d297c67a9c 100644 --- a/arch/mips/include/asm/abi.h +++ b/arch/mips/include/asm/abi.h @@ -29,4 +29,6 @@ struct mips_abi { struct mips_vdso_image *vdso; }; +extern bool o32_fp64_support; + #endif /* _ASM_ABI_H */ diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index 5aa29ced6970..dc55815923b5 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h @@ -15,6 +15,7 @@ #include <uapi/linux/elf.h> #include <asm/current.h> +#include <asm/abi.h> /* ELF header e_flags defines. */ /* MIPS architecture level. */ @@ -293,7 +294,8 @@ void mips_dump_regs64(u64 *uregs, const struct pt_regs *regs); if (((__h->e_flags & EF_MIPS_ABI) != 0) && \ ((__h->e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32)) \ __res = 0; \ - if (__h->e_flags & __MIPS_O32_FP64_MUST_BE_ZERO) \ + if ((__h->e_flags & __MIPS_O32_FP64_MUST_BE_ZERO) && \ + !o32_fp64_support) \ __res = 0; \ \ __res; \ diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c index 7b045d2a0b51..3de15308971c 100644 --- a/arch/mips/kernel/elf.c +++ b/arch/mips/kernel/elf.c @@ -11,6 +11,7 @@ #include <asm/cpu-features.h> #include <asm/cpu-info.h> +#include <asm/abi.h> #ifdef CONFIG_MIPS_FP_SUPPORT @@ -176,7 +177,7 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr, return -ELIBBAD; } - if (!IS_ENABLED(CONFIG_MIPS_O32_FP64_SUPPORT)) + if (!o32_fp64_support) return 0; fp_abi = state->fp_abi; @@ -282,7 +283,7 @@ void mips_set_personality_fp(struct arch_elf_state *state) * not be worried about N32/N64 binaries. */ - if (!IS_ENABLED(CONFIG_MIPS_O32_FP64_SUPPORT)) + if (!o32_fp64_support) return; switch (state->overall_fp_mode) { diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index ff5320b79100..1bb93941c4c1 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -760,7 +760,7 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value) return 0; /* Only accept a mode change if 64-bit FP enabled for o32. */ - if (!IS_ENABLED(CONFIG_MIPS_O32_FP64_SUPPORT)) + if (!o32_fp64_support) return -EOPNOTSUPP; /* And only for o32 tasks. */ diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 7b537fa2035d..2475843487aa 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -484,6 +484,21 @@ static int __init early_parse_elfcorehdr(char *p) early_param("elfcorehdr", early_parse_elfcorehdr); #endif +#ifdef CONFIG_MIPS_O32_FP64_SUPPORT +bool o32_fp64_support __read_mostly = true; +static int __init early_parse_o32_fp64(char *p) +{ + if (strncmp(p, "no", 2) == 0 || + strncmp(p, "disable", 7) == 0 + strncmp(p, "off", 3) == 0) + o32_fp64_support = false; + return 0; +} +early_param("o32_fp64", early_parse_o32_fp64); +#else +bool o32_fp64_support __read_mostly; +#endif + #ifdef CONFIG_KEXEC static void __init mips_parse_crashkernel(void) { diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index 587cf1d115e8..54d7a5122137 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c @@ -33,6 +33,7 @@ #include <linux/uaccess.h> #include <asm/cpu-info.h> +#include <asm/abi.h> #include <asm/processor.h> #include <asm/fpu_emulator.h> #include <asm/fpu.h> @@ -784,7 +785,7 @@ static inline int cop1_64bit(struct pt_regs *xcp) if (IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_MIPS32_O32)) return 1; else if (IS_ENABLED(CONFIG_32BIT) && - !IS_ENABLED(CONFIG_MIPS_O32_FP64_SUPPORT)) + !o32_fp64_support) return 0; return !test_thread_flag(TIF_32BIT_FPREGS);
When build with CONFIG_O32_FP64_SUPPORTS, even all of the userland is FPXX, we cannot run any FP32 binary. Then we need to disable FP64 support temporarily with a boot param: o32_fp64=no/disable Signed-off-by: YunQiang Su <syq@debian.org> --- arch/mips/include/asm/abi.h | 2 ++ arch/mips/include/asm/elf.h | 4 +++- arch/mips/kernel/elf.c | 5 +++-- arch/mips/kernel/process.c | 2 +- arch/mips/kernel/setup.c | 15 +++++++++++++++ arch/mips/math-emu/cp1emu.c | 3 ++- 6 files changed, 26 insertions(+), 5 deletions(-)