aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/vmx
diff options
context:
space:
mode:
authorDongxiao Xu <dongxiao.xu@intel.com>2013-06-27 17:01:26 +0200
committerJan Beulich <jbeulich@suse.com>2013-06-27 17:01:26 +0200
commit49b55619e4923aa1a43b7c027dd3e352575e4e52 (patch)
treede56a3a9a484bb9117af819bb23b2daab7373bf0 /xen/arch/x86/hvm/vmx
parentf0fe8227624d5c02715ed086867d12cd24f6ff47 (diff)
downloadxen-49b55619e4923aa1a43b7c027dd3e352575e4e52.tar.gz
xen-49b55619e4923aa1a43b7c027dd3e352575e4e52.tar.bz2
xen-49b55619e4923aa1a43b7c027dd3e352575e4e52.zip
nested vmx: Fix the booting of L2 PAE guest
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 <dongxiao.xu@intel.com> Tested-by: Yongjie Ren <yongjie.ren@intel.com> Acked-by: Keir Fraser <keir@xen.org> Acked-by: "Dong, Eddie" <eddie.dong@intel.com>
Diffstat (limited to 'xen/arch/x86/hvm/vmx')
-rw-r--r--xen/arch/x86/hvm/vmx/vvmx.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c
index bb7688ff6c..5dfbc54d94 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);