[RFC PATCH v2 6/8] lib: sbi: Preserve supervisor AIA interrupt priorities

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


The siselect/sireg window exposes supervisor interrupt priority state
at selector values 0x30 through 0x3f.  Save and restore the implemented
bank across domain switches when Smaia is available.

Only sireg is accessed in this selector range.  The other sireg windows
can trap and must not be read.  IMSIC indirect registers at 0x70-0xff
are not handled in this change.

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 | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/lib/sbi/sbi_domain_context.c b/lib/sbi/sbi_domain_context.c
index 961fd182..34d1bc76 100644
--- a/lib/sbi/sbi_domain_context.c
+++ b/lib/sbi/sbi_domain_context.c
@@ -93,6 +93,8 @@ struct hart_context {
 	unsigned long scountinhibit;
 	/** Supervisor indirect CSR selector */
 	unsigned long siselect;
+	/** AIA supervisor interrupt priority register bank */
+	unsigned long siprio[16];
 
 	/** Float context state */
 	struct sbi_fp_context fp_ctx;
@@ -138,6 +140,26 @@ static void hart_context_set(struct sbi_domain *dom, u32 hartindex,
 	hart_context_get(sbi_domain_thishart_ptr(),			\
 			 current_hartindex())
 
+static void hart_aia_iprio_save(struct hart_context *ctx)
+{
+	unsigned int i;
+
+	for (i = 0; i < 16; i += __riscv_xlen / 32) {
+		csr_write(CSR_SISELECT, 0x30 + i);
+		ctx->siprio[i] = csr_read(CSR_SIREG);
+	}
+}
+
+static void hart_aia_iprio_restore(const struct hart_context *ctx)
+{
+	unsigned int i;
+
+	for (i = 0; i < 16; i += __riscv_xlen / 32) {
+		csr_write(CSR_SISELECT, 0x30 + i);
+		csr_write(CSR_SIREG, ctx->siprio[i]);
+	}
+}
+
 /**
  * Switches the HART context from the current domain to the target domain.
  * This includes changing domain assignments and reconfiguring PMP, as well
@@ -251,8 +273,14 @@ static int switch_to_next_domain_context(struct hart_context *ctx,
 	    (csr_read64(CSR_MENVCFG) & ENVCFG_CDE))
 		ctx->scountinhibit = csr_swap(CSR_SCOUNTINHIBIT,
 						 dom_ctx->scountinhibit);
-	if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SSCSRIND))
+	if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SSCSRIND) ||
+	    sbi_hart_has_extension(scratch, SBI_HART_EXT_SMAIA))
 		ctx->siselect = csr_swap(CSR_SISELECT, dom_ctx->siselect);
+	if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMAIA)) {
+		hart_aia_iprio_save(ctx);
+		hart_aia_iprio_restore(dom_ctx);
+		csr_write(CSR_SISELECT, dom_ctx->siselect);
+	}
 
 	/* Eager context switch for float */
 	if (sbi_hart_has_extension(scratch, SBI_HART_EXT_F) ||
-- 
2.43.0




More information about the opensbi mailing list