On Wed, Jul 2, 2025 at 5:16 PM Anup Patel <apatel@xxxxxxxxxxxxxxxx> wrote: > > When injecting IPIs to a set of harts, the IMSIC IPI support will do > a separate MMIO write to the SETIPNUM_LE register of each target hart. > This means on a platform where IMSIC is trap-n-emulated, there will be > N MMIO traps when injecting IPI to N target harts hence IMSIC IPIs will > be slow on such platform compared to the SBI IPI extension. > > Unfortunately, there is no DT, ACPI, or any other way of discovering > whether the underlying IMSIC is trap-n-emulated. Using MMIO write to > the SETIPNUM_LE register for injecting IPI is purely a software choice > in the IMSIC driver hence add a kernel parameter to allow users disable > IMSIC IPIs on platforms with trap-n-emulated IMSIC. > > Signed-off-by: Anup Patel <apatel@xxxxxxxxxxxxxxxx> > --- > Documentation/admin-guide/kernel-parameters.txt | 7 +++++++ > drivers/irqchip/irq-riscv-imsic-early.c | 12 ++++++++++++ > 2 files changed, 19 insertions(+) > > diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt > index f1f2c0874da9..7f0e12d0d260 100644 > --- a/Documentation/admin-guide/kernel-parameters.txt > +++ b/Documentation/admin-guide/kernel-parameters.txt > @@ -2538,6 +2538,13 @@ > requires the kernel to be built with > CONFIG_ARM64_PSEUDO_NMI. > > + irqchip.riscv_imsic_noipi > + [RISC-V,EARLY] > + Force the kernel to not use IMSIC software injected MSIs > + as IPIs. Intended for system where IMSIC is trap-n-emulated, > + and thus want to reduce MMIO traps when triggering IPIs > + to multiple harts. > + > irqfixup [HW] > When an interrupt is not handled search all handlers > for it. Intended to get systems with badly broken > diff --git a/drivers/irqchip/irq-riscv-imsic-early.c b/drivers/irqchip/irq-riscv-imsic-early.c > index 1dbc41d7fe80..c6fba92dd5a9 100644 > --- a/drivers/irqchip/irq-riscv-imsic-early.c > +++ b/drivers/irqchip/irq-riscv-imsic-early.c > @@ -9,6 +9,7 @@ > #include <linux/cpu.h> > #include <linux/export.h> > #include <linux/interrupt.h> > +#include <linux/init.h> > #include <linux/io.h> > #include <linux/irq.h> > #include <linux/irqchip.h> > @@ -22,6 +23,14 @@ > #include "irq-riscv-imsic-state.h" > > static int imsic_parent_irq; > +static bool imsic_noipi; > + > +static int __init imsic_noipi_cfg(char *buf) > +{ > + imsic_noipi = true; > + return 0; > +} > +early_param("irqchip.riscv_imsic_noipi", imsic_noipi_cfg); > > #ifdef CONFIG_SMP > static void imsic_ipi_send(unsigned int cpu) > @@ -47,6 +56,9 @@ static int __init imsic_ipi_domain_init(void) > { > int virq; > > + if (imsic_noipi) > + return 0; > + We can skip enabling/disabling IMSIC_IPI_ID in imsic_ipi_starting_cpu() and imsic_ipi_dying_cpu() when imsic_noipi is set. In addition to the above, we can also re-use the reserved IPI ID for devices. I will quickly send v3. Apologies for the noise. Regards, Anup