Skip to content

Commit abb8e86

Browse files
atishp04palmer-dabbelt
authored andcommitted
RISC-V: Set current memblock limit
Currently, linux kernel can not use last 4k bytes of addressable space because IS_ERR_VALUE macro treats those as an error. This will be an issue for RV32 as any memblock allocator potentially allocate chunk of memory from the end of DRAM (2GB) leading bad address error even though the address was technically valid. Fix this issue by limiting the memblock if available memory spans the entire address space. Reviewed-by: Anup Patel <[email protected]> Signed-off-by: Atish Patra <[email protected]> Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 797f037 commit abb8e86

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

arch/riscv/mm/init.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,10 @@ static void __init setup_initrd(void)
157157
void __init setup_bootmem(void)
158158
{
159159
phys_addr_t mem_start = 0;
160-
phys_addr_t start, end = 0;
160+
phys_addr_t start, dram_end, end = 0;
161161
phys_addr_t vmlinux_end = __pa_symbol(&_end);
162162
phys_addr_t vmlinux_start = __pa_symbol(&_start);
163+
phys_addr_t max_mapped_addr = __pa(~(ulong)0);
163164
u64 i;
164165

165166
/* Find the memory region containing the kernel */
@@ -181,7 +182,18 @@ void __init setup_bootmem(void)
181182
/* Reserve from the start of the kernel to the end of the kernel */
182183
memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start);
183184

184-
max_pfn = PFN_DOWN(memblock_end_of_DRAM());
185+
dram_end = memblock_end_of_DRAM();
186+
187+
/*
188+
* memblock allocator is not aware of the fact that last 4K bytes of
189+
* the addressable memory can not be mapped because of IS_ERR_VALUE
190+
* macro. Make sure that last 4k bytes are not usable by memblock
191+
* if end of dram is equal to maximum addressable memory.
192+
*/
193+
if (max_mapped_addr == (dram_end - 1))
194+
memblock_set_current_limit(max_mapped_addr - 4096);
195+
196+
max_pfn = PFN_DOWN(dram_end);
185197
max_low_pfn = max_pfn;
186198
dma32_phys_limit = min(4UL * SZ_1G, (unsigned long)PFN_PHYS(max_low_pfn));
187199
set_max_mapnr(max_low_pfn);

0 commit comments

Comments
 (0)