Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/x86/x86 Add paranoid code to X86 Debug Registers



details:   https://anonhg.NetBSD.org/src/rev/eebd9475ceaf
branches:  trunk
changeset: 360987:eebd9475ceaf
user:      kamil <kamil%NetBSD.org@localhost>
date:      Sun Apr 08 14:21:23 2018 +0000

description:
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>

diffstat:

 sys/arch/x86/x86/dbregs.c |  37 ++++++++++++++++++++++---------------
 1 files changed, 22 insertions(+), 15 deletions(-)

diffs (67 lines):

diff -r 407fbf4107de -r eebd9475ceaf sys/arch/x86/x86/dbregs.c
--- a/sys/arch/x86/x86/dbregs.c Sun Apr 08 13:52:22 2018 +0000
+++ b/sys/arch/x86/x86/dbregs.c Sun Apr 08 14:21:23 2018 +0000
@@ -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 @@
 
 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 @@
        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 @@
 
        /*
         * 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;



Home | Main Index | Thread Index | Old Index