lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230519163023.70542-1-jiaxun.yang@flygoat.com>
Date:   Fri, 19 May 2023 17:30:23 +0100
From:   Jiaxun Yang <jiaxun.yang@...goat.com>
To:     linux-mips@...r.kernel.org
Cc:     linux-kernel@...r.kernel.org, tsbogend@...ha.franken.de,
        Jiaxun Yang <jiaxun.yang@...goat.com>
Subject: [PATCH] MIPS: Fix MIPS_O32_FP64_SUPPORT for 64bit CPUs before R2

MIPS_O32_FP64_SUPPORT enables possibility of using all 32 FPRs on 32bit
kernel in case CPU implemented FR1. As FR1 is present on all 64bit CPUs
following R4000's priviliged spec, there is no reason to limit such support
to R2+ CPUs.

Fix it by remove architecture reversion conditions in FR1 context switch
code and enable relevant bits in kernel's FIR copy.

Signed-off-by: Jiaxun Yang <jiaxun.yang@...goat.com>
---
 arch/mips/include/asm/asmmacro.h |  6 ++----
 arch/mips/include/asm/fpu.h      |  3 +--
 arch/mips/kernel/elf.c           |  5 ++---
 arch/mips/kernel/fpu-probe.c     | 17 +++++++++++++++++
 arch/mips/kernel/r4k_fpu.S       | 16 ++++++----------
 5 files changed, 28 insertions(+), 19 deletions(-)

diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h
index 067a635d3bc8..3e7c19ee6a90 100644
--- a/arch/mips/include/asm/asmmacro.h
+++ b/arch/mips/include/asm/asmmacro.h
@@ -130,8 +130,7 @@
 	.endm
 
 	.macro	fpu_save_double thread status tmp
-#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
-    defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
+#if defined(CONFIG_64BIT) || defined(CONFIG_MIPS_O32_FP64_SUPPORT)
 	sll	\tmp, \status, 5
 	bgez	\tmp, 10f
 	fpu_save_16odd \thread
@@ -189,8 +188,7 @@
 	.endm
 
 	.macro	fpu_restore_double thread status tmp
-#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
-    defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
+#if defined(CONFIG_64BIT) || defined(CONFIG_MIPS_O32_FP64_SUPPORT)
 	sll	\tmp, \status, 5
 	bgez	\tmp, 10f				# 16 register mode?
 
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h
index 86310d6e1035..1cd820e79f77 100644
--- a/arch/mips/include/asm/fpu.h
+++ b/arch/mips/include/asm/fpu.h
@@ -71,8 +71,7 @@ static inline int __enable_fpu(enum fpu_mode mode)
 		goto fr_common;
 
 	case FPU_64BIT:
-#if !(defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR5) || \
-      defined(CONFIG_CPU_MIPSR6) || defined(CONFIG_64BIT))
+#if !(defined(CONFIG_64BIT) || defined(CONFIG_MIPS_O32_FP64_SUPPORT))
 		/* we only have a 32-bit FPU */
 		return SIGFPE;
 #endif
diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c
index 5582a4ca1e9e..0895bc9b5dd7 100644
--- a/arch/mips/kernel/elf.c
+++ b/arch/mips/kernel/elf.c
@@ -250,9 +250,8 @@ int arch_check_elf(void *_ehdr, bool has_interpreter, void *_interp_ehdr,
 		state->overall_fp_mode = FP_FRE;
 	else if ((prog_req.fr1 && prog_req.frdefault) ||
 		 (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) ?
+		/* Make sure CPUs without FR1 will not pick FR1 */
+		state->overall_fp_mode = (raw_current_cpu_data.fpu_id & MIPS_FPIR_F64) ?
 					  FP_FR1 : FP_FR0;
 	else if (prog_req.fr1)
 		state->overall_fp_mode = FP_FR1;
diff --git a/arch/mips/kernel/fpu-probe.c b/arch/mips/kernel/fpu-probe.c
index e689d6a83234..383c43e5c86a 100644
--- a/arch/mips/kernel/fpu-probe.c
+++ b/arch/mips/kernel/fpu-probe.c
@@ -289,6 +289,23 @@ void cpu_set_fpu_opts(struct cpuinfo_mips *c)
 			c->options |= MIPS_CPU_FRE;
 	}
 
+	/* Fix up FIR for FPU earlier than R2 */
+	if (!cpu_has_mips_r2_r6) {
+		c->fpu_id |= MIPS_FPIR_S;
+#ifdef CONFIG_CPU_R4K_FPU
+		/* All known R4000 class FPU implemented double */
+		c->fpu_id |= MIPS_FPIR_D;
+#endif
+		if (cpu_has_64bits) {
+			/* Try to enable FR1 */
+			change_c0_status(ST0_FR, ST0_FR);
+			if (read_c0_status() & ST0_FR) {
+				c->fpu_id |= MIPS_FPIR_F64;
+				c->options |= MIPS_CPU_32FPR;
+			}
+		}
+	}
+
 	cpu_set_fpu_fcsr_mask(c);
 	cpu_set_fpu_2008(c);
 	cpu_set_nan_2008(c);
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
index 4e8c98517d9d..eeef115fc39e 100644
--- a/arch/mips/kernel/r4k_fpu.S
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -40,8 +40,7 @@
  */
 LEAF(_save_fp)
 EXPORT_SYMBOL(_save_fp)
-#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
-    defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
+#if defined(CONFIG_64BIT) || defined(CONFIG_MIPS_O32_FP64_SUPPORT)
 	mfc0	t0, CP0_STATUS
 #endif
 	fpu_save_double a0 t0 t1		# clobbers t1
@@ -52,8 +51,7 @@ EXPORT_SYMBOL(_save_fp)
  * Restore a thread's fp context.
  */
 LEAF(_restore_fp)
-#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
-    defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
+#if defined(CONFIG_64BIT) || defined(CONFIG_MIPS_O32_FP64_SUPPORT)
 	mfc0	t0, CP0_STATUS
 #endif
 	fpu_restore_double a0 t0 t1		# clobbers t1
@@ -102,11 +100,10 @@ LEAF(_save_fp_context)
 	cfc1	t1, fcr31
 	.set	pop
 
-#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
-    defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
+#if defined(CONFIG_64BIT) || defined(CONFIG_MIPS_O32_FP64_SUPPORT)
 	.set	push
 	.set	hardfloat
-#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR5)
+#if MIPS_ISA_REV < 6
 	.set	mips32r2
 	.set	fp=64
 	mfc0	t0, CP0_STATUS
@@ -170,11 +167,10 @@ LEAF(_save_fp_context)
 LEAF(_restore_fp_context)
 	EX	lw t1, 0(a1)
 
-#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPSR2) || \
-    defined(CONFIG_CPU_MIPSR5) || defined(CONFIG_CPU_MIPSR6)
+#if defined(CONFIG_64BIT) || defined(CONFIG_MIPS_O32_FP64_SUPPORT)
 	.set	push
 	.set	hardfloat
-#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR5)
+#if MIPS_ISA_REV < 6
 	.set	mips32r2
 	.set	fp=64
 	mfc0	t0, CP0_STATUS
-- 
2.39.2 (Apple Git-143)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ