summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChen Pei <[email protected]>2026-06-12 19:52:07 +0800
committerAnup Patel <[email protected]>2026-07-21 11:28:59 +0530
commit110f28518a15e84498bcc6337242160c500857fe (patch)
treea249042fd19bccc4a8809fafa13a452ede5bceda
parent92bea7bdb2334a9274a824f9592026093febec7c (diff)
lib: sbi_ipi: Validate hartids against domain, not HSM state
Commit 37eaca4ab33d ("lib: sbi_ipi: Return error for invalid hartids") added a weight check against the HSM-interruptible mask, which excludes harts in STOPPED state. This causes sbi_ipi_send_many() to return SBI_EINVAL when the kernel sends a remote fence (e.g. TLB shootdown) whose hmask includes a hart that was stopped by CPU hotplug: __sbi_rfence_v02_call: hbase = [0] hmask = [0x3] failed (error [-22]) Validate requested hartids against the domain's assigned hartmask instead. This still rejects truly invalid or cross-domain hartids, but allows HSM-STOPPED harts to be silently skipped — which is safe because a stopped hart will do a full local TLB flush on its next HSM start before re-entering S-mode. Fixes: 37eaca4ab33d ("lib: sbi_ipi: Return error for invalid hartids") Signed-off-by: Chen Pei <[email protected]> Reviewed-by: Anup Patel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
-rw-r--r--lib/sbi/sbi_ipi.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/lib/sbi/sbi_ipi.c b/lib/sbi/sbi_ipi.c
index 5b2d2f72..b04a5877 100644
--- a/lib/sbi/sbi_ipi.c
+++ b/lib/sbi/sbi_ipi.c
@@ -136,6 +136,7 @@ int sbi_ipi_send_many(ulong hmask, ulong hbase, u32 event, void *data)
if (hbase != -1UL) {
struct sbi_hartmask tmp_mask = { 0 };
+ struct sbi_hartmask domain_mask;
int count = sbi_popcount(hmask);
for (i = hbase; hmask; i++, hmask >>= 1) {
@@ -143,10 +144,16 @@ int sbi_ipi_send_many(ulong hmask, ulong hbase, u32 event, void *data)
sbi_hartmask_set_hartid(i, &tmp_mask);
}
- sbi_hartmask_and(&target_mask, &target_mask, &tmp_mask);
+ /* Validate hartids against domain assignment, not HSM state */
+ rc = sbi_domain_get_assigned_hartmask(dom, &domain_mask);
+ if (rc)
+ return rc;
- if (sbi_hartmask_weight(&target_mask) != count)
+ sbi_hartmask_and(&domain_mask, &domain_mask, &tmp_mask);
+ if (sbi_hartmask_weight(&domain_mask) != count)
return SBI_EINVAL;
+
+ sbi_hartmask_and(&target_mask, &target_mask, &tmp_mask);
}
/* Send IPIs */