]> xenbits.xensource.com Git - people/andrewcoop/xen-test-framework.git/commitdiff
Introduce a basic test for debugging infrastructure
authorAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 23 Mar 2018 15:38:05 +0000 (15:38 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 3 Apr 2018 17:50:52 +0000 (18:50 +0100)
To begin with, this just checks that the PV %dr7 latch issue is resolved.
There are many more bugs to fix.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
docs/all-tests.dox
tests/debug-regs/Makefile [new file with mode: 0644]
tests/debug-regs/main.c [new file with mode: 0644]

index 355cb800caf7d445e0dafa796f4785db96d9ea32..224e06b19935424ffbc5bfc487b9ec678db734a4 100644 (file)
@@ -124,6 +124,8 @@ guest breakout.
 
 @section index-in-development In Development
 
+@subpage test-debug-regs - Debugging facility tests.
+
 @subpage test-nested-svm - Nested SVM tests.
 
 @subpage test-nested-vmx - Nested VT-x tests.
diff --git a/tests/debug-regs/Makefile b/tests/debug-regs/Makefile
new file mode 100644 (file)
index 0000000..5cd035e
--- /dev/null
@@ -0,0 +1,9 @@
+include $(ROOT)/build/common.mk
+
+NAME      := debug-regs
+CATEGORY  := in-development
+TEST-ENVS := $(ALL_ENVIRONMENTS)
+
+obj-perenv += main.o
+
+include $(ROOT)/build/gen.mk
diff --git a/tests/debug-regs/main.c b/tests/debug-regs/main.c
new file mode 100644 (file)
index 0000000..789a899
--- /dev/null
@@ -0,0 +1,102 @@
+/**
+ * @file tests/debug-regs/main.c
+ * @ref test-debug-regs
+ *
+ * @page test-debug-regs Debug register and control tests
+ *
+ * The following misc tests are implemented:
+ *
+ * 1.  Xen, between
+ *     [65e3554908](http://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=65e355490817ac1783c9ef06c13cf980edf05b5b)
+ *     (Introduced in Xen 4.5) and
+ *     [adf8feba1a](http://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=adf8feba1afa040f3a84a82953e18af02060884a)
+ *     (Fixed in Xen 4.11) had a bug whereby some writes to @%dr7 didn't take
+ *     immediate effect.
+ *
+ *     In practice, this renders guest debugging useless, as the guest kernels
+ *     context switch of @%dr7 fails to take effect until the next full vcpu
+ *     reschedule.
+ *
+ * @see tests/debug-regs/main.c
+ */
+#include <xtf.h>
+
+const char test_title[] = "Debugging facility tests";
+
+/*
+ * 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
+ * the bug.
+ */
+static void test_pv_dr7_latch(void)
+{
+    unsigned int dummy, i;
+    unsigned long dr7;
+
+    printk("Test PV %%dr7 latch\n");
+
+    /* Reset any latched %dr7 content. */
+    write_dr7(0);
+    write_dr7(0);
+
+    /* Point %dr0 at dummy, %dr7 set with %dr0 enabled. */
+    write_dr0(_u(&dummy));
+    dr7 = X86_DR7_GE | DR7_SYM(0, G, RW, 32);
+
+    /*
+     * We can race with the Xen scheduler, which may mask the latching bug.
+     * Repeat 10 times, or until we positively see buggy behaviour.
+     */
+    for ( i = 0; i < 10; ++i )
+    {
+        exinfo_t fault = 0;
+
+        asm volatile ("mov %[dr7], %%dr7;"
+                      "movl $0, %[ptr]; 1:"
+                      _ASM_EXTABLE_HANDLER(1b, 1b, ex_record_fault_eax)
+                      : "+a" (fault),
+                        [ptr] "=m" (dummy)
+                      : [dr7] "r" (dr7), "X" (ex_record_fault_eax));
+
+        /* Reset any latched %dr7 content. */
+        write_dr7(0);
+        write_dr7(0);
+
+        if ( fault == 0 )
+        {
+            xtf_failure("  Fail: Single write to %%dr7 failed to latch\n");
+            break;
+        }
+        else if ( fault != EXINFO_SYM(DB, 0) )
+        {
+            xtf_error("  Error: Unexpected fault %#x, %pe\n",
+                      fault, _p(fault));
+            break;
+        }
+    }
+
+    if ( i == 10 )
+        printk("  All ok - %%dr7 seems to work fine\n");
+
+    /* Reset other state. */
+    write_dr0(0);
+    write_dr6(X86_DR6_RESET);
+}
+
+void test_main(void)
+{
+    if ( IS_DEFINED(CONFIG_PV) )
+        test_pv_dr7_latch();
+
+    xtf_success(NULL);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */