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> --- v8: more codingstyle 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 | 25 +++++++++++++++++-------- arch/mips/include/asm/fpu_emulator.h | 15 +++++++++++++++ 4 files changed, 44 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..eb36bbf 100644 --- a/arch/mips/include/asm/fpu.h +++ b/arch/mips/include/asm/fpu.h @@ -155,16 +155,25 @@ 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; - preempt_enable(); + if (likely(first)) { + first = 0; + pr_err("FPU support disabled, but FPU use detected!\n"); + } + ret = SIGILL; + } 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