From: "Jörg Rödel" <joro@8bytes.org>
To: Paolo Bonzini <pbonzini@redhat.com>,
Sean Christopherson <seanjc@google.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>,
ashish.kalra@amd.com, michael.roth@amd.com, nsaenz@amazon.com,
anelkz@amazon.de, James.Bottomley@HansenPartnership.com,
Melody Wang <huibo.wang@amd.com>,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
kvmarm@lists.linux.dev, loongarch@lists.linux.dev,
linux-mips@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
kvm-riscv@lists.infradead.org, x86@kernel.org,
coconut-svsm@lists.linux.dev, joerg.roedel@amd.com
Subject: [PATCH 57/60] kvm: sev: Allow for VMPL level specification in AP create
Date: Mon, 8 Jun 2026 16:42:49 +0200 [thread overview]
Message-ID: <20260608144252.351443-58-joro@8bytes.org> (raw)
In-Reply-To: <20260608144252.351443-1-joro@8bytes.org>
From: Tom Lendacky <thomas.lendacky@amd.com>
Update AP creation to support ADD/DESTROY of VMSAs at levels other than
VMPL0 in order to run under an SVSM at VMPL1 or lower. To maintain
backwards compatibility, the VMPL is specified in bits 16 to 19 of the
AP Creation request in SW_EXITINFO1 of the GHCB.
In order to track the VMSAs at different levels, create arrays for the
VMSAs, GHCBs, registered GHCBs and others. When switching VMPL levels,
these entries will be used to set the VMSA and GHCB physical addresses
in the VMCB for the VMPL level.
In order ensure that the proper responses are returned in the proper GHCB,
the GHCB must be unmapped at the current level and saved for restoration
later when switching back to that VMPL level.
Additional checks are applied to prevent a non-VMPL0 vCPU from being able
to perform an AP creation request at VMPL0. Additionally, a vCPU cannot
replace its own VMSA.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Co-developed-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/include/asm/svm.h | 9 +++
arch/x86/include/uapi/asm/svm.h | 2 +
arch/x86/kvm/svm/sev.c | 134 +++++++++++++++++++++++++-------
arch/x86/kvm/svm/svm.h | 1 +
arch/x86/kvm/x86.c | 9 +++
5 files changed, 126 insertions(+), 29 deletions(-)
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index 9822b0b346ae..32a35ee10bce 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -345,6 +345,15 @@ static_assert((X2AVIC_4K_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == X2AV
#define VMCB_ALLOWED_SEV_FEATURES_VALID BIT_ULL(63)
+enum {
+ SVM_SEV_VMPL0 = 0,
+ SVM_SEV_VMPL1,
+ SVM_SEV_VMPL2,
+ SVM_SEV_VMPL3,
+
+ SVM_SEV_VMPL_MAX
+};
+
struct vmcb_seg {
u16 selector;
u16 attrib;
diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h
index 91395b82eadd..60b7a52f6f7e 100644
--- a/arch/x86/include/uapi/asm/svm.h
+++ b/arch/x86/include/uapi/asm/svm.h
@@ -123,6 +123,8 @@
#define SVM_VMGEXIT_HVDB_QUERY 2
#define SVM_VMGEXIT_HVDB_CLEAR 3
#define SVM_VMGEXIT_HV_IPI 0x80000015ull
+#define SVM_VMGEXIT_AP_VMPL_MASK GENMASK(19, 16)
+#define SVM_VMGEXIT_AP_VMPL_SHIFT 16
#define SVM_VMGEXIT_GET_APIC_IDS 0x80000017ull
#define SVM_VMGEXIT_SNP_RUN_VMPL 0x80000018ull
#define SVM_VMGEXIT_SAVIC 0x8000001aull
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index c0b2879f8e9f..53cd3aba7368 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -3512,13 +3512,19 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm)
if (!kvm_ghcb_sw_scratch_is_valid(svm))
goto vmgexit_err;
break;
- case SVM_VMGEXIT_AP_CREATION:
+ case SVM_VMGEXIT_AP_CREATION: {
+ unsigned int request;
+
if (!is_sev_snp_guest(vcpu))
goto vmgexit_err;
- if (lower_32_bits(control->exit_info_1) != SVM_VMGEXIT_AP_DESTROY)
+
+ request = lower_32_bits(control->exit_info_1);
+ request &= ~SVM_VMGEXIT_AP_VMPL_MASK;
+ if (request != SVM_VMGEXIT_AP_DESTROY)
if (!kvm_ghcb_rax_is_valid(svm))
goto vmgexit_err;
break;
+ }
case SVM_VMGEXIT_GET_APIC_IDS:
if (!kvm_ghcb_rax_is_valid(svm))
goto vmgexit_err;
@@ -4151,8 +4157,26 @@ static void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu)
/* Use the new VMSA */
svm->vmcb->control.vmsa_pa = pfn_to_hpa(pfn);
+ /*
+ * The vCPU may not have gone through the LAUNCH_UPDATE process, so mark
+ * the guest state as protected.
+ */
+ vcpu->arch.guest_state_protected = true;
+
+ /*
+ * SEV-ES guest mandates LBR Virtualization to be _always_ ON. Enable it
+ * only after setting guest_state_protected because KVM_SET_MSRS allows
+ * dynamic toggling of LBRV (for performance reason) on write access to
+ * MSR_IA32_DEBUGCTLMSR when guest_state_protected is not set.
+ */
+ svm_enable_lbrv(vcpu);
+
/* Mark the vCPU as runnable */
- kvm_set_mp_state(vcpu, KVM_MP_STATE_RUNNABLE);
+ if (svm->sev_es.snp_ap_runnable) {
+ kvm_set_mp_state(vcpu, KVM_MP_STATE_RUNNABLE);
+ } else {
+ kvm_set_mp_state(vcpu, KVM_MP_STATE_UNINITIALIZED);
+ }
/*
* gmem pages aren't currently migratable, but if this ever changes
@@ -4162,36 +4186,87 @@ static void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu)
kvm_release_page_clean(page);
}
-static int sev_snp_ap_creation(struct vcpu_svm *svm)
+static unsigned int get_ap_creation_request(struct vcpu_svm *svm)
{
- struct kvm_sev_info_plane *sev_plane = to_kvm_sev_info_plane(svm->vcpu.plane);
- struct kvm_vcpu *vcpu = &svm->vcpu;
- struct kvm_vcpu *target_vcpu;
- struct vcpu_svm *target_svm;
- unsigned int request;
+// struct kvm_sev_info_plane *sev_plane = to_kvm_sev_info_plane(svm->vcpu.plane);
+// struct kvm_vcpu *vcpu = &svm->vcpu;
+ unsigned int req = lower_32_bits(svm->vmcb->control.exit_info_1);
+
+ return req & ~SVM_VMGEXIT_AP_VMPL_MASK;
+}
+
+static unsigned int get_ap_creation_vmpl(struct vcpu_svm *svm)
+{
+ unsigned int req = lower_32_bits(svm->vmcb->control.exit_info_1);
+
+ return (req & SVM_VMGEXIT_AP_VMPL_MASK) >> SVM_VMGEXIT_AP_VMPL_SHIFT;
+}
+
+static unsigned int get_ap_creation_apic_id(struct vcpu_svm *svm)
+{
+ return upper_32_bits(svm->vmcb->control.exit_info_1);
+}
+
+#define SVM_SEV_VMPL_MAX 4
+
+static int sev_snp_ap_creation(struct kvm_vcpu *vcpu)
+{
+ struct vcpu_svm *target_svm = NULL, *svm = to_svm(vcpu);
+ struct kvm_sev_info_plane *target_sev_plane = NULL;
+ struct kvm_plane *target_plane = NULL;
+ struct kvm_vcpu *target_vcpu = NULL;
unsigned int apic_id;
+ unsigned int request;
+ unsigned int vmpl;
- request = lower_32_bits(svm->vmcb->control.exit_info_1);
- apic_id = upper_32_bits(svm->vmcb->control.exit_info_1);
+ request = get_ap_creation_request(svm);
+ apic_id = get_ap_creation_apic_id(svm);
+ vmpl = get_ap_creation_vmpl(svm);
- /* Validate the APIC ID */
- target_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, apic_id);
- if (!target_vcpu) {
- vcpu_unimpl(vcpu, "vmgexit: invalid AP APIC ID [%#x] from guest\n",
- apic_id);
+ /* Validate the requested VMPL level */
+ if (vmpl >= SVM_SEV_VMPL_MAX) {
+ vcpu_unimpl(vcpu, "vmgexit: invalid VMPL level [%u] from guest\n",
+ vmpl);
return -EINVAL;
}
+ vmpl = array_index_nospec(vmpl, SVM_SEV_VMPL_MAX);
+
+ /* Obtain the target plane and vCPU */
+ target_plane = vcpu->kvm->planes[vmpl];
+ if (target_plane) {
+ target_vcpu = plane_get_vcpu(target_plane, apic_id);
+ } else {
+ target_vcpu = NULL;
+ }
+
+ /* Request user-space to create target plane VCPU if it does not exist */
+ if (!target_plane || !target_vcpu) {
+ vcpu->arch.complete_userspace_io = sev_snp_ap_creation;
+ return kvm_request_create_plane(vcpu, vmpl, apic_id);
+ }
target_svm = to_svm(target_vcpu);
+ target_sev_plane = &to_kvm_svm_plane(target_svm->vcpu.plane)->sev_info_plane;
guard(mutex)(&target_svm->sev_es.snp_vmsa_mutex);
+ /* VMPL0 can only be replaced by another vCPU running VMPL0 */
+ if (vmpl == SVM_SEV_VMPL0 &&
+ (vcpu == target_vcpu || vcpu->plane_level != SVM_SEV_VMPL0)) {
+ vcpu_unimpl(vcpu, "vmgexit: VMPL0 AP action not allowed\n");
+ return -EINVAL;
+ }
+
switch (request) {
case SVM_VMGEXIT_AP_CREATE_ON_INIT:
case SVM_VMGEXIT_AP_CREATE:
- if (vcpu->arch.regs[VCPU_REGS_RAX] != sev_plane->vmsa_features) {
+ /* Initialize target planes SEV features if necessary */
+ if (target_sev_plane->vmsa_features == 0)
+ target_sev_plane->vmsa_features = vcpu->arch.regs[VCPU_REGS_RAX];
+
+ if (vcpu->arch.regs[VCPU_REGS_RAX] != target_sev_plane->vmsa_features) {
vcpu_unimpl(vcpu, "vmgexit: mismatched AP sev_features [%#lx] != [%#llx] from guest\n",
- vcpu->arch.regs[VCPU_REGS_RAX], sev_plane->vmsa_features);
+ vcpu->arch.regs[VCPU_REGS_RAX], target_sev_plane->vmsa_features);
return -EINVAL;
}
@@ -4226,16 +4301,18 @@ static int sev_snp_ap_creation(struct vcpu_svm *svm)
return -EINVAL;
}
+ /* Signal the vCPU to update its state */
+ kvm_make_request(KVM_REQ_UPDATE_PROTECTED_GUEST_STATE, target_vcpu);
+
target_svm->sev_es.snp_ap_waiting_for_reset = true;
+ target_svm->sev_es.snp_ap_runnable = (request == SVM_VMGEXIT_AP_CREATE);
- /*
- * Unless Creation is deferred until INIT, signal the vCPU to update
- * its state.
- */
- if (request != SVM_VMGEXIT_AP_CREATE_ON_INIT)
- kvm_make_request_and_kick(KVM_REQ_UPDATE_PROTECTED_GUEST_STATE, target_vcpu);
+ if (request == SVM_VMGEXIT_AP_CREATE)
+ kvm_make_request(KVM_REQ_PLANE_RESCHED, target_vcpu);
- return 0;
+ kvm_vcpu_kick(target_vcpu);
+
+ return 1;
}
static int snp_handle_guest_req(struct vcpu_svm *svm, gpa_t req_gpa, gpa_t resp_gpa)
@@ -4779,12 +4856,11 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu)
ret = snp_begin_psc(svm);
break;
case SVM_VMGEXIT_AP_CREATION:
- ret = sev_snp_ap_creation(svm);
- if (ret) {
+ ret = sev_snp_ap_creation(vcpu);
+ if (ret < 0) {
svm_vmgexit_bad_input(svm, GHCB_ERR_INVALID_INPUT);
+ ret = 1;
}
-
- ret = 1;
break;
case SVM_VMGEXIT_GUEST_REQUEST:
ret = snp_handle_guest_req(svm, control->exit_info_1, control->exit_info_2);
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 57033922ddcf..7e860f2abafb 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -282,6 +282,7 @@ struct vcpu_sev_es_state {
struct mutex snp_vmsa_mutex; /* Used to handle concurrent updates of VMSA. */
gpa_t snp_vmsa_gpa;
+ bool snp_ap_runnable;
bool snp_ap_waiting_for_reset;
bool snp_has_guest_vmsa;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 0b9fa1059481..ad05350bb393 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -12165,6 +12165,15 @@ static int __kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
kvm_vcpu_block(vcpu);
kvm_vcpu_srcu_read_lock(vcpu);
+ /*
+ * It is possible that the vCPU has never run before. If the
+ * request is to update the protected guest state (AP Create),
+ * then ensure that the vCPU can now run.
+ */
+ if (kvm_test_request(KVM_REQ_UPDATE_PROTECTED_GUEST_STATE, vcpu) &&
+ vcpu->arch.mp_state == KVM_MP_STATE_UNINITIALIZED)
+ vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
+
if (kvm_apic_accept_events(vcpu) < 0) {
r = 0;
goto out;
--
2.53.0
next prev parent reply other threads:[~2026-06-08 14:54 UTC|newest]
Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-08 14:41 [PATCH 00/60] KVM Planes + SEV-SNP Support Jörg Rödel
2026-06-08 14:41 ` [PATCH 01/60] x86/sev: Define the #HV doorbell page structure Jörg Rödel
2026-06-08 14:41 ` [PATCH 02/60] KVM: SVM: Add support for the SEV-SNP #HV doorbell page NAE event Jörg Rödel
2026-06-08 14:41 ` [PATCH 03/60] KVM: SVM: Inject #HV when Restricted Injection is active Jörg Rödel
2026-06-08 14:41 ` [PATCH 04/60] KVM: SVM: Inject NMIs " Jörg Rödel
2026-06-08 14:41 ` [PATCH 05/60] KVM: SVM: Inject MCEs " Jörg Rödel
2026-06-08 14:41 ` [PATCH 06/60] KVM: SVM: Enable Restricted Injection for an SEV-SNP guest Jörg Rödel
2026-06-08 14:41 ` [PATCH 07/60] KVM: SVM: Add support for the SEV-SNP #HV IPI NAE event Jörg Rödel
2026-06-08 14:42 ` [PATCH 08/60] Documentation: kvm: introduce "VM plane" concept Jörg Rödel
2026-06-08 14:42 ` [PATCH 09/60] kvm: Introduce struct kvm_plane Jörg Rödel
2026-06-08 14:42 ` [PATCH 10/60] kvm: Move vcpu_array to " Jörg Rödel
2026-06-08 14:42 ` [PATCH 11/60] kvm: Introduce struct kvm_vcpu_common Jörg Rödel
2026-06-08 14:42 ` [PATCH 12/60] kvm: Move vcpu accounting to " Jörg Rödel
2026-06-08 14:42 ` [PATCH 13/60] kvm: Add read accessors for kvm_vcpu scheduling state Jörg Rödel
2026-06-08 14:42 ` [PATCH 14/60] kvm: Make kvm_running_vcpus point to struct kvm_vcpu_common Jörg Rödel
2026-06-08 14:42 ` [PATCH 15/60] kvm: Move VCPU scheduling state " Jörg Rödel
2026-06-08 14:42 ` [PATCH 16/60] kvm: Add accessors for kvm_vcpu->mutex Jörg Rödel
2026-06-08 14:42 ` [PATCH 17/60] kvm: Move VCPU locking to struct kvm_vcpu_common Jörg Rödel
2026-06-08 14:42 ` [PATCH 18/60] kvm: Move kvm_vcpu->rcuwait " Jörg Rödel
2026-06-08 14:42 ` [PATCH 19/60] kvm: Introduce accessors for kvm_vcpu->mode Jörg Rödel
2026-06-08 14:42 ` [PATCH 20/60] kvm: Move kvm_vcpu mode and requests field to struct kvm_vcpu_common Jörg Rödel
2026-06-08 14:42 ` [PATCH 21/60] kvm: Introduce per-plane VCPU requests Jörg Rödel
2026-06-08 14:42 ` [PATCH 22/60] kvm: Move kvm_vcpu pid members to struct kvm_vcpu_common Jörg Rödel
2026-06-08 14:42 ` [PATCH 23/60] kvm: Move kvm_vcpu sigset " Jörg Rödel
2026-06-08 14:42 ` [PATCH 24/60] kvm: Move kvm_vcpu spinloop " Jörg Rödel
2026-06-08 14:42 ` [PATCH 25/60] kvm: Move kvm_vcpu->dirty_ring " Jörg Rödel
2026-06-08 14:42 ` [PATCH 26/60] kvm: Introduce arch-specific plane state Jörg Rödel
2026-06-08 14:42 ` [PATCH 27/60] kvm: Introduce arch-specific part of struct kvm_vcpu_common Jörg Rödel
2026-06-08 14:42 ` [PATCH 28/60] kvm: Implement KVM_CAP_PLANES Jörg Rödel
2026-06-08 14:42 ` [PATCH 29/60] kvm: Implement KVM_CREATE_PLANE ioctl Jörg Rödel
2026-06-08 14:42 ` [PATCH 30/60] kvm: Add KVM_EXIT_PLANE_EVENT Jörg Rödel
2026-06-08 14:42 ` [PATCH 31/60] kvm: Allocate struct kvm_plane in architecture code Jörg Rödel
2026-06-08 14:42 ` [PATCH 32/60] kvm: Allocate struct kvm_run only for struct kvm_vcpu_common Jörg Rödel
2026-06-08 14:42 ` [PATCH 33/60] KVM: Implement KVM_CREATE_VCPU ioctl for planes Jörg Rödel
2026-06-08 14:42 ` [PATCH 34/60] kvm: Keep track of plane VCPUs in struct kvm_vcpu_common Jörg Rödel
2026-06-08 14:42 ` [PATCH 35/60] kvm: Add VCPU plane-scheduling state and helpers Jörg Rödel
2026-06-08 16:47 ` Paolo Bonzini
2026-06-08 17:52 ` Jörg Rödel
2026-06-08 17:58 ` Paolo Bonzini
2026-06-08 14:42 ` [PATCH 36/60] kvm: Add plane_level to kvm_kernel_irq_routing_entry Jörg Rödel
2026-06-08 14:42 ` [PATCH 37/60] kvm: Pass plane_level to kvm_set_routing_entry() Jörg Rödel
2026-06-08 14:42 ` [PATCH 38/60] kvm: Make KVM_SIGNAL_MSI per plane Jörg Rödel
2026-06-08 14:42 ` [PATCH 39/60] kvm: Make KVM_SET_GSI_ROUTING " Jörg Rödel
2026-06-08 14:42 ` [PATCH 40/60] kvm: x86: Handle IOAPIC EOIs " Jörg Rödel
2026-06-08 14:42 ` [PATCH 41/60] kvm: x86: Make apic_map " Jörg Rödel
2026-06-08 14:42 ` [PATCH 42/60] kvm: x86: Make local APIC code aware of planes Jörg Rödel
2026-06-08 14:42 ` [PATCH 43/60] kvm: x86: Move CPUID state to struct kvm_vcpu_arch_common Jörg Rödel
2026-06-08 14:42 ` [PATCH 44/60] kvm: x86: Move cpu_caps " Jörg Rödel
2026-06-08 14:42 ` [PATCH 45/60] kvm: x86: Update state for all plane VCPUs after CPUID update Jörg Rödel
2026-06-08 14:42 ` [PATCH 46/60] kvm: x86: Share MTRR state across planes Jörg Rödel
2026-06-08 14:42 ` [PATCH 47/60] kvm: x86: Select a plane to run Jörg Rödel
2026-06-08 14:42 ` [PATCH 48/60] kvm: x86: Make event injection VCPU requests per-plane Jörg Rödel
2026-06-08 14:42 ` [PATCH 49/60] kvm: x86: Allow hardware backend to overwrite struct kvm_plane allocation Jörg Rödel
2026-06-08 14:42 ` [PATCH 50/60] kvm: x86: Make KVM_REQ_UPDATE_PROTECTED_GUEST_STATE per plane Jörg Rödel
2026-06-08 14:42 ` [PATCH 51/60] kvm: x86: Share pio_data across planes Jörg Rödel
2026-06-08 14:42 ` [PATCH 52/60] kvm: x86: Switch to plane0 if it has events Jörg Rödel
2026-06-08 14:42 ` [PATCH 53/60] kvm: x86: Introduce max_planes x86-op Jörg Rödel
2026-06-08 14:42 ` [PATCH 54/60] kvm: x86: Restrict KVM planes support to KVM_IRQCHIP_SPLIT Jörg Rödel
2026-06-08 14:42 ` [PATCH 55/60] kvm: svm: Track vmsa_features per plane Jörg Rödel
2026-06-08 14:42 ` [PATCH 56/60] kvm: svm: Implement GET_AP_APIC_IDS NAE event Jörg Rödel
2026-06-08 14:42 ` Jörg Rödel [this message]
2026-06-08 14:42 ` [PATCH 58/60] kvm: svm: Invoke a specified VMPL level VMSA for the vCPU Jörg Rödel
2026-06-08 14:42 ` [PATCH 59/60] kvm: svm: Implement max_planes x86 operation Jörg Rödel
2026-06-08 14:42 ` [PATCH 60/60] kvm: svm: Advertise full multi-VMPL support to the SNP guest Jörg Rödel
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=20260608144252.351443-58-joro@8bytes.org \
--to=joro@8bytes.org \
--cc=James.Bottomley@HansenPartnership.com \
--cc=anelkz@amazon.de \
--cc=ashish.kalra@amd.com \
--cc=coconut-svsm@lists.linux.dev \
--cc=huibo.wang@amd.com \
--cc=joerg.roedel@amd.com \
--cc=kvm-riscv@lists.infradead.org \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mips@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=loongarch@lists.linux.dev \
--cc=michael.roth@amd.com \
--cc=nsaenz@amazon.com \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
--cc=thomas.lendacky@amd.com \
--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