aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Horne <mhorne@FreeBSD.org>2021-04-09 14:13:21 +0000
committerMitchell Horne <mhorne@FreeBSD.org>2021-04-16 13:48:39 +0000
commitc0422e6c365eca801bde5b2f644e3a7e4803dbc8 (patch)
treef550b89227c5e03a7e8943337cfefec000ec2c08
parent6fa1d613a82582e0da87169b994a5c0080258a82 (diff)
downloadsrc-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.c8
-rw-r--r--sys/arm64/arm64/machdep.c5
-rw-r--r--sys/arm64/linux/linux_sysvec.c12
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