Skip to content

Commit 04300d6

Browse files
committed
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
2 parents fbe0d45 + fa5a198 commit 04300d6

File tree

2 files changed

+47
-23
lines changed

2 files changed

+47
-23
lines changed

arch/riscv/mm/init.c

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -95,19 +95,40 @@ void __init mem_init(void)
9595
#ifdef CONFIG_BLK_DEV_INITRD
9696
static void __init setup_initrd(void)
9797
{
98+
phys_addr_t start;
9899
unsigned long size;
99100

100-
if (initrd_start >= initrd_end) {
101-
pr_info("initrd not found or empty");
101+
/* Ignore the virtul address computed during device tree parsing */
102+
initrd_start = initrd_end = 0;
103+
104+
if (!phys_initrd_size)
105+
return;
106+
/*
107+
* Round the memory region to page boundaries as per free_initrd_mem()
108+
* This allows us to detect whether the pages overlapping the initrd
109+
* are in use, but more importantly, reserves the entire set of pages
110+
* as we don't want these pages allocated for other purposes.
111+
*/
112+
start = round_down(phys_initrd_start, PAGE_SIZE);
113+
size = phys_initrd_size + (phys_initrd_start - start);
114+
size = round_up(size, PAGE_SIZE);
115+
116+
if (!memblock_is_region_memory(start, size)) {
117+
pr_err("INITRD: 0x%08llx+0x%08lx is not a memory region",
118+
(u64)start, size);
102119
goto disable;
103120
}
104-
if (__pa_symbol(initrd_end) > PFN_PHYS(max_low_pfn)) {
105-
pr_err("initrd extends beyond end of memory");
121+
122+
if (memblock_is_region_reserved(start, size)) {
123+
pr_err("INITRD: 0x%08llx+0x%08lx overlaps in-use memory region\n",
124+
(u64)start, size);
106125
goto disable;
107126
}
108127

109-
size = initrd_end - initrd_start;
110-
memblock_reserve(__pa_symbol(initrd_start), size);
128+
memblock_reserve(start, size);
129+
/* Now convert initrd to virtual addresses */
130+
initrd_start = (unsigned long)__va(phys_initrd_start);
131+
initrd_end = initrd_start + phys_initrd_size;
111132
initrd_below_start_ok = 1;
112133

113134
pr_info("Initial ramdisk at: 0x%p (%lu bytes)\n",
@@ -126,33 +147,36 @@ void __init setup_bootmem(void)
126147
{
127148
struct memblock_region *reg;
128149
phys_addr_t mem_size = 0;
150+
phys_addr_t total_mem = 0;
151+
phys_addr_t mem_start, end = 0;
129152
phys_addr_t vmlinux_end = __pa_symbol(&_end);
130153
phys_addr_t vmlinux_start = __pa_symbol(&_start);
131154

132155
/* Find the memory region containing the kernel */
133156
for_each_memblock(memory, reg) {
134-
phys_addr_t end = reg->base + reg->size;
135-
136-
if (reg->base <= vmlinux_start && vmlinux_end <= end) {
137-
mem_size = min(reg->size, (phys_addr_t)-PAGE_OFFSET);
138-
139-
/*
140-
* Remove memblock from the end of usable area to the
141-
* end of region
142-
*/
143-
if (reg->base + mem_size < end)
144-
memblock_remove(reg->base + mem_size,
145-
end - reg->base - mem_size);
146-
}
157+
end = reg->base + reg->size;
158+
if (!total_mem)
159+
mem_start = reg->base;
160+
if (reg->base <= vmlinux_start && vmlinux_end <= end)
161+
BUG_ON(reg->size == 0);
162+
total_mem = total_mem + reg->size;
147163
}
148-
BUG_ON(mem_size == 0);
164+
165+
/*
166+
* Remove memblock from the end of usable area to the
167+
* end of region
168+
*/
169+
mem_size = min(total_mem, (phys_addr_t)-PAGE_OFFSET);
170+
if (mem_start + mem_size < end)
171+
memblock_remove(mem_start + mem_size,
172+
end - mem_start - mem_size);
149173

150174
/* Reserve from the start of the kernel to the end of the kernel */
151175
memblock_reserve(vmlinux_start, vmlinux_end - vmlinux_start);
152176

153-
set_max_mapnr(PFN_DOWN(mem_size));
154177
max_pfn = PFN_DOWN(memblock_end_of_DRAM());
155178
max_low_pfn = max_pfn;
179+
set_max_mapnr(max_low_pfn);
156180

157181
#ifdef CONFIG_BLK_DEV_INITRD
158182
setup_initrd();

arch/riscv/mm/kasan_init.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ asmlinkage void __init kasan_early_init(void)
4444
(__pa(((uintptr_t) kasan_early_shadow_pmd))),
4545
__pgprot(_PAGE_TABLE)));
4646

47-
flush_tlb_all();
47+
local_flush_tlb_all();
4848
}
4949

5050
static void __init populate(void *start, void *end)
@@ -79,7 +79,7 @@ static void __init populate(void *start, void *end)
7979
pfn_pgd(PFN_DOWN(__pa(&pmd[offset])),
8080
__pgprot(_PAGE_TABLE)));
8181

82-
flush_tlb_all();
82+
local_flush_tlb_all();
8383
memset(start, 0, end - start);
8484
}
8585

0 commit comments

Comments
 (0)