Commit abb8e86b authored by Atish Patra's avatar Atish Patra Committed by Palmer Dabbelt

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: default avatarAnup Patel <anup@brainfault.org>
Signed-off-by: default avatarAtish Patra <atish.patra@wdc.com>
Signed-off-by: default avatarPalmer Dabbelt <palmerdabbelt@google.com>
parent 797f0375
...@@ -157,9 +157,10 @@ static void __init setup_initrd(void) ...@@ -157,9 +157,10 @@ static void __init setup_initrd(void)
void __init setup_bootmem(void) void __init setup_bootmem(void)
{ {
phys_addr_t mem_start = 0; phys_addr_t mem_start = 0;
phys_addr_t start, end = 0; phys_addr_t start, dram_end, end = 0;
phys_addr_t vmlinux_end = __pa_symbol(&_end); phys_addr_t vmlinux_end = __pa_symbol(&_end);
phys_addr_t vmlinux_start = __pa_symbol(&_start); phys_addr_t vmlinux_start = __pa_symbol(&_start);
phys_addr_t max_mapped_addr = __pa(~(ulong)0);
u64 i; u64 i;
/* Find the memory region containing the kernel */ /* Find the memory region containing the kernel */
...@@ -181,7 +182,18 @@ void __init setup_bootmem(void) ...@@ -181,7 +182,18 @@ void __init setup_bootmem(void)
/* Reserve from the start of the kernel to the end of the kernel */ /* Reserve from the start of the kernel to the end of the kernel */
memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start); memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start);
max_pfn = PFN_DOWN(memblock_end_of_DRAM()); dram_end = memblock_end_of_DRAM();
/*
* memblock allocator is not aware of the fact that last 4K bytes of
* the addressable memory can not be mapped because of IS_ERR_VALUE
* macro. Make sure that last 4k bytes are not usable by memblock
* if end of dram is equal to maximum addressable memory.
*/
if (max_mapped_addr == (dram_end - 1))
memblock_set_current_limit(max_mapped_addr - 4096);
max_pfn = PFN_DOWN(dram_end);
max_low_pfn = max_pfn; max_low_pfn = max_pfn;
dma32_phys_limit = min(4UL * SZ_1G, (unsigned long)PFN_PHYS(max_low_pfn)); dma32_phys_limit = min(4UL * SZ_1G, (unsigned long)PFN_PHYS(max_low_pfn));
set_max_mapnr(max_low_pfn); set_max_mapnr(max_low_pfn);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment