123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- From: Manuel Lauss <manuel.lauss@gmail.com>
- Subject: [RFC PATCH v4 2/2] MIPS: make FPU emulator optional
- This small patch makes the MIPS FPU emulator optional. The kernel
- kills float-users on systems without a hardware FPU by sending a SIGILL.
- Disabling the emulator shrinks vmlinux by about 54kBytes (32bit,
- optimizing for size).
- Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
- ---
- 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 | 14 ++++++++++++++
- arch/mips/include/asm/fpu.h | 5 +++--
- arch/mips/include/asm/fpu_emulator.h | 15 +++++++++++++++
- 4 files changed, 33 insertions(+), 3 deletions(-)
- --- a/arch/mips/Kconfig
- +++ b/arch/mips/Kconfig
- @@ -2898,6 +2898,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
- --- a/arch/mips/Makefile
- +++ b/arch/mips/Makefile
- @@ -326,7 +326,7 @@ OBJCOPYFLAGS += --remove-section=.regin
- head-y := arch/mips/kernel/head.o
-
- libs-y += arch/mips/lib/
- -libs-y += arch/mips/math-emu/
- +libs-$(CONFIG_MIPS_FPU_EMULATOR) += arch/mips/math-emu/
-
- # See arch/mips/Kbuild for content of core part of the kernel
- core-y += arch/mips/
- --- a/arch/mips/include/asm/fpu.h
- +++ b/arch/mips/include/asm/fpu.h
- @@ -230,8 +230,10 @@ static inline int init_fpu(void)
- /* Restore FRE */
- write_c0_config5(config5);
- enable_fpu_hazard();
- - } else
- + } else if (IS_ENABLED(CONFIG_MIPS_FPU_EMULATOR))
- fpu_emulator_init_fpu();
- + else
- + ret = SIGILL;
-
- return ret;
- }
- --- a/arch/mips/include/asm/fpu_emulator.h
- +++ b/arch/mips/include/asm/fpu_emulator.h
- @@ -30,6 +30,7 @@
- #include <asm/local.h>
- #include <asm/processor.h>
-
- +#ifdef CONFIG_MIPS_FPU_EMULATOR
- #ifdef CONFIG_DEBUG_FS
-
- struct mips_fpu_emulator_stats {
- @@ -179,6 +180,16 @@ do { \
- 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_EMULATOR */
- +static inline int fpu_emulator_cop1Handler(struct pt_regs *xcp,
- + struct mips_fpu_struct *ctx, int has_fpu,
- + void __user **fault_addr)
- +{
- + *fault_addr = NULL;
- + return SIGILL; /* we don't speak MIPS FPU */
- +}
- +#endif /* CONFIG_MIPS_FPU_EMULATOR */
- +
- void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr,
- struct task_struct *tsk);
- int process_fpemu_return(int sig, void __user *fault_addr,
- --- a/arch/mips/include/asm/dsemul.h
- +++ b/arch/mips/include/asm/dsemul.h
- @@ -41,6 +41,7 @@ struct task_struct;
- extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
- unsigned long branch_pc, unsigned long cont_pc);
-
- +#ifdef CONFIG_MIPS_FPU_EMULATOR
- /**
- * do_dsemulret() - Return from a delay slot 'emulation' frame
- * @xcp: User thread register context.
- @@ -88,5 +89,27 @@ extern bool dsemul_thread_rollback(struc
- * before @mm is freed in order to avoid memory leaks.
- */
- extern void dsemul_mm_cleanup(struct mm_struct *mm);
- +#else
- +static inline bool do_dsemulret(struct pt_regs *xcp)
- +{
- + return false;
- +}
- +
- +static inline bool dsemul_thread_cleanup(struct task_struct *tsk)
- +{
- + return false;
- +}
- +
- +static inline bool dsemul_thread_rollback(struct pt_regs *regs)
- +{
- + return false;
- +}
- +
- +static inline void dsemul_mm_cleanup(struct mm_struct *mm)
- +{
- +
- +}
- +
- +#endif
-
- #endif /* __MIPS_ASM_DSEMUL_H__ */
|