[PATCH 3/7] x86/sev: Allow the guest to configure interrupt vectors for the hypervisor
From: Melody Wang
Date: Wed Jul 29 2026 - 21:55:33 EST
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@xxxxxxx>
---
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