Commit 9de196f5 authored by Neeraj Upadhyay's avatar Neeraj Upadhyay Committed by Borislav Petkov (AMD)
Browse files

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: default avatarKishon Vijay Abraham I <kvijayab@amd.com>
Signed-off-by: default avatarKishon Vijay Abraham I <kvijayab@amd.com>
Signed-off-by: default avatarNeeraj Upadhyay <Neeraj.Upadhyay@amd.com>
Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: default avatarTianyu Lan <tiala@microsoft.com>
Link: https://lore.kernel.org/20250828111213.208933-1-Neeraj.Upadhyay@amd.com
parent c77683ec
Loading
Loading
Loading
Loading
+17 −9
Original line number Diff line number Diff line
@@ -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)
{
	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;
	}