Makes floating point support a selectable kernel option. Disabling this option will make the kernel 50kB lighter and kill all float uses with an illegal instruction exception. Signed-off-by: Manuel Lauss <manuel.lauss@xxxxxxxxx> --- 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 | 20 +++++++++++--------- arch/mips/include/asm/fpu_emulator.h | 15 +++++++++++++++ 4 files changed, 38 insertions(+), 10 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..f0ea5ae 100644 --- a/arch/mips/include/asm/fpu.h +++ b/arch/mips/include/asm/fpu.h @@ -155,16 +155,18 @@ static inline int init_fpu(void) { int ret = 0; - preempt_disable(); - if (cpu_has_fpu) { - ret = __own_fpu(); - if (!ret) - _init_fpu(); - } else { - fpu_emulator_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 + 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