kernel: generic: Add kernel 4.14 support
[openwrt/openwrt.git] / target / linux / generic / pending-4.14 / 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
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 @@ -2890,6 +2890,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 @@ -319,7 +319,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__ */