[RFC PATCH v2 1/8] lib: sbi: Preserve hypervisor state across domain switches
Theodorus Wensan Februanto
theodoruswensanfebruanto025 at gmail.com
Fri Oct 23 00:09:18 PDT 2026
The domain context switch saves several supervisor CSRs but leaves
hypervisor trap, delegation, interrupt, and translation state shared
between domains.
Exchange core writable H-extension CSRs when H is available. Use a
64-bit exchange for henvcfg and check Smaia before accessing RV32
high-half AIA registers.
The domain protection reconfiguration performs SFENCE/HFENCE after
the CSR exchange.
Link: https://github.com/riscv-software-src/opensbi/issues/433
Signed-off-by: Theodorus Wensan Februanto <theodoruswensanfebruanto025 at gmail.com>
---
lib/sbi/sbi_domain_context.c | 70 ++++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
diff --git a/lib/sbi/sbi_domain_context.c b/lib/sbi/sbi_domain_context.c
index 0861d541..4bafda5b 100644
--- a/lib/sbi/sbi_domain_context.c
+++ b/lib/sbi/sbi_domain_context.c
@@ -21,6 +21,34 @@
#include <sbi/sbi_vector.h>
#include <sbi/sbi_fp.h>
+struct hart_context_hext {
+ unsigned long hstatus;
+ unsigned long hedeleg;
+ unsigned long hideleg;
+ unsigned long hie;
+ unsigned long hgeie;
+ u64 henvcfg;
+ unsigned long htval;
+ unsigned long htinst;
+ unsigned long hvip;
+ unsigned long hgatp;
+#if __riscv_xlen == 32
+ unsigned long hidelegh;
+ unsigned long hviph;
+#endif
+ unsigned long hcounteren;
+ u64 htimedelta;
+ unsigned long vsstatus;
+ unsigned long vsie;
+ unsigned long vstvec;
+ unsigned long vsscratch;
+ unsigned long vsepc;
+ unsigned long vscause;
+ unsigned long vstval;
+ unsigned long vsip;
+ unsigned long vsatp;
+};
+
/** Context representation for a hart within a domain */
struct hart_context {
/** Trap-related states such as GPRs, mepc, and mstatus */
@@ -44,6 +72,8 @@ struct hart_context {
unsigned long sip;
/** Supervisor address translation and protection register */
unsigned long satp;
+
+ struct hart_context_hext hext;
/** Counter-enable register */
unsigned long scounteren;
/** Supervisor environment configuration register */
@@ -139,6 +169,46 @@ static int switch_to_next_domain_context(struct hart_context *ctx,
ctx->stval = csr_swap(CSR_STVAL, dom_ctx->stval);
ctx->sip = csr_swap(CSR_SIP, dom_ctx->sip);
ctx->satp = csr_swap(CSR_SATP, dom_ctx->satp);
+
+ if (misa_extension('H')) {
+ ctx->hext.hstatus = csr_swap(CSR_HSTATUS, dom_ctx->hext.hstatus);
+ ctx->hext.hedeleg = csr_swap(CSR_HEDELEG, dom_ctx->hext.hedeleg);
+ ctx->hext.hideleg = csr_swap(CSR_HIDELEG, dom_ctx->hext.hideleg);
+ ctx->hext.hie = csr_swap(CSR_HIE, dom_ctx->hext.hie);
+ ctx->hext.hgeie = csr_swap(CSR_HGEIE, dom_ctx->hext.hgeie);
+ ctx->hext.henvcfg = csr_swap64(CSR_HENVCFG, dom_ctx->hext.henvcfg);
+ ctx->hext.htval = csr_swap(CSR_HTVAL, dom_ctx->hext.htval);
+ ctx->hext.htinst = csr_swap(CSR_HTINST, dom_ctx->hext.htinst);
+ ctx->hext.hvip = csr_swap(CSR_HVIP, dom_ctx->hext.hvip);
+ ctx->hext.hgatp = csr_swap(CSR_HGATP, dom_ctx->hext.hgatp);
+ ctx->hext.hcounteren = csr_swap(CSR_HCOUNTEREN, dom_ctx->hext.hcounteren);
+ ctx->hext.htimedelta = csr_swap64(CSR_HTIMEDELTA, dom_ctx->hext.htimedelta);
+ ctx->hext.vsstatus = csr_swap(CSR_VSSTATUS,
+ dom_ctx->hext.vsstatus);
+ ctx->hext.vsie = csr_swap(CSR_VSIE,
+ dom_ctx->hext.vsie);
+ ctx->hext.vstvec = csr_swap(CSR_VSTVEC,
+ dom_ctx->hext.vstvec);
+ ctx->hext.vsscratch = csr_swap(CSR_VSSCRATCH,
+ dom_ctx->hext.vsscratch);
+ ctx->hext.vsepc = csr_swap(CSR_VSEPC,
+ dom_ctx->hext.vsepc);
+ ctx->hext.vscause = csr_swap(CSR_VSCAUSE,
+ dom_ctx->hext.vscause);
+ ctx->hext.vstval = csr_swap(CSR_VSTVAL,
+ dom_ctx->hext.vstval);
+ ctx->hext.vsip = csr_swap(CSR_VSIP,
+ dom_ctx->hext.vsip);
+ ctx->hext.vsatp = csr_swap(CSR_VSATP,
+ dom_ctx->hext.vsatp);
+#if __riscv_xlen == 32
+ if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMAIA)) {
+ ctx->hext.hidelegh = csr_swap(CSR_HIDELEGH,
+ dom_ctx->hext.hidelegh);
+ ctx->hext.hviph = csr_swap(CSR_HVIPH, dom_ctx->hext.hviph);
+ }
+#endif
+ }
if (sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_10)
ctx->scounteren = csr_swap(CSR_SCOUNTEREN, dom_ctx->scounteren);
if (sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_12)
--
2.43.0
More information about the opensbi
mailing list