Skip to content

Commit 994af18

Browse files
covanampalmer-dabbelt
authored andcommitted
riscv: fix overlap of allocated page and PTR_ERR
On riscv32, it is possible for the last page in virtual address space (0xfffff000) to be allocated. This page overlaps with PTR_ERR, so that shouldn't happen. There is already some code to ensure memblock won't allocate the last page. However, buddy allocator is left unchecked. Fix this by reserving physical memory that would be mapped at virtual addresses greater than 0xfffff000. Reported-by: Björn Töpel <[email protected]> Closes: https://lore.kernel.org/linux-riscv/[email protected] Fixes: 76d2a04 ("RISC-V: Init and Halt Code") Signed-off-by: Nam Cao <[email protected]> Cc: <[email protected]> Tested-by: Björn Töpel <[email protected]> Reviewed-by: Björn Töpel <[email protected]> Reviewed-by: Mike Rapoport (IBM) <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent c3f38fa commit 994af18

File tree

1 file changed

+11
-10
lines changed

1 file changed

+11
-10
lines changed

arch/riscv/mm/init.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -250,18 +250,19 @@ static void __init setup_bootmem(void)
250250
kernel_map.va_pa_offset = PAGE_OFFSET - phys_ram_base;
251251

252252
/*
253-
* memblock allocator is not aware of the fact that last 4K bytes of
254-
* the addressable memory can not be mapped because of IS_ERR_VALUE
255-
* macro. Make sure that last 4k bytes are not usable by memblock
256-
* if end of dram is equal to maximum addressable memory. For 64-bit
257-
* kernel, this problem can't happen here as the end of the virtual
258-
* address space is occupied by the kernel mapping then this check must
259-
* be done as soon as the kernel mapping base address is determined.
253+
* Reserve physical address space that would be mapped to virtual
254+
* addresses greater than (void *)(-PAGE_SIZE) because:
255+
* - This memory would overlap with ERR_PTR
256+
* - This memory belongs to high memory, which is not supported
257+
*
258+
* This is not applicable to 64-bit kernel, because virtual addresses
259+
* after (void *)(-PAGE_SIZE) are not linearly mapped: they are
260+
* occupied by kernel mapping. Also it is unrealistic for high memory
261+
* to exist on 64-bit platforms.
260262
*/
261263
if (!IS_ENABLED(CONFIG_64BIT)) {
262-
max_mapped_addr = __pa(~(ulong)0);
263-
if (max_mapped_addr == (phys_ram_end - 1))
264-
memblock_set_current_limit(max_mapped_addr - 4096);
264+
max_mapped_addr = __va_to_pa_nodebug(-PAGE_SIZE);
265+
memblock_reserve(max_mapped_addr, (phys_addr_t)-max_mapped_addr);
265266
}
266267

267268
min_low_pfn = PFN_UP(phys_ram_base);

0 commit comments

Comments
 (0)