diff options
author | Mitchell Horne <mhorne@FreeBSD.org> | 2021-04-09 14:13:21 +0000 |
---|---|---|
committer | Mitchell Horne <mhorne@FreeBSD.org> | 2021-04-16 13:48:39 +0000 |
commit | c0422e6c365eca801bde5b2f644e3a7e4803dbc8 (patch) | |
tree | f550b89227c5e03a7e8943337cfefec000ec2c08 | |
parent | 6fa1d613a82582e0da87169b994a5c0080258a82 (diff) | |
download | src-c0422e6c365eca801bde5b2f644e3a7e4803dbc8.tar.gz src-c0422e6c365eca801bde5b2f644e3a7e4803dbc8.zip |
arm64: clear debug registers after execve(2)
This is both intuitive and required, as any previous breakpoint settings
may not be applicable to the new process.
Reported by: arichardson
Reviewed by: kib
Sponsored by: The FreeBSD Foundation
(cherry picked from commit a2a8b582bdc1c8c1f4da3ae727349327f5fc9dd8)
-rw-r--r-- | sys/arm64/arm64/elf32_machdep.c | 8 | ||||
-rw-r--r-- | sys/arm64/arm64/machdep.c | 5 | ||||
-rw-r--r-- | sys/arm64/linux/linux_sysvec.c | 12 |
3 files changed, 20 insertions, 5 deletions
diff --git a/sys/arm64/arm64/elf32_machdep.c b/sys/arm64/arm64/elf32_machdep.c index 84b62caf8590..b9669616e1dd 100644 --- a/sys/arm64/arm64/elf32_machdep.c +++ b/sys/arm64/arm64/elf32_machdep.c @@ -239,6 +239,7 @@ freebsd32_setregs(struct thread *td, struct image_params *imgp, uintptr_t stack) { struct trapframe *tf = td->td_frame; + struct pcb *pcb = td->td_pcb; memset(tf, 0, sizeof(struct trapframe)); @@ -256,8 +257,13 @@ freebsd32_setregs(struct thread *td, struct image_params *imgp, tf->tf_spsr = PSR_M_32; #ifdef VFP - vfp_reset_state(td, td->td_pcb); + vfp_reset_state(td, pcb); #endif + + /* + * Clear debug register state. It is not applicable to the new process. + */ + bzero(&pcb->pcb_dbg_regs, sizeof(pcb->pcb_dbg_regs)); } void diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c index 8a1e7520aacb..5cc17d2a4612 100644 --- a/sys/arm64/arm64/machdep.c +++ b/sys/arm64/arm64/machdep.c @@ -569,7 +569,10 @@ exec_setregs(struct thread *td, struct image_params *imgp, uintptr_t stack) vfp_reset_state(td, pcb); #endif - /* TODO: Shouldn't we also reset pcb_dbg_regs? */ + /* + * Clear debug register state. It is not applicable to the new process. + */ + bzero(&pcb->pcb_dbg_regs, sizeof(pcb->pcb_dbg_regs)); } /* Sanity check these are the same size, they will be memcpy'd to and fro */ diff --git a/sys/arm64/linux/linux_sysvec.c b/sys/arm64/linux/linux_sysvec.c index df16db4040a7..e20e0fd32b91 100644 --- a/sys/arm64/linux/linux_sysvec.c +++ b/sys/arm64/linux/linux_sysvec.c @@ -351,6 +351,7 @@ linux_exec_setregs(struct thread *td, struct image_params *imgp, uintptr_t stack) { struct trapframe *regs = td->td_frame; + struct pcb *pcb = td->td_pcb; /* LINUXTODO: validate */ LIN_SDT_PROBE0(sysvec, linux_exec_setregs, todo); @@ -365,14 +366,19 @@ linux_exec_setregs(struct thread *td, struct image_params *imgp, #endif regs->tf_elr = imgp->entry_addr; - td->td_pcb->pcb_tpidr_el0 = 0; - td->td_pcb->pcb_tpidrro_el0 = 0; + pcb->pcb_tpidr_el0 = 0; + pcb->pcb_tpidrro_el0 = 0; WRITE_SPECIALREG(tpidrro_el0, 0); WRITE_SPECIALREG(tpidr_el0, 0); #ifdef VFP - vfp_reset_state(td, td->td_pcb); + vfp_reset_state(td, pcb); #endif + + /* + * Clear debug register state. It is not applicable to the new process. + */ + bzero(&pcb->pcb_dbg_regs, sizeof(pcb->pcb_dbg_regs)); } int |