The Linux NVDIMM PEM drivers require arch support to map and access the
persistent memory device. This series adds RISC-V PMEM support using
recently added Svpbmt and Zicbom support.
First two patches are fixes and remaining two patches add the required
PMEM support for Linux RISC-V.
These patches can also be found in riscv_pmem_v4 branch at:
https://github.com/avpatel/linux.git
Changes since v3:
- Pickup correct version of Drew's patch as PATCH1
Changes since v2:
- Rebased on Linux-6.1-rc1
- Replaced PATCH1 with the patch proposed by Drew
Changes since v1:
- Fix error reported by test bot
https://lore.kernel.org/all/[email protected]/
Andrew Jones (1):
RISC-V: Fix compilation without RISCV_ISA_ZICBOM
Anup Patel (3):
RISC-V: Fix ioremap_cache() and ioremap_wc() for systems with Svpbmt
RISC-V: Implement arch specific PMEM APIs
RISC-V: Enable PMEM drivers
arch/riscv/Kconfig | 1 +
arch/riscv/configs/defconfig | 1 +
arch/riscv/include/asm/cacheflush.h | 8 ------
arch/riscv/include/asm/io.h | 10 +++++++
arch/riscv/include/asm/pgtable.h | 2 ++
arch/riscv/mm/Makefile | 1 +
arch/riscv/mm/cacheflush.c | 38 ++++++++++++++++++++++++++
arch/riscv/mm/dma-noncoherent.c | 41 -----------------------------
arch/riscv/mm/pmem.c | 21 +++++++++++++++
9 files changed, 74 insertions(+), 49 deletions(-)
create mode 100644 arch/riscv/mm/pmem.c
--
2.34.1
Currently, all flavors of ioremap_xyz() function maps to the generic
ioremap() which means any ioremap_xyz() call will always map the
target memory as IO using _PAGE_IOREMAP page attributes. This breaks
ioremap_cache() and ioremap_wc() on systems with Svpbmt because memory
remapped using ioremap_cache() and ioremap_wc() will use _PAGE_IOREMAP
page attributes.
To address above (just like other architectures), we implement RISC-V
specific ioremap_cache() and ioremap_wc() which maps memory using page
attributes as defined by the Svpbmt specification.
Fixes: ff689fd21cb1 ("riscv: add RISC-V Svpbmt extension support")
Co-developed-by: Mayuresh Chitale <[email protected]>
Signed-off-by: Mayuresh Chitale <[email protected]>
Signed-off-by: Anup Patel <[email protected]>
---
arch/riscv/include/asm/io.h | 10 ++++++++++
arch/riscv/include/asm/pgtable.h | 2 ++
2 files changed, 12 insertions(+)
diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
index 92080a227937..92a31e543388 100644
--- a/arch/riscv/include/asm/io.h
+++ b/arch/riscv/include/asm/io.h
@@ -133,6 +133,16 @@ __io_writes_outs(outs, u64, q, __io_pbr(), __io_paw())
#define outsq(addr, buffer, count) __outsq(PCI_IOBASE + (addr), buffer, count)
#endif
+#ifdef CONFIG_MMU
+#define ioremap_wc(addr, size) \
+ ioremap_prot((addr), (size), _PAGE_IOREMAP_WC)
+#endif
+
#include <asm-generic/io.h>
+#ifdef CONFIG_MMU
+#define ioremap_cache(addr, size) \
+ ioremap_prot((addr), (size), _PAGE_KERNEL)
+#endif
+
#endif /* _ASM_RISCV_IO_H */
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 7ec936910a96..346b7c1a3eeb 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -182,6 +182,8 @@ extern struct pt_alloc_ops pt_ops __initdata;
#define PAGE_TABLE __pgprot(_PAGE_TABLE)
#define _PAGE_IOREMAP ((_PAGE_KERNEL & ~_PAGE_MTMASK) | _PAGE_IO)
+#define _PAGE_IOREMAP_WC ((_PAGE_KERNEL & ~_PAGE_MTMASK) | \
+ _PAGE_NOCACHE)
#define PAGE_KERNEL_IO __pgprot(_PAGE_IOREMAP)
extern pgd_t swapper_pg_dir[];
--
2.34.1
The NVDIMM PMEM driver expects arch specific APIs for cache maintenance
and if arch does not provide these APIs then NVDIMM PMEM driver will
always use MEMREMAP_WT to map persistent memory which in-turn maps as
UC memory type defined by the RISC-V Svpbmt specification.
Now that the Svpbmt and Zicbom support is available in RISC-V kernel,
we implement PMEM APIs using ALT_CMO_OP() macros so that the NVDIMM
PMEM driver can use MEMREMAP_WB to map persistent memory.
Co-developed-by: Mayuresh Chitale <[email protected]>
Signed-off-by: Mayuresh Chitale <[email protected]>
Signed-off-by: Anup Patel <[email protected]>
---
arch/riscv/Kconfig | 1 +
arch/riscv/mm/Makefile | 1 +
arch/riscv/mm/pmem.c | 21 +++++++++++++++++++++
3 files changed, 23 insertions(+)
create mode 100644 arch/riscv/mm/pmem.c
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 6b48a3ae9843..025e2a1b1c60 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -25,6 +25,7 @@ config RISCV
select ARCH_HAS_GIGANTIC_PAGE
select ARCH_HAS_KCOV
select ARCH_HAS_MMIOWB
+ select ARCH_HAS_PMEM_API
select ARCH_HAS_PTE_SPECIAL
select ARCH_HAS_SET_DIRECT_MAP if MMU
select ARCH_HAS_SET_MEMORY if MMU
diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile
index d76aabf4b94d..3b368e547f83 100644
--- a/arch/riscv/mm/Makefile
+++ b/arch/riscv/mm/Makefile
@@ -31,3 +31,4 @@ endif
obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o
obj-$(CONFIG_RISCV_DMA_NONCOHERENT) += dma-noncoherent.o
+obj-$(CONFIG_ARCH_HAS_PMEM_API) += pmem.o
diff --git a/arch/riscv/mm/pmem.c b/arch/riscv/mm/pmem.c
new file mode 100644
index 000000000000..089df92ae876
--- /dev/null
+++ b/arch/riscv/mm/pmem.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 Ventana Micro Systems Inc.
+ */
+
+#include <linux/export.h>
+#include <linux/libnvdimm.h>
+
+#include <asm/cacheflush.h>
+
+void arch_wb_cache_pmem(void *addr, size_t size)
+{
+ ALT_CMO_OP(clean, addr, size, riscv_cbom_block_size);
+}
+EXPORT_SYMBOL_GPL(arch_wb_cache_pmem);
+
+void arch_invalidate_pmem(void *addr, size_t size)
+{
+ ALT_CMO_OP(inval, addr, size, riscv_cbom_block_size);
+}
+EXPORT_SYMBOL_GPL(arch_invalidate_pmem);
--
2.34.1
We now have PMEM arch support available in RISC-V kernel so let us
enable relevant drivers in defconfig.
Signed-off-by: Anup Patel <[email protected]>
---
arch/riscv/configs/defconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/riscv/configs/defconfig b/arch/riscv/configs/defconfig
index 05fd5fcf24f9..462da9f7410d 100644
--- a/arch/riscv/configs/defconfig
+++ b/arch/riscv/configs/defconfig
@@ -159,6 +159,7 @@ CONFIG_VIRTIO_MMIO=y
CONFIG_RPMSG_CHAR=y
CONFIG_RPMSG_CTRL=y
CONFIG_RPMSG_VIRTIO=y
+CONFIG_LIBNVDIMM=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
--
2.34.1
Am Mittwoch, 19. Oktober 2022, 15:11:26 CEST schrieb Anup Patel:
> Currently, all flavors of ioremap_xyz() function maps to the generic
> ioremap() which means any ioremap_xyz() call will always map the
> target memory as IO using _PAGE_IOREMAP page attributes. This breaks
> ioremap_cache() and ioremap_wc() on systems with Svpbmt because memory
> remapped using ioremap_cache() and ioremap_wc() will use _PAGE_IOREMAP
> page attributes.
>
> To address above (just like other architectures), we implement RISC-V
> specific ioremap_cache() and ioremap_wc() which maps memory using page
> attributes as defined by the Svpbmt specification.
>
> Fixes: ff689fd21cb1 ("riscv: add RISC-V Svpbmt extension support")
> Co-developed-by: Mayuresh Chitale <[email protected]>
> Signed-off-by: Mayuresh Chitale <[email protected]>
> Signed-off-by: Anup Patel <[email protected]>
Wasn't there discussion around those functions in general in v2?
In any case, the patch doesn't break anything on qemu and d1, so
Tested-by: Heiko Stuebner <[email protected]>
> ---
> arch/riscv/include/asm/io.h | 10 ++++++++++
> arch/riscv/include/asm/pgtable.h | 2 ++
> 2 files changed, 12 insertions(+)
>
> diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
> index 92080a227937..92a31e543388 100644
> --- a/arch/riscv/include/asm/io.h
> +++ b/arch/riscv/include/asm/io.h
> @@ -133,6 +133,16 @@ __io_writes_outs(outs, u64, q, __io_pbr(), __io_paw())
> #define outsq(addr, buffer, count) __outsq(PCI_IOBASE + (addr), buffer, count)
> #endif
>
> +#ifdef CONFIG_MMU
> +#define ioremap_wc(addr, size) \
> + ioremap_prot((addr), (size), _PAGE_IOREMAP_WC)
> +#endif
> +
> #include <asm-generic/io.h>
>
> +#ifdef CONFIG_MMU
> +#define ioremap_cache(addr, size) \
> + ioremap_prot((addr), (size), _PAGE_KERNEL)
> +#endif
> +
> #endif /* _ASM_RISCV_IO_H */
> diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
> index 7ec936910a96..346b7c1a3eeb 100644
> --- a/arch/riscv/include/asm/pgtable.h
> +++ b/arch/riscv/include/asm/pgtable.h
> @@ -182,6 +182,8 @@ extern struct pt_alloc_ops pt_ops __initdata;
> #define PAGE_TABLE __pgprot(_PAGE_TABLE)
>
> #define _PAGE_IOREMAP ((_PAGE_KERNEL & ~_PAGE_MTMASK) | _PAGE_IO)
> +#define _PAGE_IOREMAP_WC ((_PAGE_KERNEL & ~_PAGE_MTMASK) | \
> + _PAGE_NOCACHE)
> #define PAGE_KERNEL_IO __pgprot(_PAGE_IOREMAP)
>
> extern pgd_t swapper_pg_dir[];
>
On Wed, Oct 19, 2022 at 7:49 PM Heiko Stuebner <[email protected]> wrote:
>
> Am Mittwoch, 19. Oktober 2022, 15:11:26 CEST schrieb Anup Patel:
> > Currently, all flavors of ioremap_xyz() function maps to the generic
> > ioremap() which means any ioremap_xyz() call will always map the
> > target memory as IO using _PAGE_IOREMAP page attributes. This breaks
> > ioremap_cache() and ioremap_wc() on systems with Svpbmt because memory
> > remapped using ioremap_cache() and ioremap_wc() will use _PAGE_IOREMAP
> > page attributes.
> >
> > To address above (just like other architectures), we implement RISC-V
> > specific ioremap_cache() and ioremap_wc() which maps memory using page
> > attributes as defined by the Svpbmt specification.
> >
> > Fixes: ff689fd21cb1 ("riscv: add RISC-V Svpbmt extension support")
> > Co-developed-by: Mayuresh Chitale <[email protected]>
> > Signed-off-by: Mayuresh Chitale <[email protected]>
> > Signed-off-by: Anup Patel <[email protected]>
>
> Wasn't there discussion around those functions in general in v2?
Yes, there was discussion about a few drivers using ioremap_xyz()
which is discouraged and drivers should use memremap().
We still need the arch specific ioremap_xyz() functions/macros
added by this patch because these are required by the generic
kernel memremap() implementation (refer, kernel/iomem.c).
>
> In any case, the patch doesn't break anything on qemu and d1, so
>
> Tested-by: Heiko Stuebner <[email protected]>
Regards,
Anup
>
>
> > ---
> > arch/riscv/include/asm/io.h | 10 ++++++++++
> > arch/riscv/include/asm/pgtable.h | 2 ++
> > 2 files changed, 12 insertions(+)
> >
> > diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
> > index 92080a227937..92a31e543388 100644
> > --- a/arch/riscv/include/asm/io.h
> > +++ b/arch/riscv/include/asm/io.h
> > @@ -133,6 +133,16 @@ __io_writes_outs(outs, u64, q, __io_pbr(), __io_paw())
> > #define outsq(addr, buffer, count) __outsq(PCI_IOBASE + (addr), buffer, count)
> > #endif
> >
> > +#ifdef CONFIG_MMU
> > +#define ioremap_wc(addr, size) \
> > + ioremap_prot((addr), (size), _PAGE_IOREMAP_WC)
> > +#endif
> > +
> > #include <asm-generic/io.h>
> >
> > +#ifdef CONFIG_MMU
> > +#define ioremap_cache(addr, size) \
> > + ioremap_prot((addr), (size), _PAGE_KERNEL)
> > +#endif
> > +
> > #endif /* _ASM_RISCV_IO_H */
> > diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
> > index 7ec936910a96..346b7c1a3eeb 100644
> > --- a/arch/riscv/include/asm/pgtable.h
> > +++ b/arch/riscv/include/asm/pgtable.h
> > @@ -182,6 +182,8 @@ extern struct pt_alloc_ops pt_ops __initdata;
> > #define PAGE_TABLE __pgprot(_PAGE_TABLE)
> >
> > #define _PAGE_IOREMAP ((_PAGE_KERNEL & ~_PAGE_MTMASK) | _PAGE_IO)
> > +#define _PAGE_IOREMAP_WC ((_PAGE_KERNEL & ~_PAGE_MTMASK) | \
> > + _PAGE_NOCACHE)
> > #define PAGE_KERNEL_IO __pgprot(_PAGE_IOREMAP)
> >
> > extern pgd_t swapper_pg_dir[];
> >
>
>
>
>
On Wed, Oct 19, 2022, at 18:10, Anup Patel wrote:
> On Wed, Oct 19, 2022 at 7:49 PM Heiko Stuebner <[email protected]> wrote:
>>
>> Am Mittwoch, 19. Oktober 2022, 15:11:26 CEST schrieb Anup Patel:
>> > Currently, all flavors of ioremap_xyz() function maps to the generic
>> > ioremap() which means any ioremap_xyz() call will always map the
>> > target memory as IO using _PAGE_IOREMAP page attributes. This breaks
>> > ioremap_cache() and ioremap_wc() on systems with Svpbmt because memory
>> > remapped using ioremap_cache() and ioremap_wc() will use _PAGE_IOREMAP
>> > page attributes.
>> >
>> > To address above (just like other architectures), we implement RISC-V
>> > specific ioremap_cache() and ioremap_wc() which maps memory using page
>> > attributes as defined by the Svpbmt specification.
>> >
>> > Fixes: ff689fd21cb1 ("riscv: add RISC-V Svpbmt extension support")
>> > Co-developed-by: Mayuresh Chitale <[email protected]>
>> > Signed-off-by: Mayuresh Chitale <[email protected]>
>> > Signed-off-by: Anup Patel <[email protected]>
>>
>> Wasn't there discussion around those functions in general in v2?
>
> Yes, there was discussion about a few drivers using ioremap_xyz()
> which is discouraged and drivers should use memremap().
>
> We still need the arch specific ioremap_xyz() functions/macros
> added by this patch because these are required by the generic
> kernel memremap() implementation (refer, kernel/iomem.c).
There is a difference between the strongly discouraged
ioremap_cache() that pretty much has no valid users, and
the ioremap_wt/ioremap_wc functions that are sometimes used
for mapping video framebuffer or similar.
It should be sufficient to provide a arch_memremap_wb()
and no ioremap_cache() to make memremap() work correctly.
Arnd
On Thu, Oct 20, 2022 at 2:20 AM Arnd Bergmann <[email protected]> wrote:
>
> On Wed, Oct 19, 2022, at 18:10, Anup Patel wrote:
> > On Wed, Oct 19, 2022 at 7:49 PM Heiko Stuebner <[email protected]> wrote:
> >>
> >> Am Mittwoch, 19. Oktober 2022, 15:11:26 CEST schrieb Anup Patel:
> >> > Currently, all flavors of ioremap_xyz() function maps to the generic
> >> > ioremap() which means any ioremap_xyz() call will always map the
> >> > target memory as IO using _PAGE_IOREMAP page attributes. This breaks
> >> > ioremap_cache() and ioremap_wc() on systems with Svpbmt because memory
> >> > remapped using ioremap_cache() and ioremap_wc() will use _PAGE_IOREMAP
> >> > page attributes.
> >> >
> >> > To address above (just like other architectures), we implement RISC-V
> >> > specific ioremap_cache() and ioremap_wc() which maps memory using page
> >> > attributes as defined by the Svpbmt specification.
> >> >
> >> > Fixes: ff689fd21cb1 ("riscv: add RISC-V Svpbmt extension support")
> >> > Co-developed-by: Mayuresh Chitale <[email protected]>
> >> > Signed-off-by: Mayuresh Chitale <[email protected]>
> >> > Signed-off-by: Anup Patel <[email protected]>
> >>
> >> Wasn't there discussion around those functions in general in v2?
> >
> > Yes, there was discussion about a few drivers using ioremap_xyz()
> > which is discouraged and drivers should use memremap().
> >
> > We still need the arch specific ioremap_xyz() functions/macros
> > added by this patch because these are required by the generic
> > kernel memremap() implementation (refer, kernel/iomem.c).
>
> There is a difference between the strongly discouraged
> ioremap_cache() that pretty much has no valid users, and
> the ioremap_wt/ioremap_wc functions that are sometimes used
> for mapping video framebuffer or similar.
>
> It should be sufficient to provide a arch_memremap_wb()
> and no ioremap_cache() to make memremap() work correctly.
>
Okay, I will simplify this patch to only implement arch_memremap_wb().
This will make the MEMREMAP_WB flag to work correctly but other
MEMREMAP_xyz flags will always use non-cacheable IO mappings.
Regards,
Anup