[RFC PATCH 2/5] lib: sbi: Save core hypervisor state across domain switches

Anup Patel anup at brainfault.org
Thu Oct 22 22:58:27 PDT 2026


On Fri, Oct 23, 2026 at 8:14 AM whensun
<theodoruswensanfebruanto025 at gmail.com> wrote:
>
> From: Theodorus Wensan Februanto <theodoruswensanfebruanto025 at gmail.com>

Patch subject should be "lib: sbi: Preserve hypervisor state across
domain switches".

>
> 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 | 36 ++++++++++++++++++++++++++++++++++++
>  1 file changed, 36 insertions(+)
>
> diff --git a/lib/sbi/sbi_domain_context.c b/lib/sbi/sbi_domain_context.c
> index 26980658..caec5486 100644
> --- a/lib/sbi/sbi_domain_context.c
> +++ b/lib/sbi/sbi_domain_context.c
> @@ -44,6 +44,22 @@ struct hart_context {
>         unsigned long sip;
>         /** Supervisor address translation and protection register */
>         unsigned long satp;
> +
> +       /** Hypervisor state */
> +       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

Please create another struct hart_context_hext and use it
here.

Also, you need to preserve various VS<xyz> CSRs as well.

>         /** Counter-enable register */
>         unsigned long scounteren;
>         /** Supervisor environment configuration register */
> @@ -141,6 +157,26 @@ 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->hstatus = csr_swap(CSR_HSTATUS, dom_ctx->hstatus);
> +               ctx->hedeleg = csr_swap(CSR_HEDELEG, dom_ctx->hedeleg);
> +               ctx->hideleg = csr_swap(CSR_HIDELEG, dom_ctx->hideleg);
> +               ctx->hie = csr_swap(CSR_HIE, dom_ctx->hie);
> +               ctx->hgeie = csr_swap(CSR_HGEIE, dom_ctx->hgeie);
> +               ctx->henvcfg = csr_swap64(CSR_HENVCFG, dom_ctx->henvcfg);
> +               ctx->htval = csr_swap(CSR_HTVAL, dom_ctx->htval);
> +               ctx->htinst = csr_swap(CSR_HTINST, dom_ctx->htinst);
> +               ctx->hvip = csr_swap(CSR_HVIP, dom_ctx->hvip);
> +               ctx->hgatp = csr_swap(CSR_HGATP, dom_ctx->hgatp);
> +#if __riscv_xlen == 32
> +               if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMAIA)) {
> +                       ctx->hidelegh = csr_swap(CSR_HIDELEGH,
> +                                               dom_ctx->hidelegh);
> +                       ctx->hviph = csr_swap(CSR_HVIPH, dom_ctx->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
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi

Regards,
Anup



More information about the opensbi mailing list