diff options
Diffstat (limited to 'arch/x86/kernel')
| -rw-r--r-- | arch/x86/kernel/apic/apic.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/apic/x2apic_savic.c | 35 |
2 files changed, 38 insertions, 0 deletions
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index ff4029b57e95..7874284c1ca7 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -1501,6 +1501,9 @@ static void setup_local_APIC(void) return; } + if (apic->setup) + apic->setup(); + /* * If this comes from kexec/kcrash the APIC might be enabled in * SPIV. Soft disable it before doing further initialization. diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c index bea844f28192..948d89497baa 100644 --- a/arch/x86/kernel/apic/x2apic_savic.c +++ b/arch/x86/kernel/apic/x2apic_savic.c @@ -8,17 +8,47 @@ */ #include <linux/cc_platform.h> +#include <linux/percpu-defs.h> #include <asm/apic.h> #include <asm/sev.h> #include "local.h" +struct secure_avic_page { + u8 regs[PAGE_SIZE]; +} __aligned(PAGE_SIZE); + +static struct secure_avic_page __percpu *savic_page __ro_after_init; + 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 void savic_setup(void) +{ + void *ap = this_cpu_ptr(savic_page); + enum es_result res; + unsigned long gpa; + + gpa = __pa(ap); + + /* + * The NPT entry for a vCPU's APIC backing page must always be + * present when the vCPU is running in order for Secure AVIC to + * function. A VMEXIT_BUSY is returned on VMRUN and the vCPU cannot + * be resumed if the NPT entry for the APIC backing page is not + * present. Notify GPA of the vCPU's APIC backing page to the + * hypervisor by calling savic_register_gpa(). Before executing + * VMRUN, the hypervisor makes use of this information to make sure + * the APIC backing page is mapped in NPT. + */ + res = savic_register_gpa(gpa); + if (res != ES_OK) + snp_abort(); +} + static int savic_probe(void) { if (!cc_platform_has(CC_ATTR_SNP_SECURE_AVIC)) @@ -30,6 +60,10 @@ static int savic_probe(void) /* unreachable */ } + savic_page = alloc_percpu(struct secure_avic_page); + if (!savic_page) + snp_abort(); + return 1; } @@ -38,6 +72,7 @@ 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, + .setup = savic_setup, .dest_mode_logical = false, |