[PATCH 07/10] MIPS: support for hybrid FPRs
Hybrid FPRs is a scheme where scalar FP registers are 64b wide, but accesses to odd indexed single registers use bits 63:32 of the preceeding even indexed 64b register. In this mode all FP code except that built for the plain FP64 ABI can execute correctly. Most notably a combination of FP64A & FP32 code can execute correctly, allowing for existing FP32 binaries to be linked with new FP64A binaries that can make use of 64 bit FP & MSA. Hybrid FPRs are implemented by setting both the FR & FRE bits, trapping & emulating single precision FP instructions (via Reserved Instruction exceptions) whilst allowing others to execute natively. It therefore has a penalty in terms of execution speed, and should only be used when no fully native mode can be. As more binaries are recompiled to use either the FPXX or FP64(A) ABIs, the need for hybrid FPRs should diminish. However in the short to mid term it allows for a gradual transition towards that world, rather than a complete ABI break which is not feasible for some users & not desirable for many. A task will be executed using the hybrid FPR scheme when its TIF_HYBRID_FPREGS flag is set & TIF_32BIT_FPREGS is clear. A further patch will set the flags as necessary, this patch simply adds the infrastructure necessary for the hybrid FPR mode to work. Signed-off-by: Paul Burton --- arch/mips/include/asm/elf.h | 3 +++ arch/mips/include/asm/fpu.h | 49 +++-- arch/mips/include/asm/thread_info.h | 2 ++ arch/mips/kernel/traps.c| 47 +++ arch/mips/math-emu/cp1emu.c | 9 +-- 5 files changed, 100 insertions(+), 10 deletions(-) diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index 1d38fe0..9343529 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h @@ -269,6 +269,8 @@ do { \ else\ set_thread_flag(TIF_32BIT_FPREGS); \ \ + clear_thread_flag(TIF_HYBRID_FPREGS); \ + \ if (personality(current->personality) != PER_LINUX) \ set_personality(PER_LINUX); \ \ @@ -325,6 +327,7 @@ do { \ \ clear_thread_flag(TIF_32BIT_REGS); \ clear_thread_flag(TIF_32BIT_FPREGS);\ + clear_thread_flag(TIF_HYBRID_FPREGS); \ clear_thread_flag(TIF_32BIT_ADDR); \ \ if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h index 4d0aeda..6e60431 100644 --- a/arch/mips/include/asm/fpu.h +++ b/arch/mips/include/asm/fpu.h @@ -36,14 +36,16 @@ extern void _restore_fp(struct task_struct *); /* * This enum specifies a mode in which we want the FPU to operate, for cores - * which implement the Status.FR bit. Note that FPU_32BIT & FPU_64BIT - * purposefully have the values 0 & 1 respectively, so that an integer value - * of Status.FR can be trivially casted to the corresponding enum fpu_mode. + * which implement the Status.FR bit. Note that the bottom bit of the value + * purposefully matches the desired value of the Status.FR bit. */ enum fpu_mode { FPU_32BIT = 0, /* FR = 0 */ - FPU_64BIT, /* FR = 1 */ + FPU_64BIT, /* FR = 1, FRE = 0 */ FPU_AS_IS, + FPU_HYBRID, /* FR = 1, FRE = 1 */ + +#define FPU_FR_MASK0x1 }; static inline int __enable_fpu(enum fpu_mode mode) @@ -57,6 +59,14 @@ static inline int __enable_fpu(enum fpu_mode mode) enable_fpu_hazard(); return 0; + case FPU_HYBRID: + if (!cpu_has_fre) + return SIGFPE; + + /* set FRE */ + write_c0_config5(read_c0_config5() | MIPS_CONF5_FRE); + goto fr_common; + case FPU_64BIT: #if !(defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_64BIT)) /* we only have a 32-bit FPU */ @@ -64,8 +74,11 @@ static inline int __enable_fpu(enum fpu_mode mode) #endif /* fall through */ case FPU_32BIT: + /* clear FRE */ + write_c0_config5(read_c0_config5() & ~MIPS_CONF5_FRE); +fr_common: /* set CU1 & change FR appropriate
Re: [PATCH 07/10] MIPS: support for hybrid FPRs
Hi, On Thu, Sep 11, 2014 at 08:30:20AM +0100, Paul Burton wrote: > Hybrid FPRs is a scheme where scalar FP registers are 64b wide, but > accesses to odd indexed single registers use bits 63:32 of the > preceeding even indexed 64b register. In this mode all FP code > except that built for the plain FP64 ABI can execute correctly. Most > notably a combination of FP64A & FP32 code can execute correctly, > allowing for existing FP32 binaries to be linked with new FP64A binaries > that can make use of 64 bit FP & MSA. This commit (4227a2d4efc9c84f35826dc4d1e6dc183f6c1c05, bisected) in 3.19-rc1 breaks my Loongson-2F system. I get endless amount of "Reserved instruction in kernel code" exceptions when booting. See some examples below. Nothing crashes, and there is some forward progress, but obviously it's completely unusable. Any ideas? [2.872000] Reserved instruction in kernel code[#1]: [2.872000] CPU: 0 PID: 231 Comm: hotplug Not tainted 3.18.0-lemote-los_7f08-09423-g988adfd #1 [2.872000] task: 98009f1c7480 ti: 98009a2e8000 task.ti: 98009a2e8000 [2.872000] $ 0 : 77d32c14 0001 [2.872000] $ 4 : 1000802c 98009a2ebeb0 0002 [2.872000] $ 8 : 0010 7efefeff 24242424 81010100 [2.872000] $12 : 100044e1 101f [2.872000] $16 : 00400164 7fdb3ee0 77d62cf8 [2.872000] $20 : 77d61ed0 77d61ed0 004022d8 [2.872000] $24 : 0005 77d4ba80 [2.872000] $28 : 98009a2e8000 98009a2ebe70 7fdb3ee8 802077e0 [2.872000] Hi: 002c [2.872000] Lo: 000b [2.872000] epc : 8020e8d4 do_cpu+0x304/0x4f0 [2.872000] Not tainted [2.872000] ra: 802077e0 ret_from_exception+0x0/0x1c [2.872000] Status: 100044e3 KX SX UX KERNEL EXL IE [2.872000] Cause : 10008028 [2.872000] PrId : 6303 (ICT Loongson-2) [2.872000] Modules linked in: [2.872000] Process hotplug (pid: 231, threadinfo=98009a2e8000, task=98009f1c7480, tls=) [2.872000] Stack : 77d5 77d62c10 c000 77d61ed0 77d622d8 00400164 7fdb3ee0 802077e0 77d32c14 7fdb3da8 77d62bf0 7fdb3db8 7fdb3d90 7fdb3ee8 bba0ffce 7efefeff 24242424 81010100 0fc1 00400164 7fdb3ee0 77d62cf8 77d61ed0 77d61ed0 004022d8 0005 77d4ba80 6474e552 77d6a000 7fdb3d90 7fdb3ee8 77d41038 ... [2.872000] Call Trace: [2.872000] [] do_cpu+0x304/0x4f0 [2.872000] [] ret_from_exception+0x0/0x1c [2.872000] [2.872000] Code: 30420001 2c420001 0040202d <40038005> 2405feff 00651824 40838005 3c032000 3c052400 [2.876000] ---[ end trace 71c7b14ce7da936f ]--- [2.88] Reserved instruction in kernel code[#2]: [2.88] CPU: 0 PID: 232 Comm: hotplug Tainted: G D 3.18.0-lemote-los_7f08-09423-g988adfd #1 [2.88] task: 98009f1c5ea8 ti: 98009a2e4000 task.ti: 98009a2e4000 [2.88] $ 0 : 77832c14 0001 [2.88] $ 4 : 1000802c 98009a2e7eb0 0002 [2.88] $ 8 : 0010 7efefeff 24242424 81010100 [2.88] $12 : 100044e1 101f [2.88] $16 : 00400164 7fd876e0 77862cf8 [2.88] $20 : 77861ed0 77861ed0 004022d8 [2.88] $24 : 0005 7784ba80 [2.88] $28 : 98009a2e4000 98009a2e7e70 7fd876e8 802077e0 [2.88] Hi: 002c [2.88] Lo: 000b [2.88] epc : 8020e8d4 do_cpu+0x304/0x4f0 [2.88] Tainted: G D [2.88] ra: 802077e0 ret_from_exception+0x0/0x1c [2.88] Status: 100044e3 KX SX UX KERNEL EXL IE [2.88] Cause : 10008028 [2.88] PrId : 6303 (ICT Loongson-2) [2.88] Modules linked in: [2.88] Process hotplug (pid: 232, threadinfo=98009a2e4000, task=98009f1c5ea8, tls=) [2.88] Stack :
Re: [PATCH 07/10] MIPS: support for hybrid FPRs
On Wed, Dec 24, 2014 at 01:21:11AM +0200, Aaro Koskinen wrote: > Hi, > > On Thu, Sep 11, 2014 at 08:30:20AM +0100, Paul Burton wrote: > > Hybrid FPRs is a scheme where scalar FP registers are 64b wide, but > > accesses to odd indexed single registers use bits 63:32 of the > > preceeding even indexed 64b register. In this mode all FP code > > except that built for the plain FP64 ABI can execute correctly. Most > > notably a combination of FP64A & FP32 code can execute correctly, > > allowing for existing FP32 binaries to be linked with new FP64A binaries > > that can make use of 64 bit FP & MSA. > > This commit (4227a2d4efc9c84f35826dc4d1e6dc183f6c1c05, bisected) > in 3.19-rc1 breaks my Loongson-2F system. I get endless amount > of "Reserved instruction in kernel code" exceptions when booting. > See some examples below. Nothing crashes, and there is some forward > progress, but obviously it's completely unusable. > > Any ideas? > > [2.872000] Reserved instruction in kernel code[#1]: ... > Code: 30420001 2c420001 0040202d <40038005> 2405feff 00651824 40838005 > 3c032000 3c052400 0x40038005 = mfc0 v1,$16,5 = mfc0 v1,Config5 Does this help (in linux-next)?: http://git.linux-mips.org/cgit/ralf/upstream-sfr.git/commit/?id=5bba8dec735f18fe7a2fcd8327f28ef095337ff2 Cheers James signature.asc Description: Digital signature
Re: [PATCH 07/10] MIPS: support for hybrid FPRs
Hi, On Tue, Dec 23, 2014 at 11:31:54PM +, James Hogan wrote: > On Wed, Dec 24, 2014 at 01:21:11AM +0200, Aaro Koskinen wrote: > > On Thu, Sep 11, 2014 at 08:30:20AM +0100, Paul Burton wrote: > > > Hybrid FPRs is a scheme where scalar FP registers are 64b wide, but > > > accesses to odd indexed single registers use bits 63:32 of the > > > preceeding even indexed 64b register. In this mode all FP code > > > except that built for the plain FP64 ABI can execute correctly. Most > > > notably a combination of FP64A & FP32 code can execute correctly, > > > allowing for existing FP32 binaries to be linked with new FP64A binaries > > > that can make use of 64 bit FP & MSA. > > > > This commit (4227a2d4efc9c84f35826dc4d1e6dc183f6c1c05, bisected) > > in 3.19-rc1 breaks my Loongson-2F system. I get endless amount > > of "Reserved instruction in kernel code" exceptions when booting. > > See some examples below. Nothing crashes, and there is some forward > > progress, but obviously it's completely unusable. > > > > Any ideas? > > > > [2.872000] Reserved instruction in kernel code[#1]: > ... > > Code: 30420001 2c420001 0040202d <40038005> 2405feff 00651824 40838005 > > 3c032000 3c052400 > > 0x40038005 = mfc0 v1,$16,5 = mfc0 v1,Config5 > > Does this help (in linux-next)?: > http://git.linux-mips.org/cgit/ralf/upstream-sfr.git/commit/?id=5bba8dec735f18fe7a2fcd8327f28ef095337ff2 Yes, it does. Many thanks! A. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/