@@ -1102,6 +1102,7 @@ static u64 svm_write_l1_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
static void svm_check_invpcid(struct vcpu_svm *svm)
{
+ struct kvm_vcpu *vcpu = &svm->vcpu;
/*
* Intercept INVPCID instruction only if shadow page table is
* enabled. Interception is not required with nested page table
@@ -1112,6 +1113,16 @@ static void svm_check_invpcid(struct vcpu_svm *svm)
svm_set_intercept(svm, INTERCEPT_INVPCID);
else
svm_clr_intercept(svm, INTERCEPT_INVPCID);
+ /*
+ * For CPL <> 0, #GP takes priority over intercepts.
+ * This means that if invpcid is present but guest has disabled
+ * it, it might end up getting a #GP instead of #UD
+ * Let kvm inject the correct exception instead.
+ */
+ if (!guest_cpuid_has(vcpu, X86_FEATURE_INVPCID))
+ set_exception_intercept(svm, GP_VECTOR);
+ else
+ clr_exception_intercept(svm, GP_VECTOR);
}
}
This is only set when the feature is available on the host but the guest has disabled it, this will allow us to inject the correct exception to the guest Signed-off-by: Bandan Das <bsd@redhat.com> --- arch/x86/kvm/svm/svm.c | 11 +++++++++++ 1 file changed, 11 insertions(+)