diff --git a/include/sbi/sbi_hsm.h b/include/sbi/sbi_hsm.h index 11ae3ac3..65aff9f1 100644 --- a/include/sbi/sbi_hsm.h +++ b/include/sbi/sbi_hsm.h @@ -17,6 +17,7 @@ #define SBI_HART_STOPPING 1 #define SBI_HART_STARTING 2 #define SBI_HART_STARTED 3 +#define SBI_HART_UNKNOWN 4 int sbi_hsm_init(struct sbi_scratch *scratch, u32 hartid, bool cold_boot); void __noreturn sbi_hsm_exit(struct sbi_scratch *scratch); diff --git a/lib/sbi/sbi_hsm.c b/lib/sbi/sbi_hsm.c index b4034237..12199241 100644 --- a/lib/sbi/sbi_hsm.c +++ b/lib/sbi/sbi_hsm.c @@ -61,6 +61,9 @@ int sbi_hsm_hart_get_state(u32 hartid) struct sbi_scratch *scratch; scratch = sbi_hartid_to_scratch(hartid); + if (!scratch) + return SBI_HART_UNKNOWN; + hdata = sbi_scratch_offset_ptr(scratch, hart_data_offset); return atomic_read(&hdata->state); @@ -165,6 +168,9 @@ int sbi_hsm_init(struct sbi_scratch *scratch, u32 hartid, bool cold_boot) /* Initialize hart state data for every hart */ for (i = 0; i < hart_count; i++) { rscratch = sbi_hartid_to_scratch(i); + if (!rscratch) + continue; + hdata = sbi_scratch_offset_ptr(rscratch, hart_data_offset); ATOMIC_INIT(&hdata->state, @@ -212,14 +218,17 @@ fail_exit: int sbi_hsm_hart_start(struct sbi_scratch *scratch, u32 hartid, ulong saddr, ulong priv) { + int rc; unsigned long init_count; unsigned int hstate; - int rc; + struct sbi_scratch *rscratch; + struct sbi_hsm_data *hdata; const struct sbi_platform *plat = sbi_platform_ptr(scratch); - struct sbi_scratch *rscratch = sbi_hartid_to_scratch(hartid); - struct sbi_hsm_data *hdata = sbi_scratch_offset_ptr(rscratch, - hart_data_offset); + rscratch = sbi_hartid_to_scratch(hartid); + if (!rscratch) + return SBI_EINVAL; + hdata = sbi_scratch_offset_ptr(rscratch, hart_data_offset); if (sbi_platform_hart_disabled(plat, hartid)) return SBI_EINVAL; hstate = arch_atomic_cmpxchg(&hdata->state, SBI_HART_STOPPED, diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c index 69015281..f75b904a 100644 --- a/lib/sbi/sbi_init.c +++ b/lib/sbi/sbi_init.c @@ -305,6 +305,9 @@ unsigned long sbi_init_count(u32 hartid) return 0; scratch = sbi_hartid_to_scratch(hartid); + if (!scratch) + return 0; + init_count = sbi_scratch_offset_ptr(scratch, init_count_offset); return *init_count; diff --git a/lib/sbi/sbi_ipi.c b/lib/sbi/sbi_ipi.c index fdd6e8ae..78db7520 100644 --- a/lib/sbi/sbi_ipi.c +++ b/lib/sbi/sbi_ipi.c @@ -41,11 +41,10 @@ static int sbi_ipi_send(struct sbi_scratch *scratch, u32 remote_hartid, return SBI_EINVAL; ipi_ops = ipi_ops_array[event]; - /* - * Set IPI type on remote hart's scratch area and - * trigger the interrupt - */ remote_scratch = sbi_hartid_to_scratch(remote_hartid); + if (!remote_scratch) + return SBI_EINVAL; + ipi_data = sbi_scratch_offset_ptr(remote_scratch, ipi_data_off); if (ipi_ops->update) { @@ -55,6 +54,10 @@ static int sbi_ipi_send(struct sbi_scratch *scratch, u32 remote_hartid, return ret; } + /* + * Set IPI type on remote hart's scratch area and + * trigger the interrupt + */ atomic_raw_set_bit(event, &ipi_data->ipi_type); smp_wmb(); sbi_platform_ipi_send(plat, remote_hartid); diff --git a/lib/sbi/sbi_scratch.c b/lib/sbi/sbi_scratch.c index 4dac8f7b..2d03a60a 100644 --- a/lib/sbi/sbi_scratch.c +++ b/lib/sbi/sbi_scratch.c @@ -72,6 +72,8 @@ done: plat = sbi_platform_ptr(scratch); for (i = 0; i < sbi_platform_hart_count(plat); i++) { rscratch = sbi_hartid_to_scratch(i); + if (!rscratch) + continue; ptr = sbi_scratch_offset_ptr(rscratch, ret); sbi_memset(ptr, 0, size); } diff --git a/lib/sbi/sbi_tlb.c b/lib/sbi/sbi_tlb.c index aab0d877..1b66fdf2 100644 --- a/lib/sbi/sbi_tlb.c +++ b/lib/sbi/sbi_tlb.c @@ -197,6 +197,9 @@ static void sbi_tlb_entry_process(struct sbi_tlb_info *tinfo) sbi_hartmask_for_each_hart(rhartid, &tinfo->smask) { rscratch = sbi_hartid_to_scratch(rhartid); + if (!rscratch) + continue; + rtlb_sync = sbi_scratch_offset_ptr(rscratch, tlb_sync_off); while (atomic_raw_xchg_ulong(rtlb_sync, 1)) ; }