mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Naveen N Rao (AMD)" <naveen@kernel.org>
To: Sean Christopherson <seanjc@google.com>, Borislav Petkov <bp@alien8.de>
Cc: <kvm@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Nikunj A Dadhania <nikunj@amd.com>,
	Tom Lendacky <thomas.lendacky@amd.com>,
	Neeraj Upadhyay <neeraj.upadhyay@amd.com>,
	Tianyu Lan <tiala@microsoft.com>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	Thomas Gleixner <tglx@kernel.org>
Subject: [RFC PATCH v3 16/27] KVM: SVM: Add handler for VMGEXIT Secure AVIC NAE event
Date: Wed,  8 Jul 2026 12:02:14 +0530	[thread overview]
Message-ID: <c0f9fdc27f3d9a1e63f2d39a40989d66b6facee3.1783490022.git.naveen@kernel.org> (raw)
In-Reply-To: <cover.1783490022.git.naveen@kernel.org>

From: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>

[DO NOT MERGE]

VMGEXIT Secure AVIC NAE event is used by the guest for two purposes
determined by VMCB->EXITINFO1:
1. SVM_VMGEXIT_SAVIC_REGISTER_GPA: Used to inform the hypervisor about
   the GPA of the page (RBX) being used as the Secure AVIC backing page.
   RAX indicates APIC ID of the target vCPU (-1 for self)
2. SVM_VMGEXIT_SAVIC_UNREGISTER_GPA: Used to inform the hypervisor that
   the GPA is no longer being used as the backing page for Secure AVIC.
   The previously registered GPA for the Secure AVIC backing page is
   returned by the hypervisor to the guest.

The primary motivation behind these is to ensure that Secure AVIC
hardware accesses to the guest APIC backing page never generate an #NPF,
since Secure AVIC hardware cannot recover from such faults. Quoting the
APM:
  "It is required that the guest APIC backing page for a vCPU is
   pinned in system memory between VMRUN and VMEXIT because some AVIC
   hardware acceleration sequences may not be restartable when secure
   AVIC is enabled. If an access to the guest's own backing page by
   AVIC hardware results in a nested page fault, EXITINFO1 bit 63
   (Not Restartable) is set (this is an Automatic Exit) and the BUSY
   bit in the VMSA is set."

A guest vCPU that has the BUSY bit set in the VMSA cannot be restarted
and the guest will have to be killed.

One of the main reasons why the SPTE for a Secure AVIC backing page may
be invalidated is if it is backed by a huge page in the host, and an
adjacent page changes state forcing the huge page to be split. Currently
though, KVM uses guest_memfd to back SEV-SNP guest private memory, and
those only use 4k pages. As such, this _may_ not be an issue today.

It is possible that KVM may still invalidate an SPTE for other reasons -
those will need to be addressed.

Co-developed-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
Co-developed-by: Naveen N Rao (AMD) <naveen@kernel.org>
Signed-off-by: Naveen N Rao (AMD) <naveen@kernel.org>
---
 arch/x86/include/uapi/asm/svm.h |  1 +
 arch/x86/kvm/svm/svm.h          |  2 +
 arch/x86/kvm/svm/sev.c          | 68 +++++++++++++++++++++++++++++++++
 3 files changed, 71 insertions(+)

diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h
index 010a45c9f614..e8531a9d998d 100644
--- a/arch/x86/include/uapi/asm/svm.h
+++ b/arch/x86/include/uapi/asm/svm.h
@@ -245,6 +245,7 @@
 	{ SVM_VMGEXIT_GUEST_REQUEST,	"vmgexit_guest_request" }, \
 	{ SVM_VMGEXIT_EXT_GUEST_REQUEST, "vmgexit_ext_guest_request" }, \
 	{ SVM_VMGEXIT_AP_CREATION,	"vmgexit_ap_creation" }, \
+	{ SVM_VMGEXIT_SAVIC,		"vmgexit_secure_avic" }, \
 	{ SVM_VMGEXIT_HV_FEATURES,	"vmgexit_hypervisor_feature" }, \
 	{ SVM_EXIT_ERR,         "invalid_guest_state" }
 
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index e48744f6d756..5e9496f8566a 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -367,6 +367,8 @@ struct vcpu_svm {
 
 	/* Guest GIF value, used when vGIF is not enabled */
 	bool guest_gif;
+
+	gpa_t snp_savic_gpa;
 };
 
 struct svm_cpu_data {
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index f5b9ff69dbc1..ca921a185b64 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -3474,6 +3474,13 @@ static bool sev_es_are_required_ghcb_fields_valid(struct vcpu_svm *svm)
 	case SVM_VMGEXIT_MMIO_WRITE:
 	case SVM_VMGEXIT_PSC:
 		return kvm_ghcb_sw_scratch_is_valid(svm);
+	case SVM_VMGEXIT_SAVIC:
+		if (!kvm_ghcb_rax_is_valid(svm) ||
+		    (control->exit_info_1 == SVM_VMGEXIT_SAVIC_REGISTER_GPA &&
+		     !kvm_ghcb_rbx_is_valid(svm)))
+			return false;
+
+		return true;
 	default:
 		return true;
 	}
@@ -4420,6 +4427,57 @@ static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm)
 	return 0;
 }
 
+static int sev_handle_savic_vmgexit(struct vcpu_svm *svm)
+{
+	struct kvm_vcpu *target_vcpu;
+	u64 apic_id;
+	gpa_t gpa;
+
+	apic_id = kvm_rax_read_raw(&svm->vcpu);
+	if (apic_id != SVM_VMGEXIT_SAVIC_SELF_GPA && upper_32_bits(apic_id))
+		goto vmgexit_err;
+
+	/* Use invoking vCPU if apic_id is -1 (SVM_VMGEXIT_SAVIC_SELF_GPA) */
+	target_vcpu = &svm->vcpu;
+	if (apic_id != SVM_VMGEXIT_SAVIC_SELF_GPA) {
+		target_vcpu = kvm_get_vcpu_by_id(svm->vcpu.kvm, (int)apic_id);
+		if (!target_vcpu)
+			goto vmgexit_err;
+	}
+
+	switch (svm->vmcb->control.exit_info_1) {
+	case SVM_VMGEXIT_SAVIC_REGISTER_GPA:
+		gpa = kvm_rbx_read_raw(&svm->vcpu);
+		if (!PAGE_ALIGNED(gpa))
+			goto vmgexit_err;
+
+		/*
+		 * TODO: Ensure that guest (Secure AVIC hardware) accesses
+		 * to the guest APIC backing page can never cause an #NPF.
+		 */
+
+		/*
+		 * Don't bother using any synchronization here if updating the
+		 * GPA for a different vCPU. If the guest is invoking this for
+		 * a specific vCPU in parallel, then it gets to keep the pieces.
+		 */
+		to_svm(target_vcpu)->snp_savic_gpa = gpa;
+		break;
+	case SVM_VMGEXIT_SAVIC_UNREGISTER_GPA:
+		kvm_rbx_write_raw(&svm->vcpu, to_svm(target_vcpu)->snp_savic_gpa);
+		to_svm(target_vcpu)->snp_savic_gpa = 0;
+		break;
+	default:
+		goto vmgexit_err;
+	}
+
+	return 1;
+
+vmgexit_err:
+	svm_vmgexit_bad_input(svm, GHCB_ERR_INVALID_INPUT);
+	return 1;
+}
+
 static bool is_snp_only_vmgexit(u64 exit_code)
 {
 	switch (exit_code) {
@@ -4427,6 +4485,7 @@ static bool is_snp_only_vmgexit(u64 exit_code)
 	case SVM_VMGEXIT_GUEST_REQUEST:
 	case SVM_VMGEXIT_EXT_GUEST_REQUEST:
 	case SVM_VMGEXIT_PSC:
+	case SVM_VMGEXIT_SAVIC:
 		return true;
 	default:
 		return false;
@@ -4490,6 +4549,13 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
 		return 1;
 	}
 
+	if (control->exit_code == SVM_VMGEXIT_SAVIC && !snp_is_secure_avic_enabled(vcpu->kvm)) {
+		vcpu_unimpl(vcpu, "vmgexit: exit code %#llx is only valid if Secure AVIC is enabled\n",
+			    control->exit_code);
+		svm_vmgexit_bad_input(svm, GHCB_ERR_INVALID_EVENT);
+		return 1;
+	}
+
 	if (!sev_es_are_required_ghcb_fields_valid(svm)) {
 		/*
 		 * Print the exit code even though it may not be marked valid
@@ -4610,6 +4676,8 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
 
 		return snp_handle_ext_guest_req(svm, control->exit_info_1,
 						control->exit_info_2);
+	case SVM_VMGEXIT_SAVIC:
+		return sev_handle_savic_vmgexit(svm);
 	case SVM_VMGEXIT_UNSUPPORTED_EVENT:
 		/*
 		 * Note, the _guest_ is reporting an unsupported #VC, i.e. this
-- 
2.54.0


  parent reply	other threads:[~2026-07-08  6:34 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-08  6:31 [RFC PATCH v3 00/27] KVM: SVM: Add support for SEV-SNP Secure AVIC Naveen N Rao (AMD)
2026-07-08  6:31 ` [RFC PATCH v3 01/27] x86/apic: Propagate APIC_SPIV writes to hv for " Naveen N Rao (AMD)
2026-07-10  2:03   ` Borislav Petkov
2026-07-10 15:02     ` Naveen N Rao
2026-07-11  4:37       ` Borislav Petkov
2026-07-13 17:38       ` Tom Lendacky
2026-07-14  8:57         ` Naveen N Rao
2026-07-08  6:32 ` [RFC PATCH v3 02/27] x86/apic: Drop savic_eoi() in favor of native_apic_msr_eoi() " Naveen N Rao (AMD)
2026-07-13 17:43   ` Tom Lendacky
2026-07-14  9:02     ` Naveen N Rao
2026-10-06  6:16       ` Sean Christopherson
2026-10-06  3:20   ` Borislav Petkov
2026-07-08  6:32 ` [RFC PATCH v3 03/27] x86/kvm: Disable PV_SEND_IPI if Secure AVIC is enabled Naveen N Rao (AMD)
2026-07-13 17:52   ` Tom Lendacky
2026-07-14  9:42     ` Naveen N Rao
2026-07-08  6:32 ` [RFC PATCH v3 04/27] x86/apic: Use AVIC_INCOMPLETE_IPI VMGEXIT for Secure AVIC IPI handling Naveen N Rao (AMD)
2026-07-13 17:59   ` Tom Lendacky
2026-07-14 10:03     ` Naveen N Rao
2026-07-08  6:32 ` [RFC PATCH v3 05/27] x86/cpufeatures: Add Secure AVIC CPU feature Naveen N Rao (AMD)
2026-07-13 18:32   ` Tom Lendacky
2026-07-08  6:32 ` [RFC PATCH v3 06/27] KVM: SVM: Add helper to check if Secure AVIC is enabled for a guest Naveen N Rao (AMD)
2026-07-13 18:35   ` Tom Lendacky
2026-07-08  6:32 ` [RFC PATCH v3 07/27] KVM: SVM: Set guest_apic_protected if Secure AVIC is enabled Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 08/27] kvm: irqfd: Have kvm_arch_has_irq_bypass() take struct kvm pointer Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 09/27] KVM: SVM: Disable IRQ bypass for Secure AVIC Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 10/27] KVM: SVM: Add avic_ipiv_is_soft_disabled() as a wrapper around enable_ipiv Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 11/27] KVM: SVM: Disable IPIv for Secure AVIC Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 12/27] KVM: SVM: Short-circuit a few AVIC flows " Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 13/27] KVM: SVM: Warn if we ever receive AVIC_UNACCELERATED_ACCESS #VMEXIT Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 14/27] KVM: SVM: Do not inhibit AVIC for SEV-SNP guests if Secure AVIC is enabled Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 15/27] KVM: SVM: Set VGIF in VMSA area for Secure AVIC guests Naveen N Rao (AMD)
2026-07-08  6:32 ` Naveen N Rao (AMD) [this message]
2026-08-26 16:09   ` [RFC PATCH v3 16/27] KVM: SVM: Add handler for VMGEXIT Secure AVIC NAE event Sean Christopherson
2026-09-22 15:01     ` Naveen N Rao
2026-09-30 14:43       ` Naveen N Rao
2026-09-30 15:45         ` Sean Christopherson
2026-09-30 19:54           ` Naveen N Rao
2026-07-08  6:32 ` [RFC PATCH v3 17/27] KVM: SVM: Do not intercept SECURE_AVIC_CONTROL MSR for Secure AVIC guests Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 18/27] KVM: x86: Add a new kvm_x86_op protected_apic_has_injectable_intr() Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 19/27] KVM: SVM: Implement kvm_x86_ops->protected_apic_has_injectable_intr() for Secure AVIC Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 20/27] KVM: SVM: Implement kvm_x86_ops->protected_apic_has_interrupt() " Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 21/27] KVM: SVM: Add interrupt delivery support for Secure AVIC guests Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 22/27] KVM: SVM: Add support for incomplete IPI handling for Secure AVIC Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 23/27] KVM: SVM: Add support for injecting NMIs for Secure AVIC guests Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 24/27] KVM: SVM: Mandate use of split irqchip for Secure AVIC Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 25/27] KVM: SVM: Do not inject exceptions " Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 26/27] KVM: SVM: Do not intercept exceptions for Secure AVIC guests Naveen N Rao (AMD)
2026-07-08  6:32 ` [RFC PATCH v3 27/27] KVM: SVM: Advertise Secure AVIC support for SEV-SNP guests Naveen N Rao (AMD)
2026-07-08  9:20 ` [RFC PATCH v3 00/27] KVM: SVM: Add support for SEV-SNP Secure AVIC Naveen N Rao

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=c0f9fdc27f3d9a1e63f2d39a40989d66b6facee3.1783490022.git.naveen@kernel.org \
    --to=naveen@kernel.org \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=neeraj.upadhyay@amd.com \
    --cc=nikunj@amd.com \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=tglx@kernel.org \
    --cc=thomas.lendacky@amd.com \
    --cc=tiala@microsoft.com \
    /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

all inboxes | Powered by JetHome®