hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4O31I?from=project-issue CVE: NA
Add "!" in memmap parameter, use memmap(memmap=nn[KMG]!ss[KMG]) reserve memory for pmem which register persistent memory in arm64.
Signed-off-by: Zhuling zhuling8@huawei.com --- Documentation/admin-guide/kernel-parameters.txt | 10 ++++-- arch/arm64/Kconfig | 9 ++++++ arch/arm64/kernel/setup.c | 10 ++++++ arch/arm64/mm/init.c | 41 +++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 5a0a68b..3c14d51 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -2831,10 +2831,16 @@ will be eaten.
memmap=nn[KMG]!ss[KMG] - [KNL,X86] Mark specific memory as protected. + [KNL,X86,ARM64] Mark specific memory as protected. Region of memory to be used, from ss to ss+nn. - The memory region may be marked as e820 type 12 (0xc) + [X86]The memory region may be marked as e820 type 12 (0xc) and is NVDIMM or ADR memory. + [ARM64]Reserve memory for persistent storage when the kernel + restart or update. the data in PMEM will not be lost and can + be loaded faster. Currently, only one pmem can be registered + and use. + Example: + memmap=100K!0x1a0000000
memmap=<size>%<offset>-<oldtype>+<newtype> [KNL,ACPI] Convert memory within the specified region diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 105221c..c6385b9 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1325,6 +1325,15 @@ config RODATA_FULL_DEFAULT_ENABLED This requires the linear region to be mapped down to pages, which may adversely affect performance in some cases.
+config ARM64_PMEM_RESERVE + bool + default n + help + Use memmap=nn[KMG]!ss[KMG](memmap=100K!0x1a0000000) reserve + memory for persistent storage. + + Say y here to enable this feature. + config ARM64_PMEM_LEGACY_DEVICE bool "Create persistent storage" depends on BLK_DEV diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index 92d75e3..3eee532 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -70,6 +70,10 @@ static int __init arm64_enable_cpu0_hotplug(char *str) __setup("arm64_cpu0_hotplug", arm64_enable_cpu0_hotplug); #endif
+#ifdef CONFIG_ARM64_PMEM_RESERVE +extern struct resource pmem_res; +#endif + phys_addr_t __fdt_pointer __initdata;
/* @@ -303,6 +307,12 @@ static void __init request_standard_resources(void) request_resource(res, &pin_memory_resource); #endif } + +#ifdef CONFIG_ARM64_PMEM_RESERVE + if (pmem_res.end && pmem_res.start) + request_resource(&iomem_resource, &pmem_res); +#endif + }
static int __init reserve_memblock_reserved_regions(void) diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 6ebfabd..488585e 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -111,6 +111,18 @@ static void __init reserve_pin_memory_res(void) */ phys_addr_t arm64_dma_phys_limit __ro_after_init;
+#ifdef CONFIG_ARM64_PMEM_RESERVE +u64 pmem_size, pmem_start; + +struct resource pmem_res = { + .name = "Persistent Memory (legacy)", + .start = 0, + .end = 0, + .flags = IORESOURCE_MEM, + .desc = IORES_DESC_PERSISTENT_MEMORY_LEGACY +}; +#endif + #ifndef CONFIG_KEXEC_CORE static void __init reserve_crashkernel(void) { @@ -442,6 +454,10 @@ static int __init parse_memmap_one(char *p) start_at = memparse(p + 1, &p); memblock_reserve(start_at, mem_size); memblock_mark_memmap(start_at, mem_size); + } else if (*p == '!') { + start_at = memparse(p+1, &p); + pmem_start = start_at; + pmem_size = mem_size; } else pr_info("Unrecognized memmap option, please check the parameter.\n");
@@ -464,6 +480,27 @@ static int __init parse_memmap_opt(char *str) } early_param("memmap", parse_memmap_opt);
+#ifdef CONFIG_ARM64_PMEM_RESERVE +static void __init reserve_pmem(void) +{ + if (!memblock_is_region_memory(pmem_start, pmem_size)) { + pr_warn("cannot reserve pmem: region is not memory!\n"); + return; + } + + if (memblock_is_region_reserved(pmem_start, pmem_size)) { + pr_warn("cannot reserve pmem: region overlaps reserved memory!\n"); + return; + } + + memblock_remove(pmem_start, pmem_size); + pr_info("pmem reserved: 0x%016llx - 0x%016llx (%lld MB)\n", + pmem_start, pmem_start + pmem_size, pmem_size >> 20); + pmem_res.start = pmem_start; + pmem_res.end = pmem_start + pmem_size - 1; +} +#endif + void __init arm64_memblock_init(void) { const s64 linear_region_size = BIT(vabits_actual - 1); @@ -638,6 +675,10 @@ void __init bootmem_init(void) reserve_quick_kexec(); #endif
+#ifdef CONFIG_ARM64_PMEM_RESERVE + reserve_pmem(); +#endif + reserve_pin_memory_res();
memblock_dump_all();