Skip to content

Commit 5cf998b

Browse files
avpatelpalmer-dabbelt
authored andcommitted
RISC-V: self-contained IPI handling routine
Currently, the IPI handling routine riscv_software_interrupt() does not take any argument and also does not perform irq_enter()/irq_exit(). This patch makes IPI handling routine more self-contained by: 1. Passing "pt_regs *" argument 2. Explicitly doing irq_enter()/irq_exit() 3. Explicitly save/restore "pt_regs *" using set_irq_regs() With above changes, IPI handling routine does not depend on caller function to perform irq_enter()/irq_exit() and save/restore of "pt_regs *" hence its more self-contained. This also enables us to call IPI handling routine from IRQCHIP drivers. Signed-off-by: Anup Patel <[email protected]> Reviewed-by: Atish Patra <[email protected]> Reviewed-by: Palmer Dabbelt <[email protected]> Acked-by: Palmer Dabbelt <[email protected]> Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent e8c7ef7 commit 5cf998b

File tree

4 files changed

+22
-9
lines changed

4 files changed

+22
-9
lines changed

arch/riscv/include/asm/irq.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#define NR_IRQS 0
1414

1515
void riscv_timer_interrupt(void);
16-
void riscv_software_interrupt(void);
1716

1817
#include <asm-generic/irq.h>
1918

arch/riscv/include/asm/smp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ void show_ipi_stats(struct seq_file *p, int prec);
2828
/* SMP initialization hook for setup_arch */
2929
void __init setup_smp(void);
3030

31+
/* Called from C code, this handles an IPI. */
32+
void handle_IPI(struct pt_regs *regs);
33+
3134
/* Hook for the generic smp_call_function_many() routine. */
3235
void arch_send_call_function_ipi_mask(struct cpumask *mask);
3336

arch/riscv/kernel/irq.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,32 +19,36 @@ int arch_show_interrupts(struct seq_file *p, int prec)
1919

2020
asmlinkage __visible void __irq_entry do_IRQ(struct pt_regs *regs)
2121
{
22-
struct pt_regs *old_regs = set_irq_regs(regs);
22+
struct pt_regs *old_regs;
2323

24-
irq_enter();
2524
switch (regs->cause & ~CAUSE_IRQ_FLAG) {
2625
case RV_IRQ_TIMER:
26+
old_regs = set_irq_regs(regs);
27+
irq_enter();
2728
riscv_timer_interrupt();
29+
irq_exit();
30+
set_irq_regs(old_regs);
2831
break;
2932
#ifdef CONFIG_SMP
3033
case RV_IRQ_SOFT:
3134
/*
3235
* We only use software interrupts to pass IPIs, so if a non-SMP
3336
* system gets one, then we don't know what to do.
3437
*/
35-
riscv_software_interrupt();
38+
handle_IPI(regs);
3639
break;
3740
#endif
3841
case RV_IRQ_EXT:
42+
old_regs = set_irq_regs(regs);
43+
irq_enter();
3944
handle_arch_irq(regs);
45+
irq_exit();
46+
set_irq_regs(old_regs);
4047
break;
4148
default:
4249
pr_alert("unexpected interrupt cause 0x%lx", regs->cause);
4350
BUG();
4451
}
45-
irq_exit();
46-
47-
set_irq_regs(old_regs);
4852
}
4953

5054
void __init init_IRQ(void)

arch/riscv/kernel/smp.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,14 @@ static inline void clear_ipi(void)
123123
clint_clear_ipi(cpuid_to_hartid_map(smp_processor_id()));
124124
}
125125

126-
void riscv_software_interrupt(void)
126+
void handle_IPI(struct pt_regs *regs)
127127
{
128+
struct pt_regs *old_regs = set_irq_regs(regs);
128129
unsigned long *pending_ipis = &ipi_data[smp_processor_id()].bits;
129130
unsigned long *stats = ipi_data[smp_processor_id()].stats;
130131

132+
irq_enter();
133+
131134
clear_ipi();
132135

133136
while (true) {
@@ -138,7 +141,7 @@ void riscv_software_interrupt(void)
138141

139142
ops = xchg(pending_ipis, 0);
140143
if (ops == 0)
141-
return;
144+
goto done;
142145

143146
if (ops & (1 << IPI_RESCHEDULE)) {
144147
stats[IPI_RESCHEDULE]++;
@@ -160,6 +163,10 @@ void riscv_software_interrupt(void)
160163
/* Order data access and bit testing. */
161164
mb();
162165
}
166+
167+
done:
168+
irq_exit();
169+
set_irq_regs(old_regs);
163170
}
164171

165172
static const char * const ipi_names[] = {

0 commit comments

Comments
 (0)