diff options
author | Neeraj Upadhyay <Neeraj.Upadhyay@amd.com> | 2025-08-28 16:42:13 +0530 |
---|---|---|
committer | Borislav Petkov (AMD) <bp@alien8.de> | 2025-09-01 12:49:25 +0200 |
commit | 9de196f519a505cf104216d6f1d8688570dacca4 (patch) | |
tree | 09bd781036f571e5ec0b09865a0b4d8efe5795a8 | |
parent | c77683eccf53428a6934df76702e33c0faf46fe5 (diff) |
x86/apic: Add support to send NMI IPI for Secure AVIC
Secure AVIC introduces a new field in the APIC backing page "NmiReq" that has
to be set by the guest to request a NMI IPI through APIC_ICR write.
Add support to set NmiReq appropriately to send NMI IPI.
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/20250828111213.208933-1-Neeraj.Upadhyay@amd.com
-rw-r--r-- | arch/x86/kernel/apic/x2apic_savic.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c index bdefe4cd4e29..8ed56e87c32f 100644 --- a/arch/x86/kernel/apic/x2apic_savic.c +++ b/arch/x86/kernel/apic/x2apic_savic.c @@ -133,12 +133,15 @@ static inline void self_ipi_reg_write(unsigned int vector) native_apic_msr_write(APIC_SELF_IPI, vector); } -static void send_ipi_dest(unsigned int cpu, unsigned int vector) +static void send_ipi_dest(unsigned int cpu, unsigned int vector, bool nmi) { - update_vector(cpu, APIC_IRR, vector, true); + if (nmi) + apic_set_reg(per_cpu_ptr(savic_page, cpu), SAVIC_NMI_REQ, 1); + else + update_vector(cpu, APIC_IRR, vector, true); } -static void send_ipi_allbut(unsigned int vector) +static void send_ipi_allbut(unsigned int vector, bool nmi) { unsigned int cpu, src_cpu; @@ -149,14 +152,17 @@ static void send_ipi_allbut(unsigned int vector) for_each_cpu(cpu, cpu_online_mask) { if (cpu == src_cpu) continue; - send_ipi_dest(cpu, vector); + send_ipi_dest(cpu, vector, nmi); } } -static inline void self_ipi(unsigned int vector) +static inline void self_ipi(unsigned int vector, bool nmi) { u32 icr_low = APIC_SELF_IPI | vector; + if (nmi) + icr_low |= APIC_DM_NMI; + native_x2apic_icr_write(icr_low, 0); } @@ -164,22 +170,24 @@ static void savic_icr_write(u32 icr_low, u32 icr_high) { unsigned int dsh, vector; u64 icr_data; + bool nmi; dsh = icr_low & APIC_DEST_ALLBUT; vector = icr_low & APIC_VECTOR_MASK; + nmi = ((icr_low & APIC_DM_FIXED_MASK) == APIC_DM_NMI); switch (dsh) { case APIC_DEST_SELF: - self_ipi(vector); + self_ipi(vector, nmi); break; case APIC_DEST_ALLINC: - self_ipi(vector); + self_ipi(vector, nmi); fallthrough; case APIC_DEST_ALLBUT: - send_ipi_allbut(vector); + send_ipi_allbut(vector, nmi); break; default: - send_ipi_dest(icr_high, vector); + send_ipi_dest(icr_high, vector, nmi); break; } |