Page MenuHomeFreeBSD

D44910.diff
No OneTemporary

D44910.diff

diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -927,7 +927,8 @@
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
--- a/share/man/man9/cpu_machdep.9
+++ b/share/man/man9/cpu_machdep.9
@@ -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,13 @@
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
.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
--- 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
@@ -673,3 +673,9 @@
pcb->pcb_fsbase = (register_t)tls_base;
return (0);
}
+
+void
+cpu_update_pcb(struct thread *td)
+{
+ 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
@@ -278,6 +278,12 @@
td->td_pcb->pcb_regs.sf_r5 = (register_t)arg; /* first arg */
}
+void
+cpu_update_pcb(struct thread *td)
+{
+ 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
@@ -290,6 +290,13 @@
td->td_pcb->pcb_x[PCB_X20] = (uintptr_t)arg;
}
+void
+cpu_update_pcb(struct thread *td)
+{
+ 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
@@ -534,6 +534,12 @@
return (0);
}
+void
+cpu_update_pcb(struct thread *td)
+{
+ 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
@@ -2421,6 +2421,9 @@
size = 0;
+ if (target_td == curthread)
+ 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
--- 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,14 +593,11 @@
* 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"));
-
pcb = td->td_pcb;
pcb_flags = pcb->pcb_flags;
@@ -1110,7 +1107,7 @@
/* 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
@@ -121,7 +121,7 @@
/* 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
@@ -239,6 +239,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
@@ -1220,6 +1220,7 @@
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 *);

File Metadata

Mime Type
text/plain
Expires
Mon, Jan 13, 12:53 AM (20 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15763237
Default Alt Text
D44910.diff (7 KB)

Event Timeline