v1.5 branch refresh based upon upstream master @ c8677ca89e53e3be7988d54280fce166cc894a7e
[librecmc/librecmc.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__ */