hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4O31I?from=project-issue CVE: NA
------------------------------
Register pmem in arm64: Use memmap(memmap=nn[KMG]!ss[KMG]) reserve memory for pmem to register persistent memory in arm64. when the kernel restart or update, the data in PMEM will not be lost and can be loaded faster. this is a general features. Currently, only one pmem can be registered and use.
If you want use this features, you need do as follows: 1.Reserve memory: add memmap to reserve memory in grub.cfg memmap=nn[KMG]!ss[KMG] exp:memmap=100K!0x1a0000000. 2.Insmod nd_e820.ko: modprobe nd_e820. 3.Check pmem device in /dev exp: /dev/pmem0
driver/nvdimm/e820.c: The function of this file is scan "iomem_resource" and take advantage of nvdimm resource discovery mechanism by registering a resource named "Persistent Memory (legacy)", this function doesn't depend on architecture.
We will push the feature to linux kernel community and discuss to modify the file name. because people have a mistaken notion that the e820.c is depend on x86.
Signed-off-by: Zhuling zhuling8@huawei.com --- arch/arm64/Kconfig | 12 ++++++++++++ arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/pmem.c | 34 ++++++++++++++++++++++++++++++++++ drivers/nvdimm/Kconfig | 7 +++++++ drivers/nvdimm/Makefile | 1 + 5 files changed, 55 insertions(+) create mode 100644 arch/arm64/kernel/pmem.c
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 2cab963..105221c 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1325,6 +1325,18 @@ 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_LEGACY_DEVICE + bool "Create persistent storage" + depends on BLK_DEV + depends on LIBNVDIMM + select ARM64_PMEM_RESERVE + help + Use reserved memory for persistent storage when the kernel + restart or update. the data in PMEM will not be lost and + can be loaded faster. + + Say y if unsure. + config ARM64_SW_TTBR0_PAN bool "Emulate Privileged Access Never using TTBR0_EL1 switching" help diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 169d90f..f615325 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -68,6 +68,7 @@ obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o obj-$(CONFIG_SHADOW_CALL_STACK) += scs.o obj-$(CONFIG_ARM64_MTE) += mte.o obj-$(CONFIG_MPAM) += mpam/ +obj-$(CONFIG_ARM64_PMEM_LEGACY_DEVICE) += pmem.o
obj-y += vdso/ probes/ obj-$(CONFIG_COMPAT_VDSO) += vdso32/ diff --git a/arch/arm64/kernel/pmem.c b/arch/arm64/kernel/pmem.c new file mode 100644 index 0000000..2312ac0 --- /dev/null +++ b/arch/arm64/kernel/pmem.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * arm64 implement PMEM. + * based on arch/x86/kernel/pmem.c + */ +#include <linux/platform_device.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/module.h> + +static int found(struct resource *res, void *data) +{ + return 1; +} + +static int __init register_e820_pmem(void) +{ + struct platform_device *pdev; + int rc; + + rc = walk_iomem_res_desc(IORES_DESC_PERSISTENT_MEMORY_LEGACY, + IORESOURCE_MEM, 0, -1, NULL, found); + if (rc <= 0) + return 0; + + /* + * See drivers/nvdimm/e820.c for the implementation, this is + * simply here to trigger the module to load on demand. + */ + pdev = platform_device_alloc("e820_pmem", -1); + +return platform_device_add(pdev); +} +device_initcall(register_e820_pmem); diff --git a/drivers/nvdimm/Kconfig b/drivers/nvdimm/Kconfig index b7d1eb3..ce5d4fd 100644 --- a/drivers/nvdimm/Kconfig +++ b/drivers/nvdimm/Kconfig @@ -132,3 +132,10 @@ config NVDIMM_TEST_BUILD infrastructure.
endif + +config PMEM_LEGACY + tristate "Pmem_legacy" + depends on X86 || ARM64 + select X86_PMEM_LEGACY if X86 + select ARM64_PMEM_LEGACY_DEVICE if ARM64 + diff --git a/drivers/nvdimm/Makefile b/drivers/nvdimm/Makefile index 0407753..6f8dc92 100644 --- a/drivers/nvdimm/Makefile +++ b/drivers/nvdimm/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_LIBNVDIMM) += libnvdimm.o obj-$(CONFIG_BLK_DEV_PMEM) += nd_pmem.o obj-$(CONFIG_ND_BTT) += nd_btt.o obj-$(CONFIG_ND_BLK) += nd_blk.o +obj-$(CONFIG_PMEM_LEGACY) += nd_e820.o obj-$(CONFIG_OF_PMEM) += of_pmem.o obj-$(CONFIG_VIRTIO_PMEM) += virtio_pmem.o nd_virtio.o
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();
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4O31I?from=project-issue CVE: NA
Enable feature add legacy pmem for arm64 by default: 1.CONFIG_ARM64_PMEM_RESERVE=y 2.CONFIG_ARM64_PMEM_LEGACY_DEVICE=y 3.CONFIG_PMEM_LEGACY=m
Signed-off-by: Zhuling zhuling8@huawei.com --- arch/arm64/configs/openeuler_defconfig | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index 771eb45..08ec971 100644 --- a/arch/arm64/configs/openeuler_defconfig +++ b/arch/arm64/configs/openeuler_defconfig @@ -416,6 +416,8 @@ CONFIG_ARM64_CPU_PARK=y CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_UNMAP_KERNEL_AT_EL0=y CONFIG_RODATA_FULL_DEFAULT_ENABLED=y +CONFIG_ARM64_PMEM_RESERVE=y +CONFIG_ARM64_PMEM_LEGACY_DEVICE=y # CONFIG_ARM64_SW_TTBR0_PAN is not set CONFIG_ARM64_TAGGED_ADDR_ABI=y CONFIG_ARM64_ILP32=y @@ -6034,6 +6036,7 @@ CONFIG_ND_BTT=m CONFIG_BTT=y CONFIG_OF_PMEM=m CONFIG_NVDIMM_KEYS=y +CONFIG_PMEM_LEGACY=m CONFIG_DAX_DRIVER=y CONFIG_DAX=y CONFIG_DEV_DAX=m