kernel: fix 304-mips_disable_fpu.patch for v4.9
[openwrt/openwrt.git] / target / linux / generic / patches-4.9 / 304-mips_disable_fpu.patch
1 From: Manuel Lauss <manuel.lauss@gmail.com>
2 Subject: [RFC PATCH v4 2/2] MIPS: make FPU emulator optional
3 Date: Mon, 7 Apr 2014 12:57:04 +0200
4 Message-Id: <1396868224-252888-2-git-send-email-manuel.lauss@gmail.com>
5
6 This small patch makes the MIPS FPU emulator optional. The kernel
7 kills float-users on systems without a hardware FPU by sending a SIGILL.
8
9 Disabling the emulator shrinks vmlinux by about 54kBytes (32bit,
10 optimizing for size).
11
12 Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
13 ---
14 v4: rediffed because of patch 1/2, should now work with micromips as well
15 v3: updated patch description with size savings.
16 v2: incorporated changes suggested by Jonas Gorski
17 force the fpu emulator on for micromips: relocating the parts
18 of the mmips code in the emulator to other areas would be a
19 much larger change; I went the cheap route instead with this.
20
21 arch/mips/Kbuild | 2 +-
22 arch/mips/Kconfig | 14 ++++++++++++++
23 arch/mips/include/asm/fpu.h | 5 +++--
24 arch/mips/include/asm/fpu_emulator.h | 15 +++++++++++++++
25 4 files changed, 33 insertions(+), 3 deletions(-)
26
27 --- a/arch/mips/Kconfig
28 +++ b/arch/mips/Kconfig
29 @@ -2891,6 +2891,20 @@
30
31 If unsure, say N.
32
33 +config MIPS_FPU_EMULATOR
34 + bool "MIPS FPU Emulator"
35 + default y
36 + help
37 + This option lets you disable the built-in MIPS FPU (Coprocessor 1)
38 + emulator, which handles floating-point instructions on processors
39 + without a hardware FPU. It is generally a good idea to keep the
40 + emulator built-in, unless you are perfectly sure you have a
41 + complete soft-float environment. With the emulator disabled, all
42 + users of float operations will be killed with an illegal instr-
43 + uction exception.
44 +
45 + Say Y, please.
46 +
47 config USE_OF
48 bool
49 select OF
50 --- a/arch/mips/Makefile
51 +++ b/arch/mips/Makefile
52 @@ -287,7 +287,7 @@
53 head-y := arch/mips/kernel/head.o
54
55 libs-y += arch/mips/lib/
56 -libs-y += arch/mips/math-emu/
57 +libs-$(CONFIG_MIPS_FPU_EMULATOR) += arch/mips/math-emu/
58
59 # See arch/mips/Kbuild for content of core part of the kernel
60 core-y += arch/mips/
61 --- a/arch/mips/include/asm/fpu.h
62 +++ b/arch/mips/include/asm/fpu.h
63 @@ -227,8 +227,10 @@
64 /* Restore FRE */
65 write_c0_config5(config5);
66 enable_fpu_hazard();
67 - } else
68 + } else if (IS_ENABLED(CONFIG_MIPS_FPU_EMULATOR))
69 fpu_emulator_init_fpu();
70 + else
71 + ret = SIGILL;
72
73 return ret;
74 }
75 --- a/arch/mips/include/asm/fpu_emulator.h
76 +++ b/arch/mips/include/asm/fpu_emulator.h
77 @@ -30,6 +30,7 @@
78 #include <asm/local.h>
79 #include <asm/processor.h>
80
81 +#ifdef CONFIG_MIPS_FPU_EMULATOR
82 #ifdef CONFIG_DEBUG_FS
83
84 struct mips_fpu_emulator_stats {
85 @@ -63,6 +64,16 @@
86 extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
87 struct mips_fpu_struct *ctx, int has_fpu,
88 void *__user *fault_addr);
89 +#else /* no CONFIG_MIPS_FPU_EMULATOR */
90 +static inline int fpu_emulator_cop1Handler(struct pt_regs *xcp,
91 + struct mips_fpu_struct *ctx, int has_fpu,
92 + void *__user *fault_addr)
93 +{
94 + *fault_addr = NULL;
95 + return SIGILL; /* we don't speak MIPS FPU */
96 +}
97 +#endif /* CONFIG_MIPS_FPU_EMULATOR */
98 +
99 void force_fcr31_sig(unsigned long fcr31, void __user *fault_addr,
100 struct task_struct *tsk);
101 int process_fpemu_return(int sig, void __user *fault_addr,
102 --- a/arch/mips/include/asm/dsemul.h
103 +++ b/arch/mips/include/asm/dsemul.h
104 @@ -41,6 +41,7 @@
105 extern int mips_dsemul(struct pt_regs *regs, mips_instruction ir,
106 unsigned long branch_pc, unsigned long cont_pc);
107
108 +#ifdef CONFIG_MIPS_FPU_EMULATOR
109 /**
110 * do_dsemulret() - Return from a delay slot 'emulation' frame
111 * @xcp: User thread register context.
112 @@ -88,5 +89,27 @@
113 * before @mm is freed in order to avoid memory leaks.
114 */
115 extern void dsemul_mm_cleanup(struct mm_struct *mm);
116 +#else
117 +static inline bool do_dsemulret(struct pt_regs *xcp)
118 +{
119 + return false;
120 +}
121 +
122 +static inline bool dsemul_thread_cleanup(struct task_struct *tsk)
123 +{
124 + return false;
125 +}
126 +
127 +static inline bool dsemul_thread_rollback(struct pt_regs *regs)
128 +{
129 + return false;
130 +}
131 +
132 +static inline void dsemul_mm_cleanup(struct mm_struct *mm)
133 +{
134 +
135 +}
136 +
137 +#endif
138
139 #endif /* __MIPS_ASM_DSEMUL_H__ */