2022-10-09 11:03:27

by Baoquan He

[permalink] [raw]
Subject: [PATCH v3 00/11] mm: ioremap: Convert architectures to take GENERIC_IOREMAP way

Currently, many architecutres have't taken the standard GENERIC_IOREMAP
way to implement ioremap_prot(), iounmap(), and ioremap_xx(), but make
these functions specifically under each arch's folder. Those cause many
duplicated codes of ioremap() and iounmap().

In this patchset, firstly adapt the hooks io[re|un]map_allowed, then
make use of them to convert those ARCH-es to take GENERIC_IOREMAP method.
With these change, duplicated ioremap/iounmap() code uder ARCH-es are
removed.

This is suggested by Christoph in below discussion:
https://lore.kernel.org/all/[email protected]/T/#u

And it's basically further action after arm64 has converted to
GENERIC_IOREMAP way in below patchset.
[PATCH v5 0/6] arm64: Cleanup ioremap() and support ioremap_prot()
https://lore.kernel.org/all/[email protected]/T/#u

v2->v3:
- Rewrite log of all patches to add more details as Christoph suggested.

- Merge the old patch 1 and 2 which adjusts return values and
parameters of arch_ioremap() into one patch, namely the current
patch 3. Christoph suggested this.

- Change the return value of arch_iounmap() to bool type since we only
do arch specific address filtering or address checking, bool value
can reflect the checking better. This is pointed out by Niklas when
he reviewed the s390 patch.

- Put hexagon patch at the beginning of patchset since hexagon has the
same ioremap() and iounmap() as standard ones, no arch_ioremap() and
arch_iounmap() hooks need be introduced. So the later arch_ioremap
and arch_iounmap() adjustment are not related in hexagon. Christophe
suggested this.

- Remove the early ioremap code from openrisc ioremap() firstly since
openrisc doesn't have early ioremap handling in openrisc arch code.
This simplifies the later converting to GENERIC_IOREMAP method.
Christoph and Stafford suggersted this.

- Fix compiling erorrs reported by lkp in parisc and sh patches.
Adding macro defintions for those port|mem io functions in
<asm/io.h> to avoid repeated definition in <asm-generic/io.h>.

v1->v2:
- Rename io[re|un]map_allowed() to arch_io[re|un]map() and made
some minor changes in patch 1~2 as per Alexander and Kefeng's
suggestions. Accordingly, adjust patches~4~11 because of the renaming
arch_io[re|un]map().

Testing:
- It's running well on arm64 system with the latest upstream kernel
and this patchset applied.
- Cross compiling passed on arc, ia64, parisc, s390, sh, xtensa.
- cross compiling is not tried on hexagon and openrisc because
- Didn't find cross compiling tools for hexagon;
- there's error with openrisc compiling, while I have no idea how to
fix it. Please see below pasted log:
---------------------------------------------------------------------
[root@intel-knightslanding-lb-02 linux]# make ARCH=openrisc defconfig
*** Default configuration is based on 'or1ksim_defconfig'
#
# configuration written to .config
#
[root@intel-knightslanding-lb-02 linux]# make ARCH=openrisc -j320 CROSS_COMPILE=/usr/bin/openrisc-linux-gnu-
SYNC include/config/auto.conf.cmd
CC scripts/mod/empty.o
./scripts/check-local-export: /usr/bin/openrisc-linux-gnu-nm failed
make[1]: *** [scripts/Makefile.build:250: scripts/mod/empty.o] Error 1
make[1]: *** Deleting file 'scripts/mod/empty.o'
make: *** [Makefile:1275: prepare0] Error 2
----------------------------------------------------------------------

Baoquan He (11):
hexagon: mm: Convert to GENERIC_IOREMAP
openrisc: mm: remove unneeded early ioremap code
mm/ioremap: change the return value of io[re|un]map_allowed and rename
mm: ioremap: allow ARCH to have its own ioremap definition
arc: mm: Convert to GENERIC_IOREMAP
ia64: mm: Convert to GENERIC_IOREMAP
openrisc: mm: Convert to GENERIC_IOREMAP
parisc: mm: Convert to GENERIC_IOREMAP
s390: mm: Convert to GENERIC_IOREMAP
sh: mm: Convert to GENERIC_IOREMAP
xtensa: mm: Convert to GENERIC_IOREMAP

arch/arc/Kconfig | 1 +
arch/arc/include/asm/io.h | 19 ++++++---
arch/arc/mm/ioremap.c | 60 ++++-----------------------
arch/arm64/include/asm/io.h | 5 ++-
arch/arm64/mm/ioremap.c | 16 +++++---
arch/hexagon/Kconfig | 1 +
arch/hexagon/include/asm/io.h | 9 ++++-
arch/hexagon/mm/ioremap.c | 44 --------------------
arch/ia64/Kconfig | 1 +
arch/ia64/include/asm/io.h | 26 +++++++-----
arch/ia64/mm/ioremap.c | 50 +++++------------------
arch/openrisc/Kconfig | 1 +
arch/openrisc/include/asm/io.h | 12 ++++--
arch/openrisc/mm/ioremap.c | 62 ++--------------------------
arch/parisc/Kconfig | 1 +
arch/parisc/include/asm/io.h | 19 ++++++---
arch/parisc/mm/ioremap.c | 65 +++---------------------------
arch/s390/Kconfig | 1 +
arch/s390/include/asm/io.h | 25 +++++++-----
arch/s390/pci/pci.c | 65 ++++++------------------------
arch/sh/Kconfig | 1 +
arch/sh/include/asm/io.h | 67 +++++++++++++++++--------------
arch/sh/include/asm/io_noioport.h | 7 ++++
arch/sh/mm/ioremap.c | 63 ++++++-----------------------
arch/xtensa/Kconfig | 1 +
arch/xtensa/include/asm/io.h | 39 ++++++++----------
arch/xtensa/mm/ioremap.c | 56 ++++++--------------------
include/asm-generic/io.h | 30 ++++++++------
mm/ioremap.c | 13 ++++--
29 files changed, 248 insertions(+), 512 deletions(-)
delete mode 100644 arch/hexagon/mm/ioremap.c

--
2.34.1


2022-10-09 11:03:40

by Baoquan He

[permalink] [raw]
Subject: [PATCH v3 11/11] xtensa: mm: Convert to GENERIC_IOREMAP

By taking GENERIC_IOREMAP method, the generic ioremap_prot() and
iounmap() are visible and available to arch. Arch only needs to
provide implementation of arch_ioremap() or arch_iounmap() if there's
arch specific handling needed in its ioremap() or iounmap(). This
change will simplify implementation by removing duplicated codes with
generic ioremap() and iounmap(), and has the equivalent functioality
as before.

For xtensa, add hooks arch_ioremap() and arch_iounmap() for xtensa's
special operation when ioremap() and iounmap(). Then define and
implement its own ioremap() and ioremap_cache() via ioremap_prot().

Signed-off-by: Baoquan He <[email protected]>
Cc: Chris Zankel <[email protected]>
Cc: Max Filippov <[email protected]>
Cc: [email protected]
---
arch/xtensa/Kconfig | 1 +
arch/xtensa/include/asm/io.h | 39 +++++++++++--------------
arch/xtensa/mm/ioremap.c | 56 ++++++++----------------------------
3 files changed, 30 insertions(+), 66 deletions(-)

diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 12ac277282ba..ee3a638f5458 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -29,6 +29,7 @@ config XTENSA
select GENERIC_LIB_UCMPDI2
select GENERIC_PCI_IOMAP
select GENERIC_SCHED_CLOCK
+ select GENERIC_IOREMAP if MMU
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index a5b707e1c0f4..126af8de5722 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -16,6 +16,7 @@
#include <asm/vectors.h>
#include <linux/bug.h>
#include <linux/kernel.h>
+#include <linux/pgtable.h>

#include <linux/types.h>

@@ -23,23 +24,29 @@
#define IO_SPACE_LIMIT ~0
#define PCI_IOBASE ((void __iomem *)XCHAL_KIO_BYPASS_VADDR)

-#ifdef CONFIG_MMU
-
-void __iomem *xtensa_ioremap_nocache(unsigned long addr, unsigned long size);
-void __iomem *xtensa_ioremap_cache(unsigned long addr, unsigned long size);
-void xtensa_iounmap(volatile void __iomem *addr);
-
/*
- * Return the virtual address for the specified bus memory.
+ * I/O memory mapping functions.
*/
+void __iomem *
+arch_ioremap(phys_addr_t *paddr, size_t size, unsigned long *prot_val);
+#define arch_ioremap arch_ioremap
+
+bool arch_iounmap(void __iomem *addr);
+#define arch_iounmap arch_iounmap
+
+void __iomem *ioremap_prot(phys_addr_t paddr, size_t size,
+ unsigned long prot);
+
static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
{
if (offset >= XCHAL_KIO_PADDR
&& offset - XCHAL_KIO_PADDR < XCHAL_KIO_SIZE)
return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_BYPASS_VADDR);
else
- return xtensa_ioremap_nocache(offset, size);
+ return ioremap_prot(offset, size,
+ pgprot_val(pgprot_noncached(PAGE_KERNEL)));
}
+#define ioremap ioremap

static inline void __iomem *ioremap_cache(unsigned long offset,
unsigned long size)
@@ -48,22 +55,10 @@ static inline void __iomem *ioremap_cache(unsigned long offset,
&& offset - XCHAL_KIO_PADDR < XCHAL_KIO_SIZE)
return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR);
else
- return xtensa_ioremap_cache(offset, size);
-}
-#define ioremap_cache ioremap_cache
-
-static inline void iounmap(volatile void __iomem *addr)
-{
- unsigned long va = (unsigned long) addr;
+ return ioremap_prot(offset, size, pgprot_val(PAGE_KERNEL));

- if (!(va >= XCHAL_KIO_CACHED_VADDR &&
- va - XCHAL_KIO_CACHED_VADDR < XCHAL_KIO_SIZE) &&
- !(va >= XCHAL_KIO_BYPASS_VADDR &&
- va - XCHAL_KIO_BYPASS_VADDR < XCHAL_KIO_SIZE))
- xtensa_iounmap(addr);
}
-
-#endif /* CONFIG_MMU */
+#define ioremap_cache ioremap_cache

#include <asm-generic/io.h>

diff --git a/arch/xtensa/mm/ioremap.c b/arch/xtensa/mm/ioremap.c
index a400188c16b9..b76c3f264f6f 100644
--- a/arch/xtensa/mm/ioremap.c
+++ b/arch/xtensa/mm/ioremap.c
@@ -6,60 +6,28 @@
*/

#include <linux/io.h>
-#include <linux/vmalloc.h>
#include <linux/pgtable.h>
#include <asm/cacheflush.h>
#include <asm/io.h>

-static void __iomem *xtensa_ioremap(unsigned long paddr, unsigned long size,
- pgprot_t prot)
+void __iomem *
+arch_ioremap(phys_addr_t *paddr, size_t size, unsigned long *prot_val)
{
- unsigned long offset = paddr & ~PAGE_MASK;
- unsigned long pfn = __phys_to_pfn(paddr);
- struct vm_struct *area;
- unsigned long vaddr;
- int err;
-
- paddr &= PAGE_MASK;
-
+ unsigned long pfn = __phys_to_pfn((*paddr));
WARN_ON(pfn_valid(pfn));

- size = PAGE_ALIGN(offset + size);
-
- area = get_vm_area(size, VM_IOREMAP);
- if (!area)
- return NULL;
-
- vaddr = (unsigned long)area->addr;
- area->phys_addr = paddr;
-
- err = ioremap_page_range(vaddr, vaddr + size, paddr, prot);
-
- if (err) {
- vunmap((void *)vaddr);
- return NULL;
- }
-
- flush_cache_vmap(vaddr, vaddr + size);
- return (void __iomem *)(offset + vaddr);
-}
-
-void __iomem *xtensa_ioremap_nocache(unsigned long addr, unsigned long size)
-{
- return xtensa_ioremap(addr, size, pgprot_noncached(PAGE_KERNEL));
+ return NULL;
}
-EXPORT_SYMBOL(xtensa_ioremap_nocache);

-void __iomem *xtensa_ioremap_cache(unsigned long addr, unsigned long size)
+bool arch_iounmap(void __iomem *addr)
{
- return xtensa_ioremap(addr, size, PAGE_KERNEL);
-}
-EXPORT_SYMBOL(xtensa_ioremap_cache);
+ unsigned long va = (unsigned long) addr;

-void xtensa_iounmap(volatile void __iomem *io_addr)
-{
- void *addr = (void *)(PAGE_MASK & (unsigned long)io_addr);
+ if ((va >= XCHAL_KIO_CACHED_VADDR &&
+ va - XCHAL_KIO_CACHED_VADDR < XCHAL_KIO_SIZE) ||
+ (va >= XCHAL_KIO_BYPASS_VADDR &&
+ va - XCHAL_KIO_BYPASS_VADDR < XCHAL_KIO_SIZE))
+ return false;

- vunmap(addr);
+ return true;
}
-EXPORT_SYMBOL(xtensa_iounmap);
--
2.34.1

2022-10-09 11:28:35

by Baoquan He

[permalink] [raw]
Subject: [PATCH v3 09/11] s390: mm: Convert to GENERIC_IOREMAP

By taking GENERIC_IOREMAP method, the generic ioremap_prot() and
iounmap() are visible and available to arch. Arch only needs to
provide implementation of arch_ioremap() or arch_iounmap() if there's
arch specific handling needed in its ioremap() or iounmap(). This
change will simplify implementation by removing duplicated codes with
generic ioremap() and iounmap(), and has the equivalent functioality
as before.

For s390, add hooks arch_ioremap() and arch_iounmap() for s390's special
operation when ioremap() and iounmap(), then ioremap_[wc|wt]() are
converted to use ioremap_prot() from GENERIC_IOREMAP.

Signed-off-by: Baoquan He <[email protected]>
Cc: Niklas Schnelle <[email protected]>
Cc: Gerald Schaefer <[email protected]>
Cc: Heiko Carstens <[email protected]>
Cc: Vasily Gorbik <[email protected]>
Cc: Alexander Gordeev <[email protected]>
Cc: Christian Borntraeger <[email protected]>
Cc: Sven Schnelle <[email protected]>
Cc: [email protected]
---
v2->v3:
- Add code comment inside arch_ioremap() to help uderstand the
obsucre code. Christoph suggested this, Niklas provided the
paragraph of text.

arch/s390/Kconfig | 1 +
arch/s390/include/asm/io.h | 25 +++++++++------
arch/s390/pci/pci.c | 65 ++++++++------------------------------
3 files changed, 30 insertions(+), 61 deletions(-)

diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 318fce77601d..c59e1b25f59d 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -135,6 +135,7 @@ config S390
select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL
select GENERIC_VDSO_TIME_NS
+ select GENERIC_IOREMAP
select HAVE_ALIGNED_STRUCT_PAGE if SLUB
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_JUMP_LABEL
diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h
index e3882b012bfa..db201563baa6 100644
--- a/arch/s390/include/asm/io.h
+++ b/arch/s390/include/asm/io.h
@@ -22,11 +22,22 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);

#define IO_SPACE_LIMIT 0

-void __iomem *ioremap_prot(phys_addr_t addr, size_t size, unsigned long prot);
-void __iomem *ioremap(phys_addr_t addr, size_t size);
-void __iomem *ioremap_wc(phys_addr_t addr, size_t size);
-void __iomem *ioremap_wt(phys_addr_t addr, size_t size);
-void iounmap(volatile void __iomem *addr);
+/*
+ * I/O memory mapping functions.
+ */
+void __iomem *
+arch_ioremap(phys_addr_t *paddr, size_t size, unsigned long *prot_val);
+#define arch_ioremap arch_ioremap
+
+bool arch_iounmap(void __iomem *addr);
+#define arch_iounmap arch_iounmap
+
+#define _PAGE_IOREMAP pgprot_val(PAGE_KERNEL)
+
+#define ioremap_wc(addr, size) \
+ ioremap_prot((addr), (size), pgprot_val(pgprot_writecombine(PAGE_KERNEL)))
+#define ioremap_wt(addr, size) \
+ ioremap_prot((addr), (size), pgprot_val(pgprot_writethrough(PAGE_KERNEL)))

static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
{
@@ -51,10 +62,6 @@ static inline void ioport_unmap(void __iomem *p)
#define pci_iomap_wc pci_iomap_wc
#define pci_iomap_wc_range pci_iomap_wc_range

-#define ioremap ioremap
-#define ioremap_wt ioremap_wt
-#define ioremap_wc ioremap_wc
-
#define memcpy_fromio(dst, src, count) zpci_memcpy_fromio(dst, src, count)
#define memcpy_toio(dst, src, count) zpci_memcpy_toio(dst, src, count)
#define memset_io(dst, val, count) zpci_memset_io(dst, val, count)
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 73cdc5539384..3c00dc7d79bc 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -244,64 +244,25 @@ void __iowrite64_copy(void __iomem *to, const void *from, size_t count)
zpci_memcpy_toio(to, from, count);
}

-static void __iomem *__ioremap(phys_addr_t addr, size_t size, pgprot_t prot)
+void __iomem *
+arch_ioremap(phys_addr_t *paddr, size_t size, unsigned long *prot_val)
{
- unsigned long offset, vaddr;
- struct vm_struct *area;
- phys_addr_t last_addr;
-
- last_addr = addr + size - 1;
- if (!size || last_addr < addr)
- return NULL;
-
+ /*
+ * When PCI MIO instructions are unavailable the "physical" address
+ * encodes a hint for accessing the PCI memory space it represents.
+ * Just pass it unchanged such that ioread/iowrite can decode it.
+ */
if (!static_branch_unlikely(&have_mio))
- return (void __iomem *) addr;
-
- offset = addr & ~PAGE_MASK;
- addr &= PAGE_MASK;
- size = PAGE_ALIGN(size + offset);
- area = get_vm_area(size, VM_IOREMAP);
- if (!area)
- return NULL;
-
- vaddr = (unsigned long) area->addr;
- if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) {
- free_vm_area(area);
- return NULL;
- }
- return (void __iomem *) ((unsigned long) area->addr + offset);
+ return (void __iomem *) *paddr;
+ return NULL;
}

-void __iomem *ioremap_prot(phys_addr_t addr, size_t size, unsigned long prot)
+bool arch_iounmap(void __iomem *addr)
{
- return __ioremap(addr, size, __pgprot(prot));
-}
-EXPORT_SYMBOL(ioremap_prot);
-
-void __iomem *ioremap(phys_addr_t addr, size_t size)
-{
- return __ioremap(addr, size, PAGE_KERNEL);
-}
-EXPORT_SYMBOL(ioremap);
-
-void __iomem *ioremap_wc(phys_addr_t addr, size_t size)
-{
- return __ioremap(addr, size, pgprot_writecombine(PAGE_KERNEL));
-}
-EXPORT_SYMBOL(ioremap_wc);
-
-void __iomem *ioremap_wt(phys_addr_t addr, size_t size)
-{
- return __ioremap(addr, size, pgprot_writethrough(PAGE_KERNEL));
-}
-EXPORT_SYMBOL(ioremap_wt);
-
-void iounmap(volatile void __iomem *addr)
-{
- if (static_branch_likely(&have_mio))
- vunmap((__force void *) ((unsigned long) addr & PAGE_MASK));
+ if (!static_branch_likely(&have_mio))
+ return false;
+ return true;
}
-EXPORT_SYMBOL(iounmap);

/* Create a virtual mapping cookie for a PCI BAR */
static void __iomem *pci_iomap_range_fh(struct pci_dev *pdev, int bar,
--
2.34.1

2022-10-09 11:28:49

by Baoquan He

[permalink] [raw]
Subject: [PATCH v3 01/11] hexagon: mm: Convert to GENERIC_IOREMAP

By taking GENERIC_IOREMAP method, the generic ioremap_prot() and
iounmap() are visible and available to arch. Arch only needs to
provide implementation of arch_ioremap() or arch_iounmap() if there's
arch specific handling needed in its ioremap() or iounmap(). This
change will simplify implementation by removing duplicated codes with
generic ioremap() and iounmap(), and has the equivalent functioality.

For hexagon, the current ioremap() and iounmap() are the same as
generic version. After taking GENERIC_IOREMAP way, the old ioremap()
and iounmap() can be completely removed.

Signed-off-by: Baoquan He <[email protected]>
Cc: Brian Cain <[email protected]>
Cc: Mark Brown <[email protected]>
Cc: Linus Walleij <[email protected]>
Cc: [email protected]
---
v2->v3:
Rewrite patch log.
Put it at the beginning of patchset since it doesn't introduce new
arch_ioremap()/arch_iounmap().

arch/hexagon/Kconfig | 1 +
arch/hexagon/include/asm/io.h | 9 +++++--
arch/hexagon/mm/ioremap.c | 44 -----------------------------------
3 files changed, 8 insertions(+), 46 deletions(-)
delete mode 100644 arch/hexagon/mm/ioremap.c

diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
index 54eadf265178..17afffde1a7f 100644
--- a/arch/hexagon/Kconfig
+++ b/arch/hexagon/Kconfig
@@ -25,6 +25,7 @@ config HEXAGON
select NEED_SG_DMA_LENGTH
select NO_IOPORT_MAP
select GENERIC_IOMAP
+ select GENERIC_IOREMAP
select GENERIC_SMP_IDLE_THREAD
select STACKTRACE_SUPPORT
select GENERIC_CLOCKEVENTS_BROADCAST
diff --git a/arch/hexagon/include/asm/io.h b/arch/hexagon/include/asm/io.h
index 46a099de85b7..dcd9cbbf5934 100644
--- a/arch/hexagon/include/asm/io.h
+++ b/arch/hexagon/include/asm/io.h
@@ -170,8 +170,13 @@ static inline void writel(u32 data, volatile void __iomem *addr)
#define writew_relaxed __raw_writew
#define writel_relaxed __raw_writel

-void __iomem *ioremap(unsigned long phys_addr, unsigned long size);
-#define ioremap_uc(X, Y) ioremap((X), (Y))
+/*
+ * I/O memory mapping functions.
+ */
+#define _PAGE_IOREMAP (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
+ (__HEXAGON_C_DEV << 6))
+
+#define ioremap_uc(addr, size) ioremap((addr), (size))


#define __raw_writel writel
diff --git a/arch/hexagon/mm/ioremap.c b/arch/hexagon/mm/ioremap.c
deleted file mode 100644
index 255c5b1ee1a7..000000000000
--- a/arch/hexagon/mm/ioremap.c
+++ /dev/null
@@ -1,44 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * I/O remap functions for Hexagon
- *
- * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- */
-
-#include <linux/io.h>
-#include <linux/vmalloc.h>
-#include <linux/mm.h>
-
-void __iomem *ioremap(unsigned long phys_addr, unsigned long size)
-{
- unsigned long last_addr, addr;
- unsigned long offset = phys_addr & ~PAGE_MASK;
- struct vm_struct *area;
-
- pgprot_t prot = __pgprot(_PAGE_PRESENT|_PAGE_READ|_PAGE_WRITE
- |(__HEXAGON_C_DEV << 6));
-
- last_addr = phys_addr + size - 1;
-
- /* Wrapping not allowed */
- if (!size || (last_addr < phys_addr))
- return NULL;
-
- /* Rounds up to next page size, including whole-page offset */
- size = PAGE_ALIGN(offset + size);
-
- area = get_vm_area(size, VM_IOREMAP);
- addr = (unsigned long)area->addr;
-
- if (ioremap_page_range(addr, addr+size, phys_addr, prot)) {
- vunmap((void *)addr);
- return NULL;
- }
-
- return (void __iomem *) (offset + addr);
-}
-
-void iounmap(const volatile void __iomem *addr)
-{
- vunmap((void *) ((unsigned long) addr & PAGE_MASK));
-}
--
2.34.1

2022-10-09 11:29:13

by Baoquan He

[permalink] [raw]
Subject: [PATCH v3 08/11] parisc: mm: Convert to GENERIC_IOREMAP

By taking GENERIC_IOREMAP method, the generic ioremap_prot() and
iounmap() are visible and available to arch. Arch only needs to
provide implementation of arch_ioremap() or arch_iounmap() if there's
arch specific handling needed in its ioremap() or iounmap(). This
change will simplify implementation by removing duplicated codes with
generic ioremap() and iounmap(), and has the equivalent functioality
as before.

For parisc, add hook arch_ioremap() for parisc's special operation when
ioremap(), then ioremap_[wc|uc]() are converted to use ioremap_prot()
from GENERIC_IOREMAP.

Meanwhile, add macro ARCH_HAS_IOREMAP_WC since the added ioremap_wc()
will conflict with the one in include/asm-generic/iomap.h, then an
compiling error is seen:

./include/asm-generic/iomap.h:97: warning: "ioremap_wc" redefined
97 | #define ioremap_wc ioremap

And benefit from the commit 437b6b35362b ("parisc: Use the generic
IO helpers"), those macros don't need be added any more.

Signed-off-by: Baoquan He <[email protected]>
Cc: "James E.J. Bottomley" <[email protected]>
Cc: Helge Deller <[email protected]>
Cc: [email protected]
---
v2->v3:
- Fix compiling error by adding macro definition, ARCH_HAS_IOREMAP_WC.
- Benefit from commit 437b6b35362b ("parisc: Use the generic IO helpers"),
those tons of port/mem io operation macro definitions are not needed
after rebasing to the latest upstream.

arch/parisc/Kconfig | 1 +
arch/parisc/include/asm/io.h | 19 ++++++++---
arch/parisc/mm/ioremap.c | 65 ++++--------------------------------
3 files changed, 21 insertions(+), 64 deletions(-)

diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index a98940e64243..0ed18e673aba 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -36,6 +36,7 @@ config PARISC
select GENERIC_ATOMIC64 if !64BIT
select GENERIC_IRQ_PROBE
select GENERIC_PCI_IOMAP
+ select GENERIC_IOREMAP
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_SMP_IDLE_THREAD
select GENERIC_ARCH_TOPOLOGY if SMP
diff --git a/arch/parisc/include/asm/io.h b/arch/parisc/include/asm/io.h
index c05e781be2f5..1c54f83d4f78 100644
--- a/arch/parisc/include/asm/io.h
+++ b/arch/parisc/include/asm/io.h
@@ -2,6 +2,8 @@
#ifndef _ASM_IO_H
#define _ASM_IO_H

+#define ARCH_HAS_IOREMAP_WC
+
#include <linux/types.h>
#include <linux/pgtable.h>

@@ -125,12 +127,19 @@ static inline void gsc_writeq(unsigned long long val, unsigned long addr)
/*
* The standard PCI ioremap interfaces
*/
-void __iomem *ioremap(unsigned long offset, unsigned long size);
-#define ioremap_wc ioremap
-#define ioremap_uc ioremap
-#define pci_iounmap pci_iounmap
+void __iomem *
+arch_ioremap(phys_addr_t *paddr, size_t size, unsigned long *prot_val);
+#define arch_ioremap arch_ioremap
+
+#define _PAGE_IOREMAP (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | \
+ _PAGE_ACCESSED | _PAGE_NO_CACHE)

-extern void iounmap(const volatile void __iomem *addr);
+#define ioremap_wc(addr, size) \
+ ioremap_prot((addr), (size), _PAGE_IOREMAP)
+#define ioremap_uc(addr, size) \
+ ioremap_prot((addr), (size), _PAGE_IOREMAP)
+
+#define pci_iounmap pci_iounmap

void memset_io(volatile void __iomem *addr, unsigned char val, int count);
void memcpy_fromio(void *dst, const volatile void __iomem *src, int count);
diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c
index 345ff0b66499..28884757fad0 100644
--- a/arch/parisc/mm/ioremap.c
+++ b/arch/parisc/mm/ioremap.c
@@ -13,38 +13,19 @@
#include <linux/io.h>
#include <linux/mm.h>

-/*
- * Generic mapping function (not visible outside):
- */
-
-/*
- * Remap an arbitrary physical address space into the kernel virtual
- * address space.
- *
- * NOTE! We need to allow non-page-aligned mappings too: we will obviously
- * have to convert them into an offset in a page-aligned mapping, but the
- * caller shouldn't need to know that small detail.
- */
-void __iomem *ioremap(unsigned long phys_addr, unsigned long size)
+void __iomem *
+arch_ioremap(phys_addr_t *paddr, size_t size, unsigned long *prot_val)
{
- void __iomem *addr;
- struct vm_struct *area;
- unsigned long offset, last_addr;
- pgprot_t pgprot;
+ phys_addr_t phys_addr = *paddr;

#ifdef CONFIG_EISA
unsigned long end = phys_addr + size - 1;
/* Support EISA addresses */
if ((phys_addr >= 0x00080000 && end < 0x000fffff) ||
(phys_addr >= 0x00500000 && end < 0x03bfffff))
- phys_addr |= F_EXTEND(0xfc000000);
+ *paddr = phys_addr |= F_EXTEND(0xfc000000);
#endif

- /* Don't allow wraparound or zero size */
- last_addr = phys_addr + size - 1;
- if (!size || last_addr < phys_addr)
- return NULL;
-
/*
* Don't allow anybody to remap normal RAM that we're using..
*/
@@ -58,43 +39,9 @@ void __iomem *ioremap(unsigned long phys_addr, unsigned long size)
for (page = virt_to_page(t_addr);
page <= virt_to_page(t_end); page++) {
if(!PageReserved(page))
- return NULL;
+ return IOMEM_ERR_PTR(-EINVAL);
}
}

- pgprot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY |
- _PAGE_ACCESSED | _PAGE_NO_CACHE);
-
- /*
- * Mappings have to be page-aligned
- */
- offset = phys_addr & ~PAGE_MASK;
- phys_addr &= PAGE_MASK;
- size = PAGE_ALIGN(last_addr + 1) - phys_addr;
-
- /*
- * Ok, go for it..
- */
- area = get_vm_area(size, VM_IOREMAP);
- if (!area)
- return NULL;
-
- addr = (void __iomem *) area->addr;
- if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
- phys_addr, pgprot)) {
- vunmap(addr);
- return NULL;
- }
-
- return (void __iomem *) (offset + (char __iomem *)addr);
-}
-EXPORT_SYMBOL(ioremap);
-
-void iounmap(const volatile void __iomem *io_addr)
-{
- unsigned long addr = (unsigned long)io_addr & PAGE_MASK;
-
- if (is_vmalloc_addr((void *)addr))
- vunmap((void *)addr);
+ return NULL;
}
-EXPORT_SYMBOL(iounmap);
--
2.34.1

2022-10-09 11:44:56

by Baoquan He

[permalink] [raw]
Subject: [PATCH v3 04/11] mm: ioremap: allow ARCH to have its own ioremap definition

Architectures like xtensa, arc, can be converted to GENERIC_IOREMAP,
to take standard ioremap_prot() and ioremap_xxx() way. But they have
ARCH specific handling for ioremap() method, than standard ioremap()
method.

In oder to convert them to take GENERIC_IOREMAP method, allow these
architecutres to have their own ioremap definition.

This is a preparation patch, no functionality change.

Signed-off-by: Baoquan He <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: [email protected]
Cc: Kefeng Wang <[email protected]>
---
include/asm-generic/io.h | 3 +++
1 file changed, 3 insertions(+)

diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index 2ae16906f3be..8878914579d8 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -1078,11 +1078,14 @@ void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size,
unsigned long prot);
void iounmap(volatile void __iomem *addr);

+#ifndef ioremap
+#define ioremap ioremap
static inline void __iomem *ioremap(phys_addr_t addr, size_t size)
{
/* _PAGE_IOREMAP needs to be supplied by the architecture */
return ioremap_prot(addr, size, _PAGE_IOREMAP);
}
+#endif
#endif /* !CONFIG_MMU || CONFIG_GENERIC_IOREMAP */

#ifndef ioremap_wc
--
2.34.1

2022-10-09 11:46:32

by Baoquan He

[permalink] [raw]
Subject: [PATCH v3 06/11] ia64: mm: Convert to GENERIC_IOREMAP

By taking GENERIC_IOREMAP method, the generic ioremap_prot() and
iounmap() are visible and available to arch. Arch only needs to
provide implementation of arch_ioremap() or arch_iounmap() if there's
arch specific handling needed in its ioremap() or iounmap(). This
change will simplify implementation by removing duplicated codes with
generic ioremap() and iounmap(), and has the equivalent functioality
as before.

Here add hooks arch_ioremap() and arch_iounmap() for ia64's special
operation when ioremap() and iounmap(), then ioremap_cache() is
converted to use ioremap_prot() from GENERIC_IOREMAP.

The old ioremap_uc() is kept and add its macro definittion.

Signed-off-by: Baoquan He <[email protected]>
Cc: [email protected]
---
arch/ia64/Kconfig | 1 +
arch/ia64/include/asm/io.h | 26 ++++++++++++--------
arch/ia64/mm/ioremap.c | 50 +++++++++-----------------------------
3 files changed, 28 insertions(+), 49 deletions(-)

diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 26ac8ea15a9e..1ca18be5dc30 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -45,6 +45,7 @@ config IA64
select GENERIC_IRQ_LEGACY
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_IOMAP
+ select GENERIC_IOREMAP
select GENERIC_SMP_IDLE_THREAD
select ARCH_TASK_STRUCT_ON_STACK
select ARCH_TASK_STRUCT_ALLOCATOR
diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h
index ce66dfc0e719..54378cea4b36 100644
--- a/arch/ia64/include/asm/io.h
+++ b/arch/ia64/include/asm/io.h
@@ -247,17 +247,23 @@ static inline void outsl(unsigned long port, const void *src,

# ifdef __KERNEL__

-extern void __iomem * ioremap(unsigned long offset, unsigned long size);
-extern void __iomem * ioremap_uc(unsigned long offset, unsigned long size);
-extern void iounmap (volatile void __iomem *addr);
-static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size)
-{
- return ioremap(phys_addr, size);
-}
-#define ioremap ioremap
-#define ioremap_cache ioremap_cache
+/*
+ * I/O memory mapping functions.
+ */
+void __iomem *
+arch_ioremap(phys_addr_t *paddr, size_t size, unsigned long *prot_val);
+#define arch_ioremap arch_ioremap
+
+bool arch_iounmap(void __iomem *addr);
+#define arch_iounmap arch_iounmap
+
+#define _PAGE_IOREMAP pgprot_val(PAGE_KERNEL)
+
+#define ioremap_cache(addr, size) \
+ ioremap_prot((addr), (size), pgprot_val(PAGE_KERNEL))
+
+void __iomem *ioremap_uc(unsigned long offset, unsigned long size);
#define ioremap_uc ioremap_uc
-#define iounmap iounmap

/*
* String version of IO memory access ops:
diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c
index 55fd3eb753ff..a290c7dc7f1e 100644
--- a/arch/ia64/mm/ioremap.c
+++ b/arch/ia64/mm/ioremap.c
@@ -30,15 +30,12 @@ early_ioremap (unsigned long phys_addr, unsigned long size)
}

void __iomem *
-ioremap (unsigned long phys_addr, unsigned long size)
+arch_ioremap(phys_addr_t *paddr, size_t size, unsigned long *prot_val)
{
- void __iomem *addr;
- struct vm_struct *area;
- unsigned long offset;
- pgprot_t prot;
- u64 attr;
+ phys_addr_t phys_addr = *paddr;
unsigned long gran_base, gran_size;
unsigned long page_base;
+ u64 attr;

/*
* For things in kern_memmap, we must use the same attribute
@@ -69,35 +66,18 @@ ioremap (unsigned long phys_addr, unsigned long size)
page_base = phys_addr & PAGE_MASK;
size = PAGE_ALIGN(phys_addr + size) - page_base;
if (efi_mem_attribute(page_base, size) & EFI_MEMORY_WB) {
- prot = PAGE_KERNEL;
-
- /*
- * Mappings have to be page-aligned
- */
- offset = phys_addr & ~PAGE_MASK;
- phys_addr &= PAGE_MASK;
-
- /*
- * Ok, go for it..
- */
- area = get_vm_area(size, VM_IOREMAP);
- if (!area)
- return NULL;
-
- area->phys_addr = phys_addr;
- addr = (void __iomem *) area->addr;
- if (ioremap_page_range((unsigned long) addr,
- (unsigned long) addr + size, phys_addr, prot)) {
- vunmap((void __force *) addr);
- return NULL;
- }
-
- return (void __iomem *) (offset + (char __iomem *)addr);
+ return NULL;
}

return __ioremap_uc(phys_addr);
}
-EXPORT_SYMBOL(ioremap);
+
+bool arch_iounmap(void __iomem *addr)
+{
+ if (REGION_NUMBER(addr) != RGN_GATE)
+ return false;
+ return true;
+}

void __iomem *
ioremap_uc(unsigned long phys_addr, unsigned long size)
@@ -113,11 +93,3 @@ void
early_iounmap (volatile void __iomem *addr, unsigned long size)
{
}
-
-void
-iounmap (volatile void __iomem *addr)
-{
- if (REGION_NUMBER(addr) == RGN_GATE)
- vunmap((void *) ((unsigned long) addr & PAGE_MASK));
-}
-EXPORT_SYMBOL(iounmap);
--
2.34.1

2022-10-09 14:40:12

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v3 09/11] s390: mm: Convert to GENERIC_IOREMAP

Hi Baoquan,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on next-20221007]
[cannot apply to akpm-mm/mm-everything openrisc/for-next deller-parisc/for-next s390/features v6.0]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/mm-ioremap-Convert-architectures-to-take-GENERIC_IOREMAP-way/20221009-183524
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a6afa4199d3d038fbfdff5511f7523b0e30cb774
config: s390-buildonly-randconfig-r006-20221009
compiler: s390-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/69f65149d2e87de076edbb2b4dd9532f8f57dd8b
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Baoquan-He/mm-ioremap-Convert-architectures-to-take-GENERIC_IOREMAP-way/20221009-183524
git checkout 69f65149d2e87de076edbb2b4dd9532f8f57dd8b
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

s390-linux-ld: mm/ioremap.o: in function `ioremap_prot':
>> ioremap.c:(.text+0x9a): undefined reference to `arch_ioremap'
s390-linux-ld: mm/ioremap.o: in function `iounmap':
>> ioremap.c:(.text+0x234): undefined reference to `arch_iounmap'
s390-linux-ld: drivers/dma/qcom/hidma.o: in function `hidma_probe':
hidma.c:(.text+0x4b46): undefined reference to `devm_ioremap_resource'
s390-linux-ld: hidma.c:(.text+0x4b9e): undefined reference to `devm_ioremap_resource'

--
0-DAY CI Kernel Test Service
https://01.org/lkp


Attachments:
(No filename) (2.21 kB)
config (64.84 kB)
Download all attachments

2022-10-09 16:26:01

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v3 11/11] xtensa: mm: Convert to GENERIC_IOREMAP

Hi Baoquan,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on next-20221007]
[cannot apply to akpm-mm/mm-everything openrisc/for-next deller-parisc/for-next s390/features v6.0]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/mm-ioremap-Convert-architectures-to-take-GENERIC_IOREMAP-way/20221009-183524
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a6afa4199d3d038fbfdff5511f7523b0e30cb774
config: xtensa-nommu_kc705_defconfig
compiler: xtensa-de212-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/1330d435c818ccf34bf24ceb36ef6acb1128cf6c
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Baoquan-He/mm-ioremap-Convert-architectures-to-take-GENERIC_IOREMAP-way/20221009-183524
git checkout 1330d435c818ccf34bf24ceb36ef6acb1128cf6c
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=xtensa prepare

If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

In file included from include/linux/io.h:13,
from include/linux/irq.h:20,
from include/asm-generic/hardirq.h:17,
from ./arch/xtensa/include/generated/asm/hardirq.h:1,
from include/linux/hardirq.h:11,
from include/linux/interrupt.h:11,
from include/linux/kernel_stat.h:9,
from include/linux/cgroup.h:26,
from include/linux/memcontrol.h:13,
from include/linux/swap.h:9,
from include/linux/suspend.h:5,
from arch/xtensa/kernel/asm-offsets.c:24:
arch/xtensa/include/asm/io.h: In function 'ioremap_cache':
>> arch/xtensa/include/asm/io.h:56:55: error: 'XCHAL_KIO_CACHED_VADDR' undeclared (first use in this function); did you mean 'XCHAL_KIO_BYPASS_VADDR'?
56 | return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR);
| ^~~~~~~~~~~~~~~~~~~~~~
| XCHAL_KIO_BYPASS_VADDR
arch/xtensa/include/asm/io.h:56:55: note: each undeclared identifier is reported only once for each function it appears in
make[2]: *** [scripts/Makefile.build:118: arch/xtensa/kernel/asm-offsets.s] Error 1
make[2]: Target '__build' not remade because of errors.
make[1]: *** [Makefile:1276: prepare0] Error 2
make[1]: Target 'prepare' not remade because of errors.
make: *** [Makefile:231: __sub-make] Error 2
make: Target 'prepare' not remade because of errors.


vim +56 arch/xtensa/include/asm/io.h

9a8fd558990215 include/asm-xtensa/io.h Chris Zankel 2005-06-23 50
02f3774877382b arch/xtensa/include/asm/io.h Max Filippov 2012-09-17 51 static inline void __iomem *ioremap_cache(unsigned long offset,
02f3774877382b arch/xtensa/include/asm/io.h Max Filippov 2012-09-17 52 unsigned long size)
9a8fd558990215 include/asm-xtensa/io.h Chris Zankel 2005-06-23 53 {
173d6681380aa1 include/asm-xtensa/io.h Chris Zankel 2006-12-10 54 if (offset >= XCHAL_KIO_PADDR
02f3774877382b arch/xtensa/include/asm/io.h Max Filippov 2012-09-17 55 && offset - XCHAL_KIO_PADDR < XCHAL_KIO_SIZE)
173d6681380aa1 include/asm-xtensa/io.h Chris Zankel 2006-12-10 @56 return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR);
173d6681380aa1 include/asm-xtensa/io.h Chris Zankel 2006-12-10 57 else
1330d435c818cc arch/xtensa/include/asm/io.h Baoquan He 2022-10-09 58 return ioremap_prot(offset, size, pgprot_val(PAGE_KERNEL));
5bb8def55dc562 arch/xtensa/include/asm/io.h Max Filippov 2015-12-10 59

--
0-DAY CI Kernel Test Service
https://01.org/lkp


Attachments:
(No filename) (4.40 kB)
config (53.22 kB)
Download all attachments

2022-10-09 17:14:03

by Christophe Leroy

[permalink] [raw]
Subject: Re: [PATCH v3 01/11] hexagon: mm: Convert to GENERIC_IOREMAP



Le 09/10/2022 à 12:31, Baoquan He a écrit :
> By taking GENERIC_IOREMAP method, the generic ioremap_prot() and
> iounmap() are visible and available to arch. Arch only needs to
> provide implementation of arch_ioremap() or arch_iounmap() if there's
> arch specific handling needed in its ioremap() or iounmap(). This
> change will simplify implementation by removing duplicated codes with
> generic ioremap() and iounmap(), and has the equivalent functioality.
>
> For hexagon, the current ioremap() and iounmap() are the same as
> generic version. After taking GENERIC_IOREMAP way, the old ioremap()
> and iounmap() can be completely removed.
>
> Signed-off-by: Baoquan He <[email protected]>
> Cc: Brian Cain <[email protected]>
> Cc: Mark Brown <[email protected]>
> Cc: Linus Walleij <[email protected]>
> Cc: [email protected]
> ---
> v2->v3:
> Rewrite patch log.
> Put it at the beginning of patchset since it doesn't introduce new
> arch_ioremap()/arch_iounmap().
>
> arch/hexagon/Kconfig | 1 +
> arch/hexagon/include/asm/io.h | 9 +++++--
> arch/hexagon/mm/ioremap.c | 44 -----------------------------------
> 3 files changed, 8 insertions(+), 46 deletions(-)
> delete mode 100644 arch/hexagon/mm/ioremap.c
>
> diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
> index 54eadf265178..17afffde1a7f 100644
> --- a/arch/hexagon/Kconfig
> +++ b/arch/hexagon/Kconfig
> @@ -25,6 +25,7 @@ config HEXAGON
> select NEED_SG_DMA_LENGTH
> select NO_IOPORT_MAP
> select GENERIC_IOMAP
> + select GENERIC_IOREMAP
> select GENERIC_SMP_IDLE_THREAD
> select STACKTRACE_SUPPORT
> select GENERIC_CLOCKEVENTS_BROADCAST
> diff --git a/arch/hexagon/include/asm/io.h b/arch/hexagon/include/asm/io.h
> index 46a099de85b7..dcd9cbbf5934 100644
> --- a/arch/hexagon/include/asm/io.h
> +++ b/arch/hexagon/include/asm/io.h
> @@ -170,8 +170,13 @@ static inline void writel(u32 data, volatile void __iomem *addr)
> #define writew_relaxed __raw_writew
> #define writel_relaxed __raw_writel
>
> -void __iomem *ioremap(unsigned long phys_addr, unsigned long size);
> -#define ioremap_uc(X, Y) ioremap((X), (Y))
> +/*
> + * I/O memory mapping functions.
> + */
> +#define _PAGE_IOREMAP (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
> + (__HEXAGON_C_DEV << 6))
> +
> +#define ioremap_uc(addr, size) ioremap((addr), (size))

Why do you need to change this macro ?

>
>
> #define __raw_writel writel
> diff --git a/arch/hexagon/mm/ioremap.c b/arch/hexagon/mm/ioremap.c
> deleted file mode 100644
> index 255c5b1ee1a7..000000000000
> --- a/arch/hexagon/mm/ioremap.c
> +++ /dev/null
> @@ -1,44 +0,0 @@
> -// SPDX-License-Identifier: GPL-2.0-only
> -/*
> - * I/O remap functions for Hexagon
> - *
> - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
> - */
> -
> -#include <linux/io.h>
> -#include <linux/vmalloc.h>
> -#include <linux/mm.h>
> -
> -void __iomem *ioremap(unsigned long phys_addr, unsigned long size)
> -{
> - unsigned long last_addr, addr;
> - unsigned long offset = phys_addr & ~PAGE_MASK;
> - struct vm_struct *area;
> -
> - pgprot_t prot = __pgprot(_PAGE_PRESENT|_PAGE_READ|_PAGE_WRITE
> - |(__HEXAGON_C_DEV << 6));
> -
> - last_addr = phys_addr + size - 1;
> -
> - /* Wrapping not allowed */
> - if (!size || (last_addr < phys_addr))
> - return NULL;
> -
> - /* Rounds up to next page size, including whole-page offset */
> - size = PAGE_ALIGN(offset + size);
> -
> - area = get_vm_area(size, VM_IOREMAP);
> - addr = (unsigned long)area->addr;
> -
> - if (ioremap_page_range(addr, addr+size, phys_addr, prot)) {
> - vunmap((void *)addr);
> - return NULL;
> - }
> -
> - return (void __iomem *) (offset + addr);
> -}
> -
> -void iounmap(const volatile void __iomem *addr)
> -{
> - vunmap((void *) ((unsigned long) addr & PAGE_MASK));
> -}

2022-10-10 01:53:05

by Baoquan He

[permalink] [raw]
Subject: Re: [PATCH v3 01/11] hexagon: mm: Convert to GENERIC_IOREMAP

On 10/09/22 at 04:39pm, Christophe Leroy wrote:
>
>
> Le 09/10/2022 ? 12:31, Baoquan He a ?crit?:
> > By taking GENERIC_IOREMAP method, the generic ioremap_prot() and
> > iounmap() are visible and available to arch. Arch only needs to
> > provide implementation of arch_ioremap() or arch_iounmap() if there's
> > arch specific handling needed in its ioremap() or iounmap(). This
> > change will simplify implementation by removing duplicated codes with
> > generic ioremap() and iounmap(), and has the equivalent functioality.
> >
> > For hexagon, the current ioremap() and iounmap() are the same as
> > generic version. After taking GENERIC_IOREMAP way, the old ioremap()
> > and iounmap() can be completely removed.
> >
> > Signed-off-by: Baoquan He <[email protected]>
> > Cc: Brian Cain <[email protected]>
> > Cc: Mark Brown <[email protected]>
> > Cc: Linus Walleij <[email protected]>
> > Cc: [email protected]
> > ---
> > v2->v3:
> > Rewrite patch log.
> > Put it at the beginning of patchset since it doesn't introduce new
> > arch_ioremap()/arch_iounmap().
> >
> > arch/hexagon/Kconfig | 1 +
> > arch/hexagon/include/asm/io.h | 9 +++++--
> > arch/hexagon/mm/ioremap.c | 44 -----------------------------------
> > 3 files changed, 8 insertions(+), 46 deletions(-)
> > delete mode 100644 arch/hexagon/mm/ioremap.c
> >
> > diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig
> > index 54eadf265178..17afffde1a7f 100644
> > --- a/arch/hexagon/Kconfig
> > +++ b/arch/hexagon/Kconfig
> > @@ -25,6 +25,7 @@ config HEXAGON
> > select NEED_SG_DMA_LENGTH
> > select NO_IOPORT_MAP
> > select GENERIC_IOMAP
> > + select GENERIC_IOREMAP
> > select GENERIC_SMP_IDLE_THREAD
> > select STACKTRACE_SUPPORT
> > select GENERIC_CLOCKEVENTS_BROADCAST
> > diff --git a/arch/hexagon/include/asm/io.h b/arch/hexagon/include/asm/io.h
> > index 46a099de85b7..dcd9cbbf5934 100644
> > --- a/arch/hexagon/include/asm/io.h
> > +++ b/arch/hexagon/include/asm/io.h
> > @@ -170,8 +170,13 @@ static inline void writel(u32 data, volatile void __iomem *addr)
> > #define writew_relaxed __raw_writew
> > #define writel_relaxed __raw_writel
> >
> > -void __iomem *ioremap(unsigned long phys_addr, unsigned long size);
> > -#define ioremap_uc(X, Y) ioremap((X), (Y))
> > +/*
> > + * I/O memory mapping functions.
> > + */
> > +#define _PAGE_IOREMAP (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \
> > + (__HEXAGON_C_DEV << 6))
> > +
> > +#define ioremap_uc(addr, size) ioremap((addr), (size))
>
> Why do you need to change this macro ?

I don't like the X, Y since they look meaningless. I can change back if
you like the old one. Thanks for checking.

2022-10-10 03:32:34

by Baoquan He

[permalink] [raw]
Subject: Re: [PATCH v3 11/11] xtensa: mm: Convert to GENERIC_IOREMAP

On 10/10/22 at 12:12am, kernel test robot wrote:
> Hi Baoquan,
>
> I love your patch! Yet something to improve:
>
> [auto build test ERROR on linus/master]
> [also build test ERROR on next-20221007]
> [cannot apply to akpm-mm/mm-everything openrisc/for-next deller-parisc/for-next s390/features v6.0]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
> url: https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/mm-ioremap-Convert-architectures-to-take-GENERIC_IOREMAP-way/20221009-183524
> base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a6afa4199d3d038fbfdff5511f7523b0e30cb774
> config: xtensa-nommu_kc705_defconfig
> compiler: xtensa-de212-linux-gcc (GCC) 12.1.0
> reproduce (this is a W=1 build):
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # https://github.com/intel-lab-lkp/linux/commit/1330d435c818ccf34bf24ceb36ef6acb1128cf6c
> git remote add linux-review https://github.com/intel-lab-lkp/linux
> git fetch --no-tags linux-review Baoquan-He/mm-ioremap-Convert-architectures-to-take-GENERIC_IOREMAP-way/20221009-183524
> git checkout 1330d435c818ccf34bf24ceb36ef6acb1128cf6c
> # save the config file
> mkdir build_dir && cp config build_dir/.config
> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=xtensa prepare
>
> If you fix the issue, kindly add following tag where applicable
> | Reported-by: kernel test robot <[email protected]>
>
> All errors (new ones prefixed by >>):
>
> In file included from include/linux/io.h:13,
> from include/linux/irq.h:20,
> from include/asm-generic/hardirq.h:17,
> from ./arch/xtensa/include/generated/asm/hardirq.h:1,
> from include/linux/hardirq.h:11,
> from include/linux/interrupt.h:11,
> from include/linux/kernel_stat.h:9,
> from include/linux/cgroup.h:26,
> from include/linux/memcontrol.h:13,
> from include/linux/swap.h:9,
> from include/linux/suspend.h:5,
> from arch/xtensa/kernel/asm-offsets.c:24:
> arch/xtensa/include/asm/io.h: In function 'ioremap_cache':
> >> arch/xtensa/include/asm/io.h:56:55: error: 'XCHAL_KIO_CACHED_VADDR' undeclared (first use in this function); did you mean 'XCHAL_KIO_BYPASS_VADDR'?
> 56 | return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR);
> | ^~~~~~~~~~~~~~~~~~~~~~
> | XCHAL_KIO_BYPASS_VADDR
> arch/xtensa/include/asm/io.h:56:55: note: each undeclared identifier is reported only once for each function it appears in
> make[2]: *** [scripts/Makefile.build:118: arch/xtensa/kernel/asm-offsets.s] Error 1
> make[2]: Target '__build' not remade because of errors.
> make[1]: *** [Makefile:1276: prepare0] Error 2
> make[1]: Target 'prepare' not remade because of errors.
> make: *** [Makefile:231: __sub-make] Error 2
> make: Target 'prepare' not remade because of errors.

Thanks for reporting.

With the provided nommu config, I reproduced above compiling error and
fix it with below change. I will merge it to the xtensa patch in v4 post.
=====
In <asm/io.h>, the io memory mapping funcions should be wrapped inside
CONFIG_MMU ifdeffery scope. Otherwise it will cause compiling error
when nommu is enabled.
Signed-off-by: Baoquan He <[email protected]>
Reported-by: kernel test robot <[email protected]>

diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index 126af8de5722..3331de4e692d 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -24,6 +24,7 @@
#define IO_SPACE_LIMIT ~0
#define PCI_IOBASE ((void __iomem *)XCHAL_KIO_BYPASS_VADDR)

+#ifdef CONFIG_MMU
/*
* I/O memory mapping functions.
*/
@@ -59,6 +60,7 @@ static inline void __iomem *ioremap_cache(unsigned long offset,

}
#define ioremap_cache ioremap_cache
+#endif /* CONFIG_MMU */

#include <asm-generic/io.h>


2022-10-10 11:27:35

by Baoquan He

[permalink] [raw]
Subject: Re: [PATCH v3 09/11] s390: mm: Convert to GENERIC_IOREMAP

On 10/09/22 at 09:54pm, kernel test robot wrote:
> Hi Baoquan,
>
> I love your patch! Yet something to improve:
>
> [auto build test ERROR on linus/master]
> [also build test ERROR on next-20221007]
> [cannot apply to akpm-mm/mm-everything openrisc/for-next deller-parisc/for-next s390/features v6.0]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch#_base_tree_information]
>
> url: https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/mm-ioremap-Convert-architectures-to-take-GENERIC_IOREMAP-way/20221009-183524
> base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a6afa4199d3d038fbfdff5511f7523b0e30cb774
> config: s390-buildonly-randconfig-r006-20221009
> compiler: s390-linux-gcc (GCC) 12.1.0
> reproduce (this is a W=1 build):
> wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> # https://github.com/intel-lab-lkp/linux/commit/69f65149d2e87de076edbb2b4dd9532f8f57dd8b
> git remote add linux-review https://github.com/intel-lab-lkp/linux
> git fetch --no-tags linux-review Baoquan-He/mm-ioremap-Convert-architectures-to-take-GENERIC_IOREMAP-way/20221009-183524
> git checkout 69f65149d2e87de076edbb2b4dd9532f8f57dd8b
> # save the config file
> mkdir build_dir && cp config build_dir/.config
> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 SHELL=/bin/bash
>
> If you fix the issue, kindly add following tag where applicable
> | Reported-by: kernel test robot <[email protected]>
>
> All errors (new ones prefixed by >>):
>
> s390-linux-ld: mm/ioremap.o: in function `ioremap_prot':
> >> ioremap.c:(.text+0x9a): undefined reference to `arch_ioremap'
> s390-linux-ld: mm/ioremap.o: in function `iounmap':
> >> ioremap.c:(.text+0x234): undefined reference to `arch_iounmap'
> s390-linux-ld: drivers/dma/qcom/hidma.o: in function `hidma_probe':
> hidma.c:(.text+0x4b46): undefined reference to `devm_ioremap_resource'
> s390-linux-ld: hidma.c:(.text+0x4b9e): undefined reference to `devm_ioremap_resource'

The above compiling errors are caused by unsetting CONFIG_PCI in
s390-buildonly-randconfig-r006-20221009 attached. I keep the items for
reference. Because s390 puts io mem functions in arch/s390/pci/pci.c.
While building arch/s390/pci/pci.c in needs CONFIG_PCI enabled. I don't
think disabling CONFIG_PCI in s390x makes sense in reality, except of
the randconfig testing.

Hi Niklas, lkp

What do you think about this? We can just ignore this building error
with randconfig in lkp?

>
> --
> 0-DAY CI Kernel Test Service
> https://01.org/lkp

> #
> # Automatically generated file; DO NOT EDIT.
> # Linux/s390 6.0.0 Kernel Configuration
> #
......
> # end of General setup
>
> CONFIG_MMU=y
......
> # Device Drivers
> #
> CONFIG_HAVE_PCI=y
> # CONFIG_PCI is not set
......

2022-10-10 12:21:26

by Niklas Schnelle

[permalink] [raw]
Subject: Re: [PATCH v3 09/11] s390: mm: Convert to GENERIC_IOREMAP

On Mon, 2022-10-10 at 18:38 +0800, Baoquan He wrote:
> On 10/09/22 at 09:54pm, kernel test robot wrote:
> > Hi Baoquan,
> >
> > I love your patch! Yet something to improve:
> >
> > [auto build test ERROR on linus/master]
> > [also build test ERROR on next-20221007]
> > [cannot apply to akpm-mm/mm-everything openrisc/for-next deller-parisc/for-next s390/features v6.0]
> > [If your patch is applied to the wrong git tree, kindly drop us a note.
> > And when submitting patch, we suggest to use '--base' as documented in
> > https://git-scm.com/docs/git-format-patch#_base_tree_information]
> >
> > url: https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/mm-ioremap-Convert-architectures-to-take-GENERIC_IOREMAP-way/20221009-183524
> > base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a6afa4199d3d038fbfdff5511f7523b0e30cb774
> > config: s390-buildonly-randconfig-r006-20221009
> > compiler: s390-linux-gcc (GCC) 12.1.0
> > reproduce (this is a W=1 build):
> > wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> > chmod +x ~/bin/make.cross
> > # https://github.com/intel-lab-lkp/linux/commit/69f65149d2e87de076edbb2b4dd9532f8f57dd8b
> > git remote add linux-review https://github.com/intel-lab-lkp/linux
> > git fetch --no-tags linux-review Baoquan-He/mm-ioremap-Convert-architectures-to-take-GENERIC_IOREMAP-way/20221009-183524
> > git checkout 69f65149d2e87de076edbb2b4dd9532f8f57dd8b
> > # save the config file
> > mkdir build_dir && cp config build_dir/.config
> > COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 SHELL=/bin/bash
> >
> > If you fix the issue, kindly add following tag where applicable
> > > Reported-by: kernel test robot <[email protected]>
> >
> > All errors (new ones prefixed by >>):
> >
> > s390-linux-ld: mm/ioremap.o: in function `ioremap_prot':
> > > > ioremap.c:(.text+0x9a): undefined reference to `arch_ioremap'
> > s390-linux-ld: mm/ioremap.o: in function `iounmap':
> > > > ioremap.c:(.text+0x234): undefined reference to `arch_iounmap'
> > s390-linux-ld: drivers/dma/qcom/hidma.o: in function `hidma_probe':
> > hidma.c:(.text+0x4b46): undefined reference to `devm_ioremap_resource'
> > s390-linux-ld: hidma.c:(.text+0x4b9e): undefined reference to `devm_ioremap_resource'
>
> The above compiling errors are caused by unsetting CONFIG_PCI in
> s390-buildonly-randconfig-r006-20221009 attached. I keep the items for
> reference. Because s390 puts io mem functions in arch/s390/pci/pci.c.
> While building arch/s390/pci/pci.c in needs CONFIG_PCI enabled. I don't
> think disabling CONFIG_PCI in s390x makes sense in reality, except of
> the randconfig testing.
>
> Hi Niklas, lkp
>
> What do you think about this? We can just ignore this building error
> with randconfig in lkp?

Hmm, that's a bummer. As s390 systems (aka mainframes) do have classic
channel devices for networking and permanent storage that are currently
even more common than PCI devices you can definitely have a fully
functional system with CONFIG_PCI=n. Also the drivers for these channel
devices do not use ioremap() which is only used for PCI, so in theory
it should be fine not to have ioremap() for CONFIG_PCI=n.

I think the reason for this concrete failure to compile is a missing
HAS_IOMEM dependency for CONFIG_QCOM_HIDMA. I'm not sure how many other
cases there are though as I think we might be the only ones where
HAS_IOMEM is only sometimes available (it depends on CONFIG_PCI for
us). Ideally I think we would have the driver dependencies. I'm a bit
confused though since in the current code it looks to me like
ioremap_prot() will be declared but not defined for CONFIG_PCI=n too as
far as I can tell at least.

>
> > --
> > 0-DAY CI Kernel Test Service
> > https://01.org/lkp
> > #
> > # Automatically generated file; DO NOT EDIT.
> > # Linux/s390 6.0.0 Kernel Configuration
> > #
> ......
> > # end of General setup
> >
> > CONFIG_MMU=y
> ......
> > # Device Drivers
> > #
> > CONFIG_HAVE_PCI=y
> > # CONFIG_PCI is not set
> ......
>


2022-10-11 03:18:13

by Baoquan He

[permalink] [raw]
Subject: Re: [PATCH v3 09/11] s390: mm: Convert to GENERIC_IOREMAP

On 10/10/22 at 01:53pm, Niklas Schnelle wrote:
> On Mon, 2022-10-10 at 18:38 +0800, Baoquan He wrote:
> > On 10/09/22 at 09:54pm, kernel test robot wrote:
> > > Hi Baoquan,
> > >
> > > I love your patch! Yet something to improve:
> > >
> > > [auto build test ERROR on linus/master]
> > > [also build test ERROR on next-20221007]
> > > [cannot apply to akpm-mm/mm-everything openrisc/for-next deller-parisc/for-next s390/features v6.0]
> > > [If your patch is applied to the wrong git tree, kindly drop us a note.
> > > And when submitting patch, we suggest to use '--base' as documented in
> > > https://git-scm.com/docs/git-format-patch#_base_tree_information]
> > >
> > > url: https://github.com/intel-lab-lkp/linux/commits/Baoquan-He/mm-ioremap-Convert-architectures-to-take-GENERIC_IOREMAP-way/20221009-183524
> > > base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a6afa4199d3d038fbfdff5511f7523b0e30cb774
> > > config: s390-buildonly-randconfig-r006-20221009
> > > compiler: s390-linux-gcc (GCC) 12.1.0
> > > reproduce (this is a W=1 build):
> > > wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
> > > chmod +x ~/bin/make.cross
> > > # https://github.com/intel-lab-lkp/linux/commit/69f65149d2e87de076edbb2b4dd9532f8f57dd8b
> > > git remote add linux-review https://github.com/intel-lab-lkp/linux
> > > git fetch --no-tags linux-review Baoquan-He/mm-ioremap-Convert-architectures-to-take-GENERIC_IOREMAP-way/20221009-183524
> > > git checkout 69f65149d2e87de076edbb2b4dd9532f8f57dd8b
> > > # save the config file
> > > mkdir build_dir && cp config build_dir/.config
> > > COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=s390 SHELL=/bin/bash
> > >
> > > If you fix the issue, kindly add following tag where applicable
> > > > Reported-by: kernel test robot <[email protected]>
> > >
> > > All errors (new ones prefixed by >>):
> > >
> > > s390-linux-ld: mm/ioremap.o: in function `ioremap_prot':
> > > > > ioremap.c:(.text+0x9a): undefined reference to `arch_ioremap'
> > > s390-linux-ld: mm/ioremap.o: in function `iounmap':
> > > > > ioremap.c:(.text+0x234): undefined reference to `arch_iounmap'
> > > s390-linux-ld: drivers/dma/qcom/hidma.o: in function `hidma_probe':
> > > hidma.c:(.text+0x4b46): undefined reference to `devm_ioremap_resource'
> > > s390-linux-ld: hidma.c:(.text+0x4b9e): undefined reference to `devm_ioremap_resource'
> >
> > The above compiling errors are caused by unsetting CONFIG_PCI in
> > s390-buildonly-randconfig-r006-20221009 attached. I keep the items for
> > reference. Because s390 puts io mem functions in arch/s390/pci/pci.c.
> > While building arch/s390/pci/pci.c in needs CONFIG_PCI enabled. I don't
> > think disabling CONFIG_PCI in s390x makes sense in reality, except of
> > the randconfig testing.
> >
> > Hi Niklas, lkp
> >
> > What do you think about this? We can just ignore this building error
> > with randconfig in lkp?
>
> Hmm, that's a bummer. As s390 systems (aka mainframes) do have classic
> channel devices for networking and permanent storage that are currently
> even more common than PCI devices you can definitely have a fully
> functional system with CONFIG_PCI=n. Also the drivers for these channel
> devices do not use ioremap() which is only used for PCI, so in theory
> it should be fine not to have ioremap() for CONFIG_PCI=n.

Thanks for detailed explanation.

I built the latest upstream kernel with the randconfig, it has the issue
either, please see below build log snippet. Means if CONFIG_PCI is unset,
it has problem with the current s390 code.

ld: drivers/dma/qcom/hidma.o: in function `hidma_probe':
hidma.c:(.text+0x4b46): undefined reference to `devm_ioremap_resource'
ld: hidma.c:(.text+0x4b9e): undefined reference to `devm_ioremap_resource'
ld: drivers/pcmcia/cistpl.o: in function `set_cis_map':
cistpl.c:(.text+0x1202): undefined reference to `ioremap'
ld: cistpl.c:(.text+0x13b0): undefined reference to `iounmap'
ld: cistpl.c:(.text+0x14a6): undefined reference to `iounmap'
ld: cistpl.c:(.text+0x1544): undefined reference to `ioremap'
ld: drivers/pcmcia/cistpl.o: in function `release_cis_mem':
cistpl.c:(.text+0x3f14): undefined reference to `iounmap'
make[1]: *** [scripts/Makefile.vmlinux:34: vmlinux] Error 1
make: *** [Makefile:1235: vmlinux] Error 2

>
> I think the reason for this concrete failure to compile is a missing
> HAS_IOMEM dependency for CONFIG_QCOM_HIDMA. I'm not sure how many other
> cases there are though as I think we might be the only ones where
> HAS_IOMEM is only sometimes available (it depends on CONFIG_PCI for
> us). Ideally I think we would have the driver dependencies. I'm a bit
> confused though since in the current code it looks to me like
> ioremap_prot() will be declared but not defined for CONFIG_PCI=n too as
> far as I can tell at least.

Yeah, depending on HAS_IOMEM for QCOM_HIDMA can fix it. And in
drivers/pcmcia/cistpl.c, there are ioremap()/iounmap() calling too.
Make PCMCIA depend on HAS_IOMEM can fix it.

ioremap_prot() will called outside if CONFIG_HAVE_IOREMAP_PROT is
enabled. With this patchset, it will only be declared and defined when
CONFIG_GENERIC_IOREMAP is enabled. Please correct me if I'm wrong.

Below draft change can fix the compiling errors with the randconfig on
s390 as you suggested. We may need post the driver code change in
another patch since it's not related to this patchset?

From 1e169ce8e825d3a33be891ad06e14008582c7011 Mon Sep 17 00:00:00 2001
From: Baoquan He <[email protected]>
Date: Tue, 11 Oct 2022 09:30:49 +0800
Subject: [PATCH] s390, ioremap: fix
Content-type: text/plain

On s390 systems (aka mainframes), it has classic channel devices for
networking and permanent storage that are currently even more common
than PCI devices. Hence it's likely to have a fully functional s390
kernel with CONFIG_PCI=n.

So let GENERIC_IOREMAP depend on PCI in s390 arch since the drivers for
those channel devices do not use ioremap() which is only used for PCI,
in theory it should be fine not to have ioremap() for CONFIG_PCI=n.

And let QCOM_HIDMA and PCMCIA PCMCIA depend on HAS_IOMEM so that they
won't be built if PCI is unset.

Signed-off-by: Baoquan He <[email protected]>
---
arch/s390/Kconfig | 2 +-
drivers/dma/qcom/Kconfig | 1 +
drivers/pcmcia/Kconfig | 1 +
3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index c59e1b25f59d..f6a7f1752f0f 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -135,7 +135,7 @@ config S390
select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL
select GENERIC_VDSO_TIME_NS
- select GENERIC_IOREMAP
+ select GENERIC_IOREMAP if PCI
select HAVE_ALIGNED_STRUCT_PAGE if SLUB
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_JUMP_LABEL
diff --git a/drivers/dma/qcom/Kconfig b/drivers/dma/qcom/Kconfig
index 3f926a653bd8..ace75d7b835a 100644
--- a/drivers/dma/qcom/Kconfig
+++ b/drivers/dma/qcom/Kconfig
@@ -45,6 +45,7 @@ config QCOM_HIDMA_MGMT

config QCOM_HIDMA
tristate "Qualcomm Technologies HIDMA Channel support"
+ depends on HAS_IOMEM
select DMA_ENGINE
help
Enable support for the Qualcomm Technologies HIDMA controller.
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 1525023e49b6..7c412bbe8bbe 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -20,6 +20,7 @@ if PCCARD

config PCMCIA
tristate "16-bit PCMCIA support"
+ depends on HAS_IOMEM
select CRC32
default y
help
--
2.34.1



2022-10-11 15:43:22

by Niklas Schnelle

[permalink] [raw]
Subject: Re: [PATCH v3 09/11] s390: mm: Convert to GENERIC_IOREMAP

On Sun, 2022-10-09 at 18:31 +0800, Baoquan He wrote:
> By taking GENERIC_IOREMAP method, the generic ioremap_prot() and
> iounmap() are visible and available to arch. Arch only needs to
> provide implementation of arch_ioremap() or arch_iounmap() if there's
> arch specific handling needed in its ioremap() or iounmap(). This
> change will simplify implementation by removing duplicated codes with
> generic ioremap() and iounmap(), and has the equivalent functioality
> as before.
>
> For s390, add hooks arch_ioremap() and arch_iounmap() for s390's special
> operation when ioremap() and iounmap(), then ioremap_[wc|wt]() are
> converted to use ioremap_prot() from GENERIC_IOREMAP.
>
> Signed-off-by: Baoquan He <[email protected]>
> Cc: Niklas Schnelle <[email protected]>
> Cc: Gerald Schaefer <[email protected]>
> Cc: Heiko Carstens <[email protected]>
> Cc: Vasily Gorbik <[email protected]>
> Cc: Alexander Gordeev <[email protected]>
> Cc: Christian Borntraeger <[email protected]>
> Cc: Sven Schnelle <[email protected]>
> Cc: [email protected]
> ---
> v2->v3:
> - Add code comment inside arch_ioremap() to help uderstand the
> obsucre code. Christoph suggested this, Niklas provided the
> paragraph of text.
>
> arch/s390/Kconfig | 1 +
> arch/s390/include/asm/io.h | 25 +++++++++------
> arch/s390/pci/pci.c | 65 ++++++++------------------------------
> 3 files changed, 30 insertions(+), 61 deletions(-)
>
> diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
> index 318fce77601d..c59e1b25f59d 100644
> --- a/arch/s390/Kconfig
> +++ b/arch/s390/Kconfig
> @@ -135,6 +135,7 @@ config S390
> select GENERIC_SMP_IDLE_THREAD
> select GENERIC_TIME_VSYSCALL
> select GENERIC_VDSO_TIME_NS
> + select GENERIC_IOREMAP

I think you should add the "if PCI" from the diff in your last mail to
this patch.

> select HAVE_ALIGNED_STRUCT_PAGE if SLUB
> select HAVE_ARCH_AUDITSYSCALL
> select HAVE_ARCH_JUMP_LABEL
> diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h
> index e3882b012bfa..db201563baa6 100644
> --- a/arch/s390/include/asm/io.h
> +++ b/arch/s390/include/asm/io.h
> @@ -22,11 +22,22 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);
>
> #define IO_SPACE_LIMIT 0
>
> -void __iomem *ioremap_prot(phys_addr_t addr, size_t size, unsigned long prot);
> -void __iomem *ioremap(phys_addr_t addr, size_t size);
> -void __iomem *ioremap_wc(phys_addr_t addr, size_t size);
> -void __iomem *ioremap_wt(phys_addr_t addr, size_t size);
> -void iounmap(volatile void __iomem *addr);
> +/*
> + * I/O memory mapping functions.
> + */
> +void __iomem *
> +arch_ioremap(phys_addr_t *paddr, size_t size, unsigned long *prot_val);
> +#define arch_ioremap arch_ioremap
> +
> +bool arch_iounmap(void __iomem *addr);
> +#define arch_iounmap arch_iounmap
> +
> +#define _PAGE_IOREMAP pgprot_val(PAGE_KERNEL)
> +
> +#define ioremap_wc(addr, size) \
> + ioremap_prot((addr), (size), pgprot_val(pgprot_writecombine(PAGE_KERNEL)))
> +#define ioremap_wt(addr, size) \
> + ioremap_prot((addr), (size), pgprot_val(pgprot_writethrough(PAGE_KERNEL)))
>
> static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
> {
> @@ -51,10 +62,6 @@ static inline void ioport_unmap(void __iomem *p)
> #define pci_iomap_wc pci_iomap_wc
> #define pci_iomap_wc_range pci_iomap_wc_range
>
> -#define ioremap ioremap
> -#define ioremap_wt ioremap_wt
> -#define ioremap_wc ioremap_wc
> -
> #define memcpy_fromio(dst, src, count) zpci_memcpy_fromio(dst, src, count)
> #define memcpy_toio(dst, src, count) zpci_memcpy_toio(dst, src, count)
> #define memset_io(dst, val, count) zpci_memset_io(dst, val, count)
> diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
> index 73cdc5539384..3c00dc7d79bc 100644
> --- a/arch/s390/pci/pci.c
> +++ b/arch/s390/pci/pci.c
> @@ -244,64 +244,25 @@ void __iowrite64_copy(void __iomem *to, const void *from, size_t count)
> zpci_memcpy_toio(to, from, count);
> }
>
> -static void __iomem *__ioremap(phys_addr_t addr, size_t size, pgprot_t prot)
> +void __iomem *
> +arch_ioremap(phys_addr_t *paddr, size_t size, unsigned long *prot_val)
> {
> - unsigned long offset, vaddr;
> - struct vm_struct *area;
> - phys_addr_t last_addr;
> -
> - last_addr = addr + size - 1;
> - if (!size || last_addr < addr)
> - return NULL;
> -
> + /*
> + * When PCI MIO instructions are unavailable the "physical" address
> + * encodes a hint for accessing the PCI memory space it represents.
> + * Just pass it unchanged such that ioread/iowrite can decode it.
> + */
> if (!static_branch_unlikely(&have_mio))
> - return (void __iomem *) addr;
> -
> - offset = addr & ~PAGE_MASK;
> - addr &= PAGE_MASK;
> - size = PAGE_ALIGN(size + offset);
> - area = get_vm_area(size, VM_IOREMAP);
> - if (!area)
> - return NULL;
> -
> - vaddr = (unsigned long) area->addr;
> - if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) {
> - free_vm_area(area);
> - return NULL;
> - }
> - return (void __iomem *) ((unsigned long) area->addr + offset);
> + return (void __iomem *) *paddr;

nit: no space after the cast

> + return NULL;
> }
>
> -void __iomem *ioremap_prot(phys_addr_t addr, size_t size, unsigned long prot)
> +bool arch_iounmap(void __iomem *addr)
> {
> - return __ioremap(addr, size, __pgprot(prot));
> -}
> -EXPORT_SYMBOL(ioremap_prot);
> -
> -void __iomem *ioremap(phys_addr_t addr, size_t size)
> -{
> - return __ioremap(addr, size, PAGE_KERNEL);
> -}
> -EXPORT_SYMBOL(ioremap);
> -
> -void __iomem *ioremap_wc(phys_addr_t addr, size_t size)
> -{
> - return __ioremap(addr, size, pgprot_writecombine(PAGE_KERNEL));
> -}
> -EXPORT_SYMBOL(ioremap_wc);
> -
> -void __iomem *ioremap_wt(phys_addr_t addr, size_t size)
> -{
> - return __ioremap(addr, size, pgprot_writethrough(PAGE_KERNEL));
> -}
> -EXPORT_SYMBOL(ioremap_wt);
> -
> -void iounmap(volatile void __iomem *addr)
> -{
> - if (static_branch_likely(&have_mio))
> - vunmap((__force void *) ((unsigned long) addr & PAGE_MASK));
> + if (!static_branch_likely(&have_mio))
> + return false;
> + return true;
> }
> -EXPORT_SYMBOL(iounmap);
>
> /* Create a virtual mapping cookie for a PCI BAR */
> static void __iomem *pci_iomap_range_fh(struct pci_dev *pdev, int bar,

Gave this a round of testing on s390 with both the MIO and non-MIO
cases. I also see you addressed my previous comments and it looks good
to me. As you showed in the other mail the compile error is a pre
existing problem so shouldn't influence this change. So assuming you
add the "if PCI" and the nit above you can add my:

Tested-by: Niklas
Schnelle <[email protected]>
Reviewed-by: Niklas Schnelle
<[email protected]>


2022-10-12 05:58:06

by Baoquan He

[permalink] [raw]
Subject: Re: [PATCH v3 09/11] s390: mm: Convert to GENERIC_IOREMAP

On 10/11/22 at 05:16pm, Niklas Schnelle wrote:
> On Sun, 2022-10-09 at 18:31 +0800, Baoquan He wrote:
> > By taking GENERIC_IOREMAP method, the generic ioremap_prot() and
> > iounmap() are visible and available to arch. Arch only needs to
> > provide implementation of arch_ioremap() or arch_iounmap() if there's
> > arch specific handling needed in its ioremap() or iounmap(). This
> > change will simplify implementation by removing duplicated codes with
> > generic ioremap() and iounmap(), and has the equivalent functioality
> > as before.
> >
> > For s390, add hooks arch_ioremap() and arch_iounmap() for s390's special
> > operation when ioremap() and iounmap(), then ioremap_[wc|wt]() are
> > converted to use ioremap_prot() from GENERIC_IOREMAP.
> >
> > Signed-off-by: Baoquan He <[email protected]>
> > Cc: Niklas Schnelle <[email protected]>
> > Cc: Gerald Schaefer <[email protected]>
> > Cc: Heiko Carstens <[email protected]>
> > Cc: Vasily Gorbik <[email protected]>
> > Cc: Alexander Gordeev <[email protected]>
> > Cc: Christian Borntraeger <[email protected]>
> > Cc: Sven Schnelle <[email protected]>
> > Cc: [email protected]
> > ---
> > v2->v3:
> > - Add code comment inside arch_ioremap() to help uderstand the
> > obsucre code. Christoph suggested this, Niklas provided the
> > paragraph of text.
> >
> > arch/s390/Kconfig | 1 +
> > arch/s390/include/asm/io.h | 25 +++++++++------
> > arch/s390/pci/pci.c | 65 ++++++++------------------------------
> > 3 files changed, 30 insertions(+), 61 deletions(-)
> >
> > diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
> > index 318fce77601d..c59e1b25f59d 100644
> > --- a/arch/s390/Kconfig
> > +++ b/arch/s390/Kconfig
> > @@ -135,6 +135,7 @@ config S390
> > select GENERIC_SMP_IDLE_THREAD
> > select GENERIC_TIME_VSYSCALL
> > select GENERIC_VDSO_TIME_NS
> > + select GENERIC_IOREMAP
>
> I think you should add the "if PCI" from the diff in your last mail to
> this patch.

That's reasonable, will do.

The code change in driver should be posted separately to get reviewing
from the relevant drvier maintainers. I may wrap it into this series in
next post so that people know its background.

>
> > select HAVE_ALIGNED_STRUCT_PAGE if SLUB
> > select HAVE_ARCH_AUDITSYSCALL
> > select HAVE_ARCH_JUMP_LABEL
......
> > diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
> > index 73cdc5539384..3c00dc7d79bc 100644
> > --- a/arch/s390/pci/pci.c
> > +++ b/arch/s390/pci/pci.c
> > @@ -244,64 +244,25 @@ void __iowrite64_copy(void __iomem *to, const void *from, size_t count)
> > zpci_memcpy_toio(to, from, count);
> > }
> >
> > -static void __iomem *__ioremap(phys_addr_t addr, size_t size, pgprot_t prot)
> > +void __iomem *
> > +arch_ioremap(phys_addr_t *paddr, size_t size, unsigned long *prot_val)
> > {
> > - unsigned long offset, vaddr;
> > - struct vm_struct *area;
> > - phys_addr_t last_addr;
> > -
> > - last_addr = addr + size - 1;
> > - if (!size || last_addr < addr)
> > - return NULL;
> > -
> > + /*
> > + * When PCI MIO instructions are unavailable the "physical" address
> > + * encodes a hint for accessing the PCI memory space it represents.
> > + * Just pass it unchanged such that ioread/iowrite can decode it.
> > + */
> > if (!static_branch_unlikely(&have_mio))
> > - return (void __iomem *) addr;
> > -
> > - offset = addr & ~PAGE_MASK;
> > - addr &= PAGE_MASK;
> > - size = PAGE_ALIGN(size + offset);
> > - area = get_vm_area(size, VM_IOREMAP);
> > - if (!area)
> > - return NULL;
> > -
> > - vaddr = (unsigned long) area->addr;
> > - if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) {
> > - free_vm_area(area);
> > - return NULL;
> > - }
> > - return (void __iomem *) ((unsigned long) area->addr + offset);
> > + return (void __iomem *) *paddr;
>
> nit: no space after the cast

Sorry, remember you pointed this out in v2, while I didn't get what
it is. Could you be more specific or give the right line of code?

Are you suggesting below line?

- return (void __iomem *) ((unsigned long) area->addr + offset);
+ return (void __iomem *)*paddr;

>
> > + return NULL;
> > }
> >
> > -void __iomem *ioremap_prot(phys_addr_t addr, size_t size, unsigned long prot)
> > +bool arch_iounmap(void __iomem *addr)
> > {
> > - return __ioremap(addr, size, __pgprot(prot));
> > -}
> > -EXPORT_SYMBOL(ioremap_prot);
> > -
> > -void __iomem *ioremap(phys_addr_t addr, size_t size)
> > -{
> > - return __ioremap(addr, size, PAGE_KERNEL);
> > -}
> > -EXPORT_SYMBOL(ioremap);
> > -
> > -void __iomem *ioremap_wc(phys_addr_t addr, size_t size)
> > -{
> > - return __ioremap(addr, size, pgprot_writecombine(PAGE_KERNEL));
> > -}
> > -EXPORT_SYMBOL(ioremap_wc);
> > -
> > -void __iomem *ioremap_wt(phys_addr_t addr, size_t size)
> > -{
> > - return __ioremap(addr, size, pgprot_writethrough(PAGE_KERNEL));
> > -}
> > -EXPORT_SYMBOL(ioremap_wt);
> > -
> > -void iounmap(volatile void __iomem *addr)
> > -{
> > - if (static_branch_likely(&have_mio))
> > - vunmap((__force void *) ((unsigned long) addr & PAGE_MASK));
> > + if (!static_branch_likely(&have_mio))
> > + return false;
> > + return true;
> > }
> > -EXPORT_SYMBOL(iounmap);
> >
> > /* Create a virtual mapping cookie for a PCI BAR */
> > static void __iomem *pci_iomap_range_fh(struct pci_dev *pdev, int bar,
>
> Gave this a round of testing on s390 with both the MIO and non-MIO
> cases. I also see you addressed my previous comments and it looks good
> to me. As you showed in the other mail the compile error is a pre
> existing problem so shouldn't influence this change. So assuming you
> add the "if PCI" and the nit above you can add my:

Thanks a lot, will add that part to this patch and add your tags.

>
> Tested-by: Niklas
> Schnelle <[email protected]>
> Reviewed-by: Niklas Schnelle
> <[email protected]>
>
>

2022-10-12 08:14:59

by Niklas Schnelle

[permalink] [raw]
Subject: Re: [PATCH v3 09/11] s390: mm: Convert to GENERIC_IOREMAP

On Wed, 2022-10-12 at 13:52 +0800, Baoquan He wrote:
> On 10/11/22 at 05:16pm, Niklas Schnelle wrote:
> > On Sun, 2022-10-09 at 18:31 +0800, Baoquan He wrote:
> > > By taking GENERIC_IOREMAP method, the generic ioremap_prot() and
> > > iounmap() are visible and available to arch. Arch only needs to
> > > provide implementation of arch_ioremap() or arch_iounmap() if there's
> > > arch specific handling needed in its ioremap() or iounmap(). This
> > > change will simplify implementation by removing duplicated codes with
> > > generic ioremap() and iounmap(), and has the equivalent functioality
> > > as before.
> > >
> > > For s390, add hooks arch_ioremap() and arch_iounmap() for s390's special
> > > operation when ioremap() and iounmap(), then ioremap_[wc|wt]() are
> > > converted to use ioremap_prot() from GENERIC_IOREMAP.
> > >
> > > Signed-off-by: Baoquan He <[email protected]>
> > > Cc: Niklas Schnelle <[email protected]>
> > > Cc: Gerald Schaefer <[email protected]>
> > > Cc: Heiko Carstens <[email protected]>
> > > Cc: Vasily Gorbik <[email protected]>
> > > Cc: Alexander Gordeev <[email protected]>
> > > Cc: Christian Borntraeger <[email protected]>
> > > Cc: Sven Schnelle <[email protected]>
> > > Cc: [email protected]
> > > ---
> > > v2->v3:
> > > - Add code comment inside arch_ioremap() to help uderstand the
> > > obsucre code. Christoph suggested this, Niklas provided the
> > > paragraph of text.
> > >
> > > arch/s390/Kconfig | 1 +
> > > arch/s390/include/asm/io.h | 25 +++++++++------
> > > arch/s390/pci/pci.c | 65 ++++++++------------------------------
> > > 3 files changed, 30 insertions(+), 61 deletions(-)
> > >
> > > diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
> > > index 318fce77601d..c59e1b25f59d 100644
> > > --- a/arch/s390/Kconfig
> > > +++ b/arch/s390/Kconfig
> > > @@ -135,6 +135,7 @@ config S390
> > > select GENERIC_SMP_IDLE_THREAD
> > > select GENERIC_TIME_VSYSCALL
> > > select GENERIC_VDSO_TIME_NS
> > > + select GENERIC_IOREMAP
> >
> > I think you should add the "if PCI" from the diff in your last mail to
> > this patch.
>
> That's reasonable, will do.
>
> The code change in driver should be posted separately to get reviewing
> from the relevant drvier maintainers. I may wrap it into this series in
> next post so that people know its background.

I agree about doing the driver change separately. Since the problem
already exists one could send it separately. If you want I can take of
that too.

>
> > > select HAVE_ALIGNED_STRUCT_PAGE if SLUB
> > > select HAVE_ARCH_AUDITSYSCALL
> > > select HAVE_ARCH_JUMP_LABEL
> ......
> > > diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
> > > index 73cdc5539384..3c00dc7d79bc 100644
> > > --- a/arch/s390/pci/pci.c
> > > +++ b/arch/s390/pci/pci.c
> > > @@ -244,64 +244,25 @@ void __iowrite64_copy(void __iomem *to, const void *from, size_t count)
> > > zpci_memcpy_toio(to, from, count);
> > > }
> > >
> > > -static void __iomem *__ioremap(phys_addr_t addr, size_t size, pgprot_t prot)
> > > +void __iomem *
> > > +arch_ioremap(phys_addr_t *paddr, size_t size, unsigned long *prot_val)
> > > {
> > > - unsigned long offset, vaddr;
> > > - struct vm_struct *area;
> > > - phys_addr_t last_addr;
> > > -
> > > - last_addr = addr + size - 1;
> > > - if (!size || last_addr < addr)
> > > - return NULL;
> > > -
> > > + /*
> > > + * When PCI MIO instructions are unavailable the "physical" address
> > > + * encodes a hint for accessing the PCI memory space it represents.
> > > + * Just pass it unchanged such that ioread/iowrite can decode it.
> > > + */
> > > if (!static_branch_unlikely(&have_mio))
> > > - return (void __iomem *) addr;
> > > -
> > > - offset = addr & ~PAGE_MASK;
> > > - addr &= PAGE_MASK;
> > > - size = PAGE_ALIGN(size + offset);
> > > - area = get_vm_area(size, VM_IOREMAP);
> > > - if (!area)
> > > - return NULL;
> > > -
> > > - vaddr = (unsigned long) area->addr;
> > > - if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) {
> > > - free_vm_area(area);
> > > - return NULL;
> > > - }
> > > - return (void __iomem *) ((unsigned long) area->addr + offset);
> > > + return (void __iomem *) *paddr;
> >
> > nit: no space after the cast
>
> Sorry, remember you pointed this out in v2, while I didn't get what
> it is. Could you be more specific or give the right line of code?
>
> Are you suggesting below line?
>
> - return (void __iomem *) ((unsigned long) area->addr + offset);
> + return (void __iomem *)*paddr;

Yes, though I did just check and somehow checkpatch doesn't complain,
maybe because of the dereference. I do think I remember it complaining
but I guess if it doesn't you might as well keep it this way.

>
> > > + return NULL;
> > > }
> > >
---8<---


2022-10-12 10:12:17

by Baoquan He

[permalink] [raw]
Subject: Re: [PATCH v3 09/11] s390: mm: Convert to GENERIC_IOREMAP

On 10/12/22 at 09:37am, Niklas Schnelle wrote:
> On Wed, 2022-10-12 at 13:52 +0800, Baoquan He wrote:
> > On 10/11/22 at 05:16pm, Niklas Schnelle wrote:
> > > On Sun, 2022-10-09 at 18:31 +0800, Baoquan He wrote:
> > > > By taking GENERIC_IOREMAP method, the generic ioremap_prot() and
> > > > iounmap() are visible and available to arch. Arch only needs to
> > > > provide implementation of arch_ioremap() or arch_iounmap() if there's
> > > > arch specific handling needed in its ioremap() or iounmap(). This
> > > > change will simplify implementation by removing duplicated codes with
> > > > generic ioremap() and iounmap(), and has the equivalent functioality
> > > > as before.
> > > >
> > > > For s390, add hooks arch_ioremap() and arch_iounmap() for s390's special
> > > > operation when ioremap() and iounmap(), then ioremap_[wc|wt]() are
> > > > converted to use ioremap_prot() from GENERIC_IOREMAP.
> > > >
> > > > Signed-off-by: Baoquan He <[email protected]>
> > > > Cc: Niklas Schnelle <[email protected]>
> > > > Cc: Gerald Schaefer <[email protected]>
> > > > Cc: Heiko Carstens <[email protected]>
> > > > Cc: Vasily Gorbik <[email protected]>
> > > > Cc: Alexander Gordeev <[email protected]>
> > > > Cc: Christian Borntraeger <[email protected]>
> > > > Cc: Sven Schnelle <[email protected]>
> > > > Cc: [email protected]
> > > > ---
> > > > v2->v3:
> > > > - Add code comment inside arch_ioremap() to help uderstand the
> > > > obsucre code. Christoph suggested this, Niklas provided the
> > > > paragraph of text.
> > > >
> > > > arch/s390/Kconfig | 1 +
> > > > arch/s390/include/asm/io.h | 25 +++++++++------
> > > > arch/s390/pci/pci.c | 65 ++++++++------------------------------
> > > > 3 files changed, 30 insertions(+), 61 deletions(-)
> > > >
> > > > diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
> > > > index 318fce77601d..c59e1b25f59d 100644
> > > > --- a/arch/s390/Kconfig
> > > > +++ b/arch/s390/Kconfig
> > > > @@ -135,6 +135,7 @@ config S390
> > > > select GENERIC_SMP_IDLE_THREAD
> > > > select GENERIC_TIME_VSYSCALL
> > > > select GENERIC_VDSO_TIME_NS
> > > > + select GENERIC_IOREMAP
> > >
> > > I think you should add the "if PCI" from the diff in your last mail to
> > > this patch.
> >
> > That's reasonable, will do.
> >
> > The code change in driver should be posted separately to get reviewing
> > from the relevant drvier maintainers. I may wrap it into this series in
> > next post so that people know its background.
>
> I agree about doing the driver change separately. Since the problem
> already exists one could send it separately. If you want I can take of
> that too.

Both is fine to me, since you suggested the fix.

>
> >
> > > > select HAVE_ALIGNED_STRUCT_PAGE if SLUB
> > > > select HAVE_ARCH_AUDITSYSCALL
> > > > select HAVE_ARCH_JUMP_LABEL
> > ......
> > > > diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
> > > > index 73cdc5539384..3c00dc7d79bc 100644
> > > > --- a/arch/s390/pci/pci.c
> > > > +++ b/arch/s390/pci/pci.c
> > > > @@ -244,64 +244,25 @@ void __iowrite64_copy(void __iomem *to, const void *from, size_t count)
> > > > zpci_memcpy_toio(to, from, count);
> > > > }
> > > >
> > > > -static void __iomem *__ioremap(phys_addr_t addr, size_t size, pgprot_t prot)
> > > > +void __iomem *
> > > > +arch_ioremap(phys_addr_t *paddr, size_t size, unsigned long *prot_val)
> > > > {
> > > > - unsigned long offset, vaddr;
> > > > - struct vm_struct *area;
> > > > - phys_addr_t last_addr;
> > > > -
> > > > - last_addr = addr + size - 1;
> > > > - if (!size || last_addr < addr)
> > > > - return NULL;
> > > > -
> > > > + /*
> > > > + * When PCI MIO instructions are unavailable the "physical" address
> > > > + * encodes a hint for accessing the PCI memory space it represents.
> > > > + * Just pass it unchanged such that ioread/iowrite can decode it.
> > > > + */
> > > > if (!static_branch_unlikely(&have_mio))
> > > > - return (void __iomem *) addr;
> > > > -
> > > > - offset = addr & ~PAGE_MASK;
> > > > - addr &= PAGE_MASK;
> > > > - size = PAGE_ALIGN(size + offset);
> > > > - area = get_vm_area(size, VM_IOREMAP);
> > > > - if (!area)
> > > > - return NULL;
> > > > -
> > > > - vaddr = (unsigned long) area->addr;
> > > > - if (ioremap_page_range(vaddr, vaddr + size, addr, prot)) {
> > > > - free_vm_area(area);
> > > > - return NULL;
> > > > - }
> > > > - return (void __iomem *) ((unsigned long) area->addr + offset);
> > > > + return (void __iomem *) *paddr;
> > >
> > > nit: no space after the cast
> >
> > Sorry, remember you pointed this out in v2, while I didn't get what
> > it is. Could you be more specific or give the right line of code?
> >
> > Are you suggesting below line?
> >
> > - return (void __iomem *) ((unsigned long) area->addr + offset);
> > + return (void __iomem *)*paddr;
>
> Yes, though I did just check and somehow checkpatch doesn't complain,
> maybe because of the dereference. I do think I remember it complaining
> but I guess if it doesn't you might as well keep it this way.

OK, I will keep it unless checkpatch complaim about it. Thanks.

2022-10-12 10:45:56

by Christophe Leroy

[permalink] [raw]
Subject: Re: [PATCH v3 00/11] mm: ioremap: Convert architectures to take GENERIC_IOREMAP way

Hi,

Le 09/10/2022 à 12:31, Baoquan He a écrit :
> Currently, many architecutres have't taken the standard GENERIC_IOREMAP
> way to implement ioremap_prot(), iounmap(), and ioremap_xx(), but make
> these functions specifically under each arch's folder. Those cause many
> duplicated codes of ioremap() and iounmap().
>
> In this patchset, firstly adapt the hooks io[re|un]map_allowed, then
> make use of them to convert those ARCH-es to take GENERIC_IOREMAP method.
> With these change, duplicated ioremap/iounmap() code uder ARCH-es are
> removed.
>
> This is suggested by Christoph in below discussion:
> https://lore.kernel.org/all/[email protected]/T/#u
>
> And it's basically further action after arm64 has converted to
> GENERIC_IOREMAP way in below patchset.
> [PATCH v5 0/6] arm64: Cleanup ioremap() and support ioremap_prot()
> https://lore.kernel.org/all/[email protected]/T/#u
>

I'm still puzzled with your series, it seems more churn than needed, and
I still deeply dislike the approach where a function called
arch_ioremap() says "Today I don't feel like doing the job so I return
NULL and you'll do it for me"

In order to better illustrate what I have in mind as discussed
previously, I have prepared a short RFC series based on your v3, taking
into account the first two architectures (ARC and IA64) of your series,
and also adding POWERPC architecture. I will send it out shortly.

Christophe

> v2->v3:
> - Rewrite log of all patches to add more details as Christoph suggested.
>
> - Merge the old patch 1 and 2 which adjusts return values and
> parameters of arch_ioremap() into one patch, namely the current
> patch 3. Christoph suggested this.
>
> - Change the return value of arch_iounmap() to bool type since we only
> do arch specific address filtering or address checking, bool value
> can reflect the checking better. This is pointed out by Niklas when
> he reviewed the s390 patch.
>
> - Put hexagon patch at the beginning of patchset since hexagon has the
> same ioremap() and iounmap() as standard ones, no arch_ioremap() and
> arch_iounmap() hooks need be introduced. So the later arch_ioremap
> and arch_iounmap() adjustment are not related in hexagon. Christophe
> suggested this.
>
> - Remove the early ioremap code from openrisc ioremap() firstly since
> openrisc doesn't have early ioremap handling in openrisc arch code.
> This simplifies the later converting to GENERIC_IOREMAP method.
> Christoph and Stafford suggersted this.
>
> - Fix compiling erorrs reported by lkp in parisc and sh patches.
> Adding macro defintions for those port|mem io functions in
> <asm/io.h> to avoid repeated definition in <asm-generic/io.h>.
>
> v1->v2:
> - Rename io[re|un]map_allowed() to arch_io[re|un]map() and made
> some minor changes in patch 1~2 as per Alexander and Kefeng's
> suggestions. Accordingly, adjust patches~4~11 because of the renaming
> arch_io[re|un]map().
>
> Testing:
> - It's running well on arm64 system with the latest upstream kernel
> and this patchset applied.
> - Cross compiling passed on arc, ia64, parisc, s390, sh, xtensa.
> - cross compiling is not tried on hexagon and openrisc because
> - Didn't find cross compiling tools for hexagon;
> - there's error with openrisc compiling, while I have no idea how to
> fix it. Please see below pasted log:
> ---------------------------------------------------------------------
> [root@intel-knightslanding-lb-02 linux]# make ARCH=openrisc defconfig
> *** Default configuration is based on 'or1ksim_defconfig'
> #
> # configuration written to .config
> #
> [root@intel-knightslanding-lb-02 linux]# make ARCH=openrisc -j320 CROSS_COMPILE=/usr/bin/openrisc-linux-gnu-
> SYNC include/config/auto.conf.cmd
> CC scripts/mod/empty.o
> ./scripts/check-local-export: /usr/bin/openrisc-linux-gnu-nm failed
> make[1]: *** [scripts/Makefile.build:250: scripts/mod/empty.o] Error 1
> make[1]: *** Deleting file 'scripts/mod/empty.o'
> make: *** [Makefile:1275: prepare0] Error 2
> ----------------------------------------------------------------------
>
> Baoquan He (11):
> hexagon: mm: Convert to GENERIC_IOREMAP
> openrisc: mm: remove unneeded early ioremap code
> mm/ioremap: change the return value of io[re|un]map_allowed and rename
> mm: ioremap: allow ARCH to have its own ioremap definition
> arc: mm: Convert to GENERIC_IOREMAP
> ia64: mm: Convert to GENERIC_IOREMAP
> openrisc: mm: Convert to GENERIC_IOREMAP
> parisc: mm: Convert to GENERIC_IOREMAP
> s390: mm: Convert to GENERIC_IOREMAP
> sh: mm: Convert to GENERIC_IOREMAP
> xtensa: mm: Convert to GENERIC_IOREMAP
>
> arch/arc/Kconfig | 1 +
> arch/arc/include/asm/io.h | 19 ++++++---
> arch/arc/mm/ioremap.c | 60 ++++-----------------------
> arch/arm64/include/asm/io.h | 5 ++-
> arch/arm64/mm/ioremap.c | 16 +++++---
> arch/hexagon/Kconfig | 1 +
> arch/hexagon/include/asm/io.h | 9 ++++-
> arch/hexagon/mm/ioremap.c | 44 --------------------
> arch/ia64/Kconfig | 1 +
> arch/ia64/include/asm/io.h | 26 +++++++-----
> arch/ia64/mm/ioremap.c | 50 +++++------------------
> arch/openrisc/Kconfig | 1 +
> arch/openrisc/include/asm/io.h | 12 ++++--
> arch/openrisc/mm/ioremap.c | 62 ++--------------------------
> arch/parisc/Kconfig | 1 +
> arch/parisc/include/asm/io.h | 19 ++++++---
> arch/parisc/mm/ioremap.c | 65 +++---------------------------
> arch/s390/Kconfig | 1 +
> arch/s390/include/asm/io.h | 25 +++++++-----
> arch/s390/pci/pci.c | 65 ++++++------------------------
> arch/sh/Kconfig | 1 +
> arch/sh/include/asm/io.h | 67 +++++++++++++++++--------------
> arch/sh/include/asm/io_noioport.h | 7 ++++
> arch/sh/mm/ioremap.c | 63 ++++++-----------------------
> arch/xtensa/Kconfig | 1 +
> arch/xtensa/include/asm/io.h | 39 ++++++++----------
> arch/xtensa/mm/ioremap.c | 56 ++++++--------------------
> include/asm-generic/io.h | 30 ++++++++------
> mm/ioremap.c | 13 ++++--
> 29 files changed, 248 insertions(+), 512 deletions(-)
> delete mode 100644 arch/hexagon/mm/ioremap.c
>