forked from Mirrors/opensbi
		
	lib: Handle failure of sbi_hartid_to_scratch() API
The sbi_hartid_to_scratch() API can fail for non-existent HARTs so all uses of sbi_hartid_to_scratch() API should check return value. Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com> Reviewed-by: Atish Patra <atish.patra@wdc.com>
This commit is contained in:
		@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -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)) ;
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user