[RFC PATCH v2 3/8] lib: sbi: Preserve Sstc timer state across domain switches

Theodorus Wensan Februanto theodoruswensanfebruanto025 at gmail.com
Fri Oct 23 00:09:20 PDT 2026


The Sstc extension provides a supervisor timer comparison register.
Without preserving this value, another domain can replace the
previous domain's timer deadline.

Keep a per-domain timer comparison value and initialize new domains
to a future deadline to avoid immediate timer interrupts.

Link: https://github.com/riscv-software-src/opensbi/issues/433
Signed-off-by: Theodorus Wensan Februanto <theodoruswensanfebruanto025 at gmail.com>
---
 include/sbi/riscv_encoding.h |  2 ++
 lib/sbi/sbi_domain_context.c | 15 +++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/sbi/riscv_encoding.h b/include/sbi/riscv_encoding.h
index ffe7666c..60a0c39e 100644
--- a/include/sbi/riscv_encoding.h
+++ b/include/sbi/riscv_encoding.h
@@ -448,6 +448,8 @@
 #define CSR_VSCAUSE			0x242
 #define CSR_VSTVAL			0x243
 #define CSR_VSIP			0x244
+#define CSR_VSTIMECMP		0x24D
+#define CSR_VSTIMECMPH		0x25D
 #define CSR_VSATP			0x280
 
 /* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */
diff --git a/lib/sbi/sbi_domain_context.c b/lib/sbi/sbi_domain_context.c
index 79419edc..33c19d04 100644
--- a/lib/sbi/sbi_domain_context.c
+++ b/lib/sbi/sbi_domain_context.c
@@ -52,6 +52,11 @@ struct hart_context_hext {
 	unsigned long vsatp;
 };
 
+struct hart_context_sstc {
+	u64 stimecmp;
+	u64 vstimecmp;
+};
+
 /** Context representation for a hart within a domain */
 struct hart_context {
 	/** Trap-related states such as GPRs, mepc, and mstatus */
@@ -83,6 +88,7 @@ struct hart_context {
 	unsigned long senvcfg;
 	/** Supervisor resource management configuration register */
 	unsigned long srmcfg;
+	struct hart_context_sstc sstc;
 
 	/** Float context state */
 	struct sbi_fp_context fp_ctx;
@@ -231,6 +237,12 @@ static int switch_to_next_domain_context(struct hart_context *ctx,
 		ctx->senvcfg	= csr_swap(CSR_SENVCFG, dom_ctx->senvcfg);
 	if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SSQOSID))
 		ctx->srmcfg	= csr_swap(CSR_SRMCFG, dom_ctx->srmcfg);
+	if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SSTC)) {
+		ctx->sstc.stimecmp = csr_swap64(CSR_STIMECMP, dom_ctx->sstc.stimecmp);
+		if (misa_extension('H'))
+			ctx->sstc.vstimecmp = csr_swap64(CSR_VSTIMECMP,
+						 dom_ctx->sstc.vstimecmp);
+	}
 
 	/* Eager context switch for float */
 	if (sbi_hart_has_extension(scratch, SBI_HART_EXT_F) ||
@@ -292,6 +304,9 @@ static int hart_context_init(u32 hartindex)
 		if (!ctx)
 			return SBI_ENOMEM;
 
+		ctx->sstc.stimecmp = ~0ULL;
+		ctx->sstc.vstimecmp = ~0ULL;
+
 		if (sbi_hart_has_extension(sbi_scratch_thishart_ptr(),
 					   SBI_HART_EXT_V)) {
 			vec_size = sbi_vector_context_size();
-- 
2.43.0




More information about the opensbi mailing list