Skip to content
Permalink
Browse files
RISC-V: Allow marking IPIs as suitable for remote FENCEs
To do remote FENCEs (i.e. remote TLB flushes) using IPI calls on
Linux RISC-V, we need hardware mechanism to directly inject IPI
from kernel instead of using SBI calls.

The upcoming ACLINT [M|S]SWI devices and AIA IMSIC devices allow
direct IPI injection from kernel. To support this, we extend the
riscv_ipi_set_virq_range() function so that irqchip drivers can
mark IPIs as suitable for remote FENCEs.

Signed-off-by: Anup Patel <anup.patel@wdc.com>
  • Loading branch information
avpatel committed Jun 17, 2021
1 parent 080895c commit 1f552b2190b2e0b7ae50beb1b599756a2fcf498b
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 3 deletions.
@@ -16,6 +16,9 @@ struct seq_file;
extern unsigned long boot_cpu_hartid;

#ifdef CONFIG_SMP

#include <linux/jump_label.h>

/*
* Mapping between linux logical cpu index and hartid.
*/
@@ -47,7 +50,12 @@ void riscv_ipi_disable(void);
void riscv_ipi_setup(void);

/* Set the IPI interrupt numbers for arch (called by irqchip drivers) */
void riscv_ipi_set_virq_range(int virq, int nr_irqs);
void riscv_ipi_set_virq_range(int virq, int nr_irqs, bool use_for_rfence);

/* Check if we can use IPIs for remote FENCEs */
DECLARE_STATIC_KEY_FALSE(riscv_ipi_for_rfence);
#define riscv_use_ipi_for_rfence() \
static_branch_unlikely(&riscv_ipi_for_rfence)

/* Secondary hart entry */
asmlinkage void smp_callin(void);
@@ -106,6 +114,11 @@ static inline void riscv_ipi_set_virq_range(int virq, int nr)
{
}

static inline bool riscv_use_ipi_for_rfence(void)
{
return false;
}

#endif /* CONFIG_SMP */

#if defined(CONFIG_HOTPLUG_CPU) && (CONFIG_SMP)
@@ -153,7 +153,7 @@ static int __init sbi_ipi_set_virq(void)
return -ENOMEM;
}

riscv_ipi_set_virq_range(virq, BITS_PER_LONG);
riscv_ipi_set_virq_range(virq, BITS_PER_LONG, false);

return 0;
}
@@ -178,14 +178,21 @@ void riscv_ipi_setup(void)
riscv_ipi_enable();
}

void riscv_ipi_set_virq_range(int virq, int nr)
DEFINE_STATIC_KEY_FALSE(riscv_ipi_for_rfence);
EXPORT_SYMBOL_GPL(riscv_ipi_for_rfence);

void riscv_ipi_set_virq_range(int virq, int nr, bool use_for_rfence)
{
if (WARN_ON(ipi_virq_base))
return;

WARN_ON(nr < IPI_MAX);
nr_ipi = min(nr, IPI_MAX);
ipi_virq_base = virq;
if (use_for_rfence)
static_branch_enable(&riscv_ipi_for_rfence);
else
static_branch_disable(&riscv_ipi_for_rfence);
}
EXPORT_SYMBOL_GPL(riscv_ipi_set_virq_range);

0 comments on commit 1f552b2

Please sign in to comment.