From cd5ba8810623f36daf1d0ed9869f0fa9f4d2342d Mon Sep 17 00:00:00 2001 From: Brian Perkins Date: Fri, 14 Aug 2026 21:11:49 +0000 Subject: [PATCH 1/2] x86/apic/savic: ipi needs to convert apicid to cpuid Signed-off-by: Brian Perkins --- arch/x86/kernel/apic/x2apic_savic.c | 54 +++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c index d4afb99c42e2..ea89b09ea217 100644 --- a/arch/x86/kernel/apic/x2apic_savic.c +++ b/arch/x86/kernel/apic/x2apic_savic.c @@ -167,7 +167,22 @@ static inline void self_ipi(unsigned int vector, bool nmi) native_x2apic_icr_write(icr_low, 0); } -static void savic_icr_write(u32 icr_low, u32 icr_high) +static int savic_apicid_to_cpu(u32 apic_id) +{ + unsigned int cpu; + + if (apic_id == BAD_APICID) + return -EINVAL; + + for_each_possible_cpu(cpu) { + if (per_cpu(x86_cpu_to_apicid, cpu) == apic_id) + return cpu; + } + + return -EINVAL; +} + +static void __savic_icr_write(u32 icr_low, u32 icr_high, int cpu) { unsigned int dsh, vector; u64 icr_data; @@ -188,7 +203,9 @@ static void savic_icr_write(u32 icr_low, u32 icr_high) send_ipi_allbut(vector, nmi); break; default: - send_ipi_dest(icr_high, vector, nmi); + if (WARN_ON_ONCE(cpu < 0)) + break; + send_ipi_dest(cpu, vector, nmi); break; } @@ -198,6 +215,16 @@ static void savic_icr_write(u32 icr_low, u32 icr_high) apic_set_reg64(this_cpu_ptr(savic_page), APIC_ICR, icr_data); } +static void savic_icr_write(u32 icr_low, u32 icr_high) +{ + int cpu = -1; + + if (!(icr_low & APIC_DEST_ALLBUT)) + cpu = savic_apicid_to_cpu(icr_high); + + __savic_icr_write(icr_low, icr_high, cpu); +} + static void savic_write(u32 reg, u32 data) { void *ap = this_cpu_ptr(savic_page); @@ -242,19 +269,26 @@ static void savic_write(u32 reg, u32 data) } } -static void send_ipi(u32 dest, unsigned int vector, unsigned int dsh) +static void send_ipi(unsigned int cpu, unsigned int vector) +{ + unsigned int icr_low; + u32 dest = per_cpu(x86_cpu_to_apicid, cpu); + + icr_low = __prepare_ICR(0, vector, APIC_DEST_PHYSICAL); + __savic_icr_write(icr_low, dest, cpu); +} + +static void send_ipi_shorthand(unsigned int vector, unsigned int dsh) { unsigned int icr_low; icr_low = __prepare_ICR(dsh, vector, APIC_DEST_PHYSICAL); - savic_icr_write(icr_low, dest); + __savic_icr_write(icr_low, 0, -1); } static void savic_send_ipi(int cpu, int vector) { - u32 dest = per_cpu(x86_cpu_to_apicid, cpu); - - send_ipi(dest, vector, 0); + send_ipi(cpu, vector); } static void send_ipi_mask(const struct cpumask *mask, unsigned int vector, bool excl_self) @@ -268,7 +302,7 @@ static void send_ipi_mask(const struct cpumask *mask, unsigned int vector, bool for_each_cpu(cpu, mask) { if (excl_self && cpu == this_cpu) continue; - send_ipi(per_cpu(x86_cpu_to_apicid, cpu), vector, 0); + send_ipi(cpu, vector); } } @@ -284,12 +318,12 @@ static void savic_send_ipi_mask_allbutself(const struct cpumask *mask, int vecto static void savic_send_ipi_allbutself(int vector) { - send_ipi(0, vector, APIC_DEST_ALLBUT); + send_ipi_shorthand(vector, APIC_DEST_ALLBUT); } static void savic_send_ipi_all(int vector) { - send_ipi(0, vector, APIC_DEST_ALLINC); + send_ipi_shorthand(vector, APIC_DEST_ALLINC); } static void savic_send_ipi_self(int vector) From c630cc37901bd22a189b3a323a1781a0b9b6339e Mon Sep 17 00:00:00 2001 From: Brian Perkins Date: Fri, 14 Aug 2026 21:14:33 +0000 Subject: [PATCH 2/2] x86/apic/savic: get GPA for SAVIC page using per_cpu_ptr_to_phys Signed-off-by: Brian Perkins --- arch/x86/kernel/apic/x2apic_savic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c index ea89b09ea217..f694802b86a5 100644 --- a/arch/x86/kernel/apic/x2apic_savic.c +++ b/arch/x86/kernel/apic/x2apic_savic.c @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include @@ -387,15 +387,15 @@ static void savic_teardown(void) static void savic_setup(void) { void *ap = this_cpu_ptr(savic_page); + phys_addr_t gpa; enum es_result res; - unsigned long gpa; unsigned long gfn; if (!cc_platform_has(CC_ATTR_SNP_SECURE_AVIC)) return; x2apic_savic_init_backing_page(ap); - gpa = __pa(ap); + gpa = per_cpu_ptr_to_phys(ap); gfn = gpa >> PAGE_SHIFT;