OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From: Manuel Lauss <manuel.lauss@gmail.com> |
2 | Subject: [RFC PATCH v4 2/2] MIPS: make FPU emulator optional |
||
3 | |||
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. |
||
6 | |||
7 | Disabling the emulator shrinks vmlinux by about 54kBytes (32bit, |
||
8 | optimizing for size). |
||
9 | |||
10 | Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com> |
||
11 | --- |
||
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. |
||
18 | |||
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(-) |
||
24 | |||
25 | --- a/arch/mips/Kconfig |
||
26 | +++ b/arch/mips/Kconfig |
||
27 | @@ -2892,6 +2892,20 @@ config MIPS_O32_FP64_SUPPORT |
||
28 | |||
29 | If unsure, say N. |
||
30 | |||
31 | +config MIPS_FPU_EMULATOR |
||
32 | + bool "MIPS FPU Emulator" |
||
33 | + default y |
||
34 | + help |
||
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- |
||
41 | + uction exception. |
||
42 | + |
||
43 | + Say Y, please. |
||
44 | + |
||
45 | config USE_OF |
||
46 | bool |
||
47 | select OF |
||
48 | --- a/arch/mips/Makefile |
||
49 | +++ b/arch/mips/Makefile |
||
50 | @@ -322,7 +322,7 @@ OBJCOPYFLAGS += --remove-section=.regin |
||
51 | head-y := arch/mips/kernel/head.o |
||
52 | |||
53 | libs-y += arch/mips/lib/ |
||
54 | -libs-y += arch/mips/math-emu/ |
||
55 | +libs-$(CONFIG_MIPS_FPU_EMULATOR) += arch/mips/math-emu/ |
||
56 | |||
57 | # See arch/mips/Kbuild for content of core part of the kernel |
||
58 | core-y += arch/mips/ |
||
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) |
||
62 | /* Restore FRE */ |
||
63 | write_c0_config5(config5); |
||
64 | enable_fpu_hazard(); |
||
65 | - } else |
||
66 | + } else if (IS_ENABLED(CONFIG_MIPS_FPU_EMULATOR)) |
||
67 | fpu_emulator_init_fpu(); |
||
68 | + else |
||
69 | + ret = SIGILL; |
||
70 | |||
71 | return ret; |
||
72 | } |
||
73 | --- a/arch/mips/include/asm/fpu_emulator.h |
||
74 | +++ b/arch/mips/include/asm/fpu_emulator.h |
||
75 | @@ -30,6 +30,7 @@ |
||
76 | #include <asm/local.h> |
||
77 | #include <asm/processor.h> |
||
78 | |||
79 | +#ifdef CONFIG_MIPS_FPU_EMULATOR |
||
80 | #ifdef CONFIG_DEBUG_FS |
||
81 | |||
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) |
||
91 | +{ |
||
92 | + *fault_addr = NULL; |
||
93 | + return SIGILL; /* we don't speak MIPS FPU */ |
||
94 | +} |
||
95 | +#endif /* CONFIG_MIPS_FPU_EMULATOR */ |
||
96 | + |
||
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); |
||
105 | |||
106 | +#ifdef CONFIG_MIPS_FPU_EMULATOR |
||
107 | /** |
||
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. |
||
112 | */ |
||
113 | extern void dsemul_mm_cleanup(struct mm_struct *mm); |
||
114 | +#else |
||
115 | +static inline bool do_dsemulret(struct pt_regs *xcp) |
||
116 | +{ |
||
117 | + return false; |
||
118 | +} |
||
119 | + |
||
120 | +static inline bool dsemul_thread_cleanup(struct task_struct *tsk) |
||
121 | +{ |
||
122 | + return false; |
||
123 | +} |
||
124 | + |
||
125 | +static inline bool dsemul_thread_rollback(struct pt_regs *regs) |
||
126 | +{ |
||
127 | + return false; |
||
128 | +} |
||
129 | + |
||
130 | +static inline void dsemul_mm_cleanup(struct mm_struct *mm) |
||
131 | +{ |
||
132 | + |
||
133 | +} |
||
134 | + |
||
135 | +#endif |
||
136 | |||
137 | #endif /* __MIPS_ASM_DSEMUL_H__ */ |