F-12876: riscv_sbi: report remote-fence timeout as SBI error

sbi_wait_ipi_done() returned void, so a target hart that never
completed its fence within the bounded wait was invisible and both
the standard and legacy remote-fence interfaces reported success
while the caller kept relying on a fence that may not have run.
Return SBI_ERR_FAILED when any target does not complete within the
bound, and propagate it through both SBI interfaces (standard
RFENCE via err, legacy v0.1 remote fence via a0).
pull/883/head
Daniele Lacamera 2026-09-07 14:54:57 +02:00
parent 394f160a83
commit 49c1fff186
1 changed files with 12 additions and 5 deletions

View File

@ -536,13 +536,16 @@ static void sbi_post_ipi(unsigned long mask, unsigned long base,
* the targets increment ipi_done after executing the fences, so this
* completes only when every target has finished its fence. The SBI
* remote-fence calls are synchronous; the bound guards against a wedged
* target turning into a wedged caller. */
static void sbi_wait_ipi_done(unsigned long mask, unsigned long base,
* target turning into a wedged caller. Returns SBI_SUCCESS when every
* target completed, SBI_ERR_FAILED when any target did not complete
* within the bound. */
static long sbi_wait_ipi_done(unsigned long mask, unsigned long base,
unsigned long self)
{
unsigned long i;
unsigned long h;
uint32_t spin;
long err = SBI_SUCCESS;
/* SBI v0.2: hart_mask_base == -1 selects all harts (see sbi_post_ipi). */
if (base == (unsigned long)-1) {
base = 0;
@ -561,7 +564,11 @@ static void sbi_wait_ipi_done(unsigned long mask, unsigned long base,
while (sbi_ipi_done[h] <= sbi_ipi_wait_gen[h] && spin > 0U) {
spin--;
}
if (sbi_ipi_done[h] <= sbi_ipi_wait_gen[h]) {
err = SBI_ERR_FAILED;
}
}
return err;
}
/* Returns the (possibly advanced) PC to resume at. For ecall we skip the
@ -658,7 +665,7 @@ unsigned long sbi_handle_ecall(unsigned long *regs, unsigned long epc)
break;
}
sbi_post_ipi(regs[A0], regs[A1], op, hartid);
sbi_wait_ipi_done(regs[A0], regs[A1], hartid);
err = sbi_wait_ipi_done(regs[A0], regs[A1], hartid);
break;
}
@ -786,9 +793,9 @@ unsigned long sbi_handle_ecall(unsigned long *regs, unsigned long epc)
sbi_post_ipi(fmask, 0,
(eid == SBI_EXT_0_1_REMOTE_FENCE_I) ?
SBI_IPI_OP_FENCE_I : SBI_IPI_OP_SFENCE, hartid);
sbi_wait_ipi_done(fmask, 0, hartid);
err = sbi_wait_ipi_done(fmask, 0, hartid);
}
regs[A0] = 0;
regs[A0] = (unsigned long)err;
return epc + 4;
case SBI_EXT_0_1_SHUTDOWN:
wolfBoot_printf("[SBI] legacy SHUTDOWN requested\n");