*/
#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));
*
* @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
* (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
void test_main(void)
{
+ test_initial_debug_state();
+
if ( IS_DEFINED(CONFIG_PV) )
{
test_pv_dr7_latch();