Skip to content

Commit 0732ea1

Browse files
bjorn-rivosvijay-suman
authored andcommitted
riscv: Properly export reserved regions in /proc/iomem
[ Upstream commit e94eb7ea6f206e229791761a5fdf9389f8dbd183 ] The /proc/iomem represents the kernel's memory map. Regions marked with "Reserved" tells the user that the range should not be tampered with. Kexec-tools, when using the older kexec_load syscall relies on the "Reserved" regions to build the memory segments, that will be the target of the new kexec'd kernel. The RISC-V port tries to expose all reserved regions to userland, but some regions were not properly exposed: Regions that resided in both the "regular" and reserved memory block, e.g. the EFI Memory Map. A missing entry could result in reserved memory being overwritten. It turns out, that arm64, and loongarch had a similar issue a while back: commit d91680e ("arm64: Fix /proc/iomem for reserved but not memory regions") commit 50d7ba3 ("arm64: export memblock_reserve()d regions via /proc/iomem") Similar to the other ports, resolve the issue by splitting the regions in an arch initcall, since we need a working allocator. Fixes: ffe0e52 ("RISC-V: Improve init_resources()") Signed-off-by: Björn Töpel <[email protected]> Reviewed-by: Alexandre Ghiti <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexandre Ghiti <[email protected]> Signed-off-by: Sasha Levin <[email protected]> (cherry picked from commit 3c03e585860a2cba3dc0cd10f92c8e14aee4a36b) Signed-off-by: Vijayendra Suman <[email protected]>
1 parent fab6036 commit 0732ea1

File tree

1 file changed

+35
-1
lines changed

1 file changed

+35
-1
lines changed

arch/riscv/kernel/setup.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ static struct resource bss_res = { .name = "Kernel bss", };
8484
static struct resource elfcorehdr_res = { .name = "ELF Core hdr", };
8585
#endif
8686

87+
static int num_standard_resources;
88+
static struct resource *standard_resources;
89+
8790
static int __init add_resource(struct resource *parent,
8891
struct resource *res)
8992
{
@@ -157,7 +160,7 @@ static void __init init_resources(void)
157160
struct resource *res = NULL;
158161
struct resource *mem_res = NULL;
159162
size_t mem_res_sz = 0;
160-
int num_resources = 0, res_idx = 0;
163+
int num_resources = 0, res_idx = 0, non_resv_res = 0;
161164
int ret = 0;
162165

163166
/* + 1 as memblock_alloc() might increase memblock.reserved.cnt */
@@ -221,6 +224,7 @@ static void __init init_resources(void)
221224
/* Add /memory regions to the resource tree */
222225
for_each_mem_region(region) {
223226
res = &mem_res[res_idx--];
227+
non_resv_res++;
224228

225229
if (unlikely(memblock_is_nomap(region))) {
226230
res->name = "Reserved";
@@ -238,6 +242,9 @@ static void __init init_resources(void)
238242
goto error;
239243
}
240244

245+
num_standard_resources = non_resv_res;
246+
standard_resources = &mem_res[res_idx + 1];
247+
241248
/* Clean-up any unused pre-allocated resources */
242249
if (res_idx >= 0)
243250
memblock_free(__pa(mem_res), (res_idx + 1) * sizeof(*mem_res));
@@ -249,6 +256,33 @@ static void __init init_resources(void)
249256
memblock_free(__pa(mem_res), mem_res_sz);
250257
}
251258

259+
static int __init reserve_memblock_reserved_regions(void)
260+
{
261+
u64 i, j;
262+
263+
for (i = 0; i < num_standard_resources; i++) {
264+
struct resource *mem = &standard_resources[i];
265+
phys_addr_t r_start, r_end, mem_size = resource_size(mem);
266+
267+
if (!memblock_is_region_reserved(mem->start, mem_size))
268+
continue;
269+
270+
for_each_reserved_mem_range(j, &r_start, &r_end) {
271+
resource_size_t start, end;
272+
273+
start = max(PFN_PHYS(PFN_DOWN(r_start)), mem->start);
274+
end = min(PFN_PHYS(PFN_UP(r_end)) - 1, mem->end);
275+
276+
if (start > mem->end || end < mem->start)
277+
continue;
278+
279+
reserve_region_with_split(mem, start, end, "Reserved");
280+
}
281+
}
282+
283+
return 0;
284+
}
285+
arch_initcall(reserve_memblock_reserved_regions);
252286

253287
static void __init parse_dtb(void)
254288
{

0 commit comments

Comments
 (0)