* [PATCH 0/7] Alternate Injection: Secure Interrupt Delivery for SEV-SNP Guests - Guest Support
@ 2026-07-30 1:48 Melody Wang
2026-07-30 1:48 ` [PATCH 1/7] x86/sev: Add support for Alternate Injection Melody Wang
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Melody Wang @ 2026-07-30 1:48 UTC (permalink / raw)
To: x86; +Cc: LKML, Tom Lendacky, Melody Wang
Alternate Injection is a method to provide secure interrupt delivery for
SEV-SNP guests against malicious injection attacks. By handing over the
control of the interrupt injection to the guest itself, the security is
applied. Alternate Injection use Secure VM Service Module (SVSM), and APIC
emulation in the SVSM to secure interrupt delivery.
This is the guest side patches. The patch set includes the following:
1. Add support for enabling Alternate Injection.
2. Add support for the SVSM APIC protocol which uses a subset of the
X2APIC MSRs.
3. Add support to allow the guest OS to request Alternate
Injection.
Thanks,
Melody
Melody Wang (7):
x86/sev: Add support for Alternate Injection
x86/apic: Add an SVSM APIC driver
x86/sev: Allow the guest to configure interrupt vectors for the
hypervisor
x86/sev: Route unsupported APIC register accesses to the hypervisor
APIC emulation
x86/sev: Add a function to contain all SEV-specific setup operations
x86/sev: Register the guest with the SVSM APIC protocol
x86/sev: Indicate that Alternate Injection is supported in the guest
arch/x86/Kconfig | 14 ++
arch/x86/boot/compressed/sev.c | 37 +++-
arch/x86/boot/compressed/sev.h | 6 +
arch/x86/boot/startup/sev-startup.c | 15 ++
arch/x86/boot/startup/sme.c | 3 +
arch/x86/coco/core.c | 3 +
arch/x86/coco/sev/core.c | 14 +-
arch/x86/coco/sev/svsm.c | 6 +
arch/x86/include/asm/cpufeatures.h | 1 +
arch/x86/include/asm/msr-index.h | 4 +-
arch/x86/include/asm/sev-common.h | 1 +
arch/x86/include/asm/sev.h | 29 ++-
arch/x86/kernel/apic/Makefile | 1 +
arch/x86/kernel/apic/svsm_apic.c | 255 ++++++++++++++++++++++++
arch/x86/kernel/apic/x2apic_savic.c | 8 +-
drivers/firmware/efi/libstub/x86-stub.c | 20 +-
include/linux/cc_platform.h | 8 +
17 files changed, 392 insertions(+), 33 deletions(-)
create mode 100644 arch/x86/kernel/apic/svsm_apic.c
--
2.43.0
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/7] x86/sev: Add support for Alternate Injection
2026-07-30 1:48 [PATCH 0/7] Alternate Injection: Secure Interrupt Delivery for SEV-SNP Guests - Guest Support Melody Wang
@ 2026-07-30 1:48 ` Melody Wang
2026-07-30 1:48 ` [PATCH 2/7] x86/apic: Add an SVSM APIC driver Melody Wang
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Melody Wang @ 2026-07-30 1:48 UTC (permalink / raw)
To: x86; +Cc: LKML, Tom Lendacky, Melody Wang
The Alternate Injection feature is a method to protect an AMD
confidential computing guest from malicious injection attacks. It allows
the guest to control the interrupt injection.
When this feature is enabled, interrupts are injected with the help of
an agent called a Secure VM Service Module (SVSM) which executes in the
security realm of the guest and uses Restricted Injection as the sole
method to receive interrupts from the hypervisor.
Add support for Alternate Injection enablement.
Signed-off-by: Melody Wang <huibo.wang@amd.com>
---
arch/x86/Kconfig | 14 ++++++++++++++
arch/x86/boot/compressed/sev.c | 2 +-
arch/x86/coco/core.c | 3 +++
arch/x86/coco/sev/core.c | 2 +-
arch/x86/include/asm/cpufeatures.h | 1 +
arch/x86/include/asm/msr-index.h | 4 ++--
include/linux/cc_platform.h | 8 ++++++++
7 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index e725b439d0a2..7ec5d2c4a8f0 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -493,6 +493,20 @@ config AMD_SECURE_AVIC
If you don't know what to do here, say N.
+config AMD_ALTERNATE_INJ
+ bool "Support Alternate Injection"
+ depends on X86_X2APIC && AMD_MEM_ENCRYPT
+ help
+ Enable AMD Alternate Injection support for SNP guests.
+
+ The Alternate Injection feature of SEV-SNP enhances the security of
+ a confidential VM by preventing the untrusted host from presenting
+ unexpected interrupts or exceptions, while still preserving the
+ standard interrupt dispatch semantics inherent to the x86
+ architecture.
+
+ If you don't know what to do here, say N.
+
config X86_POSTED_MSI
bool "Enable MSI and MSI-x delivery by posted interrupts"
depends on X86_64 && IRQ_REMAP
diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c
index c6512f2ea31e..fc2029746c50 100644
--- a/arch/x86/boot/compressed/sev.c
+++ b/arch/x86/boot/compressed/sev.c
@@ -179,7 +179,7 @@ bool sev_es_check_ghcb_fault(unsigned long address)
#define SNP_FEATURES_IMPL_REQ (MSR_AMD64_SNP_VTOM | \
MSR_AMD64_SNP_REFLECT_VC | \
MSR_AMD64_SNP_RESTRICTED_INJ | \
- MSR_AMD64_SNP_ALT_INJ | \
+ MSR_AMD64_SNP_ALTERNATE_INJ | \
MSR_AMD64_SNP_DEBUG_SWAP | \
MSR_AMD64_SNP_VMPL_SSS | \
MSR_AMD64_SNP_SECURE_TSC | \
diff --git a/arch/x86/coco/core.c b/arch/x86/coco/core.c
index 989ca9f72ba3..aabda3ddc0e2 100644
--- a/arch/x86/coco/core.c
+++ b/arch/x86/coco/core.c
@@ -107,6 +107,9 @@ static bool noinstr amd_cc_platform_has(enum cc_attr attr)
case CC_ATTR_SNP_SECURE_AVIC:
return sev_status & MSR_AMD64_SNP_SECURE_AVIC;
+ case CC_ATTR_SNP_ALTERNATE_INJECTION:
+ return sev_status & MSR_AMD64_SNP_ALTERNATE_INJ;
+
default:
return false;
}
diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
index ecd77d3217f3..197119807230 100644
--- a/arch/x86/coco/sev/core.c
+++ b/arch/x86/coco/sev/core.c
@@ -78,7 +78,7 @@ static const char * const sev_status_feat_names[] = {
[MSR_AMD64_SNP_VTOM_BIT] = "vTom",
[MSR_AMD64_SNP_REFLECT_VC_BIT] = "ReflectVC",
[MSR_AMD64_SNP_RESTRICTED_INJ_BIT] = "RI",
- [MSR_AMD64_SNP_ALT_INJ_BIT] = "AI",
+ [MSR_AMD64_SNP_ALTERNATE_INJ_BIT] = "AI",
[MSR_AMD64_SNP_DEBUG_SWAP_BIT] = "DebugSwap",
[MSR_AMD64_SNP_PREVENT_HOST_IBS_BIT] = "NoHostIBS",
[MSR_AMD64_SNP_BTB_ISOLATION_BIT] = "BTBIsol",
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 3d0940a3b9f3..70dedbf0969f 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -454,6 +454,7 @@
#define X86_FEATURE_SNP_SECURE_TSC (19*32+ 8) /* SEV-SNP Secure TSC */
#define X86_FEATURE_V_TSC_AUX (19*32+ 9) /* Virtual TSC_AUX */
#define X86_FEATURE_SME_COHERENT (19*32+10) /* hardware-enforced cache coherency */
+#define X86_FEATURE_ALTERNATE_INJECTION (19*32+13) /* SEV Alternate Injection */
#define X86_FEATURE_DEBUG_SWAP (19*32+14) /* "debug_swap" SEV-ES full debug state swap support */
#define X86_FEATURE_RMPREAD (19*32+21) /* RMPREAD instruction */
#define X86_FEATURE_SEGMENTED_RMP (19*32+23) /* Segmented RMP support */
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 18c4be75e927..e4eab2210518 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -721,8 +721,8 @@
#define MSR_AMD64_SNP_REFLECT_VC BIT_ULL(MSR_AMD64_SNP_REFLECT_VC_BIT)
#define MSR_AMD64_SNP_RESTRICTED_INJ_BIT 5
#define MSR_AMD64_SNP_RESTRICTED_INJ BIT_ULL(MSR_AMD64_SNP_RESTRICTED_INJ_BIT)
-#define MSR_AMD64_SNP_ALT_INJ_BIT 6
-#define MSR_AMD64_SNP_ALT_INJ BIT_ULL(MSR_AMD64_SNP_ALT_INJ_BIT)
+#define MSR_AMD64_SNP_ALTERNATE_INJ_BIT 6
+#define MSR_AMD64_SNP_ALTERNATE_INJ BIT_ULL(MSR_AMD64_SNP_ALTERNATE_INJ_BIT)
#define MSR_AMD64_SNP_DEBUG_SWAP_BIT 7
#define MSR_AMD64_SNP_DEBUG_SWAP BIT_ULL(MSR_AMD64_SNP_DEBUG_SWAP_BIT)
#define MSR_AMD64_SNP_PREVENT_HOST_IBS_BIT 8
diff --git a/include/linux/cc_platform.h b/include/linux/cc_platform.h
index 559353ad64ac..90ef67e85cd3 100644
--- a/include/linux/cc_platform.h
+++ b/include/linux/cc_platform.h
@@ -104,6 +104,14 @@ enum cc_attr {
* to run SEV-SNP guests with full Secure AVIC capabilities.
*/
CC_ATTR_SNP_SECURE_AVIC,
+
+ /**
+ * @CC_ATTR_SNP_ALTERNATE_INJECTION: AMD Alternate Injection enabled on the host.
+ *
+ * The host kernel is running with the necessary features
+ * needed to run Alternate Injection enabled guests.
+ */
+ CC_ATTR_SNP_ALTERNATE_INJECTION,
};
#ifdef CONFIG_ARCH_HAS_CC_PLATFORM
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/7] x86/apic: Add an SVSM APIC driver
2026-07-30 1:48 [PATCH 0/7] Alternate Injection: Secure Interrupt Delivery for SEV-SNP Guests - Guest Support Melody Wang
2026-07-30 1:48 ` [PATCH 1/7] x86/sev: Add support for Alternate Injection Melody Wang
@ 2026-07-30 1:48 ` Melody Wang
2026-07-30 1:48 ` [PATCH 3/7] x86/sev: Allow the guest to configure interrupt vectors for the hypervisor Melody Wang
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Melody Wang @ 2026-07-30 1:48 UTC (permalink / raw)
To: x86; +Cc: LKML, Tom Lendacky, Melody Wang
The SVSM specification mandates the use of a SVSM APIC protocol instead
of any other APICs when an Alternate Injection guest talks to the SVSM.
Add such a SVSM APIC driver (which implements a subset of an X2APIC),
for the APIC emulation supported by the SVSM.
Signed-off-by: Melody Wang <huibo.wang@amd.com>
---
arch/x86/coco/sev/svsm.c | 6 +
arch/x86/include/asm/sev.h | 9 ++
arch/x86/kernel/apic/Makefile | 1 +
arch/x86/kernel/apic/svsm_apic.c | 252 +++++++++++++++++++++++++++++++
4 files changed, 268 insertions(+)
create mode 100644 arch/x86/kernel/apic/svsm_apic.c
diff --git a/arch/x86/coco/sev/svsm.c b/arch/x86/coco/sev/svsm.c
index 916d62cd17dc..e2d3bc3c26eb 100644
--- a/arch/x86/coco/sev/svsm.c
+++ b/arch/x86/coco/sev/svsm.c
@@ -354,3 +354,9 @@ bool snp_svsm_vtpm_probe(void)
/* Check platform commands contains TPM_SEND_COMMAND - platform command 8 */
return call.rcx_out & BIT_ULL(8);
}
+
+int svsm_do_call(struct svsm_call *call)
+{
+ call->caa = svsm_get_caa();
+ return svsm_perform_call_protocol(call);
+}
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index 594cfa19cbd4..f958f78e1db8 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -435,6 +435,13 @@ struct svsm_call {
#define SVSM_VTPM_QUERY 0
#define SVSM_VTPM_CMD 1
+#define SVSM_APIC_CALL(x) ((3ULL << 32) | (x))
+#define SVSM_APIC_QUERY_FEATURES 0
+#define SVSM_APIC_CONFIG_EMULATION 1
+#define SVSM_APIC_READ_REGISTER 2
+#define SVSM_APIC_WRITE_REGISTER 3
+#define SVSM_APIC_CONFIG_VECTOR 4
+
#ifdef CONFIG_AMD_MEM_ENCRYPT
extern u8 snp_vmpl;
@@ -519,6 +526,7 @@ u64 sev_get_status(void);
void sev_show_status(void);
int prepare_pte_enc(struct pte_enc_desc *d);
void set_pte_enc_mask(pte_t *kpte, unsigned long pfn, pgprot_t new_prot);
+int svsm_do_call(struct svsm_call *call);
void snp_kexec_finish(void);
void snp_kexec_begin(void);
@@ -611,6 +619,7 @@ static inline int rmpadjust(unsigned long vaddr, bool rmp_psize, unsigned long a
static inline void setup_ghcb(void) { }
static inline void __init
early_snp_set_memory_private(unsigned long vaddr, unsigned long paddr, unsigned long npages) { }
+static inline int svsm_do_call(struct svsm_call *call) { return 0; }
static inline void __init
early_snp_set_memory_shared(unsigned long vaddr, unsigned long paddr, unsigned long npages) { }
static inline void snp_set_memory_shared(unsigned long vaddr, unsigned long npages) { }
diff --git a/arch/x86/kernel/apic/Makefile b/arch/x86/kernel/apic/Makefile
index 581db89477f9..d23b1c4c0e14 100644
--- a/arch/x86/kernel/apic/Makefile
+++ b/arch/x86/kernel/apic/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_SMP) += ipi.o
ifeq ($(CONFIG_X86_64),y)
# APIC probe will depend on the listing order here
obj-$(CONFIG_X86_NUMACHIP) += apic_numachip.o
+obj-$(CONFIG_AMD_ALTERNATE_INJ) += svsm_apic.o
obj-$(CONFIG_X86_UV) += x2apic_uv_x.o
obj-$(CONFIG_AMD_SECURE_AVIC) += x2apic_savic.o
obj-$(CONFIG_X86_X2APIC) += x2apic_phys.o
diff --git a/arch/x86/kernel/apic/svsm_apic.c b/arch/x86/kernel/apic/svsm_apic.c
new file mode 100644
index 000000000000..7040a1ca8b55
--- /dev/null
+++ b/arch/x86/kernel/apic/svsm_apic.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * AMD Alternate Injection Support (SEV-SNP Guests)
+ *
+ * Copyright (C) 2026 Advanced Micro Devices, Inc.
+ *
+ * Author: Melody Wang <huibo.wang@amd.com>
+ */
+
+#include <linux/cpumask.h>
+#include <linux/cc_platform.h>
+
+#include <asm/apic.h>
+#include <asm/sev.h>
+
+#include "local.h"
+
+extern u8 snp_vmpl;
+
+static int svsm_apic_probe(void)
+{
+ if (!cc_platform_has(CC_ATTR_SNP_ALTERNATE_INJECTION) || !snp_vmpl)
+ return 0;
+
+ /* Alternate Injection and Secure AVIC are mutually exclusive */
+ if (cc_platform_has(CC_ATTR_SNP_SECURE_AVIC))
+ return 0;
+
+ if (!x2apic_mode) {
+ pr_err("Alternate Injection in non x2APIC mode impossible. Terminating.\n");
+ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
+ }
+
+ pr_info("Alternate Injection SVSM APIC enabled\n");
+
+ return 1;
+}
+
+static int svsm_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+ return x2apic_enabled() && cc_platform_has(CC_ATTR_SNP_ALTERNATE_INJECTION) && snp_vmpl;
+}
+
+static void svsm_apic_msr_write(u32 reg, u32 v)
+{
+ u32 msr = APIC_BASE_MSR + (reg >> 4);
+ struct svsm_call call = {};
+ int ret;
+
+ switch (reg) {
+ case APIC_ID:
+ case APIC_TASKPRI:
+ case APIC_PROCPRI:
+ case APIC_EOI:
+ case APIC_ISR ... APIC_ISR + 0x70:
+ case APIC_TMR ... APIC_TMR + 0x70:
+ case APIC_IRR ... APIC_IRR + 0x70:
+ case APIC_ICR:
+ case APIC_SELF_IPI:
+ call.rax = SVSM_APIC_CALL(SVSM_APIC_WRITE_REGISTER);
+ call.rcx = msr;
+ call.rdx = v;
+
+ ret = svsm_do_call(&call);
+ if (ret) {
+ pr_err("SVSM_APIC_WRITE_REGISTER: 0x%x, error: %d\n", reg, ret);
+ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
+ }
+ break;
+ default:
+ pr_err("SVSM_APIC_WRITE_REGISTER 0x%x not supported\n", reg);
+ break;
+ }
+}
+
+static u32 svsm_apic_msr_read(u32 reg)
+{
+ u32 msr = APIC_BASE_MSR + (reg >> 4);
+ struct svsm_call call = {};
+ int ret;
+
+ switch (reg) {
+ case APIC_ID:
+ case APIC_TASKPRI:
+ case APIC_PROCPRI:
+ case APIC_EOI:
+ case APIC_ISR ... APIC_ISR + 0x70:
+ case APIC_TMR ... APIC_TMR + 0x70:
+ case APIC_IRR ... APIC_IRR + 0x70:
+ case APIC_ICR:
+ case APIC_SELF_IPI:
+ call.rax = SVSM_APIC_CALL(SVSM_APIC_READ_REGISTER);
+ call.rcx = msr;
+
+ ret = svsm_do_call(&call);
+ if (ret) {
+ pr_err("SVSM_APIC_READ_REGISTER: 0x%x, error: %d\n", reg, ret);
+ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
+ }
+ break;
+ default:
+ pr_err("SVSM_APIC_READ_REGISTER: 0x%x not supported\n", reg);
+ return 0;
+ }
+
+ return call.rdx_out;
+}
+
+static inline void svsm_apic_msr_eoi(void)
+{
+ svsm_apic_msr_write(APIC_EOI, APIC_EOI_ACK);
+}
+
+static inline u64 svsm_apic_icr_read(void)
+{
+ u32 reg;
+ struct svsm_call call = {};
+ int ret;
+
+ reg = APIC_ICR;
+
+ call.rax = SVSM_APIC_CALL(SVSM_APIC_READ_REGISTER);
+ call.rcx = APIC_BASE_MSR + (reg >> 4);
+
+ ret = svsm_do_call(&call);
+ if (ret) {
+ pr_err("svsm_apic_icr_read error: %d\n", ret);
+ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
+ }
+
+ return call.rdx_out;
+}
+
+static void svsm_apic_icr_write(u32 low, u32 id)
+{
+ u64 icr_data;
+ u32 reg;
+ struct svsm_call call = {};
+ int ret;
+
+ reg = APIC_ICR;
+ icr_data = ((u64)id) << 32 | low;
+
+ call.rax = SVSM_APIC_CALL(SVSM_APIC_WRITE_REGISTER);
+ call.rcx = APIC_BASE_MSR + (reg >> 4);
+ call.rdx = icr_data;
+
+ ret = svsm_do_call(&call);
+ if (ret) {
+ pr_err("svsm_apic_icr_write error: %d\n", ret);
+ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
+ }
+}
+
+static void __svsm_apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest)
+{
+ svsm_apic_icr_write(__prepare_ICR(0, vector, dest), apicid);
+}
+
+static void svsm_apic_send_IPI(int cpu, int vector)
+{
+ u32 dest = per_cpu(x86_cpu_to_apicid, cpu);
+
+ __svsm_apic_send_IPI_dest(dest, vector, APIC_DEST_PHYSICAL);
+}
+
+static void __svsm_apic_send_IPI_mask(const struct cpumask *mask, int vector, int apic_dest)
+{
+ unsigned long query_cpu;
+ unsigned long this_cpu;
+
+ guard(irqsave)();
+
+ this_cpu = smp_processor_id();
+ for_each_cpu(query_cpu, mask) {
+ if (apic_dest == APIC_DEST_ALLBUT && this_cpu == query_cpu)
+ continue;
+
+ __svsm_apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu),
+ vector, APIC_DEST_PHYSICAL);
+ }
+}
+
+static void svsm_apic_send_IPI_mask(const struct cpumask *mask, int vector)
+{
+ __svsm_apic_send_IPI_mask(mask, vector, APIC_DEST_ALLINC);
+}
+
+static void svsm_apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector)
+{
+ __svsm_apic_send_IPI_mask(mask, vector, APIC_DEST_ALLBUT);
+}
+
+static void __svsm_apic_send_IPI_shorthand(int vector, u32 which)
+{
+ svsm_apic_icr_write(__prepare_ICR(which, vector, 0), 0);
+}
+
+static void svsm_apic_send_IPI_allbutself(int vector)
+{
+ __svsm_apic_send_IPI_shorthand(vector, APIC_DEST_ALLBUT);
+}
+
+static void svsm_apic_send_IPI_all(int vector)
+{
+ __svsm_apic_send_IPI_shorthand(vector, APIC_DEST_ALLINC);
+}
+
+static void svsm_apic_send_IPI_self(int vector)
+{
+ __svsm_apic_send_IPI_shorthand(vector, APIC_DEST_SELF);
+}
+
+static u32 svsm_apic_get_apic_id(u32 id)
+{
+ return id;
+}
+
+static struct apic svsm_apic __ro_after_init = {
+
+ .name = "svsm apic",
+ .probe = svsm_apic_probe,
+ .acpi_madt_oem_check = svsm_acpi_madt_oem_check,
+
+ .dest_mode_logical = false,
+
+ .disable_esr = 0,
+
+ .cpu_present_to_apicid = default_cpu_present_to_apicid,
+
+ .max_apic_id = UINT_MAX,
+ .x2apic_set_max_apicid = true,
+ .get_apic_id = svsm_apic_get_apic_id,
+
+ .calc_dest_apicid = apic_default_calc_apicid,
+
+ .send_IPI = svsm_apic_send_IPI,
+ .send_IPI_mask = svsm_apic_send_IPI_mask,
+ .send_IPI_mask_allbutself = svsm_apic_send_IPI_mask_allbutself,
+ .send_IPI_allbutself = svsm_apic_send_IPI_allbutself,
+ .send_IPI_all = svsm_apic_send_IPI_all,
+ .send_IPI_self = svsm_apic_send_IPI_self,
+ .nmi_to_offline_cpu = true,
+
+ .read = svsm_apic_msr_read,
+ .write = svsm_apic_msr_write,
+ .eoi = svsm_apic_msr_eoi,
+ .icr_read = svsm_apic_icr_read,
+ .icr_write = svsm_apic_icr_write,
+
+};
+apic_driver(svsm_apic);
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/7] x86/sev: Allow the guest to configure interrupt vectors for the hypervisor
2026-07-30 1:48 [PATCH 0/7] Alternate Injection: Secure Interrupt Delivery for SEV-SNP Guests - Guest Support Melody Wang
2026-07-30 1:48 ` [PATCH 1/7] x86/sev: Add support for Alternate Injection Melody Wang
2026-07-30 1:48 ` [PATCH 2/7] x86/apic: Add an SVSM APIC driver Melody Wang
@ 2026-07-30 1:48 ` Melody Wang
2026-07-30 1:48 ` [PATCH 4/7] x86/sev: Route unsupported APIC register accesses to the hypervisor APIC emulation Melody Wang
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Melody Wang @ 2026-07-30 1:48 UTC (permalink / raw)
To: x86; +Cc: LKML, Tom Lendacky, Melody Wang
The SVSM APIC protocol supports 5 API calls. SVSM_APIC_CONFIGURE_VECTOR
(shortened to SVSM_APIC_CONFIG_VECTOR for brevity), call 4, provides for
the guest to configure an interrupt vector which the guest allows and
the hypervisor can use to signal interrupts for it.
Implement this call, and make the default interrupt setting permissive
when detecting an SVSM.
Signed-off-by: Melody Wang <huibo.wang@amd.com>
---
arch/x86/boot/startup/sev-startup.c | 15 +++++++++++++++
arch/x86/boot/startup/sme.c | 3 +++
arch/x86/include/asm/sev.h | 9 +++++++++
3 files changed, 27 insertions(+)
diff --git a/arch/x86/boot/startup/sev-startup.c b/arch/x86/boot/startup/sev-startup.c
index 789e99d38d17..8dea0548e004 100644
--- a/arch/x86/boot/startup/sev-startup.c
+++ b/arch/x86/boot/startup/sev-startup.c
@@ -191,6 +191,21 @@ static void __init svsm_setup(struct cc_blob_sev_info *cc_info)
boot_svsm_caa_pa = pa;
}
+/* Configure the APIC IRQ vectors with Alternate Injection */
+void __init svsm_config_vectors(void)
+{
+ struct svsm_call call = {};
+
+ if (sev_status & MSR_AMD64_SNP_ALTERNATE_INJ) {
+ call.caa = rip_rel_ptr(&boot_svsm_ca_page);
+ call.rax = SVSM_APIC_CALL(SVSM_APIC_CONFIG_VECTOR);
+ call.rcx = SVSM_IRQ_ENABLE_ALL << 8;
+
+ if (svsm_call_msr_protocol(&call))
+ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
+ }
+}
+
bool __init snp_init(struct boot_params *bp)
{
struct cc_blob_sev_info *cc_info;
diff --git a/arch/x86/boot/startup/sme.c b/arch/x86/boot/startup/sme.c
index c07a2c381ed1..664e7a549b34 100644
--- a/arch/x86/boot/startup/sme.c
+++ b/arch/x86/boot/startup/sme.c
@@ -566,6 +566,9 @@ void __init sme_enable(struct boot_params *bp)
physical_mask &= ~me_mask;
cc_vendor = CC_VENDOR_AMD;
cc_set_mask(me_mask);
+
+ if (snp_vmpl)
+ svsm_config_vectors();
}
#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index f958f78e1db8..f8a5b5cf939a 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -34,6 +34,13 @@ enum es_result {
ES_RETRY, /* Retry instruction emulation */
};
+enum svsm_vec_enable {
+ SVSM_IRQ_DISABLE_SINGLE,
+ SVSM_IRQ_ENABLE_SINGLE,
+ SVSM_IRQ_DISABLE_ALL,
+ SVSM_IRQ_ENABLE_ALL,
+};
+
struct es_fault_info {
unsigned long vector;
unsigned long error_code;
@@ -518,6 +525,7 @@ void snp_set_memory_shared(unsigned long vaddr, unsigned long npages);
void snp_set_memory_private(unsigned long vaddr, unsigned long npages);
void snp_set_wakeup_secondary_cpu(void);
bool snp_init(struct boot_params *bp);
+void svsm_config_vectors(void);
void snp_dmi_setup(void);
int snp_issue_svsm_attest_req(u64 call_id, struct svsm_call *call, struct svsm_attest_call *input);
void snp_accept_memory(phys_addr_t start, phys_addr_t end);
@@ -626,6 +634,7 @@ static inline void snp_set_memory_shared(unsigned long vaddr, unsigned long npag
static inline void snp_set_memory_private(unsigned long vaddr, unsigned long npages) { }
static inline void snp_set_wakeup_secondary_cpu(void) { }
static inline bool snp_init(struct boot_params *bp) { return false; }
+static inline void svsm_config_vectors(void) { }
static inline void snp_dmi_setup(void) { }
static inline int snp_issue_svsm_attest_req(u64 call_id, struct svsm_call *call, struct svsm_attest_call *input)
{
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/7] x86/sev: Route unsupported APIC register accesses to the hypervisor APIC emulation
2026-07-30 1:48 [PATCH 0/7] Alternate Injection: Secure Interrupt Delivery for SEV-SNP Guests - Guest Support Melody Wang
` (2 preceding siblings ...)
2026-07-30 1:48 ` [PATCH 3/7] x86/sev: Allow the guest to configure interrupt vectors for the hypervisor Melody Wang
@ 2026-07-30 1:48 ` Melody Wang
2026-07-30 1:48 ` [PATCH 5/7] x86/sev: Add a function to contain all SEV-specific setup operations Melody Wang
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Melody Wang @ 2026-07-30 1:48 UTC (permalink / raw)
To: x86; +Cc: LKML, Tom Lendacky, Melody Wang
The SVSM APIC emulation supports only a subset of the X2APIC MSRs.
Therefore, route the unsupported ones to the hypervisor's X2APIC
emulation.
Signed-off-by: Melody Wang <huibo.wang@amd.com>
---
arch/x86/coco/sev/core.c | 12 ++++++------
arch/x86/include/asm/sev-common.h | 1 +
arch/x86/include/asm/sev.h | 8 ++++----
arch/x86/kernel/apic/svsm_apic.c | 11 +++++++----
arch/x86/kernel/apic/x2apic_savic.c | 8 ++++----
5 files changed, 22 insertions(+), 18 deletions(-)
diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
index 197119807230..b293a36c3594 100644
--- a/arch/x86/coco/sev/core.c
+++ b/arch/x86/coco/sev/core.c
@@ -972,7 +972,7 @@ int __init sev_es_efi_map_ghcbs_cas(pgd_t *pgd)
return 0;
}
-u64 savic_ghcb_msr_read(u32 reg)
+u64 hvs_ghcb_msr_read(u32 reg)
{
u64 msr = APIC_BASE_MSR + (reg >> 4);
struct pt_regs regs = { .cx = msr };
@@ -988,9 +988,9 @@ u64 savic_ghcb_msr_read(u32 reg)
res = __vc_handle_msr(ghcb, &ctxt, false);
if (res != ES_OK) {
- pr_err("Secure AVIC MSR (0x%llx) read returned error (%d)\n", msr, res);
+ pr_err("Hypervisor MSR (0x%llx) read returned error (%d)\n", msr, res);
/* MSR read failures are treated as fatal errors */
- sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_SAVIC_FAIL);
+ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_APIC_MSR_FAIL);
}
__sev_put_ghcb(&state);
@@ -998,7 +998,7 @@ u64 savic_ghcb_msr_read(u32 reg)
return regs.ax | regs.dx << 32;
}
-void savic_ghcb_msr_write(u32 reg, u64 value)
+void hvs_ghcb_msr_write(u32 reg, u64 value)
{
u64 msr = APIC_BASE_MSR + (reg >> 4);
struct pt_regs regs = {
@@ -1018,9 +1018,9 @@ void savic_ghcb_msr_write(u32 reg, u64 value)
res = __vc_handle_msr(ghcb, &ctxt, true);
if (res != ES_OK) {
- pr_err("Secure AVIC MSR (0x%llx) write returned error (%d)\n", msr, res);
+ pr_err("Hypervisor MSR (0x%llx) write returned error (%d)\n", msr, res);
/* MSR writes should never fail. Any failure is fatal error for SNP guest */
- sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_SAVIC_FAIL);
+ sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_APIC_MSR_FAIL);
}
__sev_put_ghcb(&state);
diff --git a/arch/x86/include/asm/sev-common.h b/arch/x86/include/asm/sev-common.h
index 01a6e4dbe423..a41c52a16e31 100644
--- a/arch/x86/include/asm/sev-common.h
+++ b/arch/x86/include/asm/sev-common.h
@@ -209,6 +209,7 @@ struct snp_psc_desc {
#define GHCB_TERM_SECURE_TSC 10 /* Secure TSC initialization failed */
#define GHCB_TERM_SVSM_CA_REMAP_FAIL 11 /* SVSM is present but CA could not be remapped */
#define GHCB_TERM_SAVIC_FAIL 12 /* Secure AVIC-specific failure */
+#define GHCB_TERM_APIC_MSR_FAIL 13 /* APIC MSR failure */
#define GHCB_RESP_CODE(v) ((v) & GHCB_MSR_INFO_MASK)
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index f8a5b5cf939a..491a891a7694 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -549,8 +549,8 @@ void __init snp_secure_tsc_prepare(void);
void __init snp_secure_tsc_init(void);
enum es_result savic_register_gpa(u64 gpa);
enum es_result savic_unregister_gpa(u64 *gpa);
-u64 savic_ghcb_msr_read(u32 reg);
-void savic_ghcb_msr_write(u32 reg, u64 value);
+u64 hvs_ghcb_msr_read(u32 reg);
+void hvs_ghcb_msr_write(u32 reg, u64 value);
static __always_inline void vc_ghcb_invalidate(struct ghcb *ghcb)
{
@@ -659,8 +659,8 @@ static inline void __init snp_secure_tsc_init(void) { }
static inline void sev_evict_cache(void *va, int npages) {}
static inline enum es_result savic_register_gpa(u64 gpa) { return ES_UNSUPPORTED; }
static inline enum es_result savic_unregister_gpa(u64 *gpa) { return ES_UNSUPPORTED; }
-static inline void savic_ghcb_msr_write(u32 reg, u64 value) { }
-static inline u64 savic_ghcb_msr_read(u32 reg) { return 0; }
+static inline void hvs_ghcb_msr_write(u32 reg, u64 value) { }
+static inline u64 hvs_ghcb_msr_read(u32 reg) { return 0; }
#endif /* CONFIG_AMD_MEM_ENCRYPT */
diff --git a/arch/x86/kernel/apic/svsm_apic.c b/arch/x86/kernel/apic/svsm_apic.c
index 7040a1ca8b55..a4e7ba7e9985 100644
--- a/arch/x86/kernel/apic/svsm_apic.c
+++ b/arch/x86/kernel/apic/svsm_apic.c
@@ -68,7 +68,8 @@ static void svsm_apic_msr_write(u32 reg, u32 v)
}
break;
default:
- pr_err("SVSM_APIC_WRITE_REGISTER 0x%x not supported\n", reg);
+ pr_debug("SVSM_APIC_WRITE_REGISTER to HV (0x%x, val:0x%x)\n", reg, v);
+ hvs_ghcb_msr_write(reg, v);
break;
}
}
@@ -77,6 +78,7 @@ static u32 svsm_apic_msr_read(u32 reg)
{
u32 msr = APIC_BASE_MSR + (reg >> 4);
struct svsm_call call = {};
+ u64 val;
int ret;
switch (reg) {
@@ -93,17 +95,18 @@ static u32 svsm_apic_msr_read(u32 reg)
call.rcx = msr;
ret = svsm_do_call(&call);
+ val = call.rdx_out;
if (ret) {
pr_err("SVSM_APIC_READ_REGISTER: 0x%x, error: %d\n", reg, ret);
sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
}
break;
default:
- pr_err("SVSM_APIC_READ_REGISTER: 0x%x not supported\n", reg);
- return 0;
+ val = hvs_ghcb_msr_read(reg);
+ pr_debug("SVSM_APIC_READ_REGISTER from HV 0x%x, val: 0x%llx\n", reg, val);
}
- return call.rdx_out;
+ return val;
}
static inline void svsm_apic_msr_eoi(void)
diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
index 4bc6d7e018a5..71040f77dfaf 100644
--- a/arch/x86/kernel/apic/x2apic_savic.c
+++ b/arch/x86/kernel/apic/x2apic_savic.c
@@ -72,7 +72,7 @@ static u32 savic_read(u32 reg)
case APIC_LVT0:
case APIC_LVT1:
case APIC_LVTERR:
- return savic_ghcb_msr_read(reg);
+ return hvs_ghcb_msr_read(reg);
case APIC_ID:
case APIC_LVR:
case APIC_TASKPRI:
@@ -193,7 +193,7 @@ static void savic_icr_write(u32 icr_low, u32 icr_high)
icr_data = ((u64)icr_high) << 32 | icr_low;
if (dsh != APIC_DEST_SELF)
- savic_ghcb_msr_write(APIC_ICR, icr_data);
+ hvs_ghcb_msr_write(APIC_ICR, icr_data);
apic_set_reg64(this_cpu_ptr(savic_page), APIC_ICR, icr_data);
}
@@ -210,7 +210,7 @@ static void savic_write(u32 reg, u32 data)
case APIC_LVTTHMR:
case APIC_LVTPC:
case APIC_LVTERR:
- savic_ghcb_msr_write(reg, data);
+ hvs_ghcb_msr_write(reg, data);
break;
case APIC_TASKPRI:
case APIC_EOI:
@@ -316,7 +316,7 @@ static void savic_eoi(void)
* interrupts. Return to the guest from GHCB protocol event takes
* care of re-evaluating interrupt state.
*/
- savic_ghcb_msr_write(APIC_EOI, 0);
+ hvs_ghcb_msr_write(APIC_EOI, 0);
} else {
/*
* Hardware clears APIC_ISR and re-evaluates the interrupt state
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5/7] x86/sev: Add a function to contain all SEV-specific setup operations
2026-07-30 1:48 [PATCH 0/7] Alternate Injection: Secure Interrupt Delivery for SEV-SNP Guests - Guest Support Melody Wang
` (3 preceding siblings ...)
2026-07-30 1:48 ` [PATCH 4/7] x86/sev: Route unsupported APIC register accesses to the hypervisor APIC emulation Melody Wang
@ 2026-07-30 1:48 ` Melody Wang
2026-07-30 1:48 ` [PATCH 6/7] x86/sev: Register the guest with the SVSM APIC protocol Melody Wang
2026-07-30 1:48 ` [PATCH 7/7] x86/sev: Indicate that Alternate Injection is supported in the guest Melody Wang
6 siblings, 0 replies; 8+ messages in thread
From: Melody Wang @ 2026-07-30 1:48 UTC (permalink / raw)
To: x86; +Cc: LKML, Tom Lendacky, Melody Wang, Ard Biesheuvel
To make the code clean in the boot phase, add a sev_prepare() wrapper
which contains early SEV-specific checks in order to have all that code
in a single place.
No functional changes.
Signed-off-by: Melody Wang <huibo.wang@amd.com>
Cc: Ard Biesheuvel <ardb@kernel.org>
---
arch/x86/boot/compressed/sev.c | 9 +++++++++
arch/x86/include/asm/sev.h | 3 +++
drivers/firmware/efi/libstub/x86-stub.c | 20 ++++++--------------
3 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c
index fc2029746c50..655291a03dcc 100644
--- a/arch/x86/boot/compressed/sev.c
+++ b/arch/x86/boot/compressed/sev.c
@@ -511,3 +511,12 @@ bool early_is_sevsnp_guest(void)
}
return true;
}
+
+u64 sev_prepare(void)
+{
+ u64 unsupported = snp_get_unsupported_features(sev_get_status());
+ if (unsupported)
+ return unsupported;
+
+ return 0;
+}
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index 491a891a7694..b430c1aab403 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -613,6 +613,8 @@ static inline void sev_evict_cache(void *va, int npages)
}
}
+u64 sev_prepare(void);
+
#else /* !CONFIG_AMD_MEM_ENCRYPT */
#define snp_vmpl 0
@@ -661,6 +663,7 @@ static inline enum es_result savic_register_gpa(u64 gpa) { return ES_UNSUPPORTED
static inline enum es_result savic_unregister_gpa(u64 *gpa) { return ES_UNSUPPORTED; }
static inline void hvs_ghcb_msr_write(u32 reg, u64 value) { }
static inline u64 hvs_ghcb_msr_read(u32 reg) { return 0; }
+static inline u64 sev_prepare(void) { return 0; }
#endif /* CONFIG_AMD_MEM_ENCRYPT */
diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c
index cef32e2c82d8..95fa16fc9887 100644
--- a/drivers/firmware/efi/libstub/x86-stub.c
+++ b/drivers/firmware/efi/libstub/x86-stub.c
@@ -783,19 +783,6 @@ static efi_status_t exit_boot(struct boot_params *boot_params, void *handle)
return EFI_SUCCESS;
}
-static bool have_unsupported_snp_features(void)
-{
- u64 unsupported;
-
- unsupported = snp_get_unsupported_features(sev_get_status());
- if (unsupported) {
- efi_err("Unsupported SEV-SNP features detected: 0x%llx\n",
- unsupported);
- return true;
- }
- return false;
-}
-
static void efi_get_seed(void *seed, int size)
{
efi_get_random_bytes(size, seed);
@@ -919,6 +906,7 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
unsigned long kernel_entry;
struct setup_header *hdr;
efi_status_t status;
+ u64 unsup_feats;
efi_system_table = sys_table_arg;
/* Check if we were booted by the EFI firmware */
@@ -933,8 +921,12 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
hdr = &boot_params->hdr;
- if (have_unsupported_snp_features())
+ unsup_feats = sev_prepare();
+ if (unsup_feats) {
+ efi_err("Unsupported SEV-SNP features detected: 0x%llx\n",
+ unsup_feats);
efi_exit(handle, EFI_UNSUPPORTED);
+ }
if (IS_ENABLED(CONFIG_EFI_DXE_MEM_ATTRIBUTES)) {
efi_dxe_table = get_efi_config_table(EFI_DXE_SERVICES_TABLE_GUID);
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6/7] x86/sev: Register the guest with the SVSM APIC protocol
2026-07-30 1:48 [PATCH 0/7] Alternate Injection: Secure Interrupt Delivery for SEV-SNP Guests - Guest Support Melody Wang
` (4 preceding siblings ...)
2026-07-30 1:48 ` [PATCH 5/7] x86/sev: Add a function to contain all SEV-specific setup operations Melody Wang
@ 2026-07-30 1:48 ` Melody Wang
2026-07-30 1:48 ` [PATCH 7/7] x86/sev: Indicate that Alternate Injection is supported in the guest Melody Wang
6 siblings, 0 replies; 8+ messages in thread
From: Melody Wang @ 2026-07-30 1:48 UTC (permalink / raw)
To: x86; +Cc: LKML, Tom Lendacky, Melody Wang
The SVSM APIC protocol supports 5 calls. SVSM_APIC_CONFIGURE_EMULATION
(shortened to SVSM_APIC_CONFIG_EMULATION for brevity), call 1, provides
the controls whether the guest can make use of the SVSM APIC protocol.
Implement this call, and register Alternate Injection for the guest
by default.
Signed-off-by: Melody Wang <huibo.wang@amd.com>
---
arch/x86/boot/compressed/sev.c | 17 +++++++++++++++++
arch/x86/boot/compressed/sev.h | 6 ++++++
2 files changed, 23 insertions(+)
diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c
index 655291a03dcc..a98185b3869a 100644
--- a/arch/x86/boot/compressed/sev.c
+++ b/arch/x86/boot/compressed/sev.c
@@ -518,5 +518,22 @@ u64 sev_prepare(void)
if (unsupported)
return unsupported;
+ /* Register Alternate Injection */
+ if (early_is_sevsnp_guest() && snp_vmpl) {
+ struct svsm_call call = {};
+ int ret;
+
+ if (!(sev_get_status() & MSR_AMD64_SNP_ALTERNATE_INJ))
+ return 0;
+
+ call.caa = (struct svsm_ca *)boot_svsm_caa_pa;
+ call.rax = SVSM_APIC_CALL(SVSM_APIC_CONFIG_EMULATION);
+ call.rcx = SVSM_AI_REGISTER;
+
+ ret = svsm_call_msr_protocol(&call);
+ if (ret)
+ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
+ }
+
return 0;
}
diff --git a/arch/x86/boot/compressed/sev.h b/arch/x86/boot/compressed/sev.h
index 22637b416b46..dd058af2e7aa 100644
--- a/arch/x86/boot/compressed/sev.h
+++ b/arch/x86/boot/compressed/sev.h
@@ -12,6 +12,12 @@
#include <asm/shared/msr.h>
+enum svsm_ai_ctrl {
+ SVSM_AI_DISABLE,
+ SVSM_AI_DEREGISTER,
+ SVSM_AI_REGISTER,
+};
+
void snp_accept_memory(phys_addr_t start, phys_addr_t end);
u64 sev_get_status(void);
bool early_is_sevsnp_guest(void);
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 7/7] x86/sev: Indicate that Alternate Injection is supported in the guest
2026-07-30 1:48 [PATCH 0/7] Alternate Injection: Secure Interrupt Delivery for SEV-SNP Guests - Guest Support Melody Wang
` (5 preceding siblings ...)
2026-07-30 1:48 ` [PATCH 6/7] x86/sev: Register the guest with the SVSM APIC protocol Melody Wang
@ 2026-07-30 1:48 ` Melody Wang
6 siblings, 0 replies; 8+ messages in thread
From: Melody Wang @ 2026-07-30 1:48 UTC (permalink / raw)
To: x86; +Cc: LKML, Tom Lendacky, Melody Wang
Now the Alternate Injection support is complete, add it to the present
SNP features.
Signed-off-by: Melody Wang <huibo.wang@amd.com>
---
arch/x86/boot/compressed/sev.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c
index a98185b3869a..21731527fa49 100644
--- a/arch/x86/boot/compressed/sev.c
+++ b/arch/x86/boot/compressed/sev.c
@@ -197,6 +197,12 @@ bool sev_es_check_ghcb_fault(unsigned long address)
#define SNP_FEATURE_SECURE_AVIC 0
#endif
+#ifdef CONFIG_AMD_ALTERNATE_INJ
+#define SNP_FEATURE_ALTERNATE_INJ MSR_AMD64_SNP_ALTERNATE_INJ
+#else
+#define SNP_FEATURE_ALTERNATE_INJ 0
+#endif
+
/*
* SNP_FEATURES_IMPL is the mask of SNP features that are implemented
* by the guest kernel. As and when a new feature is implemented in the
@@ -204,7 +210,8 @@ bool sev_es_check_ghcb_fault(unsigned long address)
*/
#define SNP_FEATURES_IMPL (MSR_AMD64_SNP_DEBUG_SWAP | \
MSR_AMD64_SNP_SECURE_TSC | \
- SNP_FEATURE_SECURE_AVIC)
+ SNP_FEATURE_SECURE_AVIC | \
+ SNP_FEATURE_ALTERNATE_INJ)
u64 snp_get_unsupported_features(u64 status)
{
--
2.43.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-07-30 1:50 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-30 1:48 [PATCH 0/7] Alternate Injection: Secure Interrupt Delivery for SEV-SNP Guests - Guest Support Melody Wang
2026-07-30 1:48 ` [PATCH 1/7] x86/sev: Add support for Alternate Injection Melody Wang
2026-07-30 1:48 ` [PATCH 2/7] x86/apic: Add an SVSM APIC driver Melody Wang
2026-07-30 1:48 ` [PATCH 3/7] x86/sev: Allow the guest to configure interrupt vectors for the hypervisor Melody Wang
2026-07-30 1:48 ` [PATCH 4/7] x86/sev: Route unsupported APIC register accesses to the hypervisor APIC emulation Melody Wang
2026-07-30 1:48 ` [PATCH 5/7] x86/sev: Add a function to contain all SEV-specific setup operations Melody Wang
2026-07-30 1:48 ` [PATCH 6/7] x86/sev: Register the guest with the SVSM APIC protocol Melody Wang
2026-07-30 1:48 ` [PATCH 7/7] x86/sev: Indicate that Alternate Injection is supported in the guest Melody Wang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox