diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 9371efc8c7..6f19fbfe69 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -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; diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index af13de3745..56a8de8034 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -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); diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index e7b82279e7..503f8ff2de 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -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);