Skip to content

Commit d6e656c

Browse files
sean-jcbonzini
authored andcommitted
KVM: nVMX: WARN on any attempt to allocate shadow VMCS for vmcs02
WARN if KVM attempts to allocate a shadow VMCS for vmcs02. KVM emulates VMCS shadowing but doesn't virtualize it, i.e. KVM should never allocate a "real" shadow VMCS for L2. The previous code WARNed but continued anyway with the allocation, presumably in an attempt to avoid NULL pointer dereference. However, alloc_vmcs (and hence alloc_shadow_vmcs) can fail, and indeed the sole caller does: if (enable_shadow_vmcs && !alloc_shadow_vmcs(vcpu)) goto out_shadow_vmcs; which makes it not a useful attempt. Signed-off-by: Sean Christopherson <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 4cf3d3e commit d6e656c

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

arch/x86/kvm/vmx/nested.c

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4851,18 +4851,20 @@ static struct vmcs *alloc_shadow_vmcs(struct kvm_vcpu *vcpu)
48514851
struct loaded_vmcs *loaded_vmcs = vmx->loaded_vmcs;
48524852

48534853
/*
4854-
* We should allocate a shadow vmcs for vmcs01 only when L1
4855-
* executes VMXON and free it when L1 executes VMXOFF.
4856-
* As it is invalid to execute VMXON twice, we shouldn't reach
4857-
* here when vmcs01 already have an allocated shadow vmcs.
4854+
* KVM allocates a shadow VMCS only when L1 executes VMXON and frees it
4855+
* when L1 executes VMXOFF or the vCPU is forced out of nested
4856+
* operation. VMXON faults if the CPU is already post-VMXON, so it
4857+
* should be impossible to already have an allocated shadow VMCS. KVM
4858+
* doesn't support virtualization of VMCS shadowing, so vmcs01 should
4859+
* always be the loaded VMCS.
48584860
*/
4859-
WARN_ON(loaded_vmcs == &vmx->vmcs01 && loaded_vmcs->shadow_vmcs);
4861+
if (WARN_ON(loaded_vmcs != &vmx->vmcs01 || loaded_vmcs->shadow_vmcs))
4862+
return loaded_vmcs->shadow_vmcs;
4863+
4864+
loaded_vmcs->shadow_vmcs = alloc_vmcs(true);
4865+
if (loaded_vmcs->shadow_vmcs)
4866+
vmcs_clear(loaded_vmcs->shadow_vmcs);
48604867

4861-
if (!loaded_vmcs->shadow_vmcs) {
4862-
loaded_vmcs->shadow_vmcs = alloc_vmcs(true);
4863-
if (loaded_vmcs->shadow_vmcs)
4864-
vmcs_clear(loaded_vmcs->shadow_vmcs);
4865-
}
48664868
return loaded_vmcs->shadow_vmcs;
48674869
}
48684870

0 commit comments

Comments
 (0)