Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: VMX: fix nested vpid for old KVM guests

Old KVM guests invoke single-context invvpid without actually checking
whether it is supported. This was fixed by commit 518c8ae ("KVM: VMX:
Make sure single type invvpid is supported before issuing invvpid
instruction", 2010-08-01) and the patch after, but pre-2.6.36
kernels lack it including RHEL 6.

Reported-by: jmontleo@redhat.com
Tested-by: jmontleo@redhat.com
Cc: stable@vger.kernel.org
Fixes: 99b83ac893b84ed1a62ad6d1f2b6cc32026b9e85
Reviewed-by: David Matlack <dmatlack@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

+13 -1
+13 -1
arch/x86/kvm/vmx.c
··· 2712 2712 } else 2713 2713 vmx->nested.nested_vmx_ept_caps = 0; 2714 2714 2715 + /* 2716 + * Old versions of KVM use the single-context version without 2717 + * checking for support, so declare that it is supported even 2718 + * though it is treated as global context. The alternative is 2719 + * not failing the single-context invvpid, and it is worse. 2720 + */ 2715 2721 if (enable_vpid) 2716 2722 vmx->nested.nested_vmx_vpid_caps = VMX_VPID_INVVPID_BIT | 2723 + VMX_VPID_EXTENT_SINGLE_CONTEXT_BIT | 2717 2724 VMX_VPID_EXTENT_GLOBAL_CONTEXT_BIT; 2718 2725 else 2719 2726 vmx->nested.nested_vmx_vpid_caps = 0; ··· 7482 7475 } 7483 7476 7484 7477 switch (type) { 7478 + case VMX_VPID_EXTENT_SINGLE_CONTEXT: 7479 + /* 7480 + * Old versions of KVM use the single-context version so we 7481 + * have to support it; just treat it the same as all-context. 7482 + */ 7485 7483 case VMX_VPID_EXTENT_ALL_CONTEXT: 7486 7484 __vmx_flush_tlb(vcpu, to_vmx(vcpu)->nested.vpid02); 7487 7485 nested_vmx_succeed(vcpu); 7488 7486 break; 7489 7487 default: 7490 - /* Trap single context invalidation invvpid calls */ 7488 + /* Trap individual address invalidation invvpid calls */ 7491 7489 BUG_ON(1); 7492 7490 break; 7493 7491 }