|
@@ -11330,6 +11330,24 @@ static void prepare_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
|
|
|
kvm_clear_interrupt_queue(vcpu);
|
|
|
}
|
|
|
|
|
|
+static void load_vmcs12_mmu_host_state(struct kvm_vcpu *vcpu,
|
|
|
+ struct vmcs12 *vmcs12)
|
|
|
+{
|
|
|
+ u32 entry_failure_code;
|
|
|
+
|
|
|
+ nested_ept_uninit_mmu_context(vcpu);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Only PDPTE load can fail as the value of cr3 was checked on entry and
|
|
|
+ * couldn't have changed.
|
|
|
+ */
|
|
|
+ if (nested_vmx_load_cr3(vcpu, vmcs12->host_cr3, false, &entry_failure_code))
|
|
|
+ nested_vmx_abort(vcpu, VMX_ABORT_LOAD_HOST_PDPTE_FAIL);
|
|
|
+
|
|
|
+ if (!enable_ept)
|
|
|
+ vcpu->arch.walk_mmu->inject_page_fault = kvm_inject_page_fault;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* A part of what we need to when the nested L2 guest exits and we want to
|
|
|
* run its L1 parent, is to reset L1's guest state to the host state specified
|
|
@@ -11343,7 +11361,6 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
|
|
|
struct vmcs12 *vmcs12)
|
|
|
{
|
|
|
struct kvm_segment seg;
|
|
|
- u32 entry_failure_code;
|
|
|
|
|
|
if (vmcs12->vm_exit_controls & VM_EXIT_LOAD_IA32_EFER)
|
|
|
vcpu->arch.efer = vmcs12->host_ia32_efer;
|
|
@@ -11370,17 +11387,7 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
|
|
|
vcpu->arch.cr4_guest_owned_bits = ~vmcs_readl(CR4_GUEST_HOST_MASK);
|
|
|
vmx_set_cr4(vcpu, vmcs12->host_cr4);
|
|
|
|
|
|
- nested_ept_uninit_mmu_context(vcpu);
|
|
|
-
|
|
|
- /*
|
|
|
- * Only PDPTE load can fail as the value of cr3 was checked on entry and
|
|
|
- * couldn't have changed.
|
|
|
- */
|
|
|
- if (nested_vmx_load_cr3(vcpu, vmcs12->host_cr3, false, &entry_failure_code))
|
|
|
- nested_vmx_abort(vcpu, VMX_ABORT_LOAD_HOST_PDPTE_FAIL);
|
|
|
-
|
|
|
- if (!enable_ept)
|
|
|
- vcpu->arch.walk_mmu->inject_page_fault = kvm_inject_page_fault;
|
|
|
+ load_vmcs12_mmu_host_state(vcpu, vmcs12);
|
|
|
|
|
|
if (enable_vpid) {
|
|
|
/*
|
|
@@ -11610,6 +11617,9 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
|
|
|
* accordingly.
|
|
|
*/
|
|
|
nested_vmx_failValid(vcpu, VMXERR_ENTRY_INVALID_CONTROL_FIELD);
|
|
|
+
|
|
|
+ load_vmcs12_mmu_host_state(vcpu, vmcs12);
|
|
|
+
|
|
|
/*
|
|
|
* The emulated instruction was already skipped in
|
|
|
* nested_vmx_run, but the updated RIP was never
|