From: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
To: <seanjc@google.com>, <pbonzini@redhat.com>, <kvm@vger.kernel.org>
Cc: <linux-kernel@vger.kernel.org>, <bp@alien8.de>,
<tglx@linutronix.de>, <mingo@redhat.com>,
<dave.hansen@linux.intel.com>, <Thomas.Lendacky@amd.com>,
<nikunj@amd.com>, <Santosh.Shukla@amd.com>,
<Vasant.Hegde@amd.com>, <Suravee.Suthikulpanit@amd.com>,
<David.Kaplan@amd.com>, <x86@kernel.org>, <hpa@zytor.com>,
<peterz@infradead.org>, <huibo.wang@amd.com>,
<naveen.rao@amd.com>, <binbin.wu@linux.intel.com>,
<isaku.yamahata@intel.com>
Subject: [RFC PATCH 14/19] KVM: SVM/SEV: Add SVM_VMGEXIT_SECURE_AVIC GHCB protocol event handling
Date: Fri, 28 Feb 2025 14:21:10 +0530 [thread overview]
Message-ID: <20250228085115.105648-15-Neeraj.Upadhyay@amd.com> (raw)
In-Reply-To: <20250228085115.105648-1-Neeraj.Upadhyay@amd.com>
This GHCB protocol event is used by the guest to notify KVM
of the GPA of the APIC backing page being used by a vCPU. The APIC ID
parameter is used to identify the vCPU to which the backing page
action is related is assigned. An APIC ID value of 0xffff_ffff_ffff_ffff
means that the backing page action is for the vCPU performing the call.
Secure AVIC requires the guest vCPU APIC backing page entry to be
always present in the guest’s Nested Paginge Table (NPT) while the
vCPU is running because some AVIC hardware acceleration sequences
may not be restartable when Secure AVIC is enabled. If an access to
the guest's APIC backing page by Secure AVIC hardware results in a
nested page fault, the BUSY bit in the VMSA is set and subsequent
VMRUN fails with a VMEXIT_BUSY error code. VMEXIT_BUSY is unrecoverable
in this instance and the vCPU cannot be resumed post this event.
Two actions are available to the guest to notify KVM of these pages.
• SVM_VMGEXIT_SAVIC_REGISTER_BACKING_PAGE (0)
A Secure AVIC guest should use this action to inform KVM of the
page-aligned GPA that will be used as the Secure AVIC backing
page for the specified vCPU.
To ensure that the backing page NPT entry is present while vCPU is
running, KVM does a PSMASH for the GPA if the corresponding NPT entry
is of size 2M. Without PSMASH, it is possible for other allocations
to be part of the same 2M page as the APIC backing page and any
modifications (page state change from private to shared) to any one
of those allocations would result in splitting the 2M page to 4K pages.
This would result in zapping the 2M PTE while APIC backing page is
potentially being accessed by Secure AVIC hardware.
Setting a Secure AVIC backing page GPA automatically clears any
currently set Secure AVIC backing page GPA.
• SVM_VMGEXIT_SAVIC_UNREGISTER_BACKING_PAGE (1)
A guest may use this action to inform KVM that the previously set
GPA is no longer being used as the Secure AVIC backing page for
the specified vCPU. This removes the requirement on KVM to ensure
that the specified GPA is always present in the NPT of the guest
while the specified vCPU is running. KVM returns the GPA that was
currently SET or 0 if there was no previously set GPA.
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>
---
Initial GHCB draft spec for the new GHCB event for Secure AVIC is at:
https://lore.kernel.org/linux-coco/3453675d-ca29-4715-9c17-10b56b3af17e@amd.com/T/#u
The GHCB event has been updated to pass the action param
for GPA register/unregister. The new GHCB spec will be published soon.
I will share the link to the updated spec once it is available
publically.
arch/x86/include/uapi/asm/svm.h | 3 ++
arch/x86/kvm/svm/sev.c | 58 +++++++++++++++++++++++++++++++++
arch/x86/kvm/svm/svm.h | 1 +
3 files changed, 62 insertions(+)
diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h
index ec1321248dac..0a1e8687f464 100644
--- a/arch/x86/include/uapi/asm/svm.h
+++ b/arch/x86/include/uapi/asm/svm.h
@@ -117,6 +117,9 @@
#define SVM_VMGEXIT_AP_CREATE 1
#define SVM_VMGEXIT_AP_DESTROY 2
#define SVM_VMGEXIT_SNP_RUN_VMPL 0x80000018
+#define SVM_VMGEXIT_SECURE_AVIC 0x8000001a
+#define SVM_VMGEXIT_SAVIC_REGISTER_BACKING_PAGE 0
+#define SVM_VMGEXIT_SAVIC_UNREGISTER_BACKING_PAGE 1
#define SVM_VMGEXIT_HV_FEATURES 0x8000fffd
#define SVM_VMGEXIT_TERM_REQUEST 0x8000fffe
#define SVM_VMGEXIT_TERM_REASON(reason_set, reason_code) \
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 40314c4086c2..77c1ecebf677 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -3400,6 +3400,14 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
!kvm_ghcb_rcx_is_valid(svm))
goto vmgexit_err;
break;
+ case SVM_VMGEXIT_SECURE_AVIC:
+ if (!sev_savic_active(vcpu->kvm) ||
+ !kvm_ghcb_rax_is_valid(svm))
+ goto vmgexit_err;
+ if (svm->vmcb->control.exit_info_1 == SVM_VMGEXIT_SAVIC_REGISTER_BACKING_PAGE)
+ if (!kvm_ghcb_rbx_is_valid(svm))
+ goto vmgexit_err;
+ break;
case SVM_VMGEXIT_MMIO_READ:
case SVM_VMGEXIT_MMIO_WRITE:
if (!kvm_ghcb_sw_scratch_is_valid(svm))
@@ -4511,6 +4519,53 @@ static bool savic_handle_msr_exit(struct kvm_vcpu *vcpu)
return false;
}
+static int sev_handle_savic_vmgexit(struct vcpu_svm *svm)
+{
+ struct kvm_vcpu *vcpu = NULL;
+ u64 apic_id;
+
+ apic_id = kvm_rax_read(&svm->vcpu);
+
+ if (apic_id == -1ULL) {
+ vcpu = &svm->vcpu;
+ } else {
+ vcpu = kvm_get_vcpu_by_id(vcpu->kvm, apic_id);
+ if (!vcpu)
+ goto savic_request_invalid;
+ }
+
+ switch (svm->vmcb->control.exit_info_1) {
+ case SVM_VMGEXIT_SAVIC_REGISTER_BACKING_PAGE:
+ gpa_t gpa;
+
+ gpa = kvm_rbx_read(&svm->vcpu);
+ if (!PAGE_ALIGNED(gpa))
+ goto savic_request_invalid;
+
+ /*
+ * sev_handle_rmp_fault() invocation would result in PSMASH if
+ * NPTE size is 2M.
+ */
+ sev_handle_rmp_fault(vcpu, gpa, 0);
+ to_svm(vcpu)->sev_savic_gpa = gpa;
+ break;
+ case SVM_VMGEXIT_SAVIC_UNREGISTER_BACKING_PAGE:
+ kvm_rbx_write(&svm->vcpu, to_svm(vcpu)->sev_savic_gpa);
+ to_svm(vcpu)->sev_savic_gpa = 0;
+ break;
+ default:
+ goto savic_request_invalid;
+ }
+
+ return 1;
+
+savic_request_invalid:
+ ghcb_set_sw_exit_info_1(svm->sev_es.ghcb, 2);
+ ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, GHCB_ERR_INVALID_INPUT);
+
+ return 1;
+}
+
int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
@@ -4653,6 +4708,9 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
control->exit_info_1, control->exit_info_2);
ret = -EINVAL;
break;
+ case SVM_VMGEXIT_SECURE_AVIC:
+ ret = sev_handle_savic_vmgexit(svm);
+ break;
case SVM_EXIT_MSR:
if (sev_savic_active(vcpu->kvm) && savic_handle_msr_exit(vcpu))
return 1;
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 62e3581b7d31..be87b9a0284f 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -329,6 +329,7 @@ struct vcpu_svm {
bool guest_gif;
bool sev_savic_has_pending_ipi;
+ gpa_t sev_savic_gpa;
};
struct svm_cpu_data {
--
2.34.1
next prev parent reply other threads:[~2025-02-28 9:18 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-28 8:50 [RFC PATCH 00/19] AMD: Add Secure AVIC KVM Support Neeraj Upadhyay
2025-02-28 8:50 ` [RFC PATCH 01/19] KVM: TDX: Add support for find pending IRQ in a protected local APIC Neeraj Upadhyay
2025-02-28 8:50 ` [RFC PATCH 02/19] KVM: x86: Assume timer IRQ was injected if APIC state is protected Neeraj Upadhyay
2025-02-28 8:50 ` [RFC PATCH 03/19] KVM: x86: Convert guest_apic_protected bool to an enum type Neeraj Upadhyay
2025-02-28 8:51 ` [RFC PATCH 04/19] x86/cpufeatures: Add Secure AVIC CPU Feature Neeraj Upadhyay
2025-02-28 8:51 ` [RFC PATCH 05/19] KVM: SVM: Add support for Secure AVIC capability in KVM Neeraj Upadhyay
2025-02-28 8:51 ` [RFC PATCH 06/19] KVM: SVM: Initialize apic protected state for SAVIC guests Neeraj Upadhyay
2025-02-28 8:51 ` [RFC PATCH 07/19] KVM: SEV: Do not intercept SECURE_AVIC_CONTROL MSR Neeraj Upadhyay
2025-02-28 8:51 ` [RFC PATCH 08/19] KVM: SVM/SEV/X86: Secure AVIC: Add support to inject interrupts Neeraj Upadhyay
2025-02-28 8:51 ` [RFC PATCH 09/19] KVM: SVM/SEV/X86: Secure AVIC: Add hypervisor side IPI Delivery Support Neeraj Upadhyay
2025-02-28 8:51 ` [RFC PATCH 10/19] KVM: SVM: Secure AVIC: Do not inject "Exceptions" for Secure AVIC Neeraj Upadhyay
2025-02-28 8:51 ` [RFC PATCH 11/19] KVM: SVM/SEV: Do not intercept exceptions for Secure AVIC guest Neeraj Upadhyay
2025-02-28 8:51 ` [RFC PATCH 12/19] KVM: SVM/SEV: Secure AVIC: Set VGIF in VMSA area Neeraj Upadhyay
2025-02-28 8:51 ` [RFC PATCH 13/19] KVM: SVM/SEV: Secure AVIC: Enable NMI support Neeraj Upadhyay
2025-02-28 8:51 ` Neeraj Upadhyay [this message]
2025-02-28 8:51 ` [RFC PATCH 15/19] KVM: x86: Secure AVIC: Indicate APIC is enabled by guest SW _always_ Neeraj Upadhyay
2025-02-28 8:51 ` [RFC PATCH 16/19] KVM: x86: Secure AVIC: Add IOAPIC EOI support for level interrupts Neeraj Upadhyay
2025-02-28 8:51 ` [RFC PATCH 17/19] KVM: x86/ioapic: Disable RTC_GSI EOI tracking for protected APIC Neeraj Upadhyay
2025-02-28 8:51 ` [RFC PATCH 18/19] X86: SVM: Check injected vectors before waiting for timer expiry Neeraj Upadhyay
2025-02-28 8:51 ` [RFC PATCH 19/19] KVM: SVM/SEV: Allow creating VMs with Secure AVIC enabled Neeraj Upadhyay
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=20250228085115.105648-15-Neeraj.Upadhyay@amd.com \
--to=neeraj.upadhyay@amd.com \
--cc=David.Kaplan@amd.com \
--cc=Santosh.Shukla@amd.com \
--cc=Suravee.Suthikulpanit@amd.com \
--cc=Thomas.Lendacky@amd.com \
--cc=Vasant.Hegde@amd.com \
--cc=binbin.wu@linux.intel.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=huibo.wang@amd.com \
--cc=isaku.yamahata@intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=naveen.rao@amd.com \
--cc=nikunj@amd.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=seanjc@google.com \
--cc=tglx@linutronix.de \
--cc=x86@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
all inboxes | Powered by JetHome®