On 04/06/2014 12:51 PM, Manuel Lauss wrote: > This small patch makes the MIPS FPU emulator optional. The kernel > kills float-users on systems without a hardware FPU by sending a SIGILL. > > The Emulator can't be turned off on systems which support microMIPS > because parts of the microMIPS support code live in the emu code. > > Signed-off-by: Manuel Lauss <manuel.lauss@xxxxxxxxx> > --- > v2: incorporated changes suggested by Hauke Mehrtens, > 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. Did I suggest anything? I was planing to point you to the patch in OpenWrt, but Jonas already did so. > Disabling the emulator saves about 54kBytes (32bit, optimizing for size). What about putting this number into the commit message or into the help text. > arch/mips/Kbuild | 2 +- > arch/mips/Kconfig | 15 +++++++++++++++ > arch/mips/include/asm/fpu.h | 5 +++-- > arch/mips/include/asm/fpu_emulator.h | 27 ++++++++++++++++++++++++++- > 4 files changed, 45 insertions(+), 4 deletions(-) > > diff --git a/arch/mips/Kbuild b/arch/mips/Kbuild > index d2cfe45..426c264 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_EMULATOR) += math-emu/ > > ifdef CONFIG_KVM > obj-y += kvm/ > diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig > index 9b53358..e9dd80e 100644 > --- a/arch/mips/Kconfig > +++ b/arch/mips/Kconfig > @@ -2208,6 +2208,7 @@ config SYS_SUPPORTS_SMARTMIPS > > config SYS_SUPPORTS_MICROMIPS > bool > + select MIPS_FPU_EMULATOR # houses tiny parts of the mmips code > > config CPU_SUPPORTS_MSA > bool > @@ -2482,6 +2483,20 @@ config MIPS_O32_FP64_SUPPORT > > If unsure, say N. > > +config MIPS_FPU_EMULATOR > + bool "MIPS FPU Emulator" > + default y > + help > + This option lets you disable the built-in MIPS FPU (Coprocessor 1) > + emulator, which handles floating-point instructions on processors > + without a hardware FPU. It is generally a good idea to keep the > + emulator built-in, unless you are perfectly sure you have a > + complete soft-float environment. With the emulator disabled, all > + users of float operations will be killed with an illegal instr- > + uction exception. > + > + Say Y, please. > + > config USE_OF > bool > select OF > diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h > index 4d86b72..c5203bb 100644 > --- a/arch/mips/include/asm/fpu.h > +++ b/arch/mips/include/asm/fpu.h > @@ -160,9 +160,10 @@ static inline int init_fpu(void) > ret = __own_fpu(); > if (!ret) > _init_fpu(); > - } else { > + } else if (IS_ENABLED(CONFIG_MIPS_FPU_EMULATOR)) > fpu_emulator_init_fpu(); > - } > + 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 2abb587..26a71ba 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_EMULATOR > #ifdef CONFIG_DEBUG_FS > > struct mips_fpu_emulator_stats { > @@ -57,9 +58,33 @@ 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); > -int process_fpemu_return(int sig, void __user *fault_addr); > int mm_isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn, > unsigned long *contpc); > +#else /* no CONFIG_MIPS_FPU_EMULATOR */ > +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 */ > +} > + > +static inline int mm_isBranchInstr(struct pt_regs *regs, > + struct mm_decoded_insn dec_insn, > + unsigned long *contpc) > +{ > + BUG(); /* should never ever get here */ > + return 0; > +} > +#endif /* CONFIG_MIPS_FPU_EMULATOR */ > + > + > +int process_fpemu_return(int sig, void __user *fault_addr); > + > > /* > * Instruction inserted following the badinst to further tag the sequence >