Re: [PATCH v3 3/8] x86/apic: Add an SVSM APIC driver

From: Borislav Petkov

Date: Wed Sep 23 2026 - 16:32:07 EST


On Sun, Sep 20, 2026 at 06:16:55PM +0000, Melody Wang wrote:
> Alternate Injection replaces hypervisor-based interrupt queuing and
> event injection, requiring guest-controlled queuing and injection. In
> order to perform this guest-controlled queuing and injection, an SVSM
> is used to update the guest VMSA to perform the required actions.
>
> The guest uses the SVSM APIC protocol to communicate with the SVSM to
> perform selected APIC related operations instead of using standard APIC
> MSR access.
>
> Add such a SVSM APIC driver (which implements a subset of an X2APIC),
> for the APIC emulation supported by the SVSM.

Simplified the commit message a bit:

"Alternate Injection replaces hypervisor-based interrupt queuing and event
injection in favor of guest-controlled queuing and injection. In order to
accomplish that, an SVSM is used to update the guest VMSA to perform the
required actions.

The guest uses the SVSM APIC protocol to communicate with the SVSM to perform
selected APIC-related operations instead of using standard APIC MSR accesses.

Add a such SVSM APIC driver (which implements a subset of the X2APIC
interface), for the APIC emulation supported by the SVSM."

>
> Signed-off-by: Melody Wang <huibo.wang@xxxxxxx>
> ---
> arch/x86/include/asm/sev-common.h | 1 +
> arch/x86/include/asm/sev.h | 9 ++
> arch/x86/kernel/apic/Makefile | 1 +
> arch/x86/kernel/apic/x2apic_svsm.c | 236 +++++++++++++++++++++++++++++
> 4 files changed, 247 insertions(+)
> create mode 100644 arch/x86/kernel/apic/x2apic_svsm.c

...

> +static inline u64 svsm_apic_icr_read(void)
> +{
> + struct svsm_call call = {};
> + u32 reg;
> + int ret;
> +
> + reg = APIC_ICR;
> +
> + call.rax = SVSM_APIC_CALL(SVSM_APIC_READ_REGISTER);
> + call.rcx = APIC_BASE_MSR + (reg >> 4);
> +
> + ret = svsm_perform_call_protocol(&call);
> + if (ret) {
> + pr_err("%s: error: %d\n", __func__, ret);
> + sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_ALT_INJ_FAIL);
> + }
> +
> + return call.rdx_out;
> +}
> +
> +static void svsm_apic_icr_write(u32 low, u32 id)
> +{
> + struct svsm_call call = {};
> + u32 reg;
> + int ret;
> +
> + reg = APIC_ICR;
> +
> + call.rax = SVSM_APIC_CALL(SVSM_APIC_WRITE_REGISTER);
> + call.rcx = APIC_BASE_MSR + (reg >> 4);
> + call.rdx = ((u64)id) << 32 | low;
> +
> + ret = svsm_perform_call_protocol(&call);
> + if (ret) {
> + pr_err("%s: error: %d\n", __func__, ret);
> + sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_ALT_INJ_FAIL);
> + }
> +}

Those two look very similar now and since we're unifying them, you probably
should unify those two too.

Thx.

--
Regards/Gruss,
Boris.

https://people.kernel.org/tglx/notes-about-netiquette