From nobody Fri Jan 31 20:40:37 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Yl77n5Ztfz5n3PG; Fri, 31 Jan 2025 20:40:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Yl77n3xq9z3SVC; Fri, 31 Jan 2025 20:40:37 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1738356037; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=9Wmh06gCdq5kdRcWkDSK6WYLp2ZwuG4etplxBvYOvwA=; b=XbmaVLbkVNPQgC1BKPnsWawcBt/Qi2Axb8+S/PQ+MrkL4uRdcsnFmxsMb00Rt8Hqf62DPR iIk6J9BMrPLUVV1d1hWPd6s2ASwUnyJO0VJjIA7XVdlnDzEBz2ULL5ggCModcg4MarQvGZ 1blerLd/SMH8WYWlfDohGqHzLsJRnkjQYh+8DhMGrf5OGQ+MAWJwR6ojRcndVF/r4k3nw5 VitC44EVuW80vQrdfbgu/BnO96jYKLYMEa69kb4tdFp6rWgZned6AS+KD491NWvzrgb/Jg xRX0hKTj19tSusvbv6jEnwcrieCTwOa2gXSLtqFUMc0s6+Y+47KIDz9QH45FVQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1738356037; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=9Wmh06gCdq5kdRcWkDSK6WYLp2ZwuG4etplxBvYOvwA=; b=ywpetERtZzRVZIjQXUmo1tOQrAB0hM3evNt/mO+cltj/VgAjNJwMnUwFl/BgF4uhqoibZt i9OaplqCUbklSCY4ncJ8/sB3eAMeNrJhWvTvXUYFgVxIK9DYHvO19n+YQvRIFA61J7hxBs sn4NOcjLAWfPxPSkdGqzgRZnHf1mHwcONXbn8Zo8n+xFQmT7mI5z0t5AsbNvyEmMKl667w ob4wW0CNS2kxSPNKDYDNzCa/y3xpH17AMnxxORUXuuwp3/P9efL29Pk0S3lxiNfAQPIgsm QmFuFxS8gNOZf4td1tOWRK1z5RRrRhG9lXUGsshNbVnpvykWwD0HI6XvIG92LA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1738356037; a=rsa-sha256; cv=none; b=a7C3Xk27heyctFqObRCu/Us5/1oI/XscwU7Kw4fK20mEB1Y0lue8+zIj/Pp9pIuhOZlv+3 ZbfMqYOH0TJs0Dhb2HsH1FRuQq5a5ZVERpAgfjp+ZfRSMd29wO3PEQIaz9T3JlGr/7RcBi /zjLID9d9DYS+CoJYufcyu05Tk1fEPolWja9w78QJFT1tcKn5AvA5Hr23ckt5VKoOpDQyf ZsxlgDvQkiVHfTpR6R7zcUKBKOHLhrfm0z+tsN6ZNnyWNPKEPt9c1+ZWfIiFFmZGO6QT+j AcRiNFE4iTn0BZRjTM+CEWzW99hl/Gdwl0plUYAuxN5Zcr5SLQjJh0vjOFmkYw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Yl77n3CJSzZQ9; Fri, 31 Jan 2025 20:40:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 50VKeb4N052979; Fri, 31 Jan 2025 20:40:37 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 50VKebJB052976; Fri, 31 Jan 2025 20:40:37 GMT (envelope-from git) Date: Fri, 31 Jan 2025 20:40:37 GMT Message-Id: <202501312040.50VKebJB052976@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: John Baldwin Subject: git: f66a407de25e - main - sys: Add cpu_update_pcb hook List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jhb X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: f66a407de25eaa4c58b4f6f02086d55141593b63 Auto-Submitted: auto-generated The branch main has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=f66a407de25eaa4c58b4f6f02086d55141593b63 commit f66a407de25eaa4c58b4f6f02086d55141593b63 Author: John Baldwin AuthorDate: 2025-01-31 20:39:10 +0000 Commit: John Baldwin CommitDate: 2025-01-31 20:40:29 +0000 sys: Add cpu_update_pcb hook This MD function is invoked before dumping register set notes when writing out a core dump to ensure that the PCB for a given thread is up to date. This provides a centralized place to update the PCB with values of the current thread for each arch rather than doing this work in each register set's get method. Discussed with: jrtc27 Reviewed by: kib, markj Sponsored by: AFRL, DARPA Differential Revision: https://reviews.freebsd.org/D44910 --- share/man/man9/Makefile | 3 ++- share/man/man9/cpu_machdep.9 | 23 +++++++++++++++++++++-- sys/amd64/amd64/ptrace_machdep.c | 4 ---- sys/amd64/amd64/vm_machdep.c | 7 +++++++ sys/arm/arm/vm_machdep.c | 7 +++++++ sys/arm64/arm64/vm_machdep.c | 8 ++++++++ sys/i386/i386/vm_machdep.c | 7 +++++++ sys/kern/imgact_elf.c | 3 +++ sys/powerpc/include/reg.h | 5 ----- sys/powerpc/powerpc/elf32_machdep.c | 2 -- sys/powerpc/powerpc/elf64_machdep.c | 2 -- sys/powerpc/powerpc/exec_machdep.c | 6 +++--- sys/powerpc/powerpc/vm_machdep.c | 2 +- sys/riscv/riscv/vm_machdep.c | 5 +++++ sys/sys/proc.h | 1 + 15 files changed, 65 insertions(+), 20 deletions(-) diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index a284eaca5ecb..6af9880b8d57 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -931,7 +931,8 @@ MLINKS+=cpu_machdep.9 cpu_copy_thread.9 \ cpu_machdep.9 cpu_thread_clean.9 \ cpu_machdep.9 cpu_thread_exit.9 \ cpu_machdep.9 cpu_thread_free.9 \ - cpu_machdep.9 cpu_throw.9 + cpu_machdep.9 cpu_throw.9 \ + cpu_machdep.9 cpu_update_pcb.9 MLINKS+=cpuset.9 CPUSET_T_INITIALIZER.9 \ cpuset.9 CPUSET_FSET.9 \ cpuset.9 CPU_CLR.9 \ diff --git a/share/man/man9/cpu_machdep.9 b/share/man/man9/cpu_machdep.9 index 9ab42807eac1..30ac5ea36642 100644 --- a/share/man/man9/cpu_machdep.9 +++ b/share/man/man9/cpu_machdep.9 @@ -8,7 +8,7 @@ .\" Technology), and Capabilities Limited under Defense Advanced Research .\" Projects Agency (DARPA) Contract No. FA8750-24-C-B047 ("DEC"). .\" -.Dd January 3, 2025 +.Dd January 31, 2025 .Dt cpu_machdep 9 .Os .Sh NAME @@ -31,7 +31,8 @@ .Nm cpu_thread_clean , .Nm cpu_thread_exit , .Nm cpu_thread_free , -.Nm cpu_throw +.Nm cpu_throw , +.Nm cpu_update_pcb .Nd machine-dependent interfaces to handle CPU and thread state .Sh SYNOPSIS .In sys/proc.h @@ -84,6 +85,8 @@ .Fn cpu_thread_free "struct thread *td" .Ft void .Fn cpu_throw "struct thread *old" "struct thread *new" +.Ft void +.Fn cpu_update_pcb "struct thread *td" .Sh DESCRIPTION These functions provide architecture-specific implementations of machine-independent abstractions. @@ -183,6 +186,22 @@ sets a new thread's initial user thread pointer register to reference the user TLS base pointer .Fa tls_base . .Pp +.Fn cpu_update_pcb +updates the pcb of the current thread with current user register values. +This is invoked before writing out register notes in a core dump. +This function typically only has to update user registers for the current +thread that are saved in the pcb during context switches rather than +in the trapframe on kernel entry. +.Pp +Note that when +.Fn cpu_update_pcb +is used, +threads in a process other than the current thread are stopped, +typically by +.Fn thread_single . +The pcbs of those stopped threads should already be updated by +.Fn cpu_switch . +.Pp .Fn cpu_fetch_syscall_args fetches the current system call arguments for the native FreeBSD ABI from the current thread's user register state and/or user stack. diff --git a/sys/amd64/amd64/ptrace_machdep.c b/sys/amd64/amd64/ptrace_machdep.c index 3b05fded585f..715f0749bda9 100644 --- a/sys/amd64/amd64/ptrace_machdep.c +++ b/sys/amd64/amd64/ptrace_machdep.c @@ -63,8 +63,6 @@ get_segbases(struct regset *rs, struct thread *td, void *buf, 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 @@ get_segbases32(struct regset *rs, struct thread *td, void *buf, 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 index 1c6b1549422b..2b280e960b2e 100644 --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -673,3 +673,10 @@ cpu_set_user_tls(struct thread *td, void *tls_base) pcb->pcb_fsbase = (register_t)tls_base; return (0); } + +void +cpu_update_pcb(struct thread *td) +{ + MPASS(td == curthread); + update_pcb_bases(td->td_pcb); +} diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c index 4e0a6bb9cbc5..d31d36ba807d 100644 --- a/sys/arm/arm/vm_machdep.c +++ b/sys/arm/arm/vm_machdep.c @@ -278,6 +278,13 @@ cpu_fork_kthread_handler(struct thread *td, void (*func)(void *), void *arg) td->td_pcb->pcb_regs.sf_r5 = (register_t)arg; /* first arg */ } +void +cpu_update_pcb(struct thread *td) +{ + MPASS(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 index 924628001103..9869ce6cae0b 100644 --- a/sys/arm64/arm64/vm_machdep.c +++ b/sys/arm64/arm64/vm_machdep.c @@ -290,6 +290,14 @@ cpu_fork_kthread_handler(struct thread *td, void (*func)(void *), void *arg) td->td_pcb->pcb_x[PCB_X20] = (uintptr_t)arg; } +void +cpu_update_pcb(struct thread *td) +{ + MPASS(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 index b0dd7534633b..c64f19a30cbd 100644 --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -534,6 +534,13 @@ cpu_set_user_tls(struct thread *td, void *tls_base) return (0); } +void +cpu_update_pcb(struct thread *td) +{ + MPASS(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 index d94f9e1e5143..fc074ad74e6b 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -2421,6 +2421,9 @@ __elfN(prepare_register_notes)(struct thread *td, struct note_info_list *list, size = 0; + if (target_td == td) + cpu_update_pcb(target_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 index 1fe67ac3967d..781ee3b02289 100644 --- a/sys/powerpc/include/reg.h +++ b/sys/powerpc/include/reg.h @@ -69,11 +69,6 @@ int set_fpregs(struct thread *, struct fpreg *); 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 index fcdc1aa1e8a5..af01043878db 100644 --- a/sys/powerpc/powerpc/elf32_machdep.c +++ b/sys/powerpc/powerpc/elf32_machdep.c @@ -190,7 +190,6 @@ elf32_dump_thread(struct thread *td, void *dst, size_t *off) 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 @@ elf32_dump_thread(struct thread *td, void *dst, size_t *off) } 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 index b780a2ed82fc..1035e35d286e 100644 --- a/sys/powerpc/powerpc/elf64_machdep.c +++ b/sys/powerpc/powerpc/elf64_machdep.c @@ -279,7 +279,6 @@ elf64_dump_thread(struct thread *td, void *dst, size_t *off) 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 @@ elf64_dump_thread(struct thread *td, void *dst, size_t *off) } 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 index 9ab323a0e300..3586c01d6652 100644 --- a/sys/powerpc/powerpc/exec_machdep.c +++ b/sys/powerpc/powerpc/exec_machdep.c @@ -593,13 +593,13 @@ cleanup_power_extras(struct thread *td) * 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")); + ("cpu_update_pcb: td is not curthread")); pcb = td->td_pcb; @@ -1110,7 +1110,7 @@ cpu_copy_thread(struct thread *td, struct thread *td0) /* 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 index 12c64f9e38bf..d47beedb595e 100644 --- a/sys/powerpc/powerpc/vm_machdep.c +++ b/sys/powerpc/powerpc/vm_machdep.c @@ -121,7 +121,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) /* 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 index 726f95213c91..bd510080e02c 100644 --- a/sys/riscv/riscv/vm_machdep.c +++ b/sys/riscv/riscv/vm_machdep.c @@ -239,6 +239,11 @@ cpu_fork_kthread_handler(struct thread *td, void (*func)(void *), void *arg) 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 index 786cc447dc2c..46482f26e0ef 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1220,6 +1220,7 @@ extern void (*cpu_idle_hook)(sbintime_t); /* Hook to machdep CPU idler. */ void cpu_switch(struct thread *, struct thread *, struct mtx *); void cpu_sync_core(void); void cpu_throw(struct thread *, struct thread *) __dead2; +void cpu_update_pcb(struct thread *); bool curproc_sigkilled(void); void userret(struct thread *, struct trapframe *);