[RFC PATCH v2 43/45] arm64: smp: Add NMI support for LPI-backed IPIs

Jinjie Ruan ruanjinjie at huawei.com
Tue Jul 28 05:34:06 PDT 2026



在 2026/7/28 0:34, Vladimir Murzin 写道:
> LPI-backed IPIs are currently always requested and managed as regular
> IRQs. Allow IPIs selected by ipi_should_be_nmi() to be requested as
> NMIs, falling back to regular IRQs when the NMI request fails.
> 

It seems FEAT_NMI do not support LPI interrupt.

> Track which IPIs were successfully requested as NMIs so that the
> per-CPU enable and disable paths use the appropriate NMI helpers.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin at arm.com>
> ---
>  arch/arm64/kernel/smp.c | 34 +++++++++++++++++++++++++++++-----
>  1 file changed, 29 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
> index 9bacdbb2aa44..012633ea8347 100644
> --- a/arch/arm64/kernel/smp.c
> +++ b/arch/arm64/kernel/smp.c
> @@ -1123,16 +1123,24 @@ static const struct ipi_irq_ops ipi_sgi_ops = {
>  
>  static void ipi_lpi_enable(int cpu, int ipi)
>  {
> -	enable_irq(irq_desc_get_irq(get_ipi_desc(cpu, ipi)));
> +	if (test_bit(ipi, get_ipi_nmi_bitmap(cpu)))
> +		enable_nmi(irq_desc_get_irq(get_ipi_desc(cpu, ipi)));
> +	else
> +		enable_irq(irq_desc_get_irq(get_ipi_desc(cpu, ipi)));
>  }
>  
>  static void ipi_lpi_disable(int cpu, int ipi)
>  {
> -	disable_irq(irq_desc_get_irq(get_ipi_desc(cpu, ipi)));
> +	if (test_bit(ipi, get_ipi_nmi_bitmap(cpu)))
> +		disable_nmi_nosync(irq_desc_get_irq(get_ipi_desc(cpu, ipi)));
> +	else
> +		disable_irq(irq_desc_get_irq(get_ipi_desc(cpu, ipi)));
>  }
>  
>  static void ipi_lpi_setup(int ipi, int ncpus)
>  {
> +	bool is_nmi = ipi_should_be_nmi(ipi);
> +
>  	for (int cpu = 0; cpu < ncpus; cpu++) {
>  		int err, irq;
>  
> @@ -1141,13 +1149,29 @@ static void ipi_lpi_setup(int ipi, int ncpus)
>  		err = irq_force_affinity(irq, cpumask_of(cpu));
>  		WARN(err, "Could not force affinity IRQ %d, err=%d\n", irq, err);
>  
> -		err = request_irq(irq, ipi_handler, IRQF_NO_AUTOEN, "IPI",
> -				  NULL);
> -		WARN(err, "Could not request IRQ %d, err=%d\n", irq, err);
> +		/*
> +		 * Try to request NMI if it should be
> +		 */
> +		if (is_nmi && request_nmi(irq, ipi_handler, IRQF_PERCPU | IRQF_NO_AUTOEN, "IPI", NULL)) {
> +			/*
> +			 * Fallback to regular IRQ
> +			 */
> +			is_nmi = false;
> +		}
> +		/*
> +		 * Otherwise regular IRQ
> +		 */
> +		if (!is_nmi) {
> +			err = request_irq(irq, ipi_handler, IRQF_NO_AUTOEN, "IPI", NULL);
> +			WARN(err, "Could not request IRQ %d, err=%d\n", irq, err);
> +		}
>  
>  		irq_set_status_flags(irq, (IRQ_HIDDEN | IRQ_NO_BALANCING_MASK));
>  
>  		get_ipi_desc(cpu, ipi) = irq_to_desc(irq);
> +
> +		if (is_nmi)
> +			set_bit(ipi, get_ipi_nmi_bitmap(cpu));
>  	}
>  }
>  




More information about the linux-arm-kernel mailing list