summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhanpeng Zhang <zhangzhanpeng.jasper@bytedance.com>2026-07-31 15:18:20 +0800
committerAnup Patel <anup@brainfault.org>2026-09-01 12:57:33 +0530
commit35511bc6ee1c9c17b6a89b44c52e2044bb51b979 (patch)
tree600996ef9f8d2f2a48ddec5136ce05ace05310b6
parent22a5f98b3965adb2c5b2224da7ec4590807a618a (diff)
downloadopensbi-35511bc6ee1c9c17b6a89b44c52e2044bb51b979.tar.gz
opensbi-35511bc6ee1c9c17b6a89b44c52e2044bb51b979.zip
lib: sbi: sse: clear SPV for non-virtualized events
SSE injection sets hstatus.SPV to the virtualization state of the interrupted context before entering the supervisor handler. This patch completes that existing requirement and does not change the SSE ABI. The existing code sets SPV when the interrupted context is virtualized, but leaves it unchanged otherwise. A stale SPV value can therefore make an event that interrupted host execution appear to have interrupted a guest. Event completion can then resume with virtualization enabled. Clear SPV when the interrupted context is not virtualized so the handler-visible state matches the interrupted context. This also lets supervisor software, such as the Linux PMU and perf code, reliably tell whether an SSE interrupted host or virtualized execution. Fixes: c8cdf01d8f3a ("lib: sbi: Add support for Supervisor Software Events extension") Signed-off-by: Zhanpeng Zhang <zhangzhanpeng.jasper@bytedance.com> Reviewed-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/r/20260731071820.7318-1-zhangzhanpeng.jasper@bytedance.com Signed-off-by: Anup Patel <anup@brainfault.org>
-rw-r--r--lib/sbi/sbi_sse.c13
1 files changed, 4 insertions, 9 deletions
diff --git a/lib/sbi/sbi_sse.c b/lib/sbi/sbi_sse.c
index 818afb87..13d78e7c 100644
--- a/lib/sbi/sbi_sse.c
+++ b/lib/sbi/sbi_sse.c
@@ -563,19 +563,14 @@ static void sse_event_inject(struct sbi_sse_event *e,
if (misa_extension('H')) {
unsigned long hstatus = csr_read(CSR_HSTATUS);
-
-#if __riscv_xlen == 64
- if (regs->mstatus & MSTATUS_MPV)
-#elif __riscv_xlen == 32
- if (regs->mstatusH & MSTATUSH_MPV)
-#else
-#error "Unexpected __riscv_xlen"
-#endif
+ if (sbi_regs_from_virt(regs))
hstatus |= HSTATUS_SPV;
+ else
+ hstatus &= ~HSTATUS_SPV;
hstatus &= ~HSTATUS_SPVP;
if (hstatus & HSTATUS_SPV && regs->mstatus & SSTATUS_SPP)
- hstatus |= HSTATUS_SPVP;
+ hstatus |= HSTATUS_SPVP;
csr_write(CSR_HSTATUS, hstatus);
}