]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
x86/apic: Add new driver for Secure AVIC
authorNeeraj Upadhyay <Neeraj.Upadhyay@amd.com>
Thu, 28 Aug 2025 07:03:17 +0000 (12:33 +0530)
committerBorislav Petkov (AMD) <bp@alien8.de>
Thu, 28 Aug 2025 15:57:19 +0000 (17:57 +0200)
The Secure AVIC feature provides SEV-SNP guests hardware acceleration for
performance sensitive APIC accesses while securely managing the guest-owned
APIC state through the use of a private APIC backing page.

This helps prevent the hypervisor from generating unexpected interrupts for
a vCPU or otherwise violate architectural assumptions around the APIC
behavior.

Add a new x2APIC driver that will serve as the base of the Secure AVIC
support. It is initially the same as the x2APIC physical driver (without IPI
callbacks), but will be modified as features are implemented.

As the new driver does not implement Secure AVIC features yet, if the
hypervisor sets the Secure AVIC bit in SEV_STATUS, maintain the existing
behavior to enforce the guest termination.

  [ bp: Massage commit message. ]

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>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Link: https://lore.kernel.org/20250828070334.208401-2-Neeraj.Upadhyay@amd.com
arch/x86/Kconfig
arch/x86/boot/compressed/sev.c
arch/x86/coco/core.c
arch/x86/coco/sev/core.c
arch/x86/include/asm/msr-index.h
arch/x86/kernel/apic/Makefile
arch/x86/kernel/apic/x2apic_savic.c [new file with mode: 0644]
include/linux/cc_platform.h

index 58d890fe2100eb6990880bcf5ba600cdefb0a7d1..e32952728d9aa2e5f79bace9d1d6db35e92fa9fa 100644 (file)
@@ -483,6 +483,19 @@ config X86_X2APIC
 
          If in doubt, say Y.
 
+config AMD_SECURE_AVIC
+       bool "AMD Secure AVIC"
+       depends on AMD_MEM_ENCRYPT && X86_X2APIC
+       help
+         Enable this to get AMD Secure AVIC support on guests that have this feature.
+
+         AMD Secure AVIC provides hardware acceleration for performance sensitive
+         APIC accesses and support for managing guest owned APIC state for SEV-SNP
+         guests. Secure AVIC does not support xAPIC mode. It has functional
+         dependency on x2apic being enabled in the guest.
+
+         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
index fd1b67dfea228f628d4aa108a4b5c23e998b13eb..74e083feb2d9528f7819d2dfc04f23300ab174dc 100644 (file)
@@ -235,6 +235,7 @@ bool sev_es_check_ghcb_fault(unsigned long address)
                                 MSR_AMD64_SNP_VMSA_REG_PROT |          \
                                 MSR_AMD64_SNP_RESERVED_BIT13 |         \
                                 MSR_AMD64_SNP_RESERVED_BIT15 |         \
+                                MSR_AMD64_SNP_SECURE_AVIC |            \
                                 MSR_AMD64_SNP_RESERVED_MASK)
 
 /*
index d4610af68114348499ebd54a4612612dd20e97ba..989ca9f72ba30b987ac3cd2e78d3ac55c7f284bb 100644 (file)
@@ -104,6 +104,9 @@ static bool noinstr amd_cc_platform_has(enum cc_attr attr)
        case CC_ATTR_HOST_SEV_SNP:
                return cc_flags.host_sev_snp;
 
+       case CC_ATTR_SNP_SECURE_AVIC:
+               return sev_status & MSR_AMD64_SNP_SECURE_AVIC;
+
        default:
                return false;
        }
index 14ef5908fb27356a2bc2005a07681da1402828f7..f7a549f650e9c4e7dd1a384069eb333e857ede7b 100644 (file)
@@ -79,6 +79,7 @@ static const char * const sev_status_feat_names[] = {
        [MSR_AMD64_SNP_IBS_VIRT_BIT]            = "IBSVirt",
        [MSR_AMD64_SNP_VMSA_REG_PROT_BIT]       = "VMSARegProt",
        [MSR_AMD64_SNP_SMT_PROT_BIT]            = "SMTProt",
+       [MSR_AMD64_SNP_SECURE_AVIC_BIT]         = "SecureAVIC",
 };
 
 /*
index b65c3ba5fa1410bb7a9a3774fd964d0d7ea9ab5d..2a6d4fd8659a222394bb27af4a67f0da94eb709b 100644 (file)
 #define MSR_AMD64_SNP_VMSA_REG_PROT    BIT_ULL(MSR_AMD64_SNP_VMSA_REG_PROT_BIT)
 #define MSR_AMD64_SNP_SMT_PROT_BIT     17
 #define MSR_AMD64_SNP_SMT_PROT         BIT_ULL(MSR_AMD64_SNP_SMT_PROT_BIT)
-#define MSR_AMD64_SNP_RESV_BIT         18
+#define MSR_AMD64_SNP_SECURE_AVIC_BIT  18
+#define MSR_AMD64_SNP_SECURE_AVIC      BIT_ULL(MSR_AMD64_SNP_SECURE_AVIC_BIT)
+#define MSR_AMD64_SNP_RESV_BIT         19
 #define MSR_AMD64_SNP_RESERVED_MASK    GENMASK_ULL(63, MSR_AMD64_SNP_RESV_BIT)
 #define MSR_AMD64_RMP_BASE             0xc0010132
 #define MSR_AMD64_RMP_END              0xc0010133
index 52d1808ee360b09e2cd5fddc03e961a770c6c4ba..581db89477f9235584a506e1cc7c1eee4a6bf6fa 100644 (file)
@@ -18,6 +18,7 @@ ifeq ($(CONFIG_X86_64),y)
 # APIC probe will depend on the listing order here
 obj-$(CONFIG_X86_NUMACHIP)     += apic_numachip.o
 obj-$(CONFIG_X86_UV)           += x2apic_uv_x.o
+obj-$(CONFIG_AMD_SECURE_AVIC)  += x2apic_savic.o
 obj-$(CONFIG_X86_X2APIC)       += x2apic_phys.o
 obj-$(CONFIG_X86_X2APIC)       += x2apic_cluster.o
 obj-y                          += apic_flat_64.o
diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
new file mode 100644 (file)
index 0000000..bea844f
--- /dev/null
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * AMD Secure AVIC Support (SEV-SNP Guests)
+ *
+ * Copyright (C) 2024 Advanced Micro Devices, Inc.
+ *
+ * Author: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
+ */
+
+#include <linux/cc_platform.h>
+
+#include <asm/apic.h>
+#include <asm/sev.h>
+
+#include "local.h"
+
+static int savic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+       return x2apic_enabled() && cc_platform_has(CC_ATTR_SNP_SECURE_AVIC);
+}
+
+static int savic_probe(void)
+{
+       if (!cc_platform_has(CC_ATTR_SNP_SECURE_AVIC))
+               return 0;
+
+       if (!x2apic_mode) {
+               pr_err("Secure AVIC enabled in non x2APIC mode\n");
+               snp_abort();
+               /* unreachable */
+       }
+
+       return 1;
+}
+
+static struct apic apic_x2apic_savic __ro_after_init = {
+
+       .name                           = "secure avic x2apic",
+       .probe                          = savic_probe,
+       .acpi_madt_oem_check            = savic_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                    = x2apic_get_apic_id,
+
+       .calc_dest_apicid               = apic_default_calc_apicid,
+
+       .nmi_to_offline_cpu             = true,
+
+       .read                           = native_apic_msr_read,
+       .write                          = native_apic_msr_write,
+       .eoi                            = native_apic_msr_eoi,
+       .icr_read                       = native_x2apic_icr_read,
+       .icr_write                      = native_x2apic_icr_write,
+};
+
+apic_driver(apic_x2apic_savic);
index 0bf7d33a1048cf7e7643c455fc0563567a4d0e49..7fcec025c5e01d72d8df448e909144a06fb4e245 100644 (file)
@@ -96,6 +96,14 @@ enum cc_attr {
         * enabled to run SEV-SNP guests.
         */
        CC_ATTR_HOST_SEV_SNP,
+
+       /**
+        * @CC_ATTR_SNP_SECURE_AVIC: Secure AVIC mode is active.
+        *
+        * The host kernel is running with the necessary features enabled
+        * to run SEV-SNP guests with full Secure AVIC capabilities.
+        */
+       CC_ATTR_SNP_SECURE_AVIC,
 };
 
 #ifdef CONFIG_ARCH_HAS_CC_PLATFORM