On Sun, Apr 6, 2014 at 12:52 AM, Manuel Lauss <manuel.lauss@xxxxxxxxx> wrote: > Add a config option to disable the FPU emulator. > Saves around 56kB on 32bit, and kills FPU users with SIGILL. Looks similar to what we do in OpenWrt[1]. Main differences are we also stub out process_fpemu_return and emit a notice into the kernel log that the FPU emulator is disabled. > Signed-off-by: Manuel Lauss <manuel.lauss@xxxxxxxxx> > --- > arch/mips/Kbuild | 2 ++ > arch/mips/Kconfig | 14 ++++++++++++++ > arch/mips/include/asm/fpu.h | 2 ++ > arch/mips/include/asm/fpu_emulator.h | 24 +++++++++++++++++++++++- > 4 files changed, 41 insertions(+), 1 deletion(-) > > diff --git a/arch/mips/Kbuild b/arch/mips/Kbuild > index d2cfe45..da76dc0 100644 > --- a/arch/mips/Kbuild > +++ b/arch/mips/Kbuild > @@ -16,7 +16,9 @@ obj- := $(platform-) > > obj-y += kernel/ > obj-y += mm/ > +ifdef CONFIG_MIPS_FPU_EMULATOR > obj-y += math-emu/ > +endif You can write this as 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..9a8d7ed 100644 > --- a/arch/mips/Kconfig > +++ b/arch/mips/Kconfig > @@ -2482,6 +2482,20 @@ config MIPS_O32_FP64_SUPPORT > > If unsure, say N. > > +config MIPS_FPU_EMULATOR > + bool "Support for MIPS FPU Emulator" > + default y > + help > + This option lets you disable the built-in MIPS FPU (Cop1) > + Emulator. This emulator executes floating-point instructions on > + processors which don't have a built-in floating point unit. > + It is generally a very good idea to keep this support built in, > + only disable it if you have a complete soft-float userland. > + Any use of floating point operations in userspace will result in > + the process being killed with an illegal instruction 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..d6c3d97 100644 > --- a/arch/mips/include/asm/fpu.h > +++ b/arch/mips/include/asm/fpu.h > @@ -161,7 +161,9 @@ static inline int init_fpu(void) > if (!ret) > _init_fpu(); > } else { > +#ifdef CONFIG_MIPS_FPU_EMULATOR > fpu_emulator_init_fpu(); > +#endif Maybe do something like } else if (IS_ENABLED(CONFIG_MIPS_FPU_EMULATOR)) { fpu_emulator_init_fpu(); which kooks a bit nicer IMHO. > } > > preempt_enable(); > diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h > index 2abb587..b2c1524 100644 > --- a/arch/mips/include/asm/fpu_emulator.h > +++ b/arch/mips/include/asm/fpu_emulator.h > @@ -53,13 +53,35 @@ do { \ > > extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir, > unsigned long cpc); > +int process_fpemu_return(int sig, void __user *fault_addr); > + > +#ifdef CONFIG_MIPS_FPU_EMULATOR > 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) > +{ > + return 0; > +} Won't this break micromips support? mm_isBranchInstr is called from a few other places outside the FPU emulator. Regards Jonas [1] http://git.openwrt.org/?p=openwrt.git;a=blob;f=target/linux/generic/patches-3.14/304-mips_disable_fpu.patch;h=4536ce6dae80710e530dd7c67c8c8728f95ee3e6;hb=HEAD