diff --git a/sys/amd64/amd64/ptrace_machdep.c b/sys/amd64/amd64/ptrace_machdep.c --- a/sys/amd64/amd64/ptrace_machdep.c +++ b/sys/amd64/amd64/ptrace_machdep.c @@ -63,8 +63,6 @@ reg = buf; pcb = td->td_pcb; - if (td == curthread) - update_pcb_bases(pcb); reg->r_fsbase = pcb->pcb_fsbase; reg->r_gsbase = pcb->pcb_gsbase; } @@ -113,8 +111,6 @@ reg = buf; pcb = td->td_pcb; - if (td == curthread) - update_pcb_bases(pcb); reg->r_fsbase = (uint32_t)pcb->pcb_fsbase; reg->r_gsbase = (uint32_t)pcb->pcb_gsbase; } diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -693,3 +693,10 @@ pcb->pcb_fsbase = (register_t)tls_base; return (0); } + +void +cpu_update_pcb(struct thread *td) +{ + if (td == curthread) + update_pcb_bases(td->td_pcb); +} diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c --- a/sys/arm/arm/vm_machdep.c +++ b/sys/arm/arm/vm_machdep.c @@ -290,6 +290,13 @@ td->td_pcb->pcb_regs.sf_r5 = (register_t)arg; /* first arg */ } +void +cpu_update_pcb(struct thread *td) +{ + if (td == curthread) + td->td_pcb->pcb_regs.sf_tpidrurw = (register_t)get_tls(); +} + void cpu_exit(struct thread *td) { diff --git a/sys/arm64/arm64/vm_machdep.c b/sys/arm64/arm64/vm_machdep.c --- a/sys/arm64/arm64/vm_machdep.c +++ b/sys/arm64/arm64/vm_machdep.c @@ -300,6 +300,15 @@ td->td_pcb->pcb_x[PCB_X20] = (uintptr_t)arg; } +void +cpu_update_pcb(struct thread *td) +{ + if (td == curthread) { + td->td_pcb->pcb_tpidr_el0 = READ_SPECIALREG(tpidr_el0); + td->td_pcb->pcb_tpidrro_el0 = READ_SPECIALREG(tpidrro_el0); + } +} + void cpu_exit(struct thread *td) { diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -554,6 +554,13 @@ return (0); } +void +cpu_update_pcb(struct thread *td) +{ + if (td == curthread) + td->td_pcb->pcb_gs = rgs(); +} + /* * Convert kernel VA to physical address */ diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -2415,6 +2415,8 @@ size = 0; + cpu_update_pcb(td); + /* NT_PRSTATUS must be the first register set note. */ size += __elfN(register_regset_note)(td, list, &__elfN(regset_prstatus), target_td); diff --git a/sys/powerpc/include/reg.h b/sys/powerpc/include/reg.h --- a/sys/powerpc/include/reg.h +++ b/sys/powerpc/include/reg.h @@ -69,11 +69,6 @@ int fill_dbregs(struct thread *, struct dbreg *); int set_dbregs(struct thread *, struct dbreg *); -/* - * MD interfaces. - */ -void cpu_save_thread_regs(struct thread *); - #ifdef COMPAT_FREEBSD32 struct image_params; diff --git a/sys/powerpc/powerpc/elf32_machdep.c b/sys/powerpc/powerpc/elf32_machdep.c --- a/sys/powerpc/powerpc/elf32_machdep.c +++ b/sys/powerpc/powerpc/elf32_machdep.c @@ -190,7 +190,6 @@ pcb = td->td_pcb; if (pcb->pcb_flags & PCB_VEC) { - save_vec_nodrop(td); if (dst != NULL) { len += elf32_populate_note(NT_PPC_VMX, &pcb->pcb_vec, (char *)dst + len, @@ -201,7 +200,6 @@ } if (pcb->pcb_flags & PCB_VSX) { - save_fpu_nodrop(td); if (dst != NULL) { /* * Doubleword 0 of VSR0-VSR31 overlap with FPR0-FPR31 and diff --git a/sys/powerpc/powerpc/elf64_machdep.c b/sys/powerpc/powerpc/elf64_machdep.c --- a/sys/powerpc/powerpc/elf64_machdep.c +++ b/sys/powerpc/powerpc/elf64_machdep.c @@ -279,7 +279,6 @@ pcb = td->td_pcb; if (pcb->pcb_flags & PCB_VEC) { - save_vec_nodrop(td); if (dst != NULL) { len += elf64_populate_note(NT_PPC_VMX, &pcb->pcb_vec, (char *)dst + len, @@ -290,7 +289,6 @@ } if (pcb->pcb_flags & PCB_VSX) { - save_fpu_nodrop(td); if (dst != NULL) { /* * Doubleword 0 of VSR0-VSR31 overlap with FPR0-FPR31 and diff --git a/sys/powerpc/powerpc/exec_machdep.c b/sys/powerpc/powerpc/exec_machdep.c --- a/sys/powerpc/powerpc/exec_machdep.c +++ b/sys/powerpc/powerpc/exec_machdep.c @@ -593,13 +593,13 @@ * Keep this in sync with the assembly code in cpu_switch()! */ void -cpu_save_thread_regs(struct thread *td) +cpu_update_pcb(struct thread *td) { uint32_t pcb_flags; struct pcb *pcb; - KASSERT(td == curthread, - ("cpu_save_thread_regs: td is not curthread")); + if (td != curthread) + return; pcb = td->td_pcb; @@ -1109,8 +1109,7 @@ struct callframe *cf; /* Ensure td0 pcb is up to date. */ - if (td0 == curthread) - cpu_save_thread_regs(td0); + cpu_update_pcb(td0); pcb2 = td->td_pcb; diff --git a/sys/powerpc/powerpc/vm_machdep.c b/sys/powerpc/powerpc/vm_machdep.c --- a/sys/powerpc/powerpc/vm_machdep.c +++ b/sys/powerpc/powerpc/vm_machdep.c @@ -120,8 +120,7 @@ return; /* Ensure td1 is up to date before copy. */ - if (td1 == curthread) - cpu_save_thread_regs(td1); + cpu_update_pcb(td1); pcb = (struct pcb *)((td2->td_kstack + td2->td_kstack_pages * PAGE_SIZE - sizeof(struct pcb)) & ~0x2fUL); diff --git a/sys/riscv/riscv/vm_machdep.c b/sys/riscv/riscv/vm_machdep.c --- a/sys/riscv/riscv/vm_machdep.c +++ b/sys/riscv/riscv/vm_machdep.c @@ -249,6 +249,11 @@ td->td_pcb->pcb_sp = (uintptr_t)td->td_frame; } +void +cpu_update_pcb(struct thread *td) +{ +} + void cpu_exit(struct thread *td) { diff --git a/sys/sys/proc.h b/sys/sys/proc.h --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1261,6 +1261,7 @@ void cpu_thread_free(struct thread *); void cpu_thread_swapin(struct thread *); void cpu_thread_swapout(struct thread *); +void cpu_update_pcb(struct thread *); struct thread *thread_alloc(int pages); int thread_check_susp(struct thread *td, bool sleep); void thread_cow_get_proc(struct thread *newtd, struct proc *p);