lib: sbi: Add error handling to switch_to_next_domain_context

Add error handling to switch_to_next_domain_context to ensure
legal input. When switching contexts, ensure that the target to
be switched is different from the current one.

Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
Link: https://lore.kernel.org/r/20250903044619.394019-2-wxjstz@126.com
Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
Xiang W
2025-09-03 12:46:02 +08:00
committed by Anup Patel
parent 5de8c1d499
commit f7d060c26a

View File

@@ -92,17 +92,23 @@ static void hart_context_set(struct sbi_domain *dom, u32 hartindex,
* *
* @param ctx pointer to the current HART context * @param ctx pointer to the current HART context
* @param dom_ctx pointer to the target domain context * @param dom_ctx pointer to the target domain context
*
* @return 0 on success and negative error code on failure
*/ */
static void switch_to_next_domain_context(struct hart_context *ctx, static int switch_to_next_domain_context(struct hart_context *ctx,
struct hart_context *dom_ctx) struct hart_context *dom_ctx)
{ {
u32 hartindex = current_hartindex(); u32 hartindex = current_hartindex();
struct sbi_trap_context *trap_ctx; struct sbi_trap_context *trap_ctx;
struct sbi_domain *current_dom = ctx->dom; struct sbi_domain *current_dom, *target_dom;
struct sbi_domain *target_dom = dom_ctx->dom;
struct sbi_scratch *scratch = sbi_scratch_thishart_ptr(); struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
unsigned int pmp_count = sbi_hart_pmp_count(scratch); unsigned int pmp_count = sbi_hart_pmp_count(scratch);
if (!ctx || !dom_ctx || ctx == dom_ctx)
return SBI_EINVAL;
current_dom = ctx->dom;
target_dom = dom_ctx->dom;
/* Assign current hart to target domain */ /* Assign current hart to target domain */
spin_lock(&current_dom->assigned_harts_lock); spin_lock(&current_dom->assigned_harts_lock);
sbi_hartmask_clear_hartindex(hartindex, &current_dom->assigned_harts); sbi_hartmask_clear_hartindex(hartindex, &current_dom->assigned_harts);
@@ -156,6 +162,7 @@ static void switch_to_next_domain_context(struct hart_context *ctx,
else else
sbi_hsm_hart_stop(scratch, true); sbi_hsm_hart_stop(scratch, true);
} }
return 0;
} }
int sbi_domain_context_enter(struct sbi_domain *dom) int sbi_domain_context_enter(struct sbi_domain *dom)
@@ -170,9 +177,7 @@ int sbi_domain_context_enter(struct sbi_domain *dom)
/* Update target context's previous context to indicate the caller */ /* Update target context's previous context to indicate the caller */
dom_ctx->prev_ctx = ctx; dom_ctx->prev_ctx = ctx;
switch_to_next_domain_context(ctx, dom_ctx); return switch_to_next_domain_context(ctx, dom_ctx);
return 0;
} }
int sbi_domain_context_exit(void) int sbi_domain_context_exit(void)
@@ -226,9 +231,7 @@ int sbi_domain_context_exit(void)
if (!dom_ctx) if (!dom_ctx)
dom_ctx = hart_context_get(&root, hartindex); dom_ctx = hart_context_get(&root, hartindex);
switch_to_next_domain_context(ctx, dom_ctx); return switch_to_next_domain_context(ctx, dom_ctx);
return 0;
} }
int sbi_domain_context_init(void) int sbi_domain_context_init(void)