From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dongxiao Xu Subject: [PATCH] nested vmx: Fix the booting of L2 PAE guest Date: Mon, 24 Jun 2013 13:55:00 +0800 Message-ID: <1372053300-20211-1-git-send-email-dongxiao.xu@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xen.org List-Id: xen-devel@lists.xenproject.org When doing virtual VM entry and virtual VM exit, we need to sychronize the PAE PDPTR related VMCS registers. With this fix, we can boot 32bit PAE L2 guest (Win7 & RHEL6.4) on "Xen on Xen" environment. Signed-off-by: Dongxiao Xu Tested-by: Yongjie Ren --- xen/arch/x86/hvm/vmx/vvmx.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c index bb7688f..5dfbc54 100644 --- a/xen/arch/x86/hvm/vmx/vvmx.c +++ b/xen/arch/x86/hvm/vmx/vvmx.c @@ -864,6 +864,13 @@ static const u16 vmcs_gstate_field[] = { GUEST_SYSENTER_EIP, }; +static const u16 gpdptr_fields[] = { + GUEST_PDPTR0, + GUEST_PDPTR1, + GUEST_PDPTR2, + GUEST_PDPTR3, +}; + /* * Context: shadow -> virtual VMCS */ @@ -1053,18 +1060,6 @@ static void load_shadow_guest_state(struct vcpu *v) (__get_vvmcs(vvmcs, CR4_READ_SHADOW) & cr_gh_mask); __vmwrite(CR4_READ_SHADOW, cr_read_shadow); - if ( nvmx_ept_enabled(v) && hvm_pae_enabled(v) && - (v->arch.hvm_vcpu.guest_efer & EFER_LMA) ) - { - static const u16 gpdptr_fields[] = { - GUEST_PDPTR0, - GUEST_PDPTR1, - GUEST_PDPTR2, - GUEST_PDPTR3, - }; - vvmcs_to_shadow_bulk(v, ARRAY_SIZE(gpdptr_fields), gpdptr_fields); - } - /* TODO: CR3 target control */ } @@ -1159,6 +1154,10 @@ static void virtual_vmentry(struct cpu_user_regs *regs) if ( lm_l1 != lm_l2 ) paging_update_paging_modes(v); + if ( nvmx_ept_enabled(v) && hvm_pae_enabled(v) && + !(v->arch.hvm_vcpu.guest_efer & EFER_LMA) ) + vvmcs_to_shadow_bulk(v, ARRAY_SIZE(gpdptr_fields), gpdptr_fields); + regs->eip = __get_vvmcs(vvmcs, GUEST_RIP); regs->esp = __get_vvmcs(vvmcs, GUEST_RSP); regs->eflags = __get_vvmcs(vvmcs, GUEST_RFLAGS); @@ -1294,6 +1293,10 @@ static void virtual_vmexit(struct cpu_user_regs *regs) sync_vvmcs_guest_state(v, regs); sync_exception_state(v); + if ( nvmx_ept_enabled(v) && hvm_pae_enabled(v) && + !(v->arch.hvm_vcpu.guest_efer & EFER_LMA) ) + shadow_to_vvmcs_bulk(v, ARRAY_SIZE(gpdptr_fields), gpdptr_fields); + vmx_vmcs_switch(v->arch.hvm_vmx.vmcs, nvcpu->nv_n1vmcx); nestedhvm_vcpu_exit_guestmode(v); -- 1.8.1.5