]> xenbits.xensource.com Git - people/andrewcoop/xen-test-framework.git/commitdiff
debug-regs: Check the vcpu's initial register state
authorAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 25 May 2018 10:04:32 +0000 (11:04 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 2 Nov 2018 11:43:11 +0000 (11:43 +0000)
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
arch/x86/include/arch/x86-dbg-reg.h
tests/debug-regs/main.c

index da9bd9d46bd7195a0f6093725eb7979306ccef39..b70185dd2dc26293ecaa4c642eaee2ab8ecdad54 100644 (file)
  */
 #define DR7_SYM(bp, ...) TOK_OR(X86_DR7_ ## bp ## _, ##__VA_ARGS__)
 
+static inline unsigned long read_dr0(void)
+{
+    unsigned long val;
+
+    asm volatile ("mov %%dr0, %0" : "=r" (val));
+
+    return val;
+}
+
 static inline void write_dr0(unsigned long linear)
 {
     asm volatile ("mov %0, %%dr0" :: "r" (linear));
 }
 
+static inline unsigned long read_dr1(void)
+{
+    unsigned long val;
+
+    asm volatile ("mov %%dr1, %0" : "=r" (val));
+
+    return val;
+}
+
 static inline void write_dr1(unsigned long linear)
 {
     asm volatile ("mov %0, %%dr1" :: "r" (linear));
 }
 
+static inline unsigned long read_dr2(void)
+{
+    unsigned long val;
+
+    asm volatile ("mov %%dr2, %0" : "=r" (val));
+
+    return val;
+}
+
 static inline void write_dr2(unsigned long linear)
 {
     asm volatile ("mov %0, %%dr2" :: "r" (linear));
 }
 
+static inline unsigned long read_dr3(void)
+{
+    unsigned long val;
+
+    asm volatile ("mov %%dr3, %0" : "=r" (val));
+
+    return val;
+}
+
 static inline void write_dr3(unsigned long linear)
 {
     asm volatile ("mov %0, %%dr3" :: "r" (linear));
index 2835f216adc2ddf072264b1b42f50a562f02e58e..5f18feadee5bd66eb72a0fd831696dab584da12e 100644 (file)
@@ -4,6 +4,15 @@
  *
  * @page test-debug-regs Debug register and control tests
  *
+ * The following general tests are implemented:
+ *
+ * 1.  Xen, before
+ *     [46029da12e](http://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=46029da12e5efeca6d957e5793bd34f2965fa0a1)
+ *     failed to initialise the guests debug registers correctly.  On hardware
+ *     which supports Restricted Transactional Memory, this becomes visible,
+ *     as @%dr6.rtm appears asserted (clear, for backwards compatibility)
+ *     despite an RTM @#DE not having occurred.
+ *
  * The following PV tests are implemented:
  *
  * 1.  Xen, between
@@ -22,7 +31,7 @@
  *     (Xen 4.11) had a bug whereby a write which cleared @%dr7.L/G would
  *     leave stale IO shadow state visible in later reads of @%dr7.
  *
- *     Unfortunately, that changset introduced a second bug, fixed by
+ *     Unfortunately, that changeset introduced a second bug, fixed by
  *     [237c31b5a1](http://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=237c31b5a1d5aa88cdb59b8c31b1b62eb13e82d1)
  *     (Xen 4.11), which caused an attempt to set up an IO breakpoint with
  *     @%cr4.DE clear to clobber an already configured state, despite the
 
 const char test_title[] = "Debugging facility tests";
 
+static void check_initial_state(unsigned int dr, unsigned long exp,
+                                unsigned long got)
+{
+    if ( got != exp )
+        xtf_failure("  Fail: %%dr%u expected %p, got %p\n",
+                    dr, _p(exp), _p(got));
+}
+
+static void test_initial_debug_state(void)
+{
+    printk("Test initial debug state\n");
+
+    if ( read_cr4() & X86_CR4_DE )
+        xtf_failure("  Fail: %%cr4.de expected to be clear\n");
+
+    check_initial_state(0, 0, read_dr0());
+    check_initial_state(1, 0, read_dr1());
+    check_initial_state(2, 0, read_dr2());
+    check_initial_state(3, 0, read_dr3());
+    check_initial_state(6, X86_DR6_DEFAULT, read_dr6());
+    check_initial_state(7, X86_DR7_DEFAULT, read_dr7());
+
+    uint64_t val;
+    if ( (val = rdmsr(MSR_DEBUGCTL)) != 0 )
+         xtf_failure("  Fail: MSR_DEBUGCTL expected %08x, got %08"PRIx64"\n",
+                     0, val);
+}
+
 /*
  * Attempt to detect a failure to latch %dr7.  A full vcpu context switch, or
  * a second write to %dr7 will latch the correct value even in the presence of
@@ -145,6 +182,8 @@ static void test_pv_dr7_io_breakpoints(void)
 
 void test_main(void)
 {
+    test_initial_debug_state();
+
     if ( IS_DEFINED(CONFIG_PV) )
     {
         test_pv_dr7_latch();