RISC-V Fixes for 5.8-rc7
I have a few more fixes this week: * A fix to avoid using SBI calls during kasan initialization, as the SBI calls themselves have not been probed yet. * Three fixes related to systems with multiple memory regions. -----BEGIN PGP SIGNATURE----- iQJHBAABCgAxFiEEKzw3R0RoQ7JKlDp6LhMZ81+7GIkFAl8cebwTHHBhbG1lckBk YWJiZWx0LmNvbQAKCRAuExnzX7sYiV4UEACunm3LQGjjZUbHX/1/X2iAdNBcnbiZ SFSXaKuAiDzSgT0//UMloo33eywo3afGCTOCysi3zrwNU+Hbj5l9byTMnvXy9hGv QCFf2aEma9Ebk9ImdLDjkHQy2e1SiQRHQiKQcGTtP4LN470rrysh0a8qLLVAGucJ j5fDPcy9smRw4x0lGHqLXDmVIm8nQNJAj6iKVQYzA2mSJC2+RoKcPcunnXvoOUwl q/lcp41BavZyYsDIoAblRCA1/sfFL9BfocL4fUBFh4HUp/qcqwsGPv+U5QoEzkQ8 9LLLuXnHXgU5BTv4zVCUqXjMza6fgZj+qMpxXLQig0DRBetuQY2gpCdt2JAkcXTj XvkHavxkA6206myl9xY6OJueC/25I6dp0eDENBpUNET8fqbeFBhIUCuNtAzT+98J OcMImyFQgoesGU+6dkdHr6tSJHDcI3PzXlVUNH3hkIQq5Ny10g+jjAInZo6iXfpW yBu+AzvippbD6C8/L+ntP94y9F/Me5rZKWMBhT2gTLm6JLrtC/Wl+ol2fZF8gmIU wdT6TUykDY6u6bdqPSRKISzy0HfuREQNJU3qqoI496BMWQ1DaQjHB1482fdtdELI KUFkM6u9iudWu5Dap45rSCjeZu01cLqnQqO5M3LYUrCy0D02j5SiGfUwRYo+eD0S me68CtmbUPsH7Q== =FG/F -----END PGP SIGNATURE----- Merge tag 'riscv-for-linus-5.8-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux into master Pull RISC-V fixes from Palmer Dabbelt: "A few more fixes this week: - A fix to avoid using SBI calls during kasan initialization, as the SBI calls themselves have not been probed yet. - Three fixes related to systems with multiple memory regions" * tag 'riscv-for-linus-5.8-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: riscv: Parse all memory blocks to remove unusable memory RISC-V: Do not rely on initrd_start/end computed during early dt parsing RISC-V: Set maximum number of mapped pages correctly riscv: kasan: use local_tlb_flush_all() to avoid uninitialized __sbi_rfence
This commit is contained in:
Коммит
04300d66f0
|
@ -95,19 +95,40 @@ void __init mem_init(void)
|
|||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
static void __init setup_initrd(void)
|
||||
{
|
||||
phys_addr_t start;
|
||||
unsigned long size;
|
||||
|
||||
if (initrd_start >= initrd_end) {
|
||||
pr_info("initrd not found or empty");
|
||||
goto disable;
|
||||
}
|
||||
if (__pa_symbol(initrd_end) > PFN_PHYS(max_low_pfn)) {
|
||||
pr_err("initrd extends beyond end of memory");
|
||||
/* Ignore the virtul address computed during device tree parsing */
|
||||
initrd_start = initrd_end = 0;
|
||||
|
||||
if (!phys_initrd_size)
|
||||
return;
|
||||
/*
|
||||
* Round the memory region to page boundaries as per free_initrd_mem()
|
||||
* This allows us to detect whether the pages overlapping the initrd
|
||||
* are in use, but more importantly, reserves the entire set of pages
|
||||
* as we don't want these pages allocated for other purposes.
|
||||
*/
|
||||
start = round_down(phys_initrd_start, PAGE_SIZE);
|
||||
size = phys_initrd_size + (phys_initrd_start - start);
|
||||
size = round_up(size, PAGE_SIZE);
|
||||
|
||||
if (!memblock_is_region_memory(start, size)) {
|
||||
pr_err("INITRD: 0x%08llx+0x%08lx is not a memory region",
|
||||
(u64)start, size);
|
||||
goto disable;
|
||||
}
|
||||
|
||||
size = initrd_end - initrd_start;
|
||||
memblock_reserve(__pa_symbol(initrd_start), size);
|
||||
if (memblock_is_region_reserved(start, size)) {
|
||||
pr_err("INITRD: 0x%08llx+0x%08lx overlaps in-use memory region\n",
|
||||
(u64)start, size);
|
||||
goto disable;
|
||||
}
|
||||
|
||||
memblock_reserve(start, size);
|
||||
/* Now convert initrd to virtual addresses */
|
||||
initrd_start = (unsigned long)__va(phys_initrd_start);
|
||||
initrd_end = initrd_start + phys_initrd_size;
|
||||
initrd_below_start_ok = 1;
|
||||
|
||||
pr_info("Initial ramdisk at: 0x%p (%lu bytes)\n",
|
||||
|
@ -126,33 +147,36 @@ void __init setup_bootmem(void)
|
|||
{
|
||||
struct memblock_region *reg;
|
||||
phys_addr_t mem_size = 0;
|
||||
phys_addr_t total_mem = 0;
|
||||
phys_addr_t mem_start, end = 0;
|
||||
phys_addr_t vmlinux_end = __pa_symbol(&_end);
|
||||
phys_addr_t vmlinux_start = __pa_symbol(&_start);
|
||||
|
||||
/* Find the memory region containing the kernel */
|
||||
for_each_memblock(memory, reg) {
|
||||
phys_addr_t end = reg->base + reg->size;
|
||||
|
||||
if (reg->base <= vmlinux_start && vmlinux_end <= end) {
|
||||
mem_size = min(reg->size, (phys_addr_t)-PAGE_OFFSET);
|
||||
|
||||
/*
|
||||
* Remove memblock from the end of usable area to the
|
||||
* end of region
|
||||
*/
|
||||
if (reg->base + mem_size < end)
|
||||
memblock_remove(reg->base + mem_size,
|
||||
end - reg->base - mem_size);
|
||||
}
|
||||
end = reg->base + reg->size;
|
||||
if (!total_mem)
|
||||
mem_start = reg->base;
|
||||
if (reg->base <= vmlinux_start && vmlinux_end <= end)
|
||||
BUG_ON(reg->size == 0);
|
||||
total_mem = total_mem + reg->size;
|
||||
}
|
||||
BUG_ON(mem_size == 0);
|
||||
|
||||
/*
|
||||
* Remove memblock from the end of usable area to the
|
||||
* end of region
|
||||
*/
|
||||
mem_size = min(total_mem, (phys_addr_t)-PAGE_OFFSET);
|
||||
if (mem_start + mem_size < end)
|
||||
memblock_remove(mem_start + mem_size,
|
||||
end - mem_start - mem_size);
|
||||
|
||||
/* Reserve from the start of the kernel to the end of the kernel */
|
||||
memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start);
|
||||
|
||||
set_max_mapnr(PFN_DOWN(mem_size));
|
||||
max_pfn = PFN_DOWN(memblock_end_of_DRAM());
|
||||
max_low_pfn = max_pfn;
|
||||
set_max_mapnr(max_low_pfn);
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
setup_initrd();
|
||||
|
|
|
@ -44,7 +44,7 @@ asmlinkage void __init kasan_early_init(void)
|
|||
(__pa(((uintptr_t) kasan_early_shadow_pmd))),
|
||||
__pgprot(_PAGE_TABLE)));
|
||||
|
||||
flush_tlb_all();
|
||||
local_flush_tlb_all();
|
||||
}
|
||||
|
||||
static void __init populate(void *start, void *end)
|
||||
|
@ -79,7 +79,7 @@ static void __init populate(void *start, void *end)
|
|||
pfn_pgd(PFN_DOWN(__pa(&pmd[offset])),
|
||||
__pgprot(_PAGE_TABLE)));
|
||||
|
||||
flush_tlb_all();
|
||||
local_flush_tlb_all();
|
||||
memset(start, 0, end - start);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче