diff mbox series

[3/3] KVM: SVM: check if we need to track GP intercept for invpcid

Message ID 20210211212241.3958897-4-bsd@redhat.com (mailing list archive)
State New, archived
Headers show
Series AMD invpcid exception fix | expand

Commit Message

Bandan Das Feb. 11, 2021, 9:22 p.m. UTC
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(+)
diff mbox series

Patch

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 0e8ce7adb815..2ecbf9bc929f 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -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);
 	}
 }