mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Kevin Cheng <chengkev@google.com>
To: seanjc@google.com, pbonzini@redhat.com
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	yosry@kernel.org,  Kevin Cheng <chengkev@google.com>
Subject: [PATCH V4 4/4] KVM: SVM: Raise #UD if VMMCALL instruction is not intercepted
Date: Sat, 28 Feb 2026 03:33:28 +0000	[thread overview]
Message-ID: <20260228033328.2285047-5-chengkev@google.com> (raw)
In-Reply-To: <20260228033328.2285047-1-chengkev@google.com>

The AMD APM states that if VMMCALL instruction is not intercepted, the
instruction raises a #UD exception.

Create a vmmcall exit handler that generates a #UD if a VMMCALL exit
from L2 is being handled by L0, which means that L1 did not intercept
the VMMCALL instruction. The exception to this is if the exiting
instruction was for Hyper-V L2 TLB flush hypercalls as they are handled
by L0.

Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Kevin Cheng <chengkev@google.com>
---
 arch/x86/kvm/svm/hyperv.h | 11 +++++++++++
 arch/x86/kvm/svm/nested.c |  4 +---
 arch/x86/kvm/svm/svm.c    | 19 ++++++++++++++++++-
 3 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/svm/hyperv.h b/arch/x86/kvm/svm/hyperv.h
index d3f8bfc05832e..9af03970d40c2 100644
--- a/arch/x86/kvm/svm/hyperv.h
+++ b/arch/x86/kvm/svm/hyperv.h
@@ -41,6 +41,13 @@ static inline bool nested_svm_l2_tlb_flush_enabled(struct kvm_vcpu *vcpu)
 	return hv_vcpu->vp_assist_page.nested_control.features.directhypercall;
 }

+static inline bool nested_svm_is_l2_tlb_flush_hcall(struct kvm_vcpu *vcpu)
+{
+	return guest_hv_cpuid_has_l2_tlb_flush(vcpu) &&
+	       nested_svm_l2_tlb_flush_enabled(vcpu) &&
+	       kvm_hv_is_tlb_flush_hcall(vcpu);
+}
+
 void svm_hv_inject_synthetic_vmexit_post_tlb_flush(struct kvm_vcpu *vcpu);
 #else /* CONFIG_KVM_HYPERV */
 static inline void nested_svm_hv_update_vm_vp_ids(struct kvm_vcpu *vcpu) {}
@@ -48,6 +55,10 @@ static inline bool nested_svm_l2_tlb_flush_enabled(struct kvm_vcpu *vcpu)
 {
 	return false;
 }
+static inline bool nested_svm_is_l2_tlb_flush_hcall(struct kvm_vcpu *vcpu)
+{
+	return false;
+}
 static inline void svm_hv_inject_synthetic_vmexit_post_tlb_flush(struct kvm_vcpu *vcpu) {}
 #endif /* CONFIG_KVM_HYPERV */

diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
index de90b104a0dd5..45d1496031a74 100644
--- a/arch/x86/kvm/svm/nested.c
+++ b/arch/x86/kvm/svm/nested.c
@@ -1674,9 +1674,7 @@ int nested_svm_exit_special(struct vcpu_svm *svm)
 	}
 	case SVM_EXIT_VMMCALL:
 		/* Hyper-V L2 TLB flush hypercall is handled by L0 */
-		if (guest_hv_cpuid_has_l2_tlb_flush(vcpu) &&
-		    nested_svm_l2_tlb_flush_enabled(vcpu) &&
-		    kvm_hv_is_tlb_flush_hcall(vcpu))
+		if (nested_svm_is_l2_tlb_flush_hcall(vcpu))
 			return NESTED_EXIT_HOST;
 		break;
 	default:
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index f8f9b7a124c36..d662d5ce986ac 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -52,6 +52,7 @@
 #include "svm.h"
 #include "svm_ops.h"

+#include "hyperv.h"
 #include "kvm_onhyperv.h"
 #include "svm_onhyperv.h"

@@ -3258,6 +3259,22 @@ static int bus_lock_exit(struct kvm_vcpu *vcpu)
 	return 0;
 }

+static int vmmcall_interception(struct kvm_vcpu *vcpu)
+{
+	/*
+	 * Per the AMD APM, VMMCALL raises #UD if the VMMCALL intercept
+	 * is not set. For an L2 guest, inject #UD as L1 did not intercept
+	 * VMMCALL, except for Hyper-V L2 TLB flush hypercalls as they
+	 * are handled by L0.
+	 */
+	if (is_guest_mode(vcpu) && !nested_svm_is_l2_tlb_flush_hcall(vcpu)) {
+		kvm_queue_exception(vcpu, UD_VECTOR);
+		return 1;
+	}
+
+	return kvm_emulate_hypercall(vcpu);
+}
+
 static int (*const svm_exit_handlers[])(struct kvm_vcpu *vcpu) = {
 	[SVM_EXIT_READ_CR0]			= cr_interception,
 	[SVM_EXIT_READ_CR3]			= cr_interception,
@@ -3308,7 +3325,7 @@ static int (*const svm_exit_handlers[])(struct kvm_vcpu *vcpu) = {
 	[SVM_EXIT_TASK_SWITCH]			= task_switch_interception,
 	[SVM_EXIT_SHUTDOWN]			= shutdown_interception,
 	[SVM_EXIT_VMRUN]			= vmrun_interception,
-	[SVM_EXIT_VMMCALL]			= kvm_emulate_hypercall,
+	[SVM_EXIT_VMMCALL]			= vmmcall_interception,
 	[SVM_EXIT_VMLOAD]			= vmload_interception,
 	[SVM_EXIT_VMSAVE]			= vmsave_interception,
 	[SVM_EXIT_STGI]				= stgi_interception,
--
2.53.0.473.g4a7958ca14-goog


  parent reply	other threads:[~2026-02-28  3:33 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-28  3:33 [PATCH V4 0/4] Align SVM with APM defined behaviors Kevin Cheng
2026-02-28  3:33 ` [PATCH V4 1/4] KVM: SVM: Move STGI and CLGI intercept handling Kevin Cheng
2026-02-28  3:33 ` [PATCH V4 2/4] KVM: SVM: Inject #UD for INVLPGA if EFER.SVME=0 Kevin Cheng
2026-02-28  3:33 ` [PATCH V4 3/4] KVM: SVM: Recalc instructions intercepts when EFER.SVME is toggled Kevin Cheng
2026-02-28  3:33 ` Kevin Cheng [this message]
2026-03-03  2:22   ` [PATCH V4 4/4] KVM: SVM: Raise #UD if VMMCALL instruction is not intercepted Sean Christopherson
2026-03-03  9:36     ` Vitaly Kuznetsov
2026-03-02 16:21 ` [PATCH V4 0/4] Align SVM with APM defined behaviors Yosry Ahmed
2026-03-02 18:32   ` Sean Christopherson
2026-03-02 23:17     ` Sean Christopherson
2026-03-03  0:34       ` Sean Christopherson
2026-03-03 21:56         ` Kevin Cheng
2026-03-03 22:08           ` Sean Christopherson
2026-03-03 22:27             ` Kevin Cheng
2026-03-03 21:52       ` Kevin Cheng
2026-03-03 21:48   ` Kevin Cheng
2026-03-05 17:08 ` Sean Christopherson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260228033328.2285047-5-chengkev@google.com \
    --to=chengkev@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=yosry@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome