[PATCH] arm64: kexec: set asdie firmware-reserved memory regions

From: AKASHI Takahiro
Date: Fri Mar 02 2018 - 02:39:18 EST


Signed-off-by: AKASHI Takahiro <takahiro.akashi@xxxxxxxxxx>
---
arch/arm64/kernel/setup.c | 24 ++++++++++++++++++++----
arch/arm64/mm/init.c | 21 +++++++++++++++++++++
2 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
index 30ad2f085d1f..997f07e86243 100644
--- a/arch/arm64/kernel/setup.c
+++ b/arch/arm64/kernel/setup.c
@@ -87,6 +87,9 @@ static struct resource mem_res[] = {
#define kernel_code mem_res[0]
#define kernel_data mem_res[1]

+/* TODO: Firmware-reserved memory resources */
+extern struct memblock_type fw_mem;
+
/*
* The recorded values of x0 .. x3 upon kernel entry.
*/
@@ -206,7 +209,20 @@ static void __init request_standard_resources(void)
{
struct memblock_region *region;
struct resource *res;
+ int i;
+
+ /* add firmware-reserved memory first */
+ for (i = 1; i < fw_mem.cnt; i++) {
+ res = alloc_bootmem_low(sizeof(*res));
+ res->name = "reserved";
+ res->flags = IORESOURCE_MEM;
+ res->start = fw_mem.regions[i].base;
+ res->end = fw_mem.regions[i].base + fw_mem.regions[i].size - 1;

+ request_resource(&iomem_resource, res);
+ }
+
+ /* add standard resources */
kernel_code.start = __pa_symbol(_text);
kernel_code.end = __pa_symbol(__init_begin - 1);
kernel_data.start = __pa_symbol(_sdata);
@@ -224,19 +240,19 @@ static void __init request_standard_resources(void)
res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;

- request_resource(&iomem_resource, res);
+ insert_resource(&iomem_resource, res);

if (kernel_code.start >= res->start &&
kernel_code.end <= res->end)
- request_resource(res, &kernel_code);
+ insert_resource(res, &kernel_code);
if (kernel_data.start >= res->start &&
kernel_data.end <= res->end)
- request_resource(res, &kernel_data);
+ insert_resource(res, &kernel_data);
#ifdef CONFIG_KEXEC_CORE
/* Userspace will find "Crash kernel" region in /proc/iomem. */
if (crashk_res.end && crashk_res.start >= res->start &&
crashk_res.end <= res->end)
- request_resource(res, &crashk_res);
+ insert_resource(res, &crashk_res);
#endif
}
}
diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index 9f3c47acf8ff..b6f86a7bbfb7 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -62,6 +62,14 @@
s64 memstart_addr __ro_after_init = -1;
phys_addr_t arm64_dma_phys_limit __ro_after_init;

+static struct memblock_region fw_mem_regions[INIT_MEMBLOCK_REGIONS];
+struct memblock_type fw_mem = {
+ .regions = fw_mem_regions,
+ .cnt = 1, /* empty dummy entry */
+ .max = INIT_MEMBLOCK_REGIONS,
+ .name = "firmware-reserved memory",
+};
+
#ifdef CONFIG_BLK_DEV_INITRD
static int __init early_initrd(char *p)
{
@@ -362,6 +370,19 @@ static void __init fdt_enforce_memory_region(void)
void __init arm64_memblock_init(void)
{
const s64 linear_region_size = -(s64)PAGE_OFFSET;
+ struct memblock_region *region;
+
+ /*
+ * Export firmware-reserved memory regions
+ * TODO: via more generic interface
+ */
+ for_each_memblock(reserved, region) {
+ if (WARN_ON(fw_mem.cnt >= fw_mem.max))
+ break;
+ fw_mem.regions[fw_mem.cnt].base = region->base;
+ fw_mem.regions[fw_mem.cnt].size = region->size;
+ fw_mem.cnt++;
+ }

/* Handle linux,usable-memory-range property */
fdt_enforce_memory_region();
--
2.16.2