Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

um: remove auxiliary FP registers

We do not need the extra save/restore of the FP registers when getting
the fault information. This was originally added in commit 2f56debd77a8
("uml: fix FP register corruption") but at that time the code was not
saving/restoring the FP registers when switching to userspace. This was
fixed in commit fbfe9c847edf ("um: Save FPU registers between task
switches") and since then the auxiliary registers have not been useful.

Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
Link: https://patch.msgid.link/20241004233821.2130874-1-benjamin@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

authored by

Benjamin Berg and committed by
Johannes Berg
c6ce7200 48a858e0

+9 -24
-2
arch/um/include/asm/thread_info.h
··· 23 23 int preempt_count; /* 0 => preemptable, 24 24 <0 => BUG */ 25 25 struct thread_info *real_thread; /* Points to non-IRQ stack */ 26 - unsigned long aux_fp_regs[FP_SIZE]; /* auxiliary fp_regs to save/restore 27 - them out-of-band */ 28 26 }; 29 27 30 28 #define INIT_THREAD_INFO(tsk) \
+1 -1
arch/um/include/shared/os.h
··· 285 285 /* skas/process.c */ 286 286 extern int is_skas_winch(int pid, int fd, void *data); 287 287 extern int start_userspace(unsigned long stub_stack); 288 - extern void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs); 288 + extern void userspace(struct uml_pt_regs *regs); 289 289 extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)); 290 290 extern void switch_threads(jmp_buf *me, jmp_buf *you); 291 291 extern int start_idle_thread(void *stack, jmp_buf *switch_buf);
+2 -2
arch/um/kernel/process.c
··· 116 116 * callback returns only if the kernel thread execs a process 117 117 */ 118 118 fn(arg); 119 - userspace(&current->thread.regs.regs, current_thread_info()->aux_fp_regs); 119 + userspace(&current->thread.regs.regs); 120 120 } 121 121 122 122 /* Called magically, see new_thread_handler above */ ··· 133 133 134 134 current->thread.prev_sched = NULL; 135 135 136 - userspace(&current->thread.regs.regs, current_thread_info()->aux_fp_regs); 136 + userspace(&current->thread.regs.regs); 137 137 } 138 138 139 139 int copy_thread(struct task_struct * p, const struct kernel_clone_args *args)
+6 -19
arch/um/os-Linux/skas/process.c
··· 141 141 142 142 extern unsigned long current_stub_stack(void); 143 143 144 - static void get_skas_faultinfo(int pid, struct faultinfo *fi, unsigned long *aux_fp_regs) 144 + static void get_skas_faultinfo(int pid, struct faultinfo *fi) 145 145 { 146 146 int err; 147 147 148 - err = get_fp_registers(pid, aux_fp_regs); 149 - if (err < 0) { 150 - printk(UM_KERN_ERR "save_fp_registers returned %d\n", 151 - err); 152 - fatal_sigsegv(); 153 - } 154 148 err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV); 155 149 if (err) { 156 150 printk(UM_KERN_ERR "Failed to continue stub, pid = %d, " ··· 158 164 * the stub stack page. We just have to copy it. 159 165 */ 160 166 memcpy(fi, (void *)current_stub_stack(), sizeof(*fi)); 161 - 162 - err = put_fp_registers(pid, aux_fp_regs); 163 - if (err < 0) { 164 - printk(UM_KERN_ERR "put_fp_registers returned %d\n", 165 - err); 166 - fatal_sigsegv(); 167 - } 168 167 } 169 168 170 - static void handle_segv(int pid, struct uml_pt_regs *regs, unsigned long *aux_fp_regs) 169 + static void handle_segv(int pid, struct uml_pt_regs *regs) 171 170 { 172 - get_skas_faultinfo(pid, &regs->faultinfo, aux_fp_regs); 171 + get_skas_faultinfo(pid, &regs->faultinfo); 173 172 segv(regs->faultinfo, 0, 1, NULL); 174 173 } 175 174 ··· 323 336 return err; 324 337 } 325 338 326 - void userspace(struct uml_pt_regs *regs, unsigned long *aux_fp_regs) 339 + void userspace(struct uml_pt_regs *regs) 327 340 { 328 341 int err, status, op, pid = userspace_pid[0]; 329 342 siginfo_t si; ··· 422 435 case SIGSEGV: 423 436 if (PTRACE_FULL_FAULTINFO) { 424 437 get_skas_faultinfo(pid, 425 - &regs->faultinfo, aux_fp_regs); 438 + &regs->faultinfo); 426 439 (*sig_info[SIGSEGV])(SIGSEGV, (struct siginfo *)&si, 427 440 regs); 428 441 } 429 - else handle_segv(pid, regs, aux_fp_regs); 442 + else handle_segv(pid, regs); 430 443 break; 431 444 case SIGTRAP + 0x80: 432 445 handle_trap(pid, regs);