hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4O31I
Move x86's pmem.c into nvdimm, and rename X86_PMEM_LEGACY_DEVICE to PMEM_LEGACY_DEVICE, also add PMEM_LEGACY to control the built of nd_e820.o, then the code could be reused by other architectures.
Signed-off-by: Zhuling zhuling8@huawei.com --- arch/x86/Kconfig | 6 ++---- arch/x86/kernel/Makefile | 1 - drivers/nvdimm/Kconfig | 6 ++++++ drivers/nvdimm/Makefile | 2 ++ arch/x86/kernel/pmem.c => drivers/nvdimm/pmem_legacy_device.c | 0 tools/testing/nvdimm/Kbuild | 2 +- 6 files changed, 11 insertions(+), 6 deletions(-) rename arch/x86/kernel/pmem.c => drivers/nvdimm/pmem_legacy_device.c (100%)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c77ef59..1d3176a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1667,14 +1667,12 @@ config ILLEGAL_POINTER_VALUE default 0 if X86_32 default 0xdead000000000000 if X86_64
-config X86_PMEM_LEGACY_DEVICE - bool - config X86_PMEM_LEGACY tristate "Support non-standard NVDIMMs and ADR protected memory" depends on PHYS_ADDR_T_64BIT depends on BLK_DEV - select X86_PMEM_LEGACY_DEVICE + select PMEM_LEGACY + select PMEM_LEGACY_DEVICE select NUMA_KEEP_MEMINFO if NUMA select LIBNVDIMM help diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index f0606f8..1e12751 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -130,7 +130,6 @@ obj-$(CONFIG_KVM_GUEST) += kvm.o kvmclock.o obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch.o obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o -obj-$(CONFIG_X86_PMEM_LEGACY_DEVICE) += pmem.o
obj-$(CONFIG_JAILHOUSE_GUEST) += jailhouse.o
diff --git a/drivers/nvdimm/Kconfig b/drivers/nvdimm/Kconfig index b7d1eb3..632b6ed 100644 --- a/drivers/nvdimm/Kconfig +++ b/drivers/nvdimm/Kconfig @@ -19,6 +19,12 @@ menuconfig LIBNVDIMM
if LIBNVDIMM
+config PMEM_LEGACY + tristate + +config PMEM_LEGACY_DEVICE + bool + config BLK_DEV_PMEM tristate "PMEM: Persistent memory block device support" default LIBNVDIMM diff --git a/drivers/nvdimm/Makefile b/drivers/nvdimm/Makefile index 0407753..2098221 100644 --- a/drivers/nvdimm/Makefile +++ b/drivers/nvdimm/Makefile @@ -3,6 +3,8 @@ 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_DEVICE) += pmem_legacy_device.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
diff --git a/arch/x86/kernel/pmem.c b/drivers/nvdimm/pmem_legacy_device.c similarity index 100% rename from arch/x86/kernel/pmem.c rename to drivers/nvdimm/pmem_legacy_device.c diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild index 47f9cc9..77aa117 100644 --- a/tools/testing/nvdimm/Kbuild +++ b/tools/testing/nvdimm/Kbuild @@ -28,7 +28,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_X86_PMEM_LEGACY) += nd_e820.o +obj-$(CONFIG_PMEM_LEGACY) += nd_e820.o obj-$(CONFIG_ACPI_NFIT) += nfit.o ifeq ($(CONFIG_DAX),m) obj-$(CONFIG_DAX) += dax.o
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4O31I
This patch is to support persistent memory(legacy) register on arm64.
Firstly, support memory region marked as protected memory, which removed from memblock, the ranges for persistent memory are described by the 'memmap=nn[KMG]!ss[KMG]' kernel parameter", then they will be passed to the 'pmem' driver so they can be used for persistent storage. For now, the maximum memory regions supported is 8.
Secondly, add ARM64_PMEM_LEGACY Kconfig to select PMEM_LEGACY and PMEM_LEGACY_DEVICE to reuse the nvdimm resource discovery and pmem device registering mechanism provided by pmem_legacy.c and e820.c.
Note, the functions in those file should not only used by x86, but the file and function naming is x86 specific, will update after this feature upstreamed.
Here are steps to show how to use this feature on arm64, 1. setup the memmap kernel parameter, memmap=nn[KMG]!ss[KMG], eg, memmap=100K!0x1a0000000. 2. load nd_e820.ko driver, modprobe nd_e820. 3. check pmem device in /dev, eg, /dev/pmem0
Signed-off-by: Zhuling zhuling8@huawei.com --- Documentation/admin-guide/kernel-parameters.txt | 7 ++- arch/arm64/Kconfig | 18 +++++++ arch/arm64/kernel/setup.c | 4 ++ arch/arm64/mm/Makefile | 2 + arch/arm64/mm/init.c | 7 +++ arch/arm64/mm/pmem_reserve.c | 66 +++++++++++++++++++++++++ arch/arm64/mm/pmem_reserve.h | 13 +++++ 7 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 arch/arm64/mm/pmem_reserve.c create mode 100644 arch/arm64/mm/pmem_reserve.h
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 5a0a68b..4b38e33 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -2831,10 +2831,13 @@ 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] The maximum memory regions supported is 8. + 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 2cab963..e0c2f9a 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -1325,6 +1325,24 @@ 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 + +config ARM64_PMEM_LEGACY + tristate "Support Persistent Memory (legacy) register via protected memory" + depends on BLK_DEV + select ARM64_PMEM_RESERVE + select PMEM_LEGACY + select PMEM_LEGACY_DEVICE + select LIBNVDIMM + help + Protected memory ranges for persistent memory are described by the + 'memmap=nn[KMG]!ss[KMG]' kernel parameter". + The kernel will offer those memory regions to the 'pmem' driver so + they can be used for persistent storage. + + 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/setup.c b/arch/arm64/kernel/setup.c index 92d75e3..10080cf 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -54,6 +54,8 @@ #include <asm/xen/hypervisor.h> #include <asm/mmu_context.h>
+#include "../mm/pmem_reserve.h" + static int num_standard_resources; static struct resource *standard_resources;
@@ -303,6 +305,8 @@ static void __init request_standard_resources(void) request_resource(res, &pin_memory_resource); #endif } + + request_pmem_res_resource(); }
static int __init reserve_memblock_reserved_regions(void) diff --git a/arch/arm64/mm/Makefile b/arch/arm64/mm/Makefile index 5ead3c3..42e107d 100644 --- a/arch/arm64/mm/Makefile +++ b/arch/arm64/mm/Makefile @@ -13,3 +13,5 @@ KASAN_SANITIZE_physaddr.o += n
obj-$(CONFIG_KASAN) += kasan_init.o KASAN_SANITIZE_kasan_init.o := n + +obj-$(CONFIG_ARM64_PMEM_RESERVE) += pmem_reserve.o diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 6ebfabd..5e8d078 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -47,6 +47,8 @@ #include <asm/tlb.h> #include <asm/alternative.h>
+#include "pmem_reserve.h" + /* * We need to be able to catch inadvertent references to memstart_addr * that occur (potentially in generic code) before arm64_memblock_init() @@ -442,6 +444,9 @@ 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); + setup_reserve_pmem(start_at, mem_size); } else pr_info("Unrecognized memmap option, please check the parameter.\n");
@@ -638,6 +643,8 @@ void __init bootmem_init(void) reserve_quick_kexec(); #endif
+ reserve_pmem(); + reserve_pin_memory_res();
memblock_dump_all(); diff --git a/arch/arm64/mm/pmem_reserve.c b/arch/arm64/mm/pmem_reserve.c new file mode 100644 index 0000000..70fec28 --- /dev/null +++ b/arch/arm64/mm/pmem_reserve.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#define pr_fmt(fmt) "pmem_reserve: " fmt + +#include <linux/memblock.h> +#include <linux/ioport.h> +#include <linux/types.h> + +#define MAX_REGIONS 8 +static int pmem_res_cnt; +struct resource pmem_res[MAX_REGIONS]; + +void __init setup_reserve_pmem(u64 start, u64 size) +{ + if (pmem_res_cnt >= MAX_REGIONS) { + pr_err("protected memory regions above upper limit %d\n", MAX_REGIONS); + return; + } + + pmem_res[pmem_res_cnt].start = start; + pmem_res[pmem_res_cnt].end = start + size - 1; + pmem_res_cnt++; +} + +void __init request_pmem_res_resource(void) +{ + struct resource *res; + int i; + + for (i = 0; i < pmem_res_cnt; i++) { + res = &pmem_res[i]; + res->name = "Persistent Memory (legacy)"; + res->flags = IORESOURCE_MEM; + res->desc = IORES_DESC_PERSISTENT_MEMORY_LEGACY; + if (res->start && res->end) + request_resource(&iomem_resource, res); + } +} + +void __init reserve_pmem(void) +{ + struct resource *res; + phys_addr_t size; + int i; + + for (i = 0; i < pmem_res_cnt; i++) { + res = &pmem_res[i]; + size = res->end - res->start; + if (!memblock_is_region_memory(res->start, size)) { + pr_warn("region[%pa-%pa] is not in memory\n", + &res->start, &res->end); + res->start = res->end = 0; + continue; + } + + if (memblock_is_region_reserved(res->start, size)) { + pr_warn("region[%pa-%pa] overlaps reserved memory\n", + &res->start, &res->end); + res->start = res->end = 0; + continue; + } + + memblock_remove(res->start, size); + pr_info("region %d: [%pa-%pa] (%lluMB)\n", i, &res->start, &res->end, size >> 20); + } +} diff --git a/arch/arm64/mm/pmem_reserve.h b/arch/arm64/mm/pmem_reserve.h new file mode 100644 index 0000000..d143198 --- /dev/null +++ b/arch/arm64/mm/pmem_reserve.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include <linux/types.h> + +#ifdef CONFIG_ARM64_PMEM_RESERVE +void __init setup_reserve_pmem(u64 start, u64 size); +void __init reserve_pmem(void); +void __init request_pmem_res_resource(void); +#else +static inline void __init setup_reserve_pmem(u64 start, u64 size) {} +static inline void __init reserve_pmem(void) {} +static inline void __init request_pmem_res_resource(void) {} +#endif
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I4O31I
Enable legacy pmem register feature for arm64.
Signed-off-by: Zhuling zhuling8@huawei.com --- arch/arm64/configs/openeuler_defconfig | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig index 771eb45..7745715 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=m # CONFIG_ARM64_SW_TTBR0_PAN is not set CONFIG_ARM64_TAGGED_ADDR_ABI=y CONFIG_ARM64_ILP32=y @@ -6027,6 +6029,8 @@ CONFIG_USB4=m # end of Android
CONFIG_LIBNVDIMM=m +CONFIG_PMEM_LEGACY=m +CONFIG_PMEM_LEGACY_DEVICE=y CONFIG_BLK_DEV_PMEM=m CONFIG_ND_BLK=m CONFIG_ND_CLAIM=y