[PATCH v7 2/2] MIPS: optional floating point support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This small patch makes the floating point support and the FPU-emulator
optional.  A Warning will be printed once when first use of floating
point is detected.

Disabling fpu support shrinks vmlinux by about 54kBytes (32bit,
optimizing for size), and it is mainly useful for embedded devices
which have no need for float math (e.g. routers).

Signed-off-by: Manuel Lauss <manuel.lauss@xxxxxxxxx>
---
v7: codingstyle, checkpatch (Jonas Gorski)
v6: complain in kernel log about first attempted use of float ops.
v5: now disable float support completely to avoid sudden program crashes
    on buggy fpus when the fpu emulator cannot take over (suggested by
    Paul Burton).
v4: rediffed because of patch 1/2, should now work with micromips as well
v3: updated patch description with size savings.
v2: incorporated changes suggested by Jonas Gorski
    force the fpu emulator on for micromips: relocating the parts
    of the mmips code in the emulator to other areas would be a
    much larger change; I went the cheap route instead with this.

 arch/mips/Kbuild                     |  2 +-
 arch/mips/Kconfig                    | 11 +++++++++++
 arch/mips/include/asm/fpu.h          | 24 ++++++++++++++++--------
 arch/mips/include/asm/fpu_emulator.h | 15 +++++++++++++++
 4 files changed, 43 insertions(+), 9 deletions(-)

diff --git a/arch/mips/Kbuild b/arch/mips/Kbuild
index d2cfe45..730e0a7 100644
--- a/arch/mips/Kbuild
+++ b/arch/mips/Kbuild
@@ -16,7 +16,7 @@ obj- := $(platform-)
 
 obj-y += kernel/
 obj-y += mm/
-obj-y += math-emu/
+obj-$(CONFIG_MIPS_FPU_SUPPORT) += math-emu/
 
 ifdef CONFIG_KVM
 obj-y += kvm/
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 9b53358..c8040db 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2482,6 +2482,17 @@ config MIPS_O32_FP64_SUPPORT
 
 	  If unsure, say N.
 
+config MIPS_FPU_SUPPORT
+	bool "MIPS FPU Support"
+	default y
+	help
+	  Support for floating point registers and FP-hardware, and also
+	  the in-kernel FPU emulator.  Disabling this option will result
+	  in all uses of floating point hardware to be killed with an
+	  illegal instruction exception, and about a 50kB smaller kernel.
+
+	  Say Y.
+
 config USE_OF
 	bool
 	select OF
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h
index 4d86b72..954f52d 100644
--- a/arch/mips/include/asm/fpu.h
+++ b/arch/mips/include/asm/fpu.h
@@ -155,16 +155,24 @@ static inline int init_fpu(void)
 {
 	int ret = 0;
 
-	preempt_disable();
-	if (cpu_has_fpu) {
-		ret = __own_fpu();
-		if (!ret)
-			_init_fpu();
+	if (IS_ENABLED(CONFIG_MIPS_FPU_SUPPORT)) {
+		preempt_disable();
+		if (cpu_has_fpu) {
+			ret = __own_fpu();
+			if (!ret)
+				_init_fpu();
+		} else {
+			fpu_emulator_init_fpu();
+		}
+		preempt_enable();
 	} else {
-		fpu_emulator_init_fpu();
+		static int first = 1;
+		if (likely(first)) {
+			first = 0;
+			pr_err("FPU support disabled, but FPU use detected!\n");
+		}
+		ret = SIGILL;
 	}
-
-	preempt_enable();
 	return ret;
 }
 
diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h
index 283e6f3..552a054 100644
--- a/arch/mips/include/asm/fpu_emulator.h
+++ b/arch/mips/include/asm/fpu_emulator.h
@@ -27,6 +27,7 @@
 #include <asm/inst.h>
 #include <asm/local.h>
 
+#ifdef CONFIG_MIPS_FPU_SUPPORT
 #ifdef CONFIG_DEBUG_FS
 
 struct mips_fpu_emulator_stats {
@@ -57,6 +58,20 @@ extern int do_dsemulret(struct pt_regs *xcp);
 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
 				    struct mips_fpu_struct *ctx, int has_fpu,
 				    void *__user *fault_addr);
+#else	/* no CONFIG_MIPS_FPU_SUPPORT */
+static inline int do_dsemulret(struct pt_regs *xcp)
+{
+	return 0;	/* 0 means error, should never get here anyway */
+}
+
+static inline int fpu_emulator_cop1Handler(struct pt_regs *xcp,
+				struct mips_fpu_struct *ctx, int has_fpu,
+				void *__user *fault_addr)
+{
+	return SIGILL;	/* we don't speak MIPS FPU */
+}
+#endif	/* CONFIG_MIPS_FPU_SUPPORT */
+
 int process_fpemu_return(int sig, void __user *fault_addr);
 
 /*
-- 
1.9.1



[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux