hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/arch/nds32/kernel/process.c
....@@ -9,14 +9,15 @@
99 #include <linux/uaccess.h>
1010 #include <asm/elf.h>
1111 #include <asm/proc-fns.h>
12
+#include <asm/fpu.h>
1213 #include <linux/ptrace.h>
1314 #include <linux/reboot.h>
1415
15
-extern void setup_mm_for_reboot(char mode);
16
-#ifdef CONFIG_PROC_FS
17
-struct proc_dir_entry *proc_dir_cpu;
18
-EXPORT_SYMBOL(proc_dir_cpu);
16
+#if IS_ENABLED(CONFIG_LAZY_FPU)
17
+struct task_struct *last_task_used_math;
1918 #endif
19
+
20
+extern void setup_mm_for_reboot(char mode);
2021
2122 extern inline void arch_reset(char mode)
2223 {
....@@ -120,26 +121,42 @@
120121 regs->uregs[3], regs->uregs[2], regs->uregs[1], regs->uregs[0]);
121122 pr_info(" IRQs o%s Segment %s\n",
122123 interrupts_enabled(regs) ? "n" : "ff",
123
- segment_eq(get_fs(), get_ds())? "kernel" : "user");
124
+ uaccess_kernel() ? "kernel" : "user");
124125 }
125126
126127 EXPORT_SYMBOL(show_regs);
127128
129
+void exit_thread(struct task_struct *tsk)
130
+{
131
+#if defined(CONFIG_FPU) && defined(CONFIG_LAZY_FPU)
132
+ if (last_task_used_math == tsk)
133
+ last_task_used_math = NULL;
134
+#endif
135
+}
136
+
128137 void flush_thread(void)
129138 {
139
+#if defined(CONFIG_FPU)
140
+ clear_fpu(task_pt_regs(current));
141
+ clear_used_math();
142
+# ifdef CONFIG_LAZY_FPU
143
+ if (last_task_used_math == current)
144
+ last_task_used_math = NULL;
145
+# endif
146
+#endif
130147 }
131148
132149 DEFINE_PER_CPU(struct task_struct *, __entry_task);
133150
134151 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
135152 int copy_thread(unsigned long clone_flags, unsigned long stack_start,
136
- unsigned long stk_sz, struct task_struct *p)
153
+ unsigned long stk_sz, struct task_struct *p, unsigned long tls)
137154 {
138155 struct pt_regs *childregs = task_pt_regs(p);
139156
140157 memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context));
141158
142
- if (unlikely(p->flags & PF_KTHREAD)) {
159
+ if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) {
143160 memset(childregs, 0, sizeof(struct pt_regs));
144161 /* kernel thread fn */
145162 p->thread.cpu_context.r6 = stack_start;
....@@ -153,11 +170,27 @@
153170 childregs->uregs[0] = 0;
154171 childregs->osp = 0;
155172 if (clone_flags & CLONE_SETTLS)
156
- childregs->uregs[25] = childregs->uregs[3];
173
+ childregs->uregs[25] = tls;
157174 }
158175 /* cpu context switching */
159176 p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
160177 p->thread.cpu_context.sp = (unsigned long)childregs;
178
+
179
+#if IS_ENABLED(CONFIG_FPU)
180
+ if (used_math()) {
181
+# if !IS_ENABLED(CONFIG_LAZY_FPU)
182
+ unlazy_fpu(current);
183
+# else
184
+ preempt_disable();
185
+ if (last_task_used_math == current)
186
+ save_fpu(current);
187
+ preempt_enable();
188
+# endif
189
+ p->thread.fpu = current->thread.fpu;
190
+ clear_fpu(task_pt_regs(p));
191
+ set_stopped_child_used_math(p);
192
+ }
193
+#endif
161194
162195 #ifdef CONFIG_HWZOL
163196 childregs->lb = 0;
....@@ -168,12 +201,33 @@
168201 return 0;
169202 }
170203
204
+#if IS_ENABLED(CONFIG_FPU)
205
+struct task_struct *_switch_fpu(struct task_struct *prev, struct task_struct *next)
206
+{
207
+#if !IS_ENABLED(CONFIG_LAZY_FPU)
208
+ unlazy_fpu(prev);
209
+#endif
210
+ if (!(next->flags & PF_KTHREAD))
211
+ clear_fpu(task_pt_regs(next));
212
+ return prev;
213
+}
214
+#endif
215
+
171216 /*
172217 * fill in the fpe structure for a core dump...
173218 */
174219 int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpu)
175220 {
176221 int fpvalid = 0;
222
+#if IS_ENABLED(CONFIG_FPU)
223
+ struct task_struct *tsk = current;
224
+
225
+ fpvalid = tsk_used_math(tsk);
226
+ if (fpvalid) {
227
+ lose_fpu();
228
+ memcpy(fpu, &tsk->thread.fpu, sizeof(*fpu));
229
+ }
230
+#endif
177231 return fpvalid;
178232 }
179233