mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2025-10-09 18:12:18 +01:00
lib: sbi: Add hart context init when first call enter
When entering sbi_domain_context_enter for the first time, the hart context may not be initialized. Add initialization code. Signed-off-by: Xiang W <wxjstz@126.com> Reviewed-by: Anup Patel <anup@brainfault.org> Link: https://lore.kernel.org/r/20250903044619.394019-3-wxjstz@126.com Signed-off-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
@@ -165,11 +165,50 @@ static int switch_to_next_domain_context(struct hart_context *ctx,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hart_context_init(u32 hartindex)
|
||||||
|
{
|
||||||
|
struct hart_context *ctx;
|
||||||
|
struct sbi_domain *dom;
|
||||||
|
|
||||||
|
sbi_domain_for_each(dom) {
|
||||||
|
if (!sbi_hartmask_test_hartindex(hartindex,
|
||||||
|
dom->possible_harts))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ctx = sbi_zalloc(sizeof(struct hart_context));
|
||||||
|
if (!ctx)
|
||||||
|
return SBI_ENOMEM;
|
||||||
|
|
||||||
|
/* Bind context and domain */
|
||||||
|
ctx->dom = dom;
|
||||||
|
hart_context_set(dom, hartindex, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int sbi_domain_context_enter(struct sbi_domain *dom)
|
int sbi_domain_context_enter(struct sbi_domain *dom)
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
|
struct hart_context *dom_ctx;
|
||||||
struct hart_context *ctx = hart_context_thishart_get();
|
struct hart_context *ctx = hart_context_thishart_get();
|
||||||
struct hart_context *dom_ctx = hart_context_get(dom, current_hartindex());
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If it's first time to call `enter` on the current hart, no
|
||||||
|
* context allocated before. Allocate context for each valid
|
||||||
|
* domain on the current hart.
|
||||||
|
*/
|
||||||
|
if (!ctx) {
|
||||||
|
rc = hart_context_init(current_hartindex());
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
ctx = hart_context_thishart_get();
|
||||||
|
if (!ctx)
|
||||||
|
return SBI_EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dom_ctx = hart_context_get(dom, current_hartindex());
|
||||||
/* Validate the domain context existence */
|
/* Validate the domain context existence */
|
||||||
if (!dom_ctx)
|
if (!dom_ctx)
|
||||||
return SBI_EINVAL;
|
return SBI_EINVAL;
|
||||||
@@ -182,6 +221,7 @@ int sbi_domain_context_enter(struct sbi_domain *dom)
|
|||||||
|
|
||||||
int sbi_domain_context_exit(void)
|
int sbi_domain_context_exit(void)
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
u32 hartindex = current_hartindex();
|
u32 hartindex = current_hartindex();
|
||||||
struct sbi_domain *dom;
|
struct sbi_domain *dom;
|
||||||
struct hart_context *ctx = hart_context_thishart_get();
|
struct hart_context *ctx = hart_context_thishart_get();
|
||||||
@@ -193,21 +233,13 @@ int sbi_domain_context_exit(void)
|
|||||||
* its context on the current hart if valid.
|
* its context on the current hart if valid.
|
||||||
*/
|
*/
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
sbi_domain_for_each(dom) {
|
rc = hart_context_init(current_hartindex());
|
||||||
if (!sbi_hartmask_test_hartindex(hartindex,
|
if (rc)
|
||||||
dom->possible_harts))
|
return rc;
|
||||||
continue;
|
|
||||||
|
|
||||||
dom_ctx = sbi_zalloc(sizeof(struct hart_context));
|
|
||||||
if (!dom_ctx)
|
|
||||||
return SBI_ENOMEM;
|
|
||||||
|
|
||||||
/* Bind context and domain */
|
|
||||||
dom_ctx->dom = dom;
|
|
||||||
hart_context_set(dom, hartindex, dom_ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = hart_context_thishart_get();
|
ctx = hart_context_thishart_get();
|
||||||
|
if (!ctx)
|
||||||
|
return SBI_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dom_ctx = ctx->prev_ctx;
|
dom_ctx = ctx->prev_ctx;
|
||||||
|
Reference in New Issue
Block a user