]> xenbits.xensource.com Git - people/dariof/xen.git/commitdiff
x86/domain: Initialise vcpu debug registers correctly
authorAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 28 May 2018 14:18:17 +0000 (14:18 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 24 Oct 2018 13:43:05 +0000 (14:43 +0100)
In particular, initialising %dr6 with the value 0 is buggy, because on
hardware supporting Transactional Memory, it will cause the sticky RTM bit to
be asserted, even though a debug exception from a transaction hasn't actually
been observed.

Introduce arch_vcpu_regs_init() to set various architectural defaults, and
reuse this in the hvm_vcpu_reset_state() path.

Architecturally, %edx's init state contains the processors model information,
and 0xf looks to be a remnant of the old Intel processors.  We clearly have no
software which cares, seeing as it is wrong for the last decade's worth of
Intel hardware and for all other vendors, so lets use the value 0 for
simplicity.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
xen/arch/x86/domain.c
xen/arch/x86/hvm/hvm.c
xen/include/asm-x86/domain.h

index 9371efc8c75dc1f0c9600f1af143514e7c5d72a2..6f19fbfe690f88c2cd0fe0322956a237cf0d4cc9 100644 (file)
@@ -323,6 +323,18 @@ void free_vcpu_struct(struct vcpu *v)
     free_xenheap_page(v);
 }
 
+/* Initialise various registers to their architectural INIT/RESET state. */
+void arch_vcpu_regs_init(struct vcpu *v)
+{
+    v->arch.user_regs = (typeof(v->arch.user_regs)){
+        .rflags = X86_EFLAGS_MBS,
+    };
+
+    memset(v->arch.debugreg, 0, sizeof(v->arch.debugreg));
+    v->arch.debugreg[6] = X86_DR6_DEFAULT;
+    v->arch.debugreg[7] = X86_DR7_DEFAULT;
+}
+
 int arch_vcpu_create(struct vcpu *v)
 {
     struct domain *d = v->domain;
@@ -342,6 +354,8 @@ int arch_vcpu_create(struct vcpu *v)
             return rc;
 
         vmce_init_vcpu(v);
+
+        arch_vcpu_regs_init(v);
     }
     else if ( (rc = xstate_alloc_save_area(v)) != 0 )
         return rc;
index af13de3745bf4507a794c73f8eb7e33da1ad5c6c..56a8de803428de143044448159347a7c19aed7b5 100644 (file)
@@ -3850,11 +3850,9 @@ void hvm_vcpu_reset_state(struct vcpu *v, uint16_t cs, uint16_t ip)
     vcpu_setup_fpu(v, v->arch.xsave_area, NULL, FCW_RESET);
 
     v->arch.vgc_flags = VGCF_online;
-    memset(&v->arch.user_regs, 0, sizeof(v->arch.user_regs));
-    v->arch.user_regs.rflags = X86_EFLAGS_MBS;
-    v->arch.user_regs.rdx = 0x00000f00;
+
+    arch_vcpu_regs_init(v);
     v->arch.user_regs.rip = ip;
-    memset(&v->arch.debugreg, 0, sizeof(v->arch.debugreg));
 
     v->arch.hvm.guest_cr[0] = X86_CR0_ET;
     hvm_update_guest_cr(v, 0);
index e7b82279e7981303c9dc91b592403b0c94c0f1b2..503f8ff2deedc017f9af86b508287a9bd2f67df5 100644 (file)
@@ -669,6 +669,8 @@ static inline void free_vcpu_guest_context(struct vcpu_guest_context *vgc)
     vfree(vgc);
 }
 
+void arch_vcpu_regs_init(struct vcpu *v);
+
 struct vcpu_hvm_context;
 int arch_set_info_hvm_guest(struct vcpu *v, const struct vcpu_hvm_context *ctx);