forked from Mirrors/opensbi
		
	lib: utils: Mark only the largest region as reserved in FDT
In commit230278dcf, RX and RW regions were marked separately. When the RW region grows (e.g. with more harts) and it isn't a power-of-two, sbi_domain_memregion_init will upgrade the region to the next power-of-two. This will make RX and RW both start at the same base address, like so (with 64 harts): Domain0 Region01 : 0x0000000080000000-0x000000008001ffff M: (R,X) S/U: () Domain0 Region02 : 0x0000000080000000-0x00000000800fffff M: (R,W) S/U: () This doesn't break the permission enforcement because of static priorities in PMP but makes the kernel complain about the regions overlapping each other. Like so: [ 0.000000] OF: reserved mem: OVERLAP DETECTED! [ 0.000000] mmode_resv0@80000000 (0x0000000080000000--0x0000000080020000) \ overlaps with mmode_resv1@80000000 (0x0000000080000000--0x0000000080100000) To fix this warning, among the multiple regions having same base address but different sizes, add only the largest region as reserved region during fdt fixup. Fixes:230278dcf(lib: sbi: Add separate entries for firmware RX and RW regions) Signed-off-by: Himanshu Chauhan <hchauhan@ventanamicro.com> Reviewed-by: Anup Patel <anup@brainfault.org>
This commit is contained in:
		
				
					committed by
					
						
						Anup Patel
					
				
			
			
				
	
			
			
			
						parent
						
							84d15f4f52
						
					
				
				
					commit
					199189bd1c
				
			@@ -1,3 +1,4 @@
 | 
			
		||||
 | 
			
		||||
// SPDX-License-Identifier: BSD-2-Clause
 | 
			
		||||
/*
 | 
			
		||||
 * fdt_fixup.c - Flat Device Tree parsing helper routines
 | 
			
		||||
@@ -14,6 +15,7 @@
 | 
			
		||||
#include <sbi/sbi_hart.h>
 | 
			
		||||
#include <sbi/sbi_scratch.h>
 | 
			
		||||
#include <sbi/sbi_string.h>
 | 
			
		||||
#include <sbi/sbi_error.h>
 | 
			
		||||
#include <sbi_utils/fdt/fdt_fixup.h>
 | 
			
		||||
#include <sbi_utils/fdt/fdt_pmu.h>
 | 
			
		||||
#include <sbi_utils/fdt/fdt_helper.h>
 | 
			
		||||
@@ -285,8 +287,10 @@ int fdt_reserved_memory_fixup(void *fdt)
 | 
			
		||||
	struct sbi_domain_memregion *reg;
 | 
			
		||||
	struct sbi_domain *dom = sbi_domain_thishart_ptr();
 | 
			
		||||
	struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
 | 
			
		||||
	unsigned long filtered_base[PMP_COUNT] = { 0 };
 | 
			
		||||
	unsigned char filtered_order[PMP_COUNT] = { 0 };
 | 
			
		||||
	unsigned long addr, size;
 | 
			
		||||
	int err, parent, i;
 | 
			
		||||
	int err, parent, i, j;
 | 
			
		||||
	int na = fdt_address_cells(fdt, 0);
 | 
			
		||||
	int ns = fdt_size_cells(fdt, 0);
 | 
			
		||||
 | 
			
		||||
@@ -351,11 +355,33 @@ int fdt_reserved_memory_fixup(void *fdt)
 | 
			
		||||
		if (reg->flags & SBI_DOMAIN_MEMREGION_SU_EXECUTABLE)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (i > PMP_COUNT) {
 | 
			
		||||
			sbi_printf("%s: Too many memory regions to fixup.\n",
 | 
			
		||||
				   __func__);
 | 
			
		||||
			return SBI_ENOSPC;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		addr = reg->base;
 | 
			
		||||
		size = 1UL << reg->order;
 | 
			
		||||
		fdt_resv_memory_update_node(fdt, addr, size, i, parent,
 | 
			
		||||
			(sbi_hart_pmp_count(scratch)) ? false : true);
 | 
			
		||||
		for (j = 0; j < i; j++) {
 | 
			
		||||
			if (addr == filtered_base[j]
 | 
			
		||||
			    && filtered_order[j] < reg->order) {
 | 
			
		||||
				filtered_order[j] = reg->order;
 | 
			
		||||
				goto next_entry;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		filtered_base[i] = reg->base;
 | 
			
		||||
		filtered_order[i] = reg->order;
 | 
			
		||||
		i++;
 | 
			
		||||
	next_entry:
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (j = 0; j < i; j++) {
 | 
			
		||||
		addr = filtered_base[j];
 | 
			
		||||
		size = 1UL << filtered_order[j];
 | 
			
		||||
		fdt_resv_memory_update_node(fdt, addr, size, j, parent,
 | 
			
		||||
					    (sbi_hart_pmp_count(scratch))
 | 
			
		||||
					    ? false : true);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user