git: a8b75a57c9b2 - main - x86: add x86_clear_dbregs() helper

Konstantin Belousov kib at FreeBSD.org
Sat Apr 10 01:25:11 UTC 2021


The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=a8b75a57c9b2cb3388746f097a55086a0f8c5d38

commit a8b75a57c9b2cb3388746f097a55086a0f8c5d38
Author:     Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2021-04-09 23:19:23 +0000
Commit:     Konstantin Belousov <kib at FreeBSD.org>
CommitDate: 2021-04-10 01:25:01 +0000

    x86: add x86_clear_dbregs() helper
    
    Move the code from exec_setregs() to reset debug registers state on exec,
    to the x86_clear_dbregs() helper
    
    Reviewed by:    jhb
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D29687
---
 sys/amd64/amd64/machdep.c | 50 +++++++++++++++++++++++++++--------------------
 sys/i386/i386/machdep.c   | 50 +++++++++++++++++++++++++++--------------------
 sys/x86/include/x86_var.h |  1 +
 3 files changed, 59 insertions(+), 42 deletions(-)

diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 5c8a3ae6bb4e..362ea6eea825 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -581,6 +581,34 @@ freebsd4_sigreturn(struct thread *td, struct freebsd4_sigreturn_args *uap)
 }
 #endif
 
+/*
+ * Reset the hardware debug registers if they were in use.
+ * They won't have any meaning for the newly exec'd process.
+ */
+void
+x86_clear_dbregs(struct pcb *pcb)
+{
+	if ((pcb->pcb_flags & PCB_DBREGS) == 0)
+		return;
+
+	pcb->pcb_dr0 = 0;
+	pcb->pcb_dr1 = 0;
+	pcb->pcb_dr2 = 0;
+	pcb->pcb_dr3 = 0;
+	pcb->pcb_dr6 = 0;
+	pcb->pcb_dr7 = 0;
+
+	if (pcb == curpcb) {
+		/*
+		 * Clear the debug registers on the running CPU,
+		 * otherwise they will end up affecting the next
+		 * process we switch to.
+		 */
+		reset_dbregs();
+	}
+	clear_pcb_flags(pcb, PCB_DBREGS);
+}
+
 /*
  * Reset registers to default values on exec.
  */
@@ -617,27 +645,7 @@ exec_setregs(struct thread *td, struct image_params *imgp, uintptr_t stack)
 	regs->tf_gs = _ugssel;
 	regs->tf_flags = TF_HASSEGS;
 
-	/*
-	 * Reset the hardware debug registers if they were in use.
-	 * They won't have any meaning for the newly exec'd process.
-	 */
-	if (pcb->pcb_flags & PCB_DBREGS) {
-		pcb->pcb_dr0 = 0;
-		pcb->pcb_dr1 = 0;
-		pcb->pcb_dr2 = 0;
-		pcb->pcb_dr3 = 0;
-		pcb->pcb_dr6 = 0;
-		pcb->pcb_dr7 = 0;
-		if (pcb == curpcb) {
-			/*
-			 * Clear the debug registers on the running
-			 * CPU, otherwise they will end up affecting
-			 * the next process we switch to.
-			 */
-			reset_dbregs();
-		}
-		clear_pcb_flags(pcb, PCB_DBREGS);
-	}
+	x86_clear_dbregs(pcb);
 
 	/*
 	 * Drop the FP state if we hold it, so that the process gets a
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index a9749d331f89..5fec2e448c53 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -1121,6 +1121,34 @@ setup_priv_lcall_gate(struct proc *p)
 }
 #endif
 
+/*
+ * Reset the hardware debug registers if they were in use.
+ * They won't have any meaning for the newly exec'd process.
+ */
+void
+x86_clear_dbregs(struct pcb *pcb)
+{
+        if ((pcb->pcb_flags & PCB_DBREGS) == 0)
+		return;
+
+	pcb->pcb_dr0 = 0;
+	pcb->pcb_dr1 = 0;
+	pcb->pcb_dr2 = 0;
+	pcb->pcb_dr3 = 0;
+	pcb->pcb_dr6 = 0;
+	pcb->pcb_dr7 = 0;
+
+	if (pcb == curpcb) {
+		/*
+		 * Clear the debug registers on the running CPU,
+		 * otherwise they will end up affecting the next
+		 * process we switch to.
+		 */
+		reset_dbregs();
+	}
+	pcb->pcb_flags &= ~PCB_DBREGS;
+}
+
 /*
  * Reset registers to default values on exec.
  */
@@ -1174,27 +1202,7 @@ exec_setregs(struct thread *td, struct image_params *imgp, uintptr_t stack)
 	/* PS_STRINGS value for BSD/OS binaries.  It is 0 for non-BSD/OS. */
 	regs->tf_ebx = (register_t)imgp->ps_strings;
 
-        /*
-         * Reset the hardware debug registers if they were in use.
-         * They won't have any meaning for the newly exec'd process.  
-         */
-        if (pcb->pcb_flags & PCB_DBREGS) {
-                pcb->pcb_dr0 = 0;
-                pcb->pcb_dr1 = 0;
-                pcb->pcb_dr2 = 0;
-                pcb->pcb_dr3 = 0;
-                pcb->pcb_dr6 = 0;
-                pcb->pcb_dr7 = 0;
-                if (pcb == curpcb) {
-		        /*
-			 * Clear the debug registers on the running
-			 * CPU, otherwise they will end up affecting
-			 * the next process we switch to.
-			 */
-		        reset_dbregs();
-                }
-		pcb->pcb_flags &= ~PCB_DBREGS;
-        }
+	x86_clear_dbregs(pcb);
 
 	pcb->pcb_initial_npxcw = __INITIAL_NPXCW__;
 
diff --git a/sys/x86/include/x86_var.h b/sys/x86/include/x86_var.h
index 3e5aa847304e..983c353327fd 100644
--- a/sys/x86/include/x86_var.h
+++ b/sys/x86/include/x86_var.h
@@ -123,6 +123,7 @@ void	cpu_setregs(void);
 int	dbreg_set_watchpoint(vm_offset_t addr, vm_size_t size, int access);
 int	dbreg_clr_watchpoint(vm_offset_t addr, vm_size_t size);
 void	dbreg_list_watchpoints(void);
+void	x86_clear_dbregs(struct pcb *pcb);
 bool	disable_wp(void);
 void	restore_wp(bool old_wp);
 void	finishidentcpu(void);


More information about the dev-commits-src-all mailing list