Module Name:    src
Committed By:   kamil
Date:           Sun Apr  8 14:21:23 UTC 2018

Modified Files:
        src/sys/arch/x86/x86: dbregs.c

Log Message:
Add paranoid code to X86 Debug Registers

Reset certain bits in DR6 and DR7 in x86_dbregs_setup_initdbstate().

Reset X86_BREAKPOINT_CONDITION_DETECTED in DR6.
Reset X86_DR7_GENERAL_DETECT_ENABLE in DR7.

It's allowed by devices or software before the kernel boot, to
use these registers for their own purposes. Handle this paranoid case
explicitly setting the mentioned bits to zero.

Sponsored by <The NetBSD Foundation>


To generate a diff of this commit:
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/x86/x86/dbregs.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/x86/x86/dbregs.c
diff -u src/sys/arch/x86/x86/dbregs.c:1.8 src/sys/arch/x86/x86/dbregs.c:1.9
--- src/sys/arch/x86/x86/dbregs.c:1.8	Thu Apr  5 14:14:27 2018
+++ src/sys/arch/x86/x86/dbregs.c	Sun Apr  8 14:21:23 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: dbregs.c,v 1.8 2018/04/05 14:14:27 maxv Exp $	*/
+/*	$NetBSD: dbregs.c,v 1.9 2018/04/08 14:21:23 kamil Exp $	*/
 
 /*-
  * Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -43,6 +43,18 @@ extern struct pool x86_dbregspl;
 
 static struct dbreg initdbstate;
 
+#define X86_BREAKPOINT_CONDITION_DETECTED	( \
+	X86_DR6_DR0_BREAKPOINT_CONDITION_DETECTED | \
+	X86_DR6_DR1_BREAKPOINT_CONDITION_DETECTED | \
+	X86_DR6_DR2_BREAKPOINT_CONDITION_DETECTED | \
+	X86_DR6_DR3_BREAKPOINT_CONDITION_DETECTED )
+
+#define X86_GLOBAL_BREAKPOINT	( \
+	X86_DR7_GLOBAL_DR0_BREAKPOINT | \
+	X86_DR7_GLOBAL_DR1_BREAKPOINT | \
+	X86_DR7_GLOBAL_DR2_BREAKPOINT | \
+	X86_DR7_GLOBAL_DR3_BREAKPOINT )
+
 void
 x86_dbregs_setup_initdbstate(void)
 {
@@ -56,19 +68,17 @@ x86_dbregs_setup_initdbstate(void)
 	initdbstate.dr[6] = rdr6();
 	initdbstate.dr[7] = rdr7();
 	/* DR8-DR15 are reserved - skip */
-}
 
-#define X86_BREAKPOINT_CONDITION_DETECTED	( \
-	X86_DR6_DR0_BREAKPOINT_CONDITION_DETECTED | \
-	X86_DR6_DR1_BREAKPOINT_CONDITION_DETECTED | \
-	X86_DR6_DR2_BREAKPOINT_CONDITION_DETECTED | \
-	X86_DR6_DR3_BREAKPOINT_CONDITION_DETECTED )
+	/*
+	 * Paranoid case.
+	 *
+	 * Explicitly reset some bits just in case they could be
+	 * set by brave software/hardware before the kernel boot.
+	 */
+	initdbstate.dr[6] &= ~X86_BREAKPOINT_CONDITION_DETECTED;
 
-#define X86_GLOBAL_BREAKPOINT	( \
-	X86_DR7_GLOBAL_DR0_BREAKPOINT | \
-	X86_DR7_GLOBAL_DR1_BREAKPOINT | \
-	X86_DR7_GLOBAL_DR2_BREAKPOINT | \
-	X86_DR7_GLOBAL_DR3_BREAKPOINT )
+	initdbstate.dr[7] &= ~X86_DR7_GENERAL_DETECT_ENABLE;
+}
 
 void
 x86_dbregs_clear(struct lwp *l)
@@ -196,9 +206,6 @@ x86_dbregs_validate(const struct dbreg *
 
 	/*
 	 * Skip checks for reserved registers (DR4-DR5, DR8-DR15).
-	 *
-	 * Don't validate DR6-DR7 as some bits are set by hardware and a user
-	 * cannot overwrite them.
 	 */
 
 	return 0;

Reply via email to