All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] MIPS: FP cleanup & no-FP support
@ 2017-06-05 18:21 ` Paul Burton
  0 siblings, 0 replies; 23+ messages in thread
From: Paul Burton @ 2017-06-05 18:21 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

This series tidies up support for floating point a little, then
introduces support for disabling it via Kconfig. The end result is that
it becomes possible to compile a kernel which does not include any
support for userland which makes use of floating point instructions -
meaning that it never enables an FPU & does not include the FPU
emulator. The benefit of this is that if you know your userland code
will not use FP instructions then you can shrink the kernel by around
65KiB.

Applies atop v4.12-rc4.

Paul Burton (5):
  MIPS: Remove unused R6000 support
  MIPS: Move r4k FP code from r4k_switch.S to r4k_fpu.S
  MIPS: Move r2300 FP code from r2300_switch.S to r2300_fpu.S
  MIPS: Remove unused ST_OFF from r2300_switch.S
  MIPS: Allow floating point support to be disabled

 arch/mips/Kconfig                    |  41 ++++---
 arch/mips/Makefile                   |   3 +-
 arch/mips/include/asm/cpu-features.h |  11 +-
 arch/mips/include/asm/cpu-type.h     |   5 -
 arch/mips/include/asm/cpu.h          |   5 -
 arch/mips/include/asm/dsemul.h       |  34 ++++++
 arch/mips/include/asm/fpu.h          |   3 +
 arch/mips/include/asm/fpu_emulator.h |  16 +++
 arch/mips/include/asm/module.h       |   2 -
 arch/mips/kernel/Makefile            |  13 ++-
 arch/mips/kernel/cpu-probe.c         |  18 ----
 arch/mips/kernel/octeon_switch.S     |   5 -
 arch/mips/kernel/process.c           |   8 ++
 arch/mips/kernel/r2300_fpu.S         |  78 +++++++++++++-
 arch/mips/kernel/r2300_switch.S      |  81 --------------
 arch/mips/kernel/r4k_fpu.S           | 196 +++++++++++++++++++++++++++++++++
 arch/mips/kernel/r4k_switch.S        | 203 -----------------------------------
 arch/mips/kernel/r6000_fpu.S         |  99 -----------------
 arch/mips/kernel/traps.c             |  15 ---
 arch/mips/mm/tlbex.c                 |   5 -
 20 files changed, 376 insertions(+), 465 deletions(-)
 delete mode 100644 arch/mips/kernel/r6000_fpu.S

-- 
2.13.0

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 0/5] MIPS: FP cleanup & no-FP support
@ 2017-06-05 18:21 ` Paul Burton
  0 siblings, 0 replies; 23+ messages in thread
From: Paul Burton @ 2017-06-05 18:21 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

This series tidies up support for floating point a little, then
introduces support for disabling it via Kconfig. The end result is that
it becomes possible to compile a kernel which does not include any
support for userland which makes use of floating point instructions -
meaning that it never enables an FPU & does not include the FPU
emulator. The benefit of this is that if you know your userland code
will not use FP instructions then you can shrink the kernel by around
65KiB.

Applies atop v4.12-rc4.

Paul Burton (5):
  MIPS: Remove unused R6000 support
  MIPS: Move r4k FP code from r4k_switch.S to r4k_fpu.S
  MIPS: Move r2300 FP code from r2300_switch.S to r2300_fpu.S
  MIPS: Remove unused ST_OFF from r2300_switch.S
  MIPS: Allow floating point support to be disabled

 arch/mips/Kconfig                    |  41 ++++---
 arch/mips/Makefile                   |   3 +-
 arch/mips/include/asm/cpu-features.h |  11 +-
 arch/mips/include/asm/cpu-type.h     |   5 -
 arch/mips/include/asm/cpu.h          |   5 -
 arch/mips/include/asm/dsemul.h       |  34 ++++++
 arch/mips/include/asm/fpu.h          |   3 +
 arch/mips/include/asm/fpu_emulator.h |  16 +++
 arch/mips/include/asm/module.h       |   2 -
 arch/mips/kernel/Makefile            |  13 ++-
 arch/mips/kernel/cpu-probe.c         |  18 ----
 arch/mips/kernel/octeon_switch.S     |   5 -
 arch/mips/kernel/process.c           |   8 ++
 arch/mips/kernel/r2300_fpu.S         |  78 +++++++++++++-
 arch/mips/kernel/r2300_switch.S      |  81 --------------
 arch/mips/kernel/r4k_fpu.S           | 196 +++++++++++++++++++++++++++++++++
 arch/mips/kernel/r4k_switch.S        | 203 -----------------------------------
 arch/mips/kernel/r6000_fpu.S         |  99 -----------------
 arch/mips/kernel/traps.c             |  15 ---
 arch/mips/mm/tlbex.c                 |   5 -
 20 files changed, 376 insertions(+), 465 deletions(-)
 delete mode 100644 arch/mips/kernel/r6000_fpu.S

-- 
2.13.0

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH 1/5] MIPS: Remove unused R6000 support
@ 2017-06-05 18:21   ` Paul Burton
  0 siblings, 0 replies; 23+ messages in thread
From: Paul Burton @ 2017-06-05 18:21 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

The kernel contains a small amount of incomplete code aimed at
supporting old R6000 CPUs. This is:

  - Unused, as no machine selects CONFIG_SYS_HAS_CPU_R6000.

  - Broken, since there are glaring errors such as r6000_fpu.S moving
    the FCSR register to t1, then ignoring it & instead saving t0 into
    struct sigcontext...

  - A maintenance headache, since it's code that nobody can test which
    nevertheless imposes constraints on code which it shares with other
    machines.

Remove this incomplete & broken R6000 CPU support in order to clean up
and in preparation for changes which will no longer need to consider
dragging the pretense of R6000 support along with them.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/Kconfig                | 17 ++-----
 arch/mips/Makefile               |  1 -
 arch/mips/include/asm/cpu-type.h |  5 --
 arch/mips/include/asm/cpu.h      |  5 --
 arch/mips/include/asm/module.h   |  2 -
 arch/mips/kernel/Makefile        |  1 -
 arch/mips/kernel/cpu-probe.c     | 18 --------
 arch/mips/kernel/r6000_fpu.S     | 99 ----------------------------------------
 arch/mips/kernel/traps.c         | 15 ------
 arch/mips/mm/tlbex.c             |  5 --
 10 files changed, 3 insertions(+), 165 deletions(-)
 delete mode 100644 arch/mips/kernel/r6000_fpu.S

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 2828ecde133d..40ea50aabd06 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1615,14 +1615,6 @@ config CPU_R5500
 	  NEC VR5500 and VR5500A series processors implement 64-bit MIPS IV
 	  instruction set.
 
-config CPU_R6000
-	bool "R6000"
-	depends on SYS_HAS_CPU_R6000
-	select CPU_SUPPORTS_32BIT_KERNEL
-	help
-	  MIPS Technologies R6000 and R6000A series processors.  Note these
-	  processors are extremely rare and the support for them is incomplete.
-
 config CPU_NEVADA
 	bool "RM52xx"
 	depends on SYS_HAS_CPU_NEVADA
@@ -1938,9 +1930,6 @@ config SYS_HAS_CPU_R5432
 config SYS_HAS_CPU_R5500
 	bool
 
-config SYS_HAS_CPU_R6000
-	bool
-
 config SYS_HAS_CPU_NEVADA
 	bool
 
@@ -2168,7 +2157,7 @@ config PAGE_SIZE_32KB
 
 config PAGE_SIZE_64KB
 	bool "64kB"
-	depends on !CPU_R3000 && !CPU_TX39XX && !CPU_R6000
+	depends on !CPU_R3000 && !CPU_TX39XX
 	help
 	  Using 64kB page size will result in higher performance kernel at
 	  the price of higher memory consumption.  This option is available on
@@ -2236,11 +2225,11 @@ config CPU_HAS_PREFETCH
 
 config CPU_GENERIC_DUMP_TLB
 	bool
-	default y if !(CPU_R3000 || CPU_R6000 || CPU_R8000 || CPU_TX39XX)
+	default y if !(CPU_R3000 || CPU_R8000 || CPU_TX39XX)
 
 config CPU_R4K_FPU
 	bool
-	default y if !(CPU_R3000 || CPU_R6000 || CPU_TX39XX || CPU_CAVIUM_OCTEON)
+	default y if !(CPU_R3000 || CPU_TX39XX || CPU_CAVIUM_OCTEON)
 
 config CPU_R4K_CACHE_TLB
 	bool
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 02a1787c888c..3d2f247310e4 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -151,7 +151,6 @@ cflags-y += -fno-stack-check
 #
 cflags-$(CONFIG_CPU_R3000)	+= -march=r3000
 cflags-$(CONFIG_CPU_TX39XX)	+= -march=r3900
-cflags-$(CONFIG_CPU_R6000)	+= -march=r6000 -Wa,--trap
 cflags-$(CONFIG_CPU_R4300)	+= -march=r4300 -Wa,--trap
 cflags-$(CONFIG_CPU_VR41XX)	+= -march=r4100 -Wa,--trap
 cflags-$(CONFIG_CPU_R4X00)	+= -march=r4600 -Wa,--trap
diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h
index bdd6dc18e65c..de5788091b16 100644
--- a/arch/mips/include/asm/cpu-type.h
+++ b/arch/mips/include/asm/cpu-type.h
@@ -150,11 +150,6 @@ static inline int __pure __get_cpu_type(const int cpu_type)
 	case CPU_R5500:
 #endif
 
-#ifdef CONFIG_SYS_HAS_CPU_R6000
-	case CPU_R6000:
-	case CPU_R6000A:
-#endif
-
 #ifdef CONFIG_SYS_HAS_CPU_NEVADA
 	case CPU_NEVADA:
 #endif
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index 98f59307e6a3..55d1d49fbba8 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -284,11 +284,6 @@ enum cpu_type_enum {
 	CPU_R3081, CPU_R3081E,
 
 	/*
-	 * R6000 class processors
-	 */
-	CPU_R6000, CPU_R6000A,
-
-	/*
 	 * R4000 class processors
 	 */
 	CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200, CPU_R4300, CPU_R4310,
diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h
index 702c273e67a9..32c7c524b8eb 100644
--- a/arch/mips/include/asm/module.h
+++ b/arch/mips/include/asm/module.h
@@ -114,8 +114,6 @@ search_module_dbetables(unsigned long addr)
 #define MODULE_PROC_FAMILY "R5432 "
 #elif defined CONFIG_CPU_R5500
 #define MODULE_PROC_FAMILY "R5500 "
-#elif defined CONFIG_CPU_R6000
-#define MODULE_PROC_FAMILY "R6000 "
 #elif defined CONFIG_CPU_NEVADA
 #define MODULE_PROC_FAMILY "NEVADA "
 #elif defined CONFIG_CPU_R8000
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 9a0e37b92ce0..f3af9e07e888 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -38,7 +38,6 @@ obj-$(CONFIG_FUNCTION_TRACER)	+= mcount.o ftrace.o
 
 obj-$(CONFIG_CPU_R4K_FPU)	+= r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_R3000)		+= r2300_fpu.o r2300_switch.o
-obj-$(CONFIG_CPU_R6000)		+= r6000_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_TX39XX)	+= r2300_fpu.o r2300_switch.o
 obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= r4k_fpu.o octeon_switch.o
 
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 1aba27786bd5..ddc86f98eb86 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -1391,24 +1391,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
 			     MIPS_CPU_DIVEC | MIPS_CPU_LLSC;
 		c->tlbsize = 48;
 		break;
-	case PRID_IMP_R6000:
-		c->cputype = CPU_R6000;
-		__cpu_name[cpu] = "R6000";
-		set_isa(c, MIPS_CPU_ISA_II);
-		c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
-		c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
-			     MIPS_CPU_LLSC;
-		c->tlbsize = 32;
-		break;
-	case PRID_IMP_R6000A:
-		c->cputype = CPU_R6000A;
-		__cpu_name[cpu] = "R6000A";
-		set_isa(c, MIPS_CPU_ISA_II);
-		c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
-		c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
-			     MIPS_CPU_LLSC;
-		c->tlbsize = 32;
-		break;
 	case PRID_IMP_RM7000:
 		c->cputype = CPU_RM7000;
 		__cpu_name[cpu] = "RM7000";
diff --git a/arch/mips/kernel/r6000_fpu.S b/arch/mips/kernel/r6000_fpu.S
deleted file mode 100644
index 9cc7bfab3419..000000000000
--- a/arch/mips/kernel/r6000_fpu.S
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * r6000_fpu.S: Save/restore floating point context for signal handlers.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1996 by Ralf Baechle
- *
- * Multi-arch abstraction and asm macros for easier reading:
- * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
- */
-#include <asm/asm.h>
-#include <asm/fpregdef.h>
-#include <asm/mipsregs.h>
-#include <asm/asm-offsets.h>
-#include <asm/regdef.h>
-
-	.set	noreorder
-	.set	mips2
-	.set	push
-	SET_HARDFLOAT
-
-/**
- * _save_fp_context() - save FP context from the FPU
- * @a0 - pointer to fpregs field of sigcontext
- * @a1 - pointer to fpc_csr field of sigcontext
- *
- * Save FP context, including the 32 FP data registers and the FP
- * control & status register, from the FPU to signal context.
- */
-	LEAF(_save_fp_context)
-	mfc0	t0,CP0_STATUS
-	sll	t0,t0,2
-	bgez	t0,1f
-	 nop
-
-	cfc1	t1,fcr31
-	/* Store the 16 double precision registers */
-	sdc1	$f0,0(a0)
-	sdc1	$f2,16(a0)
-	sdc1	$f4,32(a0)
-	sdc1	$f6,48(a0)
-	sdc1	$f8,64(a0)
-	sdc1	$f10,80(a0)
-	sdc1	$f12,96(a0)
-	sdc1	$f14,112(a0)
-	sdc1	$f16,128(a0)
-	sdc1	$f18,144(a0)
-	sdc1	$f20,160(a0)
-	sdc1	$f22,176(a0)
-	sdc1	$f24,192(a0)
-	sdc1	$f26,208(a0)
-	sdc1	$f28,224(a0)
-	sdc1	$f30,240(a0)
-	jr	ra
-	 sw	t0,(a1)
-1:	jr	ra
-	 nop
-	END(_save_fp_context)
-
-/**
- * _restore_fp_context() - restore FP context to the FPU
- * @a0 - pointer to fpregs field of sigcontext
- * @a1 - pointer to fpc_csr field of sigcontext
- *
- * Restore FP context, including the 32 FP data registers and the FP
- * control & status register, from signal context to the FPU.
- */
-	LEAF(_restore_fp_context)
-	mfc0	t0,CP0_STATUS
-	sll	t0,t0,2
-
-	bgez	t0,1f
-	 lw	t0,(a1)
-	/* Restore the 16 double precision registers */
-	ldc1	$f0,0(a0)
-	ldc1	$f2,16(a0)
-	ldc1	$f4,32(a0)
-	ldc1	$f6,48(a0)
-	ldc1	$f8,64(a0)
-	ldc1	$f10,80(a0)
-	ldc1	$f12,96(a0)
-	ldc1	$f14,112(a0)
-	ldc1	$f16,128(a0)
-	ldc1	$f18,144(a0)
-	ldc1	$f20,160(a0)
-	ldc1	$f22,176(a0)
-	ldc1	$f24,192(a0)
-	ldc1	$f26,208(a0)
-	ldc1	$f28,224(a0)
-	ldc1	$f30,240(a0)
-	jr	ra
-	 ctc1	t0,fcr31
-1:	jr	ra
-	 nop
-	END(_restore_fp_context)
-
-	.set pop	/* SET_HARDFLOAT */
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 9681b5877140..4ad3e4f39339 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -2425,21 +2425,6 @@ void __init trap_init(void)
 	set_except_vector(EXCCODE_TR, handle_tr);
 	set_except_vector(EXCCODE_MSAFPE, handle_msa_fpe);
 
-	if (current_cpu_type() == CPU_R6000 ||
-	    current_cpu_type() == CPU_R6000A) {
-		/*
-		 * The R6000 is the only R-series CPU that features a machine
-		 * check exception (similar to the R4000 cache error) and
-		 * unaligned ldc1/sdc1 exception.  The handlers have not been
-		 * written yet.	 Well, anyway there is no R6000 machine on the
-		 * current list of targets for Linux/MIPS.
-		 * (Duh, crap, there is someone with a triple R6k machine)
-		 */
-		//set_except_vector(14, handle_mc);
-		//set_except_vector(15, handle_ndc);
-	}
-
-
 	if (board_nmi_handler_setup)
 		board_nmi_handler_setup();
 
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index ed1c5297547a..7dfc8f8b9960 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -2599,11 +2599,6 @@ void build_tlb_refill_handler(void)
 #endif
 		break;
 
-	case CPU_R6000:
-	case CPU_R6000A:
-		panic("No R6000 TLB refill handler yet");
-		break;
-
 	case CPU_R8000:
 		panic("No R8000 TLB refill handler yet");
 		break;
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 1/5] MIPS: Remove unused R6000 support
@ 2017-06-05 18:21   ` Paul Burton
  0 siblings, 0 replies; 23+ messages in thread
From: Paul Burton @ 2017-06-05 18:21 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

The kernel contains a small amount of incomplete code aimed at
supporting old R6000 CPUs. This is:

  - Unused, as no machine selects CONFIG_SYS_HAS_CPU_R6000.

  - Broken, since there are glaring errors such as r6000_fpu.S moving
    the FCSR register to t1, then ignoring it & instead saving t0 into
    struct sigcontext...

  - A maintenance headache, since it's code that nobody can test which
    nevertheless imposes constraints on code which it shares with other
    machines.

Remove this incomplete & broken R6000 CPU support in order to clean up
and in preparation for changes which will no longer need to consider
dragging the pretense of R6000 support along with them.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/Kconfig                | 17 ++-----
 arch/mips/Makefile               |  1 -
 arch/mips/include/asm/cpu-type.h |  5 --
 arch/mips/include/asm/cpu.h      |  5 --
 arch/mips/include/asm/module.h   |  2 -
 arch/mips/kernel/Makefile        |  1 -
 arch/mips/kernel/cpu-probe.c     | 18 --------
 arch/mips/kernel/r6000_fpu.S     | 99 ----------------------------------------
 arch/mips/kernel/traps.c         | 15 ------
 arch/mips/mm/tlbex.c             |  5 --
 10 files changed, 3 insertions(+), 165 deletions(-)
 delete mode 100644 arch/mips/kernel/r6000_fpu.S

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 2828ecde133d..40ea50aabd06 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1615,14 +1615,6 @@ config CPU_R5500
 	  NEC VR5500 and VR5500A series processors implement 64-bit MIPS IV
 	  instruction set.
 
-config CPU_R6000
-	bool "R6000"
-	depends on SYS_HAS_CPU_R6000
-	select CPU_SUPPORTS_32BIT_KERNEL
-	help
-	  MIPS Technologies R6000 and R6000A series processors.  Note these
-	  processors are extremely rare and the support for them is incomplete.
-
 config CPU_NEVADA
 	bool "RM52xx"
 	depends on SYS_HAS_CPU_NEVADA
@@ -1938,9 +1930,6 @@ config SYS_HAS_CPU_R5432
 config SYS_HAS_CPU_R5500
 	bool
 
-config SYS_HAS_CPU_R6000
-	bool
-
 config SYS_HAS_CPU_NEVADA
 	bool
 
@@ -2168,7 +2157,7 @@ config PAGE_SIZE_32KB
 
 config PAGE_SIZE_64KB
 	bool "64kB"
-	depends on !CPU_R3000 && !CPU_TX39XX && !CPU_R6000
+	depends on !CPU_R3000 && !CPU_TX39XX
 	help
 	  Using 64kB page size will result in higher performance kernel at
 	  the price of higher memory consumption.  This option is available on
@@ -2236,11 +2225,11 @@ config CPU_HAS_PREFETCH
 
 config CPU_GENERIC_DUMP_TLB
 	bool
-	default y if !(CPU_R3000 || CPU_R6000 || CPU_R8000 || CPU_TX39XX)
+	default y if !(CPU_R3000 || CPU_R8000 || CPU_TX39XX)
 
 config CPU_R4K_FPU
 	bool
-	default y if !(CPU_R3000 || CPU_R6000 || CPU_TX39XX || CPU_CAVIUM_OCTEON)
+	default y if !(CPU_R3000 || CPU_TX39XX || CPU_CAVIUM_OCTEON)
 
 config CPU_R4K_CACHE_TLB
 	bool
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 02a1787c888c..3d2f247310e4 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -151,7 +151,6 @@ cflags-y += -fno-stack-check
 #
 cflags-$(CONFIG_CPU_R3000)	+= -march=r3000
 cflags-$(CONFIG_CPU_TX39XX)	+= -march=r3900
-cflags-$(CONFIG_CPU_R6000)	+= -march=r6000 -Wa,--trap
 cflags-$(CONFIG_CPU_R4300)	+= -march=r4300 -Wa,--trap
 cflags-$(CONFIG_CPU_VR41XX)	+= -march=r4100 -Wa,--trap
 cflags-$(CONFIG_CPU_R4X00)	+= -march=r4600 -Wa,--trap
diff --git a/arch/mips/include/asm/cpu-type.h b/arch/mips/include/asm/cpu-type.h
index bdd6dc18e65c..de5788091b16 100644
--- a/arch/mips/include/asm/cpu-type.h
+++ b/arch/mips/include/asm/cpu-type.h
@@ -150,11 +150,6 @@ static inline int __pure __get_cpu_type(const int cpu_type)
 	case CPU_R5500:
 #endif
 
-#ifdef CONFIG_SYS_HAS_CPU_R6000
-	case CPU_R6000:
-	case CPU_R6000A:
-#endif
-
 #ifdef CONFIG_SYS_HAS_CPU_NEVADA
 	case CPU_NEVADA:
 #endif
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index 98f59307e6a3..55d1d49fbba8 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -284,11 +284,6 @@ enum cpu_type_enum {
 	CPU_R3081, CPU_R3081E,
 
 	/*
-	 * R6000 class processors
-	 */
-	CPU_R6000, CPU_R6000A,
-
-	/*
 	 * R4000 class processors
 	 */
 	CPU_R4000PC, CPU_R4000SC, CPU_R4000MC, CPU_R4200, CPU_R4300, CPU_R4310,
diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h
index 702c273e67a9..32c7c524b8eb 100644
--- a/arch/mips/include/asm/module.h
+++ b/arch/mips/include/asm/module.h
@@ -114,8 +114,6 @@ search_module_dbetables(unsigned long addr)
 #define MODULE_PROC_FAMILY "R5432 "
 #elif defined CONFIG_CPU_R5500
 #define MODULE_PROC_FAMILY "R5500 "
-#elif defined CONFIG_CPU_R6000
-#define MODULE_PROC_FAMILY "R6000 "
 #elif defined CONFIG_CPU_NEVADA
 #define MODULE_PROC_FAMILY "NEVADA "
 #elif defined CONFIG_CPU_R8000
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 9a0e37b92ce0..f3af9e07e888 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -38,7 +38,6 @@ obj-$(CONFIG_FUNCTION_TRACER)	+= mcount.o ftrace.o
 
 obj-$(CONFIG_CPU_R4K_FPU)	+= r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_R3000)		+= r2300_fpu.o r2300_switch.o
-obj-$(CONFIG_CPU_R6000)		+= r6000_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_TX39XX)	+= r2300_fpu.o r2300_switch.o
 obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= r4k_fpu.o octeon_switch.o
 
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 1aba27786bd5..ddc86f98eb86 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -1391,24 +1391,6 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
 			     MIPS_CPU_DIVEC | MIPS_CPU_LLSC;
 		c->tlbsize = 48;
 		break;
-	case PRID_IMP_R6000:
-		c->cputype = CPU_R6000;
-		__cpu_name[cpu] = "R6000";
-		set_isa(c, MIPS_CPU_ISA_II);
-		c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
-		c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
-			     MIPS_CPU_LLSC;
-		c->tlbsize = 32;
-		break;
-	case PRID_IMP_R6000A:
-		c->cputype = CPU_R6000A;
-		__cpu_name[cpu] = "R6000A";
-		set_isa(c, MIPS_CPU_ISA_II);
-		c->fpu_msk31 |= FPU_CSR_CONDX | FPU_CSR_FS;
-		c->options = MIPS_CPU_TLB | MIPS_CPU_FPU |
-			     MIPS_CPU_LLSC;
-		c->tlbsize = 32;
-		break;
 	case PRID_IMP_RM7000:
 		c->cputype = CPU_RM7000;
 		__cpu_name[cpu] = "RM7000";
diff --git a/arch/mips/kernel/r6000_fpu.S b/arch/mips/kernel/r6000_fpu.S
deleted file mode 100644
index 9cc7bfab3419..000000000000
--- a/arch/mips/kernel/r6000_fpu.S
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * r6000_fpu.S: Save/restore floating point context for signal handlers.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1996 by Ralf Baechle
- *
- * Multi-arch abstraction and asm macros for easier reading:
- * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
- */
-#include <asm/asm.h>
-#include <asm/fpregdef.h>
-#include <asm/mipsregs.h>
-#include <asm/asm-offsets.h>
-#include <asm/regdef.h>
-
-	.set	noreorder
-	.set	mips2
-	.set	push
-	SET_HARDFLOAT
-
-/**
- * _save_fp_context() - save FP context from the FPU
- * @a0 - pointer to fpregs field of sigcontext
- * @a1 - pointer to fpc_csr field of sigcontext
- *
- * Save FP context, including the 32 FP data registers and the FP
- * control & status register, from the FPU to signal context.
- */
-	LEAF(_save_fp_context)
-	mfc0	t0,CP0_STATUS
-	sll	t0,t0,2
-	bgez	t0,1f
-	 nop
-
-	cfc1	t1,fcr31
-	/* Store the 16 double precision registers */
-	sdc1	$f0,0(a0)
-	sdc1	$f2,16(a0)
-	sdc1	$f4,32(a0)
-	sdc1	$f6,48(a0)
-	sdc1	$f8,64(a0)
-	sdc1	$f10,80(a0)
-	sdc1	$f12,96(a0)
-	sdc1	$f14,112(a0)
-	sdc1	$f16,128(a0)
-	sdc1	$f18,144(a0)
-	sdc1	$f20,160(a0)
-	sdc1	$f22,176(a0)
-	sdc1	$f24,192(a0)
-	sdc1	$f26,208(a0)
-	sdc1	$f28,224(a0)
-	sdc1	$f30,240(a0)
-	jr	ra
-	 sw	t0,(a1)
-1:	jr	ra
-	 nop
-	END(_save_fp_context)
-
-/**
- * _restore_fp_context() - restore FP context to the FPU
- * @a0 - pointer to fpregs field of sigcontext
- * @a1 - pointer to fpc_csr field of sigcontext
- *
- * Restore FP context, including the 32 FP data registers and the FP
- * control & status register, from signal context to the FPU.
- */
-	LEAF(_restore_fp_context)
-	mfc0	t0,CP0_STATUS
-	sll	t0,t0,2
-
-	bgez	t0,1f
-	 lw	t0,(a1)
-	/* Restore the 16 double precision registers */
-	ldc1	$f0,0(a0)
-	ldc1	$f2,16(a0)
-	ldc1	$f4,32(a0)
-	ldc1	$f6,48(a0)
-	ldc1	$f8,64(a0)
-	ldc1	$f10,80(a0)
-	ldc1	$f12,96(a0)
-	ldc1	$f14,112(a0)
-	ldc1	$f16,128(a0)
-	ldc1	$f18,144(a0)
-	ldc1	$f20,160(a0)
-	ldc1	$f22,176(a0)
-	ldc1	$f24,192(a0)
-	ldc1	$f26,208(a0)
-	ldc1	$f28,224(a0)
-	ldc1	$f30,240(a0)
-	jr	ra
-	 ctc1	t0,fcr31
-1:	jr	ra
-	 nop
-	END(_restore_fp_context)
-
-	.set pop	/* SET_HARDFLOAT */
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 9681b5877140..4ad3e4f39339 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -2425,21 +2425,6 @@ void __init trap_init(void)
 	set_except_vector(EXCCODE_TR, handle_tr);
 	set_except_vector(EXCCODE_MSAFPE, handle_msa_fpe);
 
-	if (current_cpu_type() == CPU_R6000 ||
-	    current_cpu_type() == CPU_R6000A) {
-		/*
-		 * The R6000 is the only R-series CPU that features a machine
-		 * check exception (similar to the R4000 cache error) and
-		 * unaligned ldc1/sdc1 exception.  The handlers have not been
-		 * written yet.	 Well, anyway there is no R6000 machine on the
-		 * current list of targets for Linux/MIPS.
-		 * (Duh, crap, there is someone with a triple R6k machine)
-		 */
-		//set_except_vector(14, handle_mc);
-		//set_except_vector(15, handle_ndc);
-	}
-
-
 	if (board_nmi_handler_setup)
 		board_nmi_handler_setup();
 
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index ed1c5297547a..7dfc8f8b9960 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -2599,11 +2599,6 @@ void build_tlb_refill_handler(void)
 #endif
 		break;
 
-	case CPU_R6000:
-	case CPU_R6000A:
-		panic("No R6000 TLB refill handler yet");
-		break;
-
 	case CPU_R8000:
 		panic("No R8000 TLB refill handler yet");
 		break;
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2/5] MIPS: Move r4k FP code from r4k_switch.S to r4k_fpu.S
@ 2017-06-05 18:21   ` Paul Burton
  0 siblings, 0 replies; 23+ messages in thread
From: Paul Burton @ 2017-06-05 18:21 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Move _save_fp(), _restore_fp(), _save_msa(), _restore_msa(),
_init_msa_upper() & _init_fpu() out of r4k_switch.S & into r4k_fpu.S.
This allows us to clean up the way in which Octeon includes the default
r4k implementations of these FP functions despite replacing resume(),
and makes CONFIG_R4K_FPU more straightforwardly represent all
configurations that have an R4K-style FPU, including Octeon.

Besides cleaning up this will be useful for later patches which disable
FP support.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/Kconfig                |   2 +-
 arch/mips/kernel/Makefile        |  13 ++-
 arch/mips/kernel/octeon_switch.S |   5 -
 arch/mips/kernel/r4k_fpu.S       | 196 +++++++++++++++++++++++++++++++++++++
 arch/mips/kernel/r4k_switch.S    | 203 ---------------------------------------
 5 files changed, 206 insertions(+), 213 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 40ea50aabd06..20958af88522 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2229,7 +2229,7 @@ config CPU_GENERIC_DUMP_TLB
 
 config CPU_R4K_FPU
 	bool
-	default y if !(CPU_R3000 || CPU_TX39XX || CPU_CAVIUM_OCTEON)
+	default y if !(CPU_R3000 || CPU_TX39XX)
 
 config CPU_R4K_CACHE_TLB
 	bool
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index f3af9e07e888..10d75888f6ae 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -36,10 +36,15 @@ obj-$(CONFIG_MODULES_USE_ELF_RELA) += module-rela.o
 obj-$(CONFIG_FTRACE_SYSCALLS)	+= ftrace.o
 obj-$(CONFIG_FUNCTION_TRACER)	+= mcount.o ftrace.o
 
-obj-$(CONFIG_CPU_R4K_FPU)	+= r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_R3000)		+= r2300_fpu.o r2300_switch.o
-obj-$(CONFIG_CPU_TX39XX)	+= r2300_fpu.o r2300_switch.o
-obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= r4k_fpu.o octeon_switch.o
+sw-y				:= r4k_switch.o
+sw-$(CONFIG_CPU_R3000)		:= r2300_switch.o
+sw-$(CONFIG_CPU_TX39XX)		:= r2300_switch.o
+sw-$(CONFIG_CPU_CAVIUM_OCTEON)	:= octeon_switch.o
+obj-y				+= $(sw-y)
+
+obj-$(CONFIG_CPU_R4K_FPU)	+= r4k_fpu.o
+obj-$(CONFIG_CPU_R3000)		+= r2300_fpu.o
+obj-$(CONFIG_CPU_TX39XX)	+= r2300_fpu.o
 
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_SMP_UP)		+= smp-up.o
diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S
index 3375745b9198..dbfe4ff83ea3 100644
--- a/arch/mips/kernel/octeon_switch.S
+++ b/arch/mips/kernel/octeon_switch.S
@@ -11,11 +11,6 @@
  *    written by Carsten Langgaard, carstenl@mips.com
  */
 
-#define USE_ALTERNATE_RESUME_IMPL 1
-	.set push
-	.set arch=mips64r2
-#include "r4k_switch.S"
-	.set pop
 /*
  * task_struct *resume(task_struct *prev, task_struct *next,
  *		       struct thread_info *next_ti)
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
index 56d86b09c917..0a83b1708b3c 100644
--- a/arch/mips/kernel/r4k_fpu.S
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -15,6 +15,7 @@
 #include <asm/asm.h>
 #include <asm/asmmacro.h>
 #include <asm/errno.h>
+#include <asm/export.h>
 #include <asm/fpregdef.h>
 #include <asm/mipsregs.h>
 #include <asm/asm-offsets.h>
@@ -34,6 +35,201 @@
 	.previous
 	.endm
 
+/*
+ * Save a thread's fp context.
+ */
+LEAF(_save_fp)
+EXPORT_SYMBOL(_save_fp)
+#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
+		defined(CONFIG_CPU_MIPS32_R6)
+	mfc0	t0, CP0_STATUS
+#endif
+	fpu_save_double a0 t0 t1		# clobbers t1
+	jr	ra
+	END(_save_fp)
+
+/*
+ * Restore a thread's fp context.
+ */
+LEAF(_restore_fp)
+#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
+		defined(CONFIG_CPU_MIPS32_R6)
+	mfc0	t0, CP0_STATUS
+#endif
+	fpu_restore_double a0 t0 t1		# clobbers t1
+	jr	ra
+	END(_restore_fp)
+
+#ifdef CONFIG_CPU_HAS_MSA
+
+/*
+ * Save a thread's MSA vector context.
+ */
+LEAF(_save_msa)
+EXPORT_SYMBOL(_save_msa)
+	msa_save_all	a0
+	jr	ra
+	END(_save_msa)
+
+/*
+ * Restore a thread's MSA vector context.
+ */
+LEAF(_restore_msa)
+	msa_restore_all	a0
+	jr	ra
+	END(_restore_msa)
+
+LEAF(_init_msa_upper)
+	msa_init_all_upper
+	jr	ra
+	END(_init_msa_upper)
+
+#endif
+
+/*
+ * Load the FPU with signalling NANS.  This bit pattern we're using has
+ * the property that no matter whether considered as single or as double
+ * precision represents signaling NANS.
+ *
+ * The value to initialize fcr31 to comes in $a0.
+ */
+
+	.set push
+	SET_HARDFLOAT
+
+LEAF(_init_fpu)
+	mfc0	t0, CP0_STATUS
+	li	t1, ST0_CU1
+	or	t0, t1
+	mtc0	t0, CP0_STATUS
+	enable_fpu_hazard
+
+	ctc1	a0, fcr31
+
+	li	t1, -1				# SNaN
+
+#ifdef CONFIG_64BIT
+	sll	t0, t0, 5
+	bgez	t0, 1f				# 16 / 32 register mode?
+
+	dmtc1	t1, $f1
+	dmtc1	t1, $f3
+	dmtc1	t1, $f5
+	dmtc1	t1, $f7
+	dmtc1	t1, $f9
+	dmtc1	t1, $f11
+	dmtc1	t1, $f13
+	dmtc1	t1, $f15
+	dmtc1	t1, $f17
+	dmtc1	t1, $f19
+	dmtc1	t1, $f21
+	dmtc1	t1, $f23
+	dmtc1	t1, $f25
+	dmtc1	t1, $f27
+	dmtc1	t1, $f29
+	dmtc1	t1, $f31
+1:
+#endif
+
+#ifdef CONFIG_CPU_MIPS32
+	mtc1	t1, $f0
+	mtc1	t1, $f1
+	mtc1	t1, $f2
+	mtc1	t1, $f3
+	mtc1	t1, $f4
+	mtc1	t1, $f5
+	mtc1	t1, $f6
+	mtc1	t1, $f7
+	mtc1	t1, $f8
+	mtc1	t1, $f9
+	mtc1	t1, $f10
+	mtc1	t1, $f11
+	mtc1	t1, $f12
+	mtc1	t1, $f13
+	mtc1	t1, $f14
+	mtc1	t1, $f15
+	mtc1	t1, $f16
+	mtc1	t1, $f17
+	mtc1	t1, $f18
+	mtc1	t1, $f19
+	mtc1	t1, $f20
+	mtc1	t1, $f21
+	mtc1	t1, $f22
+	mtc1	t1, $f23
+	mtc1	t1, $f24
+	mtc1	t1, $f25
+	mtc1	t1, $f26
+	mtc1	t1, $f27
+	mtc1	t1, $f28
+	mtc1	t1, $f29
+	mtc1	t1, $f30
+	mtc1	t1, $f31
+
+#if defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_CPU_MIPS32_R6)
+	.set    push
+	.set    MIPS_ISA_LEVEL_RAW
+	.set	fp=64
+	sll     t0, t0, 5			# is Status.FR set?
+	bgez    t0, 1f				# no: skip setting upper 32b
+
+	mthc1   t1, $f0
+	mthc1   t1, $f1
+	mthc1   t1, $f2
+	mthc1   t1, $f3
+	mthc1   t1, $f4
+	mthc1   t1, $f5
+	mthc1   t1, $f6
+	mthc1   t1, $f7
+	mthc1   t1, $f8
+	mthc1   t1, $f9
+	mthc1   t1, $f10
+	mthc1   t1, $f11
+	mthc1   t1, $f12
+	mthc1   t1, $f13
+	mthc1   t1, $f14
+	mthc1   t1, $f15
+	mthc1   t1, $f16
+	mthc1   t1, $f17
+	mthc1   t1, $f18
+	mthc1   t1, $f19
+	mthc1   t1, $f20
+	mthc1   t1, $f21
+	mthc1   t1, $f22
+	mthc1   t1, $f23
+	mthc1   t1, $f24
+	mthc1   t1, $f25
+	mthc1   t1, $f26
+	mthc1   t1, $f27
+	mthc1   t1, $f28
+	mthc1   t1, $f29
+	mthc1   t1, $f30
+	mthc1   t1, $f31
+1:	.set    pop
+#endif /* CONFIG_CPU_MIPS32_R2 || CONFIG_CPU_MIPS32_R6 */
+#else
+	.set	MIPS_ISA_ARCH_LEVEL_RAW
+	dmtc1	t1, $f0
+	dmtc1	t1, $f2
+	dmtc1	t1, $f4
+	dmtc1	t1, $f6
+	dmtc1	t1, $f8
+	dmtc1	t1, $f10
+	dmtc1	t1, $f12
+	dmtc1	t1, $f14
+	dmtc1	t1, $f16
+	dmtc1	t1, $f18
+	dmtc1	t1, $f20
+	dmtc1	t1, $f22
+	dmtc1	t1, $f24
+	dmtc1	t1, $f26
+	dmtc1	t1, $f28
+	dmtc1	t1, $f30
+#endif
+	jr	ra
+	END(_init_fpu)
+
+	.set pop	/* SET_HARDFLOAT */
+
 	.set	noreorder
 
 /**
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
index 7b386d54fd65..17cf9341c1cf 100644
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -12,8 +12,6 @@
  */
 #include <asm/asm.h>
 #include <asm/cachectl.h>
-#include <asm/export.h>
-#include <asm/fpregdef.h>
 #include <asm/mipsregs.h>
 #include <asm/asm-offsets.h>
 #include <asm/regdef.h>
@@ -22,10 +20,6 @@
 
 #include <asm/asmmacro.h>
 
-/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
-#undef fp
-
-#ifndef USE_ALTERNATE_RESUME_IMPL
 /*
  * task_struct *resume(task_struct *prev, task_struct *next,
  *		       struct thread_info *next_ti)
@@ -63,200 +57,3 @@
 	move	v0, a0
 	jr	ra
 	END(resume)
-
-#endif /* USE_ALTERNATE_RESUME_IMPL */
-
-/*
- * Save a thread's fp context.
- */
-LEAF(_save_fp)
-EXPORT_SYMBOL(_save_fp)
-#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
-		defined(CONFIG_CPU_MIPS32_R6)
-	mfc0	t0, CP0_STATUS
-#endif
-	fpu_save_double a0 t0 t1		# clobbers t1
-	jr	ra
-	END(_save_fp)
-
-/*
- * Restore a thread's fp context.
- */
-LEAF(_restore_fp)
-#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
-		defined(CONFIG_CPU_MIPS32_R6)
-	mfc0	t0, CP0_STATUS
-#endif
-	fpu_restore_double a0 t0 t1		# clobbers t1
-	jr	ra
-	END(_restore_fp)
-
-#ifdef CONFIG_CPU_HAS_MSA
-
-/*
- * Save a thread's MSA vector context.
- */
-LEAF(_save_msa)
-EXPORT_SYMBOL(_save_msa)
-	msa_save_all	a0
-	jr	ra
-	END(_save_msa)
-
-/*
- * Restore a thread's MSA vector context.
- */
-LEAF(_restore_msa)
-	msa_restore_all	a0
-	jr	ra
-	END(_restore_msa)
-
-LEAF(_init_msa_upper)
-	msa_init_all_upper
-	jr	ra
-	END(_init_msa_upper)
-
-#endif
-
-/*
- * Load the FPU with signalling NANS.  This bit pattern we're using has
- * the property that no matter whether considered as single or as double
- * precision represents signaling NANS.
- *
- * The value to initialize fcr31 to comes in $a0.
- */
-
-	.set push
-	SET_HARDFLOAT
-
-LEAF(_init_fpu)
-	mfc0	t0, CP0_STATUS
-	li	t1, ST0_CU1
-	or	t0, t1
-	mtc0	t0, CP0_STATUS
-	enable_fpu_hazard
-
-	ctc1	a0, fcr31
-
-	li	t1, -1				# SNaN
-
-#ifdef CONFIG_64BIT
-	sll	t0, t0, 5
-	bgez	t0, 1f				# 16 / 32 register mode?
-
-	dmtc1	t1, $f1
-	dmtc1	t1, $f3
-	dmtc1	t1, $f5
-	dmtc1	t1, $f7
-	dmtc1	t1, $f9
-	dmtc1	t1, $f11
-	dmtc1	t1, $f13
-	dmtc1	t1, $f15
-	dmtc1	t1, $f17
-	dmtc1	t1, $f19
-	dmtc1	t1, $f21
-	dmtc1	t1, $f23
-	dmtc1	t1, $f25
-	dmtc1	t1, $f27
-	dmtc1	t1, $f29
-	dmtc1	t1, $f31
-1:
-#endif
-
-#ifdef CONFIG_CPU_MIPS32
-	mtc1	t1, $f0
-	mtc1	t1, $f1
-	mtc1	t1, $f2
-	mtc1	t1, $f3
-	mtc1	t1, $f4
-	mtc1	t1, $f5
-	mtc1	t1, $f6
-	mtc1	t1, $f7
-	mtc1	t1, $f8
-	mtc1	t1, $f9
-	mtc1	t1, $f10
-	mtc1	t1, $f11
-	mtc1	t1, $f12
-	mtc1	t1, $f13
-	mtc1	t1, $f14
-	mtc1	t1, $f15
-	mtc1	t1, $f16
-	mtc1	t1, $f17
-	mtc1	t1, $f18
-	mtc1	t1, $f19
-	mtc1	t1, $f20
-	mtc1	t1, $f21
-	mtc1	t1, $f22
-	mtc1	t1, $f23
-	mtc1	t1, $f24
-	mtc1	t1, $f25
-	mtc1	t1, $f26
-	mtc1	t1, $f27
-	mtc1	t1, $f28
-	mtc1	t1, $f29
-	mtc1	t1, $f30
-	mtc1	t1, $f31
-
-#if defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_CPU_MIPS32_R6)
-	.set    push
-	.set    MIPS_ISA_LEVEL_RAW
-	.set	fp=64
-	sll     t0, t0, 5			# is Status.FR set?
-	bgez    t0, 1f				# no: skip setting upper 32b
-
-	mthc1   t1, $f0
-	mthc1   t1, $f1
-	mthc1   t1, $f2
-	mthc1   t1, $f3
-	mthc1   t1, $f4
-	mthc1   t1, $f5
-	mthc1   t1, $f6
-	mthc1   t1, $f7
-	mthc1   t1, $f8
-	mthc1   t1, $f9
-	mthc1   t1, $f10
-	mthc1   t1, $f11
-	mthc1   t1, $f12
-	mthc1   t1, $f13
-	mthc1   t1, $f14
-	mthc1   t1, $f15
-	mthc1   t1, $f16
-	mthc1   t1, $f17
-	mthc1   t1, $f18
-	mthc1   t1, $f19
-	mthc1   t1, $f20
-	mthc1   t1, $f21
-	mthc1   t1, $f22
-	mthc1   t1, $f23
-	mthc1   t1, $f24
-	mthc1   t1, $f25
-	mthc1   t1, $f26
-	mthc1   t1, $f27
-	mthc1   t1, $f28
-	mthc1   t1, $f29
-	mthc1   t1, $f30
-	mthc1   t1, $f31
-1:	.set    pop
-#endif /* CONFIG_CPU_MIPS32_R2 || CONFIG_CPU_MIPS32_R6 */
-#else
-	.set	MIPS_ISA_ARCH_LEVEL_RAW
-	dmtc1	t1, $f0
-	dmtc1	t1, $f2
-	dmtc1	t1, $f4
-	dmtc1	t1, $f6
-	dmtc1	t1, $f8
-	dmtc1	t1, $f10
-	dmtc1	t1, $f12
-	dmtc1	t1, $f14
-	dmtc1	t1, $f16
-	dmtc1	t1, $f18
-	dmtc1	t1, $f20
-	dmtc1	t1, $f22
-	dmtc1	t1, $f24
-	dmtc1	t1, $f26
-	dmtc1	t1, $f28
-	dmtc1	t1, $f30
-#endif
-	jr	ra
-	END(_init_fpu)
-
-	.set pop	/* SET_HARDFLOAT */
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 2/5] MIPS: Move r4k FP code from r4k_switch.S to r4k_fpu.S
@ 2017-06-05 18:21   ` Paul Burton
  0 siblings, 0 replies; 23+ messages in thread
From: Paul Burton @ 2017-06-05 18:21 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Move _save_fp(), _restore_fp(), _save_msa(), _restore_msa(),
_init_msa_upper() & _init_fpu() out of r4k_switch.S & into r4k_fpu.S.
This allows us to clean up the way in which Octeon includes the default
r4k implementations of these FP functions despite replacing resume(),
and makes CONFIG_R4K_FPU more straightforwardly represent all
configurations that have an R4K-style FPU, including Octeon.

Besides cleaning up this will be useful for later patches which disable
FP support.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/Kconfig                |   2 +-
 arch/mips/kernel/Makefile        |  13 ++-
 arch/mips/kernel/octeon_switch.S |   5 -
 arch/mips/kernel/r4k_fpu.S       | 196 +++++++++++++++++++++++++++++++++++++
 arch/mips/kernel/r4k_switch.S    | 203 ---------------------------------------
 5 files changed, 206 insertions(+), 213 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 40ea50aabd06..20958af88522 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2229,7 +2229,7 @@ config CPU_GENERIC_DUMP_TLB
 
 config CPU_R4K_FPU
 	bool
-	default y if !(CPU_R3000 || CPU_TX39XX || CPU_CAVIUM_OCTEON)
+	default y if !(CPU_R3000 || CPU_TX39XX)
 
 config CPU_R4K_CACHE_TLB
 	bool
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index f3af9e07e888..10d75888f6ae 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -36,10 +36,15 @@ obj-$(CONFIG_MODULES_USE_ELF_RELA) += module-rela.o
 obj-$(CONFIG_FTRACE_SYSCALLS)	+= ftrace.o
 obj-$(CONFIG_FUNCTION_TRACER)	+= mcount.o ftrace.o
 
-obj-$(CONFIG_CPU_R4K_FPU)	+= r4k_fpu.o r4k_switch.o
-obj-$(CONFIG_CPU_R3000)		+= r2300_fpu.o r2300_switch.o
-obj-$(CONFIG_CPU_TX39XX)	+= r2300_fpu.o r2300_switch.o
-obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= r4k_fpu.o octeon_switch.o
+sw-y				:= r4k_switch.o
+sw-$(CONFIG_CPU_R3000)		:= r2300_switch.o
+sw-$(CONFIG_CPU_TX39XX)		:= r2300_switch.o
+sw-$(CONFIG_CPU_CAVIUM_OCTEON)	:= octeon_switch.o
+obj-y				+= $(sw-y)
+
+obj-$(CONFIG_CPU_R4K_FPU)	+= r4k_fpu.o
+obj-$(CONFIG_CPU_R3000)		+= r2300_fpu.o
+obj-$(CONFIG_CPU_TX39XX)	+= r2300_fpu.o
 
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_SMP_UP)		+= smp-up.o
diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S
index 3375745b9198..dbfe4ff83ea3 100644
--- a/arch/mips/kernel/octeon_switch.S
+++ b/arch/mips/kernel/octeon_switch.S
@@ -11,11 +11,6 @@
  *    written by Carsten Langgaard, carstenl@mips.com
  */
 
-#define USE_ALTERNATE_RESUME_IMPL 1
-	.set push
-	.set arch=mips64r2
-#include "r4k_switch.S"
-	.set pop
 /*
  * task_struct *resume(task_struct *prev, task_struct *next,
  *		       struct thread_info *next_ti)
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
index 56d86b09c917..0a83b1708b3c 100644
--- a/arch/mips/kernel/r4k_fpu.S
+++ b/arch/mips/kernel/r4k_fpu.S
@@ -15,6 +15,7 @@
 #include <asm/asm.h>
 #include <asm/asmmacro.h>
 #include <asm/errno.h>
+#include <asm/export.h>
 #include <asm/fpregdef.h>
 #include <asm/mipsregs.h>
 #include <asm/asm-offsets.h>
@@ -34,6 +35,201 @@
 	.previous
 	.endm
 
+/*
+ * Save a thread's fp context.
+ */
+LEAF(_save_fp)
+EXPORT_SYMBOL(_save_fp)
+#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
+		defined(CONFIG_CPU_MIPS32_R6)
+	mfc0	t0, CP0_STATUS
+#endif
+	fpu_save_double a0 t0 t1		# clobbers t1
+	jr	ra
+	END(_save_fp)
+
+/*
+ * Restore a thread's fp context.
+ */
+LEAF(_restore_fp)
+#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
+		defined(CONFIG_CPU_MIPS32_R6)
+	mfc0	t0, CP0_STATUS
+#endif
+	fpu_restore_double a0 t0 t1		# clobbers t1
+	jr	ra
+	END(_restore_fp)
+
+#ifdef CONFIG_CPU_HAS_MSA
+
+/*
+ * Save a thread's MSA vector context.
+ */
+LEAF(_save_msa)
+EXPORT_SYMBOL(_save_msa)
+	msa_save_all	a0
+	jr	ra
+	END(_save_msa)
+
+/*
+ * Restore a thread's MSA vector context.
+ */
+LEAF(_restore_msa)
+	msa_restore_all	a0
+	jr	ra
+	END(_restore_msa)
+
+LEAF(_init_msa_upper)
+	msa_init_all_upper
+	jr	ra
+	END(_init_msa_upper)
+
+#endif
+
+/*
+ * Load the FPU with signalling NANS.  This bit pattern we're using has
+ * the property that no matter whether considered as single or as double
+ * precision represents signaling NANS.
+ *
+ * The value to initialize fcr31 to comes in $a0.
+ */
+
+	.set push
+	SET_HARDFLOAT
+
+LEAF(_init_fpu)
+	mfc0	t0, CP0_STATUS
+	li	t1, ST0_CU1
+	or	t0, t1
+	mtc0	t0, CP0_STATUS
+	enable_fpu_hazard
+
+	ctc1	a0, fcr31
+
+	li	t1, -1				# SNaN
+
+#ifdef CONFIG_64BIT
+	sll	t0, t0, 5
+	bgez	t0, 1f				# 16 / 32 register mode?
+
+	dmtc1	t1, $f1
+	dmtc1	t1, $f3
+	dmtc1	t1, $f5
+	dmtc1	t1, $f7
+	dmtc1	t1, $f9
+	dmtc1	t1, $f11
+	dmtc1	t1, $f13
+	dmtc1	t1, $f15
+	dmtc1	t1, $f17
+	dmtc1	t1, $f19
+	dmtc1	t1, $f21
+	dmtc1	t1, $f23
+	dmtc1	t1, $f25
+	dmtc1	t1, $f27
+	dmtc1	t1, $f29
+	dmtc1	t1, $f31
+1:
+#endif
+
+#ifdef CONFIG_CPU_MIPS32
+	mtc1	t1, $f0
+	mtc1	t1, $f1
+	mtc1	t1, $f2
+	mtc1	t1, $f3
+	mtc1	t1, $f4
+	mtc1	t1, $f5
+	mtc1	t1, $f6
+	mtc1	t1, $f7
+	mtc1	t1, $f8
+	mtc1	t1, $f9
+	mtc1	t1, $f10
+	mtc1	t1, $f11
+	mtc1	t1, $f12
+	mtc1	t1, $f13
+	mtc1	t1, $f14
+	mtc1	t1, $f15
+	mtc1	t1, $f16
+	mtc1	t1, $f17
+	mtc1	t1, $f18
+	mtc1	t1, $f19
+	mtc1	t1, $f20
+	mtc1	t1, $f21
+	mtc1	t1, $f22
+	mtc1	t1, $f23
+	mtc1	t1, $f24
+	mtc1	t1, $f25
+	mtc1	t1, $f26
+	mtc1	t1, $f27
+	mtc1	t1, $f28
+	mtc1	t1, $f29
+	mtc1	t1, $f30
+	mtc1	t1, $f31
+
+#if defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_CPU_MIPS32_R6)
+	.set    push
+	.set    MIPS_ISA_LEVEL_RAW
+	.set	fp=64
+	sll     t0, t0, 5			# is Status.FR set?
+	bgez    t0, 1f				# no: skip setting upper 32b
+
+	mthc1   t1, $f0
+	mthc1   t1, $f1
+	mthc1   t1, $f2
+	mthc1   t1, $f3
+	mthc1   t1, $f4
+	mthc1   t1, $f5
+	mthc1   t1, $f6
+	mthc1   t1, $f7
+	mthc1   t1, $f8
+	mthc1   t1, $f9
+	mthc1   t1, $f10
+	mthc1   t1, $f11
+	mthc1   t1, $f12
+	mthc1   t1, $f13
+	mthc1   t1, $f14
+	mthc1   t1, $f15
+	mthc1   t1, $f16
+	mthc1   t1, $f17
+	mthc1   t1, $f18
+	mthc1   t1, $f19
+	mthc1   t1, $f20
+	mthc1   t1, $f21
+	mthc1   t1, $f22
+	mthc1   t1, $f23
+	mthc1   t1, $f24
+	mthc1   t1, $f25
+	mthc1   t1, $f26
+	mthc1   t1, $f27
+	mthc1   t1, $f28
+	mthc1   t1, $f29
+	mthc1   t1, $f30
+	mthc1   t1, $f31
+1:	.set    pop
+#endif /* CONFIG_CPU_MIPS32_R2 || CONFIG_CPU_MIPS32_R6 */
+#else
+	.set	MIPS_ISA_ARCH_LEVEL_RAW
+	dmtc1	t1, $f0
+	dmtc1	t1, $f2
+	dmtc1	t1, $f4
+	dmtc1	t1, $f6
+	dmtc1	t1, $f8
+	dmtc1	t1, $f10
+	dmtc1	t1, $f12
+	dmtc1	t1, $f14
+	dmtc1	t1, $f16
+	dmtc1	t1, $f18
+	dmtc1	t1, $f20
+	dmtc1	t1, $f22
+	dmtc1	t1, $f24
+	dmtc1	t1, $f26
+	dmtc1	t1, $f28
+	dmtc1	t1, $f30
+#endif
+	jr	ra
+	END(_init_fpu)
+
+	.set pop	/* SET_HARDFLOAT */
+
 	.set	noreorder
 
 /**
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
index 7b386d54fd65..17cf9341c1cf 100644
--- a/arch/mips/kernel/r4k_switch.S
+++ b/arch/mips/kernel/r4k_switch.S
@@ -12,8 +12,6 @@
  */
 #include <asm/asm.h>
 #include <asm/cachectl.h>
-#include <asm/export.h>
-#include <asm/fpregdef.h>
 #include <asm/mipsregs.h>
 #include <asm/asm-offsets.h>
 #include <asm/regdef.h>
@@ -22,10 +20,6 @@
 
 #include <asm/asmmacro.h>
 
-/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
-#undef fp
-
-#ifndef USE_ALTERNATE_RESUME_IMPL
 /*
  * task_struct *resume(task_struct *prev, task_struct *next,
  *		       struct thread_info *next_ti)
@@ -63,200 +57,3 @@
 	move	v0, a0
 	jr	ra
 	END(resume)
-
-#endif /* USE_ALTERNATE_RESUME_IMPL */
-
-/*
- * Save a thread's fp context.
- */
-LEAF(_save_fp)
-EXPORT_SYMBOL(_save_fp)
-#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
-		defined(CONFIG_CPU_MIPS32_R6)
-	mfc0	t0, CP0_STATUS
-#endif
-	fpu_save_double a0 t0 t1		# clobbers t1
-	jr	ra
-	END(_save_fp)
-
-/*
- * Restore a thread's fp context.
- */
-LEAF(_restore_fp)
-#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) || \
-		defined(CONFIG_CPU_MIPS32_R6)
-	mfc0	t0, CP0_STATUS
-#endif
-	fpu_restore_double a0 t0 t1		# clobbers t1
-	jr	ra
-	END(_restore_fp)
-
-#ifdef CONFIG_CPU_HAS_MSA
-
-/*
- * Save a thread's MSA vector context.
- */
-LEAF(_save_msa)
-EXPORT_SYMBOL(_save_msa)
-	msa_save_all	a0
-	jr	ra
-	END(_save_msa)
-
-/*
- * Restore a thread's MSA vector context.
- */
-LEAF(_restore_msa)
-	msa_restore_all	a0
-	jr	ra
-	END(_restore_msa)
-
-LEAF(_init_msa_upper)
-	msa_init_all_upper
-	jr	ra
-	END(_init_msa_upper)
-
-#endif
-
-/*
- * Load the FPU with signalling NANS.  This bit pattern we're using has
- * the property that no matter whether considered as single or as double
- * precision represents signaling NANS.
- *
- * The value to initialize fcr31 to comes in $a0.
- */
-
-	.set push
-	SET_HARDFLOAT
-
-LEAF(_init_fpu)
-	mfc0	t0, CP0_STATUS
-	li	t1, ST0_CU1
-	or	t0, t1
-	mtc0	t0, CP0_STATUS
-	enable_fpu_hazard
-
-	ctc1	a0, fcr31
-
-	li	t1, -1				# SNaN
-
-#ifdef CONFIG_64BIT
-	sll	t0, t0, 5
-	bgez	t0, 1f				# 16 / 32 register mode?
-
-	dmtc1	t1, $f1
-	dmtc1	t1, $f3
-	dmtc1	t1, $f5
-	dmtc1	t1, $f7
-	dmtc1	t1, $f9
-	dmtc1	t1, $f11
-	dmtc1	t1, $f13
-	dmtc1	t1, $f15
-	dmtc1	t1, $f17
-	dmtc1	t1, $f19
-	dmtc1	t1, $f21
-	dmtc1	t1, $f23
-	dmtc1	t1, $f25
-	dmtc1	t1, $f27
-	dmtc1	t1, $f29
-	dmtc1	t1, $f31
-1:
-#endif
-
-#ifdef CONFIG_CPU_MIPS32
-	mtc1	t1, $f0
-	mtc1	t1, $f1
-	mtc1	t1, $f2
-	mtc1	t1, $f3
-	mtc1	t1, $f4
-	mtc1	t1, $f5
-	mtc1	t1, $f6
-	mtc1	t1, $f7
-	mtc1	t1, $f8
-	mtc1	t1, $f9
-	mtc1	t1, $f10
-	mtc1	t1, $f11
-	mtc1	t1, $f12
-	mtc1	t1, $f13
-	mtc1	t1, $f14
-	mtc1	t1, $f15
-	mtc1	t1, $f16
-	mtc1	t1, $f17
-	mtc1	t1, $f18
-	mtc1	t1, $f19
-	mtc1	t1, $f20
-	mtc1	t1, $f21
-	mtc1	t1, $f22
-	mtc1	t1, $f23
-	mtc1	t1, $f24
-	mtc1	t1, $f25
-	mtc1	t1, $f26
-	mtc1	t1, $f27
-	mtc1	t1, $f28
-	mtc1	t1, $f29
-	mtc1	t1, $f30
-	mtc1	t1, $f31
-
-#if defined(CONFIG_CPU_MIPS32_R2) || defined(CONFIG_CPU_MIPS32_R6)
-	.set    push
-	.set    MIPS_ISA_LEVEL_RAW
-	.set	fp=64
-	sll     t0, t0, 5			# is Status.FR set?
-	bgez    t0, 1f				# no: skip setting upper 32b
-
-	mthc1   t1, $f0
-	mthc1   t1, $f1
-	mthc1   t1, $f2
-	mthc1   t1, $f3
-	mthc1   t1, $f4
-	mthc1   t1, $f5
-	mthc1   t1, $f6
-	mthc1   t1, $f7
-	mthc1   t1, $f8
-	mthc1   t1, $f9
-	mthc1   t1, $f10
-	mthc1   t1, $f11
-	mthc1   t1, $f12
-	mthc1   t1, $f13
-	mthc1   t1, $f14
-	mthc1   t1, $f15
-	mthc1   t1, $f16
-	mthc1   t1, $f17
-	mthc1   t1, $f18
-	mthc1   t1, $f19
-	mthc1   t1, $f20
-	mthc1   t1, $f21
-	mthc1   t1, $f22
-	mthc1   t1, $f23
-	mthc1   t1, $f24
-	mthc1   t1, $f25
-	mthc1   t1, $f26
-	mthc1   t1, $f27
-	mthc1   t1, $f28
-	mthc1   t1, $f29
-	mthc1   t1, $f30
-	mthc1   t1, $f31
-1:	.set    pop
-#endif /* CONFIG_CPU_MIPS32_R2 || CONFIG_CPU_MIPS32_R6 */
-#else
-	.set	MIPS_ISA_ARCH_LEVEL_RAW
-	dmtc1	t1, $f0
-	dmtc1	t1, $f2
-	dmtc1	t1, $f4
-	dmtc1	t1, $f6
-	dmtc1	t1, $f8
-	dmtc1	t1, $f10
-	dmtc1	t1, $f12
-	dmtc1	t1, $f14
-	dmtc1	t1, $f16
-	dmtc1	t1, $f18
-	dmtc1	t1, $f20
-	dmtc1	t1, $f22
-	dmtc1	t1, $f24
-	dmtc1	t1, $f26
-	dmtc1	t1, $f28
-	dmtc1	t1, $f30
-#endif
-	jr	ra
-	END(_init_fpu)
-
-	.set pop	/* SET_HARDFLOAT */
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 3/5] MIPS: Move r2300 FP code from r2300_switch.S to r2300_fpu.S
@ 2017-06-05 18:21   ` Paul Burton
  0 siblings, 0 replies; 23+ messages in thread
From: Paul Burton @ 2017-06-05 18:21 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Move _save_fp(), _restore_fp() & _init_fpu() out of r2300_switch.S &
into r2300_fpu.S. This logically places all FP-related asm code into
r2300_fpu.S & provides consistency with R4K after the preceding commit.

Besides cleaning up this will be useful for later patches which disable
FP support.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/kernel/r2300_fpu.S    | 78 ++++++++++++++++++++++++++++++++++++++++-
 arch/mips/kernel/r2300_switch.S | 75 ---------------------------------------
 2 files changed, 77 insertions(+), 76 deletions(-)

diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S
index 918f2f6d3861..5d65132d4bca 100644
--- a/arch/mips/kernel/r2300_fpu.S
+++ b/arch/mips/kernel/r2300_fpu.S
@@ -31,9 +31,85 @@
 	PTR	9b+4,bad_stack;					\
 	.previous
 
-	.set	noreorder
 	.set	mips1
 
+/*
+ * Save a thread's fp context.
+ */
+LEAF(_save_fp)
+EXPORT_SYMBOL(_save_fp)
+	fpu_save_single a0, t1			# clobbers t1
+	jr	ra
+	END(_save_fp)
+
+/*
+ * Restore a thread's fp context.
+ */
+LEAF(_restore_fp)
+	fpu_restore_single a0, t1		# clobbers t1
+	jr	ra
+	END(_restore_fp)
+
+/*
+ * Load the FPU with signalling NANS.  This bit pattern we're using has
+ * the property that no matter whether considered as single or as double
+ * precision represents signaling NANS.
+ *
+ * The value to initialize fcr31 to comes in $a0.
+ */
+
+	.set push
+	SET_HARDFLOAT
+
+LEAF(_init_fpu)
+	mfc0	t0, CP0_STATUS
+	li	t1, ST0_CU1
+	or	t0, t1
+	mtc0	t0, CP0_STATUS
+
+	ctc1	a0, fcr31
+
+	li	t0, -1
+
+	mtc1	t0, $f0
+	mtc1	t0, $f1
+	mtc1	t0, $f2
+	mtc1	t0, $f3
+	mtc1	t0, $f4
+	mtc1	t0, $f5
+	mtc1	t0, $f6
+	mtc1	t0, $f7
+	mtc1	t0, $f8
+	mtc1	t0, $f9
+	mtc1	t0, $f10
+	mtc1	t0, $f11
+	mtc1	t0, $f12
+	mtc1	t0, $f13
+	mtc1	t0, $f14
+	mtc1	t0, $f15
+	mtc1	t0, $f16
+	mtc1	t0, $f17
+	mtc1	t0, $f18
+	mtc1	t0, $f19
+	mtc1	t0, $f20
+	mtc1	t0, $f21
+	mtc1	t0, $f22
+	mtc1	t0, $f23
+	mtc1	t0, $f24
+	mtc1	t0, $f25
+	mtc1	t0, $f26
+	mtc1	t0, $f27
+	mtc1	t0, $f28
+	mtc1	t0, $f29
+	mtc1	t0, $f30
+	mtc1	t0, $f31
+	jr	ra
+	END(_init_fpu)
+
+	.set pop
+
+	.set	noreorder
+
 /**
  * _save_fp_context() - save FP context from the FPU
  * @a0 - pointer to fpregs field of sigcontext
diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S
index 1049eeafd97d..887f836cfa5c 100644
--- a/arch/mips/kernel/r2300_switch.S
+++ b/arch/mips/kernel/r2300_switch.S
@@ -68,78 +68,3 @@ LEAF(resume)
 	move	v0, a0
 	jr	ra
 	END(resume)
-
-/*
- * Save a thread's fp context.
- */
-LEAF(_save_fp)
-EXPORT_SYMBOL(_save_fp)
-	fpu_save_single a0, t1			# clobbers t1
-	jr	ra
-	END(_save_fp)
-
-/*
- * Restore a thread's fp context.
- */
-LEAF(_restore_fp)
-	fpu_restore_single a0, t1		# clobbers t1
-	jr	ra
-	END(_restore_fp)
-
-/*
- * Load the FPU with signalling NANS.  This bit pattern we're using has
- * the property that no matter whether considered as single or as double
- * precision represents signaling NANS.
- *
- * The value to initialize fcr31 to comes in $a0.
- */
-
-	.set push
-	SET_HARDFLOAT
-
-LEAF(_init_fpu)
-	mfc0	t0, CP0_STATUS
-	li	t1, ST0_CU1
-	or	t0, t1
-	mtc0	t0, CP0_STATUS
-
-	ctc1	a0, fcr31
-
-	li	t0, -1
-
-	mtc1	t0, $f0
-	mtc1	t0, $f1
-	mtc1	t0, $f2
-	mtc1	t0, $f3
-	mtc1	t0, $f4
-	mtc1	t0, $f5
-	mtc1	t0, $f6
-	mtc1	t0, $f7
-	mtc1	t0, $f8
-	mtc1	t0, $f9
-	mtc1	t0, $f10
-	mtc1	t0, $f11
-	mtc1	t0, $f12
-	mtc1	t0, $f13
-	mtc1	t0, $f14
-	mtc1	t0, $f15
-	mtc1	t0, $f16
-	mtc1	t0, $f17
-	mtc1	t0, $f18
-	mtc1	t0, $f19
-	mtc1	t0, $f20
-	mtc1	t0, $f21
-	mtc1	t0, $f22
-	mtc1	t0, $f23
-	mtc1	t0, $f24
-	mtc1	t0, $f25
-	mtc1	t0, $f26
-	mtc1	t0, $f27
-	mtc1	t0, $f28
-	mtc1	t0, $f29
-	mtc1	t0, $f30
-	mtc1	t0, $f31
-	jr	ra
-	END(_init_fpu)
-
-	.set pop
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 3/5] MIPS: Move r2300 FP code from r2300_switch.S to r2300_fpu.S
@ 2017-06-05 18:21   ` Paul Burton
  0 siblings, 0 replies; 23+ messages in thread
From: Paul Burton @ 2017-06-05 18:21 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Move _save_fp(), _restore_fp() & _init_fpu() out of r2300_switch.S &
into r2300_fpu.S. This logically places all FP-related asm code into
r2300_fpu.S & provides consistency with R4K after the preceding commit.

Besides cleaning up this will be useful for later patches which disable
FP support.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/kernel/r2300_fpu.S    | 78 ++++++++++++++++++++++++++++++++++++++++-
 arch/mips/kernel/r2300_switch.S | 75 ---------------------------------------
 2 files changed, 77 insertions(+), 76 deletions(-)

diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S
index 918f2f6d3861..5d65132d4bca 100644
--- a/arch/mips/kernel/r2300_fpu.S
+++ b/arch/mips/kernel/r2300_fpu.S
@@ -31,9 +31,85 @@
 	PTR	9b+4,bad_stack;					\
 	.previous
 
-	.set	noreorder
 	.set	mips1
 
+/*
+ * Save a thread's fp context.
+ */
+LEAF(_save_fp)
+EXPORT_SYMBOL(_save_fp)
+	fpu_save_single a0, t1			# clobbers t1
+	jr	ra
+	END(_save_fp)
+
+/*
+ * Restore a thread's fp context.
+ */
+LEAF(_restore_fp)
+	fpu_restore_single a0, t1		# clobbers t1
+	jr	ra
+	END(_restore_fp)
+
+/*
+ * Load the FPU with signalling NANS.  This bit pattern we're using has
+ * the property that no matter whether considered as single or as double
+ * precision represents signaling NANS.
+ *
+ * The value to initialize fcr31 to comes in $a0.
+ */
+
+	.set push
+	SET_HARDFLOAT
+
+LEAF(_init_fpu)
+	mfc0	t0, CP0_STATUS
+	li	t1, ST0_CU1
+	or	t0, t1
+	mtc0	t0, CP0_STATUS
+
+	ctc1	a0, fcr31
+
+	li	t0, -1
+
+	mtc1	t0, $f0
+	mtc1	t0, $f1
+	mtc1	t0, $f2
+	mtc1	t0, $f3
+	mtc1	t0, $f4
+	mtc1	t0, $f5
+	mtc1	t0, $f6
+	mtc1	t0, $f7
+	mtc1	t0, $f8
+	mtc1	t0, $f9
+	mtc1	t0, $f10
+	mtc1	t0, $f11
+	mtc1	t0, $f12
+	mtc1	t0, $f13
+	mtc1	t0, $f14
+	mtc1	t0, $f15
+	mtc1	t0, $f16
+	mtc1	t0, $f17
+	mtc1	t0, $f18
+	mtc1	t0, $f19
+	mtc1	t0, $f20
+	mtc1	t0, $f21
+	mtc1	t0, $f22
+	mtc1	t0, $f23
+	mtc1	t0, $f24
+	mtc1	t0, $f25
+	mtc1	t0, $f26
+	mtc1	t0, $f27
+	mtc1	t0, $f28
+	mtc1	t0, $f29
+	mtc1	t0, $f30
+	mtc1	t0, $f31
+	jr	ra
+	END(_init_fpu)
+
+	.set pop
+
+	.set	noreorder
+
 /**
  * _save_fp_context() - save FP context from the FPU
  * @a0 - pointer to fpregs field of sigcontext
diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S
index 1049eeafd97d..887f836cfa5c 100644
--- a/arch/mips/kernel/r2300_switch.S
+++ b/arch/mips/kernel/r2300_switch.S
@@ -68,78 +68,3 @@ LEAF(resume)
 	move	v0, a0
 	jr	ra
 	END(resume)
-
-/*
- * Save a thread's fp context.
- */
-LEAF(_save_fp)
-EXPORT_SYMBOL(_save_fp)
-	fpu_save_single a0, t1			# clobbers t1
-	jr	ra
-	END(_save_fp)
-
-/*
- * Restore a thread's fp context.
- */
-LEAF(_restore_fp)
-	fpu_restore_single a0, t1		# clobbers t1
-	jr	ra
-	END(_restore_fp)
-
-/*
- * Load the FPU with signalling NANS.  This bit pattern we're using has
- * the property that no matter whether considered as single or as double
- * precision represents signaling NANS.
- *
- * The value to initialize fcr31 to comes in $a0.
- */
-
-	.set push
-	SET_HARDFLOAT
-
-LEAF(_init_fpu)
-	mfc0	t0, CP0_STATUS
-	li	t1, ST0_CU1
-	or	t0, t1
-	mtc0	t0, CP0_STATUS
-
-	ctc1	a0, fcr31
-
-	li	t0, -1
-
-	mtc1	t0, $f0
-	mtc1	t0, $f1
-	mtc1	t0, $f2
-	mtc1	t0, $f3
-	mtc1	t0, $f4
-	mtc1	t0, $f5
-	mtc1	t0, $f6
-	mtc1	t0, $f7
-	mtc1	t0, $f8
-	mtc1	t0, $f9
-	mtc1	t0, $f10
-	mtc1	t0, $f11
-	mtc1	t0, $f12
-	mtc1	t0, $f13
-	mtc1	t0, $f14
-	mtc1	t0, $f15
-	mtc1	t0, $f16
-	mtc1	t0, $f17
-	mtc1	t0, $f18
-	mtc1	t0, $f19
-	mtc1	t0, $f20
-	mtc1	t0, $f21
-	mtc1	t0, $f22
-	mtc1	t0, $f23
-	mtc1	t0, $f24
-	mtc1	t0, $f25
-	mtc1	t0, $f26
-	mtc1	t0, $f27
-	mtc1	t0, $f28
-	mtc1	t0, $f29
-	mtc1	t0, $f30
-	mtc1	t0, $f31
-	jr	ra
-	END(_init_fpu)
-
-	.set pop
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 4/5] MIPS: Remove unused ST_OFF from r2300_switch.S
@ 2017-06-05 18:21   ` Paul Burton
  0 siblings, 0 replies; 23+ messages in thread
From: Paul Burton @ 2017-06-05 18:21 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Commit 1a3d59579b9f ("MIPS: Tidy up FPU context switching") removed
usage of ST_OFF, leaving it behind as dead code. Commit 828d1e4e9865
("MIPS: Remove dead define of ST_OFF") then removed the definition of
ST_OFF from r4k_switch.S as a cleanup. However the unused definition of
ST_OFF has been left behind in r2300_switch.S. Remove it.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/kernel/r2300_switch.S | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S
index 887f836cfa5c..e57703b1de50 100644
--- a/arch/mips/kernel/r2300_switch.S
+++ b/arch/mips/kernel/r2300_switch.S
@@ -26,12 +26,6 @@
 	.align	5
 
 /*
- * Offset to the current process status flags, the first 32 bytes of the
- * stack are not used.
- */
-#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS)
-
-/*
  * task_struct *resume(task_struct *prev, task_struct *next,
  *		       struct thread_info *next_ti)
  */
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 4/5] MIPS: Remove unused ST_OFF from r2300_switch.S
@ 2017-06-05 18:21   ` Paul Burton
  0 siblings, 0 replies; 23+ messages in thread
From: Paul Burton @ 2017-06-05 18:21 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Commit 1a3d59579b9f ("MIPS: Tidy up FPU context switching") removed
usage of ST_OFF, leaving it behind as dead code. Commit 828d1e4e9865
("MIPS: Remove dead define of ST_OFF") then removed the definition of
ST_OFF from r4k_switch.S as a cleanup. However the unused definition of
ST_OFF has been left behind in r2300_switch.S. Remove it.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org
---

 arch/mips/kernel/r2300_switch.S | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S
index 887f836cfa5c..e57703b1de50 100644
--- a/arch/mips/kernel/r2300_switch.S
+++ b/arch/mips/kernel/r2300_switch.S
@@ -26,12 +26,6 @@
 	.align	5
 
 /*
- * Offset to the current process status flags, the first 32 bytes of the
- * stack are not used.
- */
-#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS)
-
-/*
  * task_struct *resume(task_struct *prev, task_struct *next,
  *		       struct thread_info *next_ti)
  */
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 5/5] MIPS: Allow floating point support to be disabled
@ 2017-06-05 18:21   ` Paul Burton
  0 siblings, 0 replies; 23+ messages in thread
From: Paul Burton @ 2017-06-05 18:21 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Floating point support has up until now always been included in all MIPS
kernels. On systems that will run exclusively soft-float code this means
the kernel includes a considerable amount of code which will never be
executed.

This patch introduces a Kconfig option to disable floating point support
in the kernel. Doing so will result in a kernel that never enables an
FPU for userland, and that always responds to use of floating point
instructions with SIGILL. With a maltasmvp_defconfig kernel this shaves
~65KiB from the size of the kernel binary.

Further optimisations would be possible, for example removing the FP &
MSA vector context from struct thread_struct when FP support is
disabled, and compiling out the code that provides access to that
through ptrace. Such changes are more invasive than those in this patch
however, so they're left as potential later work.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org

---

 arch/mips/Kconfig                    | 26 +++++++++++++++++++++++---
 arch/mips/Makefile                   |  2 +-
 arch/mips/include/asm/cpu-features.h | 11 ++++++++---
 arch/mips/include/asm/dsemul.h       | 34 ++++++++++++++++++++++++++++++++++
 arch/mips/include/asm/fpu.h          |  3 +++
 arch/mips/include/asm/fpu_emulator.h | 16 ++++++++++++++++
 arch/mips/kernel/Makefile            |  3 +--
 arch/mips/kernel/process.c           |  8 ++++++++
 8 files changed, 94 insertions(+), 9 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 20958af88522..c6255acd6d99 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2227,9 +2227,29 @@ config CPU_GENERIC_DUMP_TLB
 	bool
 	default y if !(CPU_R3000 || CPU_R8000 || CPU_TX39XX)
 
+config FP_SUPPORT
+	bool "Floating Point Support"
+	default y
+	help
+	  Select this to enable support for programs which make use of floating
+	  point instructions. This allows the kernel to support initialising, context
+	  switching & emulating the Floating Point Unit (FPU) in order to allow such
+	  programs to execute correctly.
+
+	  If you disable this then any program which attempts to execute a floating
+	  point instruction will receive a SIGILL signal & is likely to fail.
+
+	  If in doubt, say Y.
+
+config CPU_R2300_FPU
+	bool
+	depends on FP_SUPPORT
+	default y if CPU_R3000 || CPU_TX39XX
+
 config CPU_R4K_FPU
 	bool
-	default y if !(CPU_R3000 || CPU_TX39XX)
+	depends on FP_SUPPORT
+	default y if !CPU_R2300_FPU
 
 config CPU_R4K_CACHE_TLB
 	bool
@@ -2279,7 +2299,7 @@ config MIPS_MT_FPAFF
 
 config MIPSR2_TO_R6_EMULATOR
 	bool "MIPS R2-to-R6 emulator"
-	depends on CPU_MIPSR6
+	depends on CPU_MIPSR6 && FP_SUPPORT
 	default y
 	help
 	  Choose this option if you want to run non-R6 MIPS userland code.
@@ -2423,7 +2443,7 @@ endchoice
 
 config CPU_HAS_MSA
 	bool "Support for the MIPS SIMD Architecture"
-	depends on CPU_SUPPORTS_MSA
+	depends on CPU_SUPPORTS_MSA && FP_SUPPORT
 	depends on 64BIT || MIPS_O32_FP64_SUPPORT
 	help
 	  MIPS SIMD Architecture (MSA) introduces 128 bit wide vector registers
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 3d2f247310e4..4900bec32bed 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -301,7 +301,7 @@ OBJCOPYFLAGS		+= --remove-section=.reginfo
 head-y := arch/mips/kernel/head.o
 
 libs-y			+= arch/mips/lib/
-libs-y			+= arch/mips/math-emu/
+libs-$(CONFIG_FP_SUPPORT)	+= arch/mips/math-emu/
 
 # See arch/mips/Kbuild for content of core part of the kernel
 core-y += arch/mips/
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index 494d38274142..fc0a974545c8 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -76,10 +76,15 @@
 #endif
 /* Don't override `cpu_has_fpu' to 1 or the "nofpu" option won't work.  */
 #ifndef cpu_has_fpu
-#define cpu_has_fpu		(current_cpu_data.options & MIPS_CPU_FPU)
-#define raw_cpu_has_fpu		(raw_current_cpu_data.options & MIPS_CPU_FPU)
+# ifdef CONFIG_FP_SUPPORT
+#  define cpu_has_fpu		(current_cpu_data.options & MIPS_CPU_FPU)
+#  define raw_cpu_has_fpu	(raw_current_cpu_data.options & MIPS_CPU_FPU)
+# else
+#  define cpu_has_fpu		0
+#  define raw_cpu_has_fpu	0
+# endif
 #else
-#define raw_cpu_has_fpu		cpu_has_fpu
+# define raw_cpu_has_fpu	cpu_has_fpu
 #endif
 #ifndef cpu_has_32fpr
 #define cpu_has_32fpr		(cpu_data[0].options & MIPS_CPU_32FPR)
diff --git a/arch/mips/include/asm/dsemul.h b/arch/mips/include/asm/dsemul.h
index a6e067801f23..c5e1e719318b 100644
--- a/arch/mips/include/asm/dsemul.h
+++ b/arch/mips/include/asm/dsemul.h
@@ -13,6 +13,7 @@
 
 #include <asm/break.h>
 #include <asm/inst.h>
+#include <asm/signal.h>
 
 /* Break instruction with special math emu break code set */
 #define BREAK_MATH(micromips)	(((micromips) ? 0x7 : 0xd) | (BRK_MEMU << 16))
@@ -38,8 +39,16 @@ struct task_struct;
  *
  * Return: Zero on success, negative if ir is a NOP, signal number on failure.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
 		       unsigned long branch_pc, unsigned long cont_pc);
+#else
+static inline int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
+			      unsigned long branch_pc, unsigned long cont_pc)
+{
+	return SIGILL;
+}
+#endif
 
 /**
  * do_dsemulret() - Return from a delay slot 'emulation' frame
@@ -52,7 +61,14 @@ extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
  *
  * Return: True if an emulation frame was returned from, else false.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern bool do_dsemulret(struct pt_regs *xcp);
+#else
+static inline bool do_dsemulret(struct pt_regs *xcp)
+{
+	return false;
+}
+#endif
 
 /**
  * dsemul_thread_cleanup() - Cleanup thread 'emulation' frame
@@ -63,7 +79,14 @@ extern bool do_dsemulret(struct pt_regs *xcp);
  *
  * Return: True if a frame was freed, else false.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern bool dsemul_thread_cleanup(struct task_struct *tsk);
+#else
+static inline bool dsemul_thread_cleanup(struct task_struct *tsk)
+{
+	return false;
+}
+#endif
 
 /**
  * dsemul_thread_rollback() - Rollback from an 'emulation' frame
@@ -77,7 +100,14 @@ extern bool dsemul_thread_cleanup(struct task_struct *tsk);
  *
  * Return: True if a frame was exited, else false.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern bool dsemul_thread_rollback(struct pt_regs *regs);
+#else
+static inline bool dsemul_thread_rollback(struct pt_regs *regs)
+{
+	return false;
+}
+#endif
 
 /**
  * dsemul_mm_cleanup() - Cleanup per-mm delay slot 'emulation' state
@@ -87,6 +117,10 @@ extern bool dsemul_thread_rollback(struct pt_regs *regs);
  * for delay slot 'emulation' book-keeping is freed. This is to be called
  * before @mm is freed in order to avoid memory leaks.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern void dsemul_mm_cleanup(struct mm_struct *mm);
+#else
+static inline void dsemul_mm_cleanup(struct mm_struct *mm) { }
+#endif
 
 #endif /* __MIPS_ASM_DSEMUL_H__ */
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h
index a2813fe381cf..a7b2a6b76c14 100644
--- a/arch/mips/include/asm/fpu.h
+++ b/arch/mips/include/asm/fpu.h
@@ -61,6 +61,9 @@ static inline int __enable_fpu(enum fpu_mode mode)
 {
 	int fr;
 
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return SIGFPE;
+
 	switch (mode) {
 	case FPU_AS_IS:
 		/* just enable the FPU in its current mode */
diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h
index c05369e0b8d6..6a513ecf9e18 100644
--- a/arch/mips/include/asm/fpu_emulator.h
+++ b/arch/mips/include/asm/fpu_emulator.h
@@ -60,9 +60,25 @@ do {									\
 #define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)
 #endif /* CONFIG_DEBUG_FS */
 
+#ifdef CONFIG_FP_SUPPORT
+
 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
 				    struct mips_fpu_struct *ctx, int has_fpu,
 				    void *__user *fault_addr);
+
+#else /* !CONFIG_FP_SUPPORT */
+
+static inline int fpu_emulator_cop1Handler(struct pt_regs *xcp,
+					   struct mips_fpu_struct *ctx,
+					   int has_fpu,
+					   void *__user *fault_addr)
+{
+	*fault_addr = NULL;
+	return SIGILL;
+}
+
+#endif /* !CONFIG_FP_SUPPORT */
+
 void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr,
 		     struct task_struct *tsk);
 int process_fpemu_return(int sig, void __user *fault_addr,
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 10d75888f6ae..b1a40708e932 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -42,9 +42,8 @@ sw-$(CONFIG_CPU_TX39XX)		:= r2300_switch.o
 sw-$(CONFIG_CPU_CAVIUM_OCTEON)	:= octeon_switch.o
 obj-y				+= $(sw-y)
 
+obj-$(CONFIG_CPU_R2300_FPU)	+= r2300_fpu.o
 obj-$(CONFIG_CPU_R4K_FPU)	+= r4k_fpu.o
-obj-$(CONFIG_CPU_R3000)		+= r2300_fpu.o
-obj-$(CONFIG_CPU_TX39XX)	+= r2300_fpu.o
 
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_SMP_UP)		+= smp-up.o
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 5351e1f3950d..e9799e597a5d 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -663,6 +663,10 @@ int mips_get_process_fp_mode(struct task_struct *task)
 {
 	int value = 0;
 
+	/* We can do nothing sensible if we have no FP support */
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return -EOPNOTSUPP;
+
 	if (!test_tsk_thread_flag(task, TIF_32BIT_FPREGS))
 		value |= PR_FP_MODE_FR;
 	if (test_tsk_thread_flag(task, TIF_HYBRID_FPREGS))
@@ -685,6 +689,10 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
 	struct task_struct *t;
 	int max_users;
 
+	/* We can do nothing sensible if we have no FP support */
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return -EOPNOTSUPP;
+
 	/* Check the value is valid */
 	if (value & ~known_bits)
 		return -EOPNOTSUPP;
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH 5/5] MIPS: Allow floating point support to be disabled
@ 2017-06-05 18:21   ` Paul Burton
  0 siblings, 0 replies; 23+ messages in thread
From: Paul Burton @ 2017-06-05 18:21 UTC (permalink / raw)
  To: linux-mips; +Cc: Ralf Baechle, Paul Burton

Floating point support has up until now always been included in all MIPS
kernels. On systems that will run exclusively soft-float code this means
the kernel includes a considerable amount of code which will never be
executed.

This patch introduces a Kconfig option to disable floating point support
in the kernel. Doing so will result in a kernel that never enables an
FPU for userland, and that always responds to use of floating point
instructions with SIGILL. With a maltasmvp_defconfig kernel this shaves
~65KiB from the size of the kernel binary.

Further optimisations would be possible, for example removing the FP &
MSA vector context from struct thread_struct when FP support is
disabled, and compiling out the code that provides access to that
through ptrace. Such changes are more invasive than those in this patch
however, so they're left as potential later work.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org

---

 arch/mips/Kconfig                    | 26 +++++++++++++++++++++++---
 arch/mips/Makefile                   |  2 +-
 arch/mips/include/asm/cpu-features.h | 11 ++++++++---
 arch/mips/include/asm/dsemul.h       | 34 ++++++++++++++++++++++++++++++++++
 arch/mips/include/asm/fpu.h          |  3 +++
 arch/mips/include/asm/fpu_emulator.h | 16 ++++++++++++++++
 arch/mips/kernel/Makefile            |  3 +--
 arch/mips/kernel/process.c           |  8 ++++++++
 8 files changed, 94 insertions(+), 9 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 20958af88522..c6255acd6d99 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2227,9 +2227,29 @@ config CPU_GENERIC_DUMP_TLB
 	bool
 	default y if !(CPU_R3000 || CPU_R8000 || CPU_TX39XX)
 
+config FP_SUPPORT
+	bool "Floating Point Support"
+	default y
+	help
+	  Select this to enable support for programs which make use of floating
+	  point instructions. This allows the kernel to support initialising, context
+	  switching & emulating the Floating Point Unit (FPU) in order to allow such
+	  programs to execute correctly.
+
+	  If you disable this then any program which attempts to execute a floating
+	  point instruction will receive a SIGILL signal & is likely to fail.
+
+	  If in doubt, say Y.
+
+config CPU_R2300_FPU
+	bool
+	depends on FP_SUPPORT
+	default y if CPU_R3000 || CPU_TX39XX
+
 config CPU_R4K_FPU
 	bool
-	default y if !(CPU_R3000 || CPU_TX39XX)
+	depends on FP_SUPPORT
+	default y if !CPU_R2300_FPU
 
 config CPU_R4K_CACHE_TLB
 	bool
@@ -2279,7 +2299,7 @@ config MIPS_MT_FPAFF
 
 config MIPSR2_TO_R6_EMULATOR
 	bool "MIPS R2-to-R6 emulator"
-	depends on CPU_MIPSR6
+	depends on CPU_MIPSR6 && FP_SUPPORT
 	default y
 	help
 	  Choose this option if you want to run non-R6 MIPS userland code.
@@ -2423,7 +2443,7 @@ endchoice
 
 config CPU_HAS_MSA
 	bool "Support for the MIPS SIMD Architecture"
-	depends on CPU_SUPPORTS_MSA
+	depends on CPU_SUPPORTS_MSA && FP_SUPPORT
 	depends on 64BIT || MIPS_O32_FP64_SUPPORT
 	help
 	  MIPS SIMD Architecture (MSA) introduces 128 bit wide vector registers
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 3d2f247310e4..4900bec32bed 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -301,7 +301,7 @@ OBJCOPYFLAGS		+= --remove-section=.reginfo
 head-y := arch/mips/kernel/head.o
 
 libs-y			+= arch/mips/lib/
-libs-y			+= arch/mips/math-emu/
+libs-$(CONFIG_FP_SUPPORT)	+= arch/mips/math-emu/
 
 # See arch/mips/Kbuild for content of core part of the kernel
 core-y += arch/mips/
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index 494d38274142..fc0a974545c8 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -76,10 +76,15 @@
 #endif
 /* Don't override `cpu_has_fpu' to 1 or the "nofpu" option won't work.  */
 #ifndef cpu_has_fpu
-#define cpu_has_fpu		(current_cpu_data.options & MIPS_CPU_FPU)
-#define raw_cpu_has_fpu		(raw_current_cpu_data.options & MIPS_CPU_FPU)
+# ifdef CONFIG_FP_SUPPORT
+#  define cpu_has_fpu		(current_cpu_data.options & MIPS_CPU_FPU)
+#  define raw_cpu_has_fpu	(raw_current_cpu_data.options & MIPS_CPU_FPU)
+# else
+#  define cpu_has_fpu		0
+#  define raw_cpu_has_fpu	0
+# endif
 #else
-#define raw_cpu_has_fpu		cpu_has_fpu
+# define raw_cpu_has_fpu	cpu_has_fpu
 #endif
 #ifndef cpu_has_32fpr
 #define cpu_has_32fpr		(cpu_data[0].options & MIPS_CPU_32FPR)
diff --git a/arch/mips/include/asm/dsemul.h b/arch/mips/include/asm/dsemul.h
index a6e067801f23..c5e1e719318b 100644
--- a/arch/mips/include/asm/dsemul.h
+++ b/arch/mips/include/asm/dsemul.h
@@ -13,6 +13,7 @@
 
 #include <asm/break.h>
 #include <asm/inst.h>
+#include <asm/signal.h>
 
 /* Break instruction with special math emu break code set */
 #define BREAK_MATH(micromips)	(((micromips) ? 0x7 : 0xd) | (BRK_MEMU << 16))
@@ -38,8 +39,16 @@ struct task_struct;
  *
  * Return: Zero on success, negative if ir is a NOP, signal number on failure.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
 		       unsigned long branch_pc, unsigned long cont_pc);
+#else
+static inline int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
+			      unsigned long branch_pc, unsigned long cont_pc)
+{
+	return SIGILL;
+}
+#endif
 
 /**
  * do_dsemulret() - Return from a delay slot 'emulation' frame
@@ -52,7 +61,14 @@ extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
  *
  * Return: True if an emulation frame was returned from, else false.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern bool do_dsemulret(struct pt_regs *xcp);
+#else
+static inline bool do_dsemulret(struct pt_regs *xcp)
+{
+	return false;
+}
+#endif
 
 /**
  * dsemul_thread_cleanup() - Cleanup thread 'emulation' frame
@@ -63,7 +79,14 @@ extern bool do_dsemulret(struct pt_regs *xcp);
  *
  * Return: True if a frame was freed, else false.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern bool dsemul_thread_cleanup(struct task_struct *tsk);
+#else
+static inline bool dsemul_thread_cleanup(struct task_struct *tsk)
+{
+	return false;
+}
+#endif
 
 /**
  * dsemul_thread_rollback() - Rollback from an 'emulation' frame
@@ -77,7 +100,14 @@ extern bool dsemul_thread_cleanup(struct task_struct *tsk);
  *
  * Return: True if a frame was exited, else false.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern bool dsemul_thread_rollback(struct pt_regs *regs);
+#else
+static inline bool dsemul_thread_rollback(struct pt_regs *regs)
+{
+	return false;
+}
+#endif
 
 /**
  * dsemul_mm_cleanup() - Cleanup per-mm delay slot 'emulation' state
@@ -87,6 +117,10 @@ extern bool dsemul_thread_rollback(struct pt_regs *regs);
  * for delay slot 'emulation' book-keeping is freed. This is to be called
  * before @mm is freed in order to avoid memory leaks.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern void dsemul_mm_cleanup(struct mm_struct *mm);
+#else
+static inline void dsemul_mm_cleanup(struct mm_struct *mm) { }
+#endif
 
 #endif /* __MIPS_ASM_DSEMUL_H__ */
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h
index a2813fe381cf..a7b2a6b76c14 100644
--- a/arch/mips/include/asm/fpu.h
+++ b/arch/mips/include/asm/fpu.h
@@ -61,6 +61,9 @@ static inline int __enable_fpu(enum fpu_mode mode)
 {
 	int fr;
 
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return SIGFPE;
+
 	switch (mode) {
 	case FPU_AS_IS:
 		/* just enable the FPU in its current mode */
diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h
index c05369e0b8d6..6a513ecf9e18 100644
--- a/arch/mips/include/asm/fpu_emulator.h
+++ b/arch/mips/include/asm/fpu_emulator.h
@@ -60,9 +60,25 @@ do {									\
 #define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)
 #endif /* CONFIG_DEBUG_FS */
 
+#ifdef CONFIG_FP_SUPPORT
+
 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
 				    struct mips_fpu_struct *ctx, int has_fpu,
 				    void *__user *fault_addr);
+
+#else /* !CONFIG_FP_SUPPORT */
+
+static inline int fpu_emulator_cop1Handler(struct pt_regs *xcp,
+					   struct mips_fpu_struct *ctx,
+					   int has_fpu,
+					   void *__user *fault_addr)
+{
+	*fault_addr = NULL;
+	return SIGILL;
+}
+
+#endif /* !CONFIG_FP_SUPPORT */
+
 void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr,
 		     struct task_struct *tsk);
 int process_fpemu_return(int sig, void __user *fault_addr,
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 10d75888f6ae..b1a40708e932 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -42,9 +42,8 @@ sw-$(CONFIG_CPU_TX39XX)		:= r2300_switch.o
 sw-$(CONFIG_CPU_CAVIUM_OCTEON)	:= octeon_switch.o
 obj-y				+= $(sw-y)
 
+obj-$(CONFIG_CPU_R2300_FPU)	+= r2300_fpu.o
 obj-$(CONFIG_CPU_R4K_FPU)	+= r4k_fpu.o
-obj-$(CONFIG_CPU_R3000)		+= r2300_fpu.o
-obj-$(CONFIG_CPU_TX39XX)	+= r2300_fpu.o
 
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_SMP_UP)		+= smp-up.o
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 5351e1f3950d..e9799e597a5d 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -663,6 +663,10 @@ int mips_get_process_fp_mode(struct task_struct *task)
 {
 	int value = 0;
 
+	/* We can do nothing sensible if we have no FP support */
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return -EOPNOTSUPP;
+
 	if (!test_tsk_thread_flag(task, TIF_32BIT_FPREGS))
 		value |= PR_FP_MODE_FR;
 	if (test_tsk_thread_flag(task, TIF_HYBRID_FPREGS))
@@ -685,6 +689,10 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
 	struct task_struct *t;
 	int max_users;
 
+	/* We can do nothing sensible if we have no FP support */
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return -EOPNOTSUPP;
+
 	/* Check the value is valid */
 	if (value & ~known_bits)
 		return -EOPNOTSUPP;
-- 
2.13.0

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/5] MIPS: FP cleanup & no-FP support
@ 2017-06-16  2:55   ` Maciej W. Rozycki
  0 siblings, 0 replies; 23+ messages in thread
From: Maciej W. Rozycki @ 2017-06-16  2:55 UTC (permalink / raw)
  To: Paul Burton; +Cc: linux-mips, Ralf Baechle

On Mon, 5 Jun 2017, Paul Burton wrote:

> This series tidies up support for floating point a little, then
> introduces support for disabling it via Kconfig. The end result is that
> it becomes possible to compile a kernel which does not include any
> support for userland which makes use of floating point instructions -
> meaning that it never enables an FPU & does not include the FPU
> emulator. The benefit of this is that if you know your userland code
> will not use FP instructions then you can shrink the kernel by around
> 65KiB.
> 
> Applies atop v4.12-rc4.
> 
> Paul Burton (5):
>   MIPS: Remove unused R6000 support
>   MIPS: Move r4k FP code from r4k_switch.S to r4k_fpu.S
>   MIPS: Move r2300 FP code from r2300_switch.S to r2300_fpu.S
>   MIPS: Remove unused ST_OFF from r2300_switch.S
>   MIPS: Allow floating point support to be disabled

 Doesn't ptrace(2) require suitable updates for requests that deal with 
the FP context?  Preferably along with the last change (or maybe ahead of 
it) so that we don't have a kernel revision that presents rubbish to the 
userland (of course tools like GDB will have to be updated accordingly to 
cope, but that's out of scope for Linux itself).

 Also how about those prctl(2) calls that also operate on FP state?

  Maciej

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/5] MIPS: FP cleanup & no-FP support
@ 2017-06-16  2:55   ` Maciej W. Rozycki
  0 siblings, 0 replies; 23+ messages in thread
From: Maciej W. Rozycki @ 2017-06-16  2:55 UTC (permalink / raw)
  To: Paul Burton; +Cc: linux-mips, Ralf Baechle

On Mon, 5 Jun 2017, Paul Burton wrote:

> This series tidies up support for floating point a little, then
> introduces support for disabling it via Kconfig. The end result is that
> it becomes possible to compile a kernel which does not include any
> support for userland which makes use of floating point instructions -
> meaning that it never enables an FPU & does not include the FPU
> emulator. The benefit of this is that if you know your userland code
> will not use FP instructions then you can shrink the kernel by around
> 65KiB.
> 
> Applies atop v4.12-rc4.
> 
> Paul Burton (5):
>   MIPS: Remove unused R6000 support
>   MIPS: Move r4k FP code from r4k_switch.S to r4k_fpu.S
>   MIPS: Move r2300 FP code from r2300_switch.S to r2300_fpu.S
>   MIPS: Remove unused ST_OFF from r2300_switch.S
>   MIPS: Allow floating point support to be disabled

 Doesn't ptrace(2) require suitable updates for requests that deal with 
the FP context?  Preferably along with the last change (or maybe ahead of 
it) so that we don't have a kernel revision that presents rubbish to the 
userland (of course tools like GDB will have to be updated accordingly to 
cope, but that's out of scope for Linux itself).

 Also how about those prctl(2) calls that also operate on FP state?

  Maciej

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/5] MIPS: FP cleanup & no-FP support
@ 2017-06-16 16:49     ` Paul Burton
  0 siblings, 0 replies; 23+ messages in thread
From: Paul Burton @ 2017-06-16 16:49 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: linux-mips, Ralf Baechle

[-- Attachment #1: Type: text/plain, Size: 2493 bytes --]

Hi Maciej,

On Thursday, 15 June 2017 19:55:26 PDT Maciej W. Rozycki wrote:
> On Mon, 5 Jun 2017, Paul Burton wrote:
> > This series tidies up support for floating point a little, then
> > introduces support for disabling it via Kconfig. The end result is that
> > it becomes possible to compile a kernel which does not include any
> > support for userland which makes use of floating point instructions -
> > meaning that it never enables an FPU & does not include the FPU
> > emulator. The benefit of this is that if you know your userland code
> > will not use FP instructions then you can shrink the kernel by around
> > 65KiB.
> > 
> > Applies atop v4.12-rc4.
> > 
> > Paul Burton (5):
> >   MIPS: Remove unused R6000 support
> >   MIPS: Move r4k FP code from r4k_switch.S to r4k_fpu.S
> >   MIPS: Move r2300 FP code from r2300_switch.S to r2300_fpu.S
> >   MIPS: Remove unused ST_OFF from r2300_switch.S
> >   MIPS: Allow floating point support to be disabled
> 
> Doesn't ptrace(2) require suitable updates for requests that deal with
> the FP context?

I mentioned in the commit message for patch 5 that removing the actual context 
fields & ptrace access to them could be done as a further improvement.

> Preferably along with the last change (or maybe ahead of
> it) so that we don't have a kernel revision that presents rubbish to the
> userland (of course tools like GDB will have to be updated accordingly to
> cope, but that's out of scope for Linux itself).

Well, as-is ptrace would still let you read & write to FP registers if you 
try, it's just those values will never be used. Are you opposed to that 
behaviour? If we do later remove the context entirely then presumably ptrace 
would either read 0 or return an error, and ignore writes or return an error - 
I suppose if we want to ensure consistent behaviour for that potential future 
change then we could choose one of those options & do that here.

In practice I'm not sure I see much benefit - if a debugger wants to write to 
context corresponding to registers that just aren't there then letting it 
doesn't seem like a big problem. Do you disagree? Note that we already allow 
this for hi & lo registers on r6 for example - ptrace will freely read/write 
the context even though the registers don't exist.

> Also how about those prctl(2) calls that also operate on FP state?

Patch 5 has them return -EOPNOTSUPP, which is consistent with behaviour when 
attempting to set an unsupported mode.

Thanks,
    Paul

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/5] MIPS: FP cleanup & no-FP support
@ 2017-06-16 16:49     ` Paul Burton
  0 siblings, 0 replies; 23+ messages in thread
From: Paul Burton @ 2017-06-16 16:49 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: linux-mips, Ralf Baechle

[-- Attachment #1: Type: text/plain, Size: 2493 bytes --]

Hi Maciej,

On Thursday, 15 June 2017 19:55:26 PDT Maciej W. Rozycki wrote:
> On Mon, 5 Jun 2017, Paul Burton wrote:
> > This series tidies up support for floating point a little, then
> > introduces support for disabling it via Kconfig. The end result is that
> > it becomes possible to compile a kernel which does not include any
> > support for userland which makes use of floating point instructions -
> > meaning that it never enables an FPU & does not include the FPU
> > emulator. The benefit of this is that if you know your userland code
> > will not use FP instructions then you can shrink the kernel by around
> > 65KiB.
> > 
> > Applies atop v4.12-rc4.
> > 
> > Paul Burton (5):
> >   MIPS: Remove unused R6000 support
> >   MIPS: Move r4k FP code from r4k_switch.S to r4k_fpu.S
> >   MIPS: Move r2300 FP code from r2300_switch.S to r2300_fpu.S
> >   MIPS: Remove unused ST_OFF from r2300_switch.S
> >   MIPS: Allow floating point support to be disabled
> 
> Doesn't ptrace(2) require suitable updates for requests that deal with
> the FP context?

I mentioned in the commit message for patch 5 that removing the actual context 
fields & ptrace access to them could be done as a further improvement.

> Preferably along with the last change (or maybe ahead of
> it) so that we don't have a kernel revision that presents rubbish to the
> userland (of course tools like GDB will have to be updated accordingly to
> cope, but that's out of scope for Linux itself).

Well, as-is ptrace would still let you read & write to FP registers if you 
try, it's just those values will never be used. Are you opposed to that 
behaviour? If we do later remove the context entirely then presumably ptrace 
would either read 0 or return an error, and ignore writes or return an error - 
I suppose if we want to ensure consistent behaviour for that potential future 
change then we could choose one of those options & do that here.

In practice I'm not sure I see much benefit - if a debugger wants to write to 
context corresponding to registers that just aren't there then letting it 
doesn't seem like a big problem. Do you disagree? Note that we already allow 
this for hi & lo registers on r6 for example - ptrace will freely read/write 
the context even though the registers don't exist.

> Also how about those prctl(2) calls that also operate on FP state?

Patch 5 has them return -EOPNOTSUPP, which is consistent with behaviour when 
attempting to set an unsupported mode.

Thanks,
    Paul

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/5] MIPS: FP cleanup & no-FP support
@ 2017-06-16 19:50       ` Maciej W. Rozycki
  0 siblings, 0 replies; 23+ messages in thread
From: Maciej W. Rozycki @ 2017-06-16 19:50 UTC (permalink / raw)
  To: Paul Burton; +Cc: linux-mips, Ralf Baechle

Paul,

> > > Paul Burton (5):
> > >   MIPS: Remove unused R6000 support
> > >   MIPS: Move r4k FP code from r4k_switch.S to r4k_fpu.S
> > >   MIPS: Move r2300 FP code from r2300_switch.S to r2300_fpu.S
> > >   MIPS: Remove unused ST_OFF from r2300_switch.S
> > >   MIPS: Allow floating point support to be disabled
> > 
> > Doesn't ptrace(2) require suitable updates for requests that deal with
> > the FP context?
> 
> I mentioned in the commit message for patch 5 that removing the actual context 
> fields & ptrace access to them could be done as a further improvement.

 Somehow I missed that, sorry, but in any case I don't find it acceptable.

> > Preferably along with the last change (or maybe ahead of
> > it) so that we don't have a kernel revision that presents rubbish to the
> > userland (of course tools like GDB will have to be updated accordingly to
> > cope, but that's out of scope for Linux itself).
> 
> Well, as-is ptrace would still let you read & write to FP registers if you 
> try, it's just those values will never be used. Are you opposed to that 
> behaviour? If we do later remove the context entirely then presumably ptrace 
> would either read 0 or return an error, and ignore writes or return an error - 
> I suppose if we want to ensure consistent behaviour for that potential future 
> change then we could choose one of those options & do that here.
> 
> In practice I'm not sure I see much benefit - if a debugger wants to write to 
> context corresponding to registers that just aren't there then letting it 
> doesn't seem like a big problem. Do you disagree? Note that we already allow 
> this for hi & lo registers on r6 for example - ptrace will freely read/write 
> the context even though the registers don't exist.

 I think there must be -EIO for access to any inexistent resource, just as 
we already do for missing DSP registers.  The client can then handle this 
appropriately.  (ENXIO would probably be more accurate, however EIO has 
already been embedded in GDB and changing it would be problematic).

 I wasn't aware about the HI/LO case with R6 -- it clearly looks like a 
bug to me.  Of course it means more work for GDB and other such software 
maintainers, but I find it unacceptable if we present users with resources 
which are not there.

> > Also how about those prctl(2) calls that also operate on FP state?
> 
> Patch 5 has them return -EOPNOTSUPP, which is consistent with behaviour when 
> attempting to set an unsupported mode.

 I missed that, sorry.  I'm not sure if -EOPNOTSUPP (-EINVAL?) or -EIO 
(-ENXIO?) would be the right code here, i.e. unrecognised vs unsupported, 
but I can see the existing code does not tell these two cases apart, so I 
think I'd accept your proposal here as it stands, although this may have 
to be eventually fixed.  Also glibc code will have to be audited for 
correct error handling here.

  Maciej

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH 0/5] MIPS: FP cleanup & no-FP support
@ 2017-06-16 19:50       ` Maciej W. Rozycki
  0 siblings, 0 replies; 23+ messages in thread
From: Maciej W. Rozycki @ 2017-06-16 19:50 UTC (permalink / raw)
  To: Paul Burton; +Cc: linux-mips, Ralf Baechle

Paul,

> > > Paul Burton (5):
> > >   MIPS: Remove unused R6000 support
> > >   MIPS: Move r4k FP code from r4k_switch.S to r4k_fpu.S
> > >   MIPS: Move r2300 FP code from r2300_switch.S to r2300_fpu.S
> > >   MIPS: Remove unused ST_OFF from r2300_switch.S
> > >   MIPS: Allow floating point support to be disabled
> > 
> > Doesn't ptrace(2) require suitable updates for requests that deal with
> > the FP context?
> 
> I mentioned in the commit message for patch 5 that removing the actual context 
> fields & ptrace access to them could be done as a further improvement.

 Somehow I missed that, sorry, but in any case I don't find it acceptable.

> > Preferably along with the last change (or maybe ahead of
> > it) so that we don't have a kernel revision that presents rubbish to the
> > userland (of course tools like GDB will have to be updated accordingly to
> > cope, but that's out of scope for Linux itself).
> 
> Well, as-is ptrace would still let you read & write to FP registers if you 
> try, it's just those values will never be used. Are you opposed to that 
> behaviour? If we do later remove the context entirely then presumably ptrace 
> would either read 0 or return an error, and ignore writes or return an error - 
> I suppose if we want to ensure consistent behaviour for that potential future 
> change then we could choose one of those options & do that here.
> 
> In practice I'm not sure I see much benefit - if a debugger wants to write to 
> context corresponding to registers that just aren't there then letting it 
> doesn't seem like a big problem. Do you disagree? Note that we already allow 
> this for hi & lo registers on r6 for example - ptrace will freely read/write 
> the context even though the registers don't exist.

 I think there must be -EIO for access to any inexistent resource, just as 
we already do for missing DSP registers.  The client can then handle this 
appropriately.  (ENXIO would probably be more accurate, however EIO has 
already been embedded in GDB and changing it would be problematic).

 I wasn't aware about the HI/LO case with R6 -- it clearly looks like a 
bug to me.  Of course it means more work for GDB and other such software 
maintainers, but I find it unacceptable if we present users with resources 
which are not there.

> > Also how about those prctl(2) calls that also operate on FP state?
> 
> Patch 5 has them return -EOPNOTSUPP, which is consistent with behaviour when 
> attempting to set an unsupported mode.

 I missed that, sorry.  I'm not sure if -EOPNOTSUPP (-EINVAL?) or -EIO 
(-ENXIO?) would be the right code here, i.e. unrecognised vs unsupported, 
but I can see the existing code does not tell these two cases apart, so I 
think I'd accept your proposal here as it stands, although this may have 
to be eventually fixed.  Also glibc code will have to be audited for 
correct error handling here.

  Maciej

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v2 5/5] MIPS: Allow floating point support to be disabled
@ 2017-06-16 20:21         ` Paul Burton
  0 siblings, 0 replies; 23+ messages in thread
From: Paul Burton @ 2017-06-16 20:21 UTC (permalink / raw)
  To: linux-mips, Maciej W . Rozycki; +Cc: Paul Burton, Ralf Baechle

Floating point support has up until now always been included in all MIPS
kernels. On systems that will run exclusively soft-float code this means
the kernel includes a considerable amount of code which will never be
executed.

This patch introduces a Kconfig option to disable floating point support
in the kernel. Doing so will result in a kernel that never enables an
FPU for userland, and that always responds to use of floating point
instructions with SIGILL. With a maltasmvp_defconfig kernel this shaves
~65KiB from the size of the kernel binary.

Further optimisations would be possible, for example removing the FP &
MSA vector context from struct thread_struct when FP support is
disabled, and compiling out the code that provides access to that
through ptrace. Such changes are more invasive than those in this patch
however, so they're left as potential later work.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org

---

Changes in v2:
- Have ptrace return -EIO for access to FP context.
- Avoid cpu_set_fpu_opts(), fixing boot of a CONFIG_FP_SUPPORT=n kernel on a system that actually does have an FPU.

 arch/mips/Kconfig                    | 26 +++++++++++++++++++++++---
 arch/mips/Makefile                   |  2 +-
 arch/mips/include/asm/cpu-features.h | 11 ++++++++---
 arch/mips/include/asm/dsemul.h       | 34 ++++++++++++++++++++++++++++++++++
 arch/mips/include/asm/fpu.h          |  3 +++
 arch/mips/include/asm/fpu_emulator.h | 16 ++++++++++++++++
 arch/mips/kernel/Makefile            |  3 +--
 arch/mips/kernel/cpu-probe.c         |  2 +-
 arch/mips/kernel/process.c           |  8 ++++++++
 arch/mips/kernel/ptrace.c            | 33 +++++++++++++++++++++++++++++++++
 arch/mips/kernel/ptrace32.c          | 20 ++++++++++++++++++++
 11 files changed, 148 insertions(+), 10 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 20958af88522..c6255acd6d99 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2227,9 +2227,29 @@ config CPU_GENERIC_DUMP_TLB
 	bool
 	default y if !(CPU_R3000 || CPU_R8000 || CPU_TX39XX)
 
+config FP_SUPPORT
+	bool "Floating Point Support"
+	default y
+	help
+	  Select this to enable support for programs which make use of floating
+	  point instructions. This allows the kernel to support initialising, context
+	  switching & emulating the Floating Point Unit (FPU) in order to allow such
+	  programs to execute correctly.
+
+	  If you disable this then any program which attempts to execute a floating
+	  point instruction will receive a SIGILL signal & is likely to fail.
+
+	  If in doubt, say Y.
+
+config CPU_R2300_FPU
+	bool
+	depends on FP_SUPPORT
+	default y if CPU_R3000 || CPU_TX39XX
+
 config CPU_R4K_FPU
 	bool
-	default y if !(CPU_R3000 || CPU_TX39XX)
+	depends on FP_SUPPORT
+	default y if !CPU_R2300_FPU
 
 config CPU_R4K_CACHE_TLB
 	bool
@@ -2279,7 +2299,7 @@ config MIPS_MT_FPAFF
 
 config MIPSR2_TO_R6_EMULATOR
 	bool "MIPS R2-to-R6 emulator"
-	depends on CPU_MIPSR6
+	depends on CPU_MIPSR6 && FP_SUPPORT
 	default y
 	help
 	  Choose this option if you want to run non-R6 MIPS userland code.
@@ -2423,7 +2443,7 @@ endchoice
 
 config CPU_HAS_MSA
 	bool "Support for the MIPS SIMD Architecture"
-	depends on CPU_SUPPORTS_MSA
+	depends on CPU_SUPPORTS_MSA && FP_SUPPORT
 	depends on 64BIT || MIPS_O32_FP64_SUPPORT
 	help
 	  MIPS SIMD Architecture (MSA) introduces 128 bit wide vector registers
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 3d2f247310e4..4900bec32bed 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -301,7 +301,7 @@ OBJCOPYFLAGS		+= --remove-section=.reginfo
 head-y := arch/mips/kernel/head.o
 
 libs-y			+= arch/mips/lib/
-libs-y			+= arch/mips/math-emu/
+libs-$(CONFIG_FP_SUPPORT)	+= arch/mips/math-emu/
 
 # See arch/mips/Kbuild for content of core part of the kernel
 core-y += arch/mips/
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index 494d38274142..fc0a974545c8 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -76,10 +76,15 @@
 #endif
 /* Don't override `cpu_has_fpu' to 1 or the "nofpu" option won't work.  */
 #ifndef cpu_has_fpu
-#define cpu_has_fpu		(current_cpu_data.options & MIPS_CPU_FPU)
-#define raw_cpu_has_fpu		(raw_current_cpu_data.options & MIPS_CPU_FPU)
+# ifdef CONFIG_FP_SUPPORT
+#  define cpu_has_fpu		(current_cpu_data.options & MIPS_CPU_FPU)
+#  define raw_cpu_has_fpu	(raw_current_cpu_data.options & MIPS_CPU_FPU)
+# else
+#  define cpu_has_fpu		0
+#  define raw_cpu_has_fpu	0
+# endif
 #else
-#define raw_cpu_has_fpu		cpu_has_fpu
+# define raw_cpu_has_fpu	cpu_has_fpu
 #endif
 #ifndef cpu_has_32fpr
 #define cpu_has_32fpr		(cpu_data[0].options & MIPS_CPU_32FPR)
diff --git a/arch/mips/include/asm/dsemul.h b/arch/mips/include/asm/dsemul.h
index a6e067801f23..c5e1e719318b 100644
--- a/arch/mips/include/asm/dsemul.h
+++ b/arch/mips/include/asm/dsemul.h
@@ -13,6 +13,7 @@
 
 #include <asm/break.h>
 #include <asm/inst.h>
+#include <asm/signal.h>
 
 /* Break instruction with special math emu break code set */
 #define BREAK_MATH(micromips)	(((micromips) ? 0x7 : 0xd) | (BRK_MEMU << 16))
@@ -38,8 +39,16 @@ struct task_struct;
  *
  * Return: Zero on success, negative if ir is a NOP, signal number on failure.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
 		       unsigned long branch_pc, unsigned long cont_pc);
+#else
+static inline int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
+			      unsigned long branch_pc, unsigned long cont_pc)
+{
+	return SIGILL;
+}
+#endif
 
 /**
  * do_dsemulret() - Return from a delay slot 'emulation' frame
@@ -52,7 +61,14 @@ extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
  *
  * Return: True if an emulation frame was returned from, else false.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern bool do_dsemulret(struct pt_regs *xcp);
+#else
+static inline bool do_dsemulret(struct pt_regs *xcp)
+{
+	return false;
+}
+#endif
 
 /**
  * dsemul_thread_cleanup() - Cleanup thread 'emulation' frame
@@ -63,7 +79,14 @@ extern bool do_dsemulret(struct pt_regs *xcp);
  *
  * Return: True if a frame was freed, else false.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern bool dsemul_thread_cleanup(struct task_struct *tsk);
+#else
+static inline bool dsemul_thread_cleanup(struct task_struct *tsk)
+{
+	return false;
+}
+#endif
 
 /**
  * dsemul_thread_rollback() - Rollback from an 'emulation' frame
@@ -77,7 +100,14 @@ extern bool dsemul_thread_cleanup(struct task_struct *tsk);
  *
  * Return: True if a frame was exited, else false.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern bool dsemul_thread_rollback(struct pt_regs *regs);
+#else
+static inline bool dsemul_thread_rollback(struct pt_regs *regs)
+{
+	return false;
+}
+#endif
 
 /**
  * dsemul_mm_cleanup() - Cleanup per-mm delay slot 'emulation' state
@@ -87,6 +117,10 @@ extern bool dsemul_thread_rollback(struct pt_regs *regs);
  * for delay slot 'emulation' book-keeping is freed. This is to be called
  * before @mm is freed in order to avoid memory leaks.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern void dsemul_mm_cleanup(struct mm_struct *mm);
+#else
+static inline void dsemul_mm_cleanup(struct mm_struct *mm) { }
+#endif
 
 #endif /* __MIPS_ASM_DSEMUL_H__ */
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h
index a2813fe381cf..a7b2a6b76c14 100644
--- a/arch/mips/include/asm/fpu.h
+++ b/arch/mips/include/asm/fpu.h
@@ -61,6 +61,9 @@ static inline int __enable_fpu(enum fpu_mode mode)
 {
 	int fr;
 
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return SIGFPE;
+
 	switch (mode) {
 	case FPU_AS_IS:
 		/* just enable the FPU in its current mode */
diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h
index c05369e0b8d6..6a513ecf9e18 100644
--- a/arch/mips/include/asm/fpu_emulator.h
+++ b/arch/mips/include/asm/fpu_emulator.h
@@ -60,9 +60,25 @@ do {									\
 #define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)
 #endif /* CONFIG_DEBUG_FS */
 
+#ifdef CONFIG_FP_SUPPORT
+
 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
 				    struct mips_fpu_struct *ctx, int has_fpu,
 				    void *__user *fault_addr);
+
+#else /* !CONFIG_FP_SUPPORT */
+
+static inline int fpu_emulator_cop1Handler(struct pt_regs *xcp,
+					   struct mips_fpu_struct *ctx,
+					   int has_fpu,
+					   void *__user *fault_addr)
+{
+	*fault_addr = NULL;
+	return SIGILL;
+}
+
+#endif /* !CONFIG_FP_SUPPORT */
+
 void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr,
 		     struct task_struct *tsk);
 int process_fpemu_return(int sig, void __user *fault_addr,
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 10d75888f6ae..b1a40708e932 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -42,9 +42,8 @@ sw-$(CONFIG_CPU_TX39XX)		:= r2300_switch.o
 sw-$(CONFIG_CPU_CAVIUM_OCTEON)	:= octeon_switch.o
 obj-y				+= $(sw-y)
 
+obj-$(CONFIG_CPU_R2300_FPU)	+= r2300_fpu.o
 obj-$(CONFIG_CPU_R4K_FPU)	+= r4k_fpu.o
-obj-$(CONFIG_CPU_R3000)		+= r2300_fpu.o
-obj-$(CONFIG_CPU_TX39XX)	+= r2300_fpu.o
 
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_SMP_UP)		+= smp-up.o
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index ddc86f98eb86..f2e81282e61d 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -2022,7 +2022,7 @@ void cpu_probe(void)
 			       ~(1 << MIPS_PWCTL_PWEN_SHIFT));
 	}
 
-	if (c->options & MIPS_CPU_FPU)
+	if (IS_ENABLED(CONFIG_FP_SUPPORT) && c->options & MIPS_CPU_FPU)
 		cpu_set_fpu_opts(c);
 	else
 		cpu_set_nofpu_opts(c);
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 5351e1f3950d..e9799e597a5d 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -663,6 +663,10 @@ int mips_get_process_fp_mode(struct task_struct *task)
 {
 	int value = 0;
 
+	/* We can do nothing sensible if we have no FP support */
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return -EOPNOTSUPP;
+
 	if (!test_tsk_thread_flag(task, TIF_32BIT_FPREGS))
 		value |= PR_FP_MODE_FR;
 	if (test_tsk_thread_flag(task, TIF_HYBRID_FPREGS))
@@ -685,6 +689,10 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
 	struct task_struct *t;
 	int max_users;
 
+	/* We can do nothing sensible if we have no FP support */
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return -EOPNOTSUPP;
+
 	/* Check the value is valid */
 	if (value & ~known_bits)
 		return -EOPNOTSUPP;
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 6931fe722a0b..b7f61bef25e3 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -151,6 +151,9 @@ int ptrace_getfpregs(struct task_struct *child, __u32 __user *data)
 {
 	int i;
 
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return -EIO;
+
 	if (!access_ok(VERIFY_WRITE, data, 33 * 8))
 		return -EIO;
 
@@ -177,6 +180,9 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
 	u32 value;
 	int i;
 
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return -EIO;
+
 	if (!access_ok(VERIFY_READ, data, 33 * 8))
 		return -EIO;
 
@@ -419,6 +425,9 @@ static int fpr_get(struct task_struct *target,
 	int err;
 	u64 fpr_val;
 
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return -EIO;
+
 	/* XXX fcr31  */
 
 	if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t))
@@ -447,6 +456,9 @@ static int fpr_set(struct task_struct *target,
 	int err;
 	u64 fpr_val;
 
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return -EIO;
+
 	/* XXX fcr31  */
 
 	init_fp_ctx(target);
@@ -662,6 +674,10 @@ long arch_ptrace(struct task_struct *child, long request,
 			tmp = regs->regs[addr];
 			break;
 		case FPR_BASE ... FPR_BASE + 31:
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				goto out;
+			}
 			if (!tsk_used_math(child)) {
 				/* FP not yet used */
 				tmp = -1;
@@ -704,10 +720,18 @@ long arch_ptrace(struct task_struct *child, long request,
 			break;
 #endif
 		case FPC_CSR:
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				goto out;
+			}
 			tmp = child->thread.fpu.fcr31;
 			break;
 		case FPC_EIR:
 			/* implementation / version register */
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				goto out;
+			}
 			tmp = boot_cpu_data.fpu_id;
 			break;
 		case DSP_BASE ... DSP_BASE + 5: {
@@ -757,6 +781,11 @@ long arch_ptrace(struct task_struct *child, long request,
 		case FPR_BASE ... FPR_BASE + 31: {
 			union fpureg *fregs = get_fpu_regs(child);
 
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				break;
+			}
+
 			init_fp_ctx(child);
 #ifdef CONFIG_32BIT
 			if (test_thread_flag(TIF_32BIT_FPREGS)) {
@@ -788,6 +817,10 @@ long arch_ptrace(struct task_struct *child, long request,
 			break;
 #endif
 		case FPC_CSR:
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				break;
+			}
 			init_fp_ctx(child);
 			ptrace_setfcr31(child, data);
 			break;
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index 40e212d6b26b..1a19593e165b 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -92,6 +92,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 			tmp = regs->regs[addr];
 			break;
 		case FPR_BASE ... FPR_BASE + 31:
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				goto out;
+			}
 			if (!tsk_used_math(child)) {
 				/* FP not yet used */
 				tmp = -1;
@@ -126,10 +130,18 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 			tmp = regs->lo;
 			break;
 		case FPC_CSR:
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				goto out;
+			}
 			tmp = child->thread.fpu.fcr31;
 			break;
 		case FPC_EIR:
 			/* implementation / version register */
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				goto out;
+			}
 			tmp = boot_cpu_data.fpu_id;
 			break;
 		case DSP_BASE ... DSP_BASE + 5: {
@@ -199,6 +211,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 		case FPR_BASE ... FPR_BASE + 31: {
 			union fpureg *fregs = get_fpu_regs(child);
 
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				break;
+			}
 			if (!tsk_used_math(child)) {
 				/* FP not yet used  */
 				memset(&child->thread.fpu, ~0,
@@ -228,6 +244,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 			regs->lo = data;
 			break;
 		case FPC_CSR:
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				break;
+			}
 			child->thread.fpu.fcr31 = data;
 			break;
 		case DSP_BASE ... DSP_BASE + 5: {
-- 
2.13.1

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 5/5] MIPS: Allow floating point support to be disabled
@ 2017-06-16 20:21         ` Paul Burton
  0 siblings, 0 replies; 23+ messages in thread
From: Paul Burton @ 2017-06-16 20:21 UTC (permalink / raw)
  To: linux-mips, Maciej W . Rozycki; +Cc: Paul Burton, Ralf Baechle

Floating point support has up until now always been included in all MIPS
kernels. On systems that will run exclusively soft-float code this means
the kernel includes a considerable amount of code which will never be
executed.

This patch introduces a Kconfig option to disable floating point support
in the kernel. Doing so will result in a kernel that never enables an
FPU for userland, and that always responds to use of floating point
instructions with SIGILL. With a maltasmvp_defconfig kernel this shaves
~65KiB from the size of the kernel binary.

Further optimisations would be possible, for example removing the FP &
MSA vector context from struct thread_struct when FP support is
disabled, and compiling out the code that provides access to that
through ptrace. Such changes are more invasive than those in this patch
however, so they're left as potential later work.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: linux-mips@linux-mips.org

---

Changes in v2:
- Have ptrace return -EIO for access to FP context.
- Avoid cpu_set_fpu_opts(), fixing boot of a CONFIG_FP_SUPPORT=n kernel on a system that actually does have an FPU.

 arch/mips/Kconfig                    | 26 +++++++++++++++++++++++---
 arch/mips/Makefile                   |  2 +-
 arch/mips/include/asm/cpu-features.h | 11 ++++++++---
 arch/mips/include/asm/dsemul.h       | 34 ++++++++++++++++++++++++++++++++++
 arch/mips/include/asm/fpu.h          |  3 +++
 arch/mips/include/asm/fpu_emulator.h | 16 ++++++++++++++++
 arch/mips/kernel/Makefile            |  3 +--
 arch/mips/kernel/cpu-probe.c         |  2 +-
 arch/mips/kernel/process.c           |  8 ++++++++
 arch/mips/kernel/ptrace.c            | 33 +++++++++++++++++++++++++++++++++
 arch/mips/kernel/ptrace32.c          | 20 ++++++++++++++++++++
 11 files changed, 148 insertions(+), 10 deletions(-)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 20958af88522..c6255acd6d99 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2227,9 +2227,29 @@ config CPU_GENERIC_DUMP_TLB
 	bool
 	default y if !(CPU_R3000 || CPU_R8000 || CPU_TX39XX)
 
+config FP_SUPPORT
+	bool "Floating Point Support"
+	default y
+	help
+	  Select this to enable support for programs which make use of floating
+	  point instructions. This allows the kernel to support initialising, context
+	  switching & emulating the Floating Point Unit (FPU) in order to allow such
+	  programs to execute correctly.
+
+	  If you disable this then any program which attempts to execute a floating
+	  point instruction will receive a SIGILL signal & is likely to fail.
+
+	  If in doubt, say Y.
+
+config CPU_R2300_FPU
+	bool
+	depends on FP_SUPPORT
+	default y if CPU_R3000 || CPU_TX39XX
+
 config CPU_R4K_FPU
 	bool
-	default y if !(CPU_R3000 || CPU_TX39XX)
+	depends on FP_SUPPORT
+	default y if !CPU_R2300_FPU
 
 config CPU_R4K_CACHE_TLB
 	bool
@@ -2279,7 +2299,7 @@ config MIPS_MT_FPAFF
 
 config MIPSR2_TO_R6_EMULATOR
 	bool "MIPS R2-to-R6 emulator"
-	depends on CPU_MIPSR6
+	depends on CPU_MIPSR6 && FP_SUPPORT
 	default y
 	help
 	  Choose this option if you want to run non-R6 MIPS userland code.
@@ -2423,7 +2443,7 @@ endchoice
 
 config CPU_HAS_MSA
 	bool "Support for the MIPS SIMD Architecture"
-	depends on CPU_SUPPORTS_MSA
+	depends on CPU_SUPPORTS_MSA && FP_SUPPORT
 	depends on 64BIT || MIPS_O32_FP64_SUPPORT
 	help
 	  MIPS SIMD Architecture (MSA) introduces 128 bit wide vector registers
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 3d2f247310e4..4900bec32bed 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -301,7 +301,7 @@ OBJCOPYFLAGS		+= --remove-section=.reginfo
 head-y := arch/mips/kernel/head.o
 
 libs-y			+= arch/mips/lib/
-libs-y			+= arch/mips/math-emu/
+libs-$(CONFIG_FP_SUPPORT)	+= arch/mips/math-emu/
 
 # See arch/mips/Kbuild for content of core part of the kernel
 core-y += arch/mips/
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index 494d38274142..fc0a974545c8 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -76,10 +76,15 @@
 #endif
 /* Don't override `cpu_has_fpu' to 1 or the "nofpu" option won't work.  */
 #ifndef cpu_has_fpu
-#define cpu_has_fpu		(current_cpu_data.options & MIPS_CPU_FPU)
-#define raw_cpu_has_fpu		(raw_current_cpu_data.options & MIPS_CPU_FPU)
+# ifdef CONFIG_FP_SUPPORT
+#  define cpu_has_fpu		(current_cpu_data.options & MIPS_CPU_FPU)
+#  define raw_cpu_has_fpu	(raw_current_cpu_data.options & MIPS_CPU_FPU)
+# else
+#  define cpu_has_fpu		0
+#  define raw_cpu_has_fpu	0
+# endif
 #else
-#define raw_cpu_has_fpu		cpu_has_fpu
+# define raw_cpu_has_fpu	cpu_has_fpu
 #endif
 #ifndef cpu_has_32fpr
 #define cpu_has_32fpr		(cpu_data[0].options & MIPS_CPU_32FPR)
diff --git a/arch/mips/include/asm/dsemul.h b/arch/mips/include/asm/dsemul.h
index a6e067801f23..c5e1e719318b 100644
--- a/arch/mips/include/asm/dsemul.h
+++ b/arch/mips/include/asm/dsemul.h
@@ -13,6 +13,7 @@
 
 #include <asm/break.h>
 #include <asm/inst.h>
+#include <asm/signal.h>
 
 /* Break instruction with special math emu break code set */
 #define BREAK_MATH(micromips)	(((micromips) ? 0x7 : 0xd) | (BRK_MEMU << 16))
@@ -38,8 +39,16 @@ struct task_struct;
  *
  * Return: Zero on success, negative if ir is a NOP, signal number on failure.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
 		       unsigned long branch_pc, unsigned long cont_pc);
+#else
+static inline int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
+			      unsigned long branch_pc, unsigned long cont_pc)
+{
+	return SIGILL;
+}
+#endif
 
 /**
  * do_dsemulret() - Return from a delay slot 'emulation' frame
@@ -52,7 +61,14 @@ extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
  *
  * Return: True if an emulation frame was returned from, else false.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern bool do_dsemulret(struct pt_regs *xcp);
+#else
+static inline bool do_dsemulret(struct pt_regs *xcp)
+{
+	return false;
+}
+#endif
 
 /**
  * dsemul_thread_cleanup() - Cleanup thread 'emulation' frame
@@ -63,7 +79,14 @@ extern bool do_dsemulret(struct pt_regs *xcp);
  *
  * Return: True if a frame was freed, else false.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern bool dsemul_thread_cleanup(struct task_struct *tsk);
+#else
+static inline bool dsemul_thread_cleanup(struct task_struct *tsk)
+{
+	return false;
+}
+#endif
 
 /**
  * dsemul_thread_rollback() - Rollback from an 'emulation' frame
@@ -77,7 +100,14 @@ extern bool dsemul_thread_cleanup(struct task_struct *tsk);
  *
  * Return: True if a frame was exited, else false.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern bool dsemul_thread_rollback(struct pt_regs *regs);
+#else
+static inline bool dsemul_thread_rollback(struct pt_regs *regs)
+{
+	return false;
+}
+#endif
 
 /**
  * dsemul_mm_cleanup() - Cleanup per-mm delay slot 'emulation' state
@@ -87,6 +117,10 @@ extern bool dsemul_thread_rollback(struct pt_regs *regs);
  * for delay slot 'emulation' book-keeping is freed. This is to be called
  * before @mm is freed in order to avoid memory leaks.
  */
+#ifdef CONFIG_FP_SUPPORT
 extern void dsemul_mm_cleanup(struct mm_struct *mm);
+#else
+static inline void dsemul_mm_cleanup(struct mm_struct *mm) { }
+#endif
 
 #endif /* __MIPS_ASM_DSEMUL_H__ */
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h
index a2813fe381cf..a7b2a6b76c14 100644
--- a/arch/mips/include/asm/fpu.h
+++ b/arch/mips/include/asm/fpu.h
@@ -61,6 +61,9 @@ static inline int __enable_fpu(enum fpu_mode mode)
 {
 	int fr;
 
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return SIGFPE;
+
 	switch (mode) {
 	case FPU_AS_IS:
 		/* just enable the FPU in its current mode */
diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h
index c05369e0b8d6..6a513ecf9e18 100644
--- a/arch/mips/include/asm/fpu_emulator.h
+++ b/arch/mips/include/asm/fpu_emulator.h
@@ -60,9 +60,25 @@ do {									\
 #define MIPS_FPU_EMU_INC_STATS(M) do { } while (0)
 #endif /* CONFIG_DEBUG_FS */
 
+#ifdef CONFIG_FP_SUPPORT
+
 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
 				    struct mips_fpu_struct *ctx, int has_fpu,
 				    void *__user *fault_addr);
+
+#else /* !CONFIG_FP_SUPPORT */
+
+static inline int fpu_emulator_cop1Handler(struct pt_regs *xcp,
+					   struct mips_fpu_struct *ctx,
+					   int has_fpu,
+					   void *__user *fault_addr)
+{
+	*fault_addr = NULL;
+	return SIGILL;
+}
+
+#endif /* !CONFIG_FP_SUPPORT */
+
 void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr,
 		     struct task_struct *tsk);
 int process_fpemu_return(int sig, void __user *fault_addr,
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 10d75888f6ae..b1a40708e932 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -42,9 +42,8 @@ sw-$(CONFIG_CPU_TX39XX)		:= r2300_switch.o
 sw-$(CONFIG_CPU_CAVIUM_OCTEON)	:= octeon_switch.o
 obj-y				+= $(sw-y)
 
+obj-$(CONFIG_CPU_R2300_FPU)	+= r2300_fpu.o
 obj-$(CONFIG_CPU_R4K_FPU)	+= r4k_fpu.o
-obj-$(CONFIG_CPU_R3000)		+= r2300_fpu.o
-obj-$(CONFIG_CPU_TX39XX)	+= r2300_fpu.o
 
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_SMP_UP)		+= smp-up.o
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index ddc86f98eb86..f2e81282e61d 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -2022,7 +2022,7 @@ void cpu_probe(void)
 			       ~(1 << MIPS_PWCTL_PWEN_SHIFT));
 	}
 
-	if (c->options & MIPS_CPU_FPU)
+	if (IS_ENABLED(CONFIG_FP_SUPPORT) && c->options & MIPS_CPU_FPU)
 		cpu_set_fpu_opts(c);
 	else
 		cpu_set_nofpu_opts(c);
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 5351e1f3950d..e9799e597a5d 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -663,6 +663,10 @@ int mips_get_process_fp_mode(struct task_struct *task)
 {
 	int value = 0;
 
+	/* We can do nothing sensible if we have no FP support */
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return -EOPNOTSUPP;
+
 	if (!test_tsk_thread_flag(task, TIF_32BIT_FPREGS))
 		value |= PR_FP_MODE_FR;
 	if (test_tsk_thread_flag(task, TIF_HYBRID_FPREGS))
@@ -685,6 +689,10 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
 	struct task_struct *t;
 	int max_users;
 
+	/* We can do nothing sensible if we have no FP support */
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return -EOPNOTSUPP;
+
 	/* Check the value is valid */
 	if (value & ~known_bits)
 		return -EOPNOTSUPP;
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 6931fe722a0b..b7f61bef25e3 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -151,6 +151,9 @@ int ptrace_getfpregs(struct task_struct *child, __u32 __user *data)
 {
 	int i;
 
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return -EIO;
+
 	if (!access_ok(VERIFY_WRITE, data, 33 * 8))
 		return -EIO;
 
@@ -177,6 +180,9 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
 	u32 value;
 	int i;
 
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return -EIO;
+
 	if (!access_ok(VERIFY_READ, data, 33 * 8))
 		return -EIO;
 
@@ -419,6 +425,9 @@ static int fpr_get(struct task_struct *target,
 	int err;
 	u64 fpr_val;
 
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return -EIO;
+
 	/* XXX fcr31  */
 
 	if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t))
@@ -447,6 +456,9 @@ static int fpr_set(struct task_struct *target,
 	int err;
 	u64 fpr_val;
 
+	if (!IS_ENABLED(CONFIG_FP_SUPPORT))
+		return -EIO;
+
 	/* XXX fcr31  */
 
 	init_fp_ctx(target);
@@ -662,6 +674,10 @@ long arch_ptrace(struct task_struct *child, long request,
 			tmp = regs->regs[addr];
 			break;
 		case FPR_BASE ... FPR_BASE + 31:
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				goto out;
+			}
 			if (!tsk_used_math(child)) {
 				/* FP not yet used */
 				tmp = -1;
@@ -704,10 +720,18 @@ long arch_ptrace(struct task_struct *child, long request,
 			break;
 #endif
 		case FPC_CSR:
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				goto out;
+			}
 			tmp = child->thread.fpu.fcr31;
 			break;
 		case FPC_EIR:
 			/* implementation / version register */
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				goto out;
+			}
 			tmp = boot_cpu_data.fpu_id;
 			break;
 		case DSP_BASE ... DSP_BASE + 5: {
@@ -757,6 +781,11 @@ long arch_ptrace(struct task_struct *child, long request,
 		case FPR_BASE ... FPR_BASE + 31: {
 			union fpureg *fregs = get_fpu_regs(child);
 
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				break;
+			}
+
 			init_fp_ctx(child);
 #ifdef CONFIG_32BIT
 			if (test_thread_flag(TIF_32BIT_FPREGS)) {
@@ -788,6 +817,10 @@ long arch_ptrace(struct task_struct *child, long request,
 			break;
 #endif
 		case FPC_CSR:
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				break;
+			}
 			init_fp_ctx(child);
 			ptrace_setfcr31(child, data);
 			break;
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index 40e212d6b26b..1a19593e165b 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -92,6 +92,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 			tmp = regs->regs[addr];
 			break;
 		case FPR_BASE ... FPR_BASE + 31:
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				goto out;
+			}
 			if (!tsk_used_math(child)) {
 				/* FP not yet used */
 				tmp = -1;
@@ -126,10 +130,18 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 			tmp = regs->lo;
 			break;
 		case FPC_CSR:
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				goto out;
+			}
 			tmp = child->thread.fpu.fcr31;
 			break;
 		case FPC_EIR:
 			/* implementation / version register */
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				goto out;
+			}
 			tmp = boot_cpu_data.fpu_id;
 			break;
 		case DSP_BASE ... DSP_BASE + 5: {
@@ -199,6 +211,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 		case FPR_BASE ... FPR_BASE + 31: {
 			union fpureg *fregs = get_fpu_regs(child);
 
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				break;
+			}
 			if (!tsk_used_math(child)) {
 				/* FP not yet used  */
 				memset(&child->thread.fpu, ~0,
@@ -228,6 +244,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 			regs->lo = data;
 			break;
 		case FPC_CSR:
+			if (!IS_ENABLED(CONFIG_FP_SUPPORT)) {
+				ret = -EIO;
+				break;
+			}
 			child->thread.fpu.fcr31 = data;
 			break;
 		case DSP_BASE ... DSP_BASE + 5: {
-- 
2.13.1

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 5/5] MIPS: Allow floating point support to be disabled
  2017-06-16 20:21         ` Paul Burton
  (?)
@ 2017-08-07  9:41         ` Ralf Baechle
  2017-08-10  8:46             ` Maciej W. Rozycki
  -1 siblings, 1 reply; 23+ messages in thread
From: Ralf Baechle @ 2017-08-07  9:41 UTC (permalink / raw)
  To: Paul Burton; +Cc: linux-mips, Maciej W . Rozycki

On Fri, Jun 16, 2017 at 01:21:20PM -0700, Paul Burton wrote:

> Floating point support has up until now always been included in all MIPS
> kernels. On systems that will run exclusively soft-float code this means
> the kernel includes a considerable amount of code which will never be
> executed.
> 
> This patch introduces a Kconfig option to disable floating point support
> in the kernel. Doing so will result in a kernel that never enables an
> FPU for userland, and that always responds to use of floating point
> instructions with SIGILL. With a maltasmvp_defconfig kernel this shaves
> ~65KiB from the size of the kernel binary.
> 
> Further optimisations would be possible, for example removing the FP &
> MSA vector context from struct thread_struct when FP support is
> disabled, and compiling out the code that provides access to that
> through ptrace. Such changes are more invasive than those in this patch
> however, so they're left as potential later work.
> 
> Signed-off-by: Paul Burton <paul.burton@imgtec.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: linux-mips@linux-mips.org
> 
> ---
> 
> Changes in v2:
> - Have ptrace return -EIO for access to FP context.
> - Avoid cpu_set_fpu_opts(), fixing boot of a CONFIG_FP_SUPPORT=n kernel on a system that actually does have an FPU.
> 
>  arch/mips/Kconfig                    | 26 +++++++++++++++++++++++---
>  arch/mips/Makefile                   |  2 +-
>  arch/mips/include/asm/cpu-features.h | 11 ++++++++---
>  arch/mips/include/asm/dsemul.h       | 34 ++++++++++++++++++++++++++++++++++
>  arch/mips/include/asm/fpu.h          |  3 +++
>  arch/mips/include/asm/fpu_emulator.h | 16 ++++++++++++++++
>  arch/mips/kernel/Makefile            |  3 +--
>  arch/mips/kernel/cpu-probe.c         |  2 +-
>  arch/mips/kernel/process.c           |  8 ++++++++
>  arch/mips/kernel/ptrace.c            | 33 +++++++++++++++++++++++++++++++++
>  arch/mips/kernel/ptrace32.c          | 20 ++++++++++++++++++++
>  11 files changed, 148 insertions(+), 10 deletions(-)
> 
> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
> index 20958af88522..c6255acd6d99 100644
> --- a/arch/mips/Kconfig
> +++ b/arch/mips/Kconfig
> @@ -2227,9 +2227,29 @@ config CPU_GENERIC_DUMP_TLB
>  	bool
>  	default y if !(CPU_R3000 || CPU_R8000 || CPU_TX39XX)
>  
> +config FP_SUPPORT
> +	bool "Floating Point Support"
> +	default y
> +	help
> +	  Select this to enable support for programs which make use of floating
> +	  point instructions. This allows the kernel to support initialising, context
> +	  switching & emulating the Floating Point Unit (FPU) in order to allow such
> +	  programs to execute correctly.
> +
> +	  If you disable this then any program which attempts to execute a floating
> +	  point instruction will receive a SIGILL signal & is likely to fail.
> +
> +	  If in doubt, say Y.

In the dark past FP support was optional and people with FPUs were
machinegunning theselves into both feet resulting in an endless stream
of bug reports for years and no amount of documentation was able to solve
that issue.

I've applied the other parts of your series but please change this one
so platforms use a "select FP_SUPPORT" to non-interactively enable FPU
support then throw in a bunch of these selects to cover all CPUs from
the SYS_HAS_CPU_* statements and platforms.  R2000 and R3000 I think were
always used together with the R2010/R3010 FPUs, most later R-series CPUs
had FPUs.  The MTI synthesizable cores starting from 4K and 5k are more
complicated because for most of them FP was an optional feature, so
the SOC and platform config statements can drive that.

Or we simply make the kernel panic when it detects an FPU but has no
FPU support?

  Ralf

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 5/5] MIPS: Allow floating point support to be disabled
@ 2017-08-10  8:46             ` Maciej W. Rozycki
  0 siblings, 0 replies; 23+ messages in thread
From: Maciej W. Rozycki @ 2017-08-10  8:46 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: Paul Burton, linux-mips

On Mon, 7 Aug 2017, Ralf Baechle wrote:

> Or we simply make the kernel panic when it detects an FPU but has no
> FPU support?

 Why would we want to make the kernel panic in the presence of an optional 
unused hardware component?

 Paul's proposal looks reasonable to me.  If people want to throw away FPU 
support to save on memory, then let them do that.  Just make that depend 
on EMBEDDED or suchlike, so that it's not a decision taken lightly.

  Maciej

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 5/5] MIPS: Allow floating point support to be disabled
@ 2017-08-10  8:46             ` Maciej W. Rozycki
  0 siblings, 0 replies; 23+ messages in thread
From: Maciej W. Rozycki @ 2017-08-10  8:46 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: Paul Burton, linux-mips

On Mon, 7 Aug 2017, Ralf Baechle wrote:

> Or we simply make the kernel panic when it detects an FPU but has no
> FPU support?

 Why would we want to make the kernel panic in the presence of an optional 
unused hardware component?

 Paul's proposal looks reasonable to me.  If people want to throw away FPU 
support to save on memory, then let them do that.  Just make that depend 
on EMBEDDED or suchlike, so that it's not a decision taken lightly.

  Maciej

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2017-08-10  8:47 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-05 18:21 [PATCH 0/5] MIPS: FP cleanup & no-FP support Paul Burton
2017-06-05 18:21 ` Paul Burton
2017-06-05 18:21 ` [PATCH 1/5] MIPS: Remove unused R6000 support Paul Burton
2017-06-05 18:21   ` Paul Burton
2017-06-05 18:21 ` [PATCH 2/5] MIPS: Move r4k FP code from r4k_switch.S to r4k_fpu.S Paul Burton
2017-06-05 18:21   ` Paul Burton
2017-06-05 18:21 ` [PATCH 3/5] MIPS: Move r2300 FP code from r2300_switch.S to r2300_fpu.S Paul Burton
2017-06-05 18:21   ` Paul Burton
2017-06-05 18:21 ` [PATCH 4/5] MIPS: Remove unused ST_OFF from r2300_switch.S Paul Burton
2017-06-05 18:21   ` Paul Burton
2017-06-05 18:21 ` [PATCH 5/5] MIPS: Allow floating point support to be disabled Paul Burton
2017-06-05 18:21   ` Paul Burton
2017-06-16  2:55 ` [PATCH 0/5] MIPS: FP cleanup & no-FP support Maciej W. Rozycki
2017-06-16  2:55   ` Maciej W. Rozycki
2017-06-16 16:49   ` Paul Burton
2017-06-16 16:49     ` Paul Burton
2017-06-16 19:50     ` Maciej W. Rozycki
2017-06-16 19:50       ` Maciej W. Rozycki
2017-06-16 20:21       ` [PATCH v2 5/5] MIPS: Allow floating point support to be disabled Paul Burton
2017-06-16 20:21         ` Paul Burton
2017-08-07  9:41         ` Ralf Baechle
2017-08-10  8:46           ` Maciej W. Rozycki
2017-08-10  8:46             ` Maciej W. Rozycki

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.