1 From: Manuel Lauss <manuel.lauss@gmail.com>
2 Subject: [RFC PATCH v4 2/2] MIPS: make FPU emulator optional
4 This small patch makes the MIPS FPU emulator optional. The kernel
5 kills float-users on systems without a hardware FPU by sending a SIGILL.
7 Disabling the emulator shrinks vmlinux by about 54kBytes (32bit,
10 Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
12 v4: rediffed because of patch 1/2, should now work with micromips as well
13 v3: updated patch description with size savings.
14 v2: incorporated changes suggested by Jonas Gorski
15 force the fpu emulator on for micromips: relocating the parts
16 of the mmips code in the emulator to other areas would be a
17 much larger change; I went the cheap route instead with this.
19 arch/mips/Kbuild | 2 +-
20 arch/mips/Kconfig | 14 ++++++++++++++
21 arch/mips/include/asm/fpu.h | 5 +++--
22 arch/mips/include/asm/fpu_emulator.h | 15 +++++++++++++++
23 4 files changed, 33 insertions(+), 3 deletions(-)
25 --- a/arch/mips/Kconfig
26 +++ b/arch/mips/Kconfig
27 @@ -2890,6 +2890,20 @@ config MIPS_O32_FP64_SUPPORT
31 +config MIPS_FPU_EMULATOR
32 + bool "MIPS FPU Emulator"
35 + This option lets you disable the built-in MIPS FPU (Coprocessor 1)
36 + emulator, which handles floating-point instructions on processors
37 + without a hardware FPU. It is generally a good idea to keep the
38 + emulator built-in, unless you are perfectly sure you have a
39 + complete soft-float environment. With the emulator disabled, all
40 + users of float operations will be killed with an illegal instr-
48 --- a/arch/mips/Makefile
49 +++ b/arch/mips/Makefile
50 @@ -319,7 +319,7 @@ OBJCOPYFLAGS += --remove-section=.regin
51 head-y := arch/mips/kernel/head.o
53 libs-y += arch/mips/lib/
54 -libs-y += arch/mips/math-emu/
55 +libs-$(CONFIG_MIPS_FPU_EMULATOR) += arch/mips/math-emu/
57 # See arch/mips/Kbuild for content of core part of the kernel
59 --- a/arch/mips/include/asm/fpu.h
60 +++ b/arch/mips/include/asm/fpu.h
61 @@ -230,8 +230,10 @@ static inline int init_fpu(void)
63 write_c0_config5(config5);
66 + } else if (IS_ENABLED(CONFIG_MIPS_FPU_EMULATOR))
67 fpu_emulator_init_fpu();
73 --- a/arch/mips/include/asm/fpu_emulator.h
74 +++ b/arch/mips/include/asm/fpu_emulator.h
76 #include <asm/local.h>
77 #include <asm/processor.h>
79 +#ifdef CONFIG_MIPS_FPU_EMULATOR
80 #ifdef CONFIG_DEBUG_FS
82 struct mips_fpu_emulator_stats {
83 @@ -179,6 +180,16 @@ do { \
84 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
85 struct mips_fpu_struct *ctx, int has_fpu,
86 void __user **fault_addr);
87 +#else /* no CONFIG_MIPS_FPU_EMULATOR */
88 +static inline int fpu_emulator_cop1Handler(struct pt_regs *xcp,
89 + struct mips_fpu_struct *ctx, int has_fpu,
90 + void __user **fault_addr)
93 + return SIGILL; /* we don't speak MIPS FPU */
95 +#endif /* CONFIG_MIPS_FPU_EMULATOR */
97 void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr,
98 struct task_struct *tsk);
99 int process_fpemu_return(int sig, void __user *fault_addr,
100 --- a/arch/mips/include/asm/dsemul.h
101 +++ b/arch/mips/include/asm/dsemul.h
102 @@ -41,6 +41,7 @@ struct task_struct;
103 extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
104 unsigned long branch_pc, unsigned long cont_pc);
106 +#ifdef CONFIG_MIPS_FPU_EMULATOR
108 * do_dsemulret() - Return from a delay slot 'emulation' frame
109 * @xcp: User thread register context.
110 @@ -88,5 +89,27 @@ extern bool dsemul_thread_rollback(struc
111 * before @mm is freed in order to avoid memory leaks.
113 extern void dsemul_mm_cleanup(struct mm_struct *mm);
115 +static inline bool do_dsemulret(struct pt_regs *xcp)
120 +static inline bool dsemul_thread_cleanup(struct task_struct *tsk)
125 +static inline bool dsemul_thread_rollback(struct pt_regs *regs)
130 +static inline void dsemul_mm_cleanup(struct mm_struct *mm)
137 #endif /* __MIPS_ASM_DSEMUL_H__ */