linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/10] unify ioremap definitions and introduce memremap
@ 2015-07-20  0:17 Dan Williams
  2015-07-20  0:17 ` [PATCH 01/10] mm, x86: Fix warning in ioremap RAM check Dan Williams
                   ` (9 more replies)
  0 siblings, 10 replies; 24+ messages in thread
From: Dan Williams @ 2015-07-20  0:17 UTC (permalink / raw)
  To: tglx, mingo, hpa
  Cc: linux-arch, tony.luck, toshi.kani, arnd, benh, mcgrof, x86,
	linux-kernel, geert, Mike Travis, Roland Dreier, Andy Shevchenko,
	Ingo Molnar, Borislav Petkov, ralf, linux, Andrew Morton,
	kbuild test robot, hch, ross.zwisler, linux-arm-kernel

While developing the pmem driver it became clear that not all
architectures implement all the various ioremap types, and when they do
implement an ioremap instance the declaration is inconsistent.

In addition to ioremap prototype confusion, it was also noticed that
several usages of ioremap_cache() were ignoring the __iomem annotation
on returned pointers.  The common theme of these call sites is treating
the return value from ioremap() as an unannotated pointer to normal
memory.  Introduce memremap() as a method to treat a given resource as
memory (safe to speculatively read, pre-fetch, write-combine, etc).

Note that Christoph proposed, in the longer term, changing the calling
convention of ioremap() to take a mapping and prot flags.  It seems that
outside of the _nocache usages of ioremap_*() most instances should be
converted to some form of memremap().  For this reason memremap() takes
a mapping type 'flags' argument and breaks from the pattern of
"ioremap_<type>()".

This series also folds in, with a few fixups, Toshi's fixes for
region_is_ram().  The memremap() implementation needs a functional
region_is_ram() to block attempts to remap system memory.

The series applies against latest 4.2-rc and is targeted for -tip, but
I'm open to carrying a branch, or, if proposed, a better alternative to
handle this cross-tree thrash.  This content has passed a cycle through
the 0day-kbuild infrastructure.

---

Dan Williams (7):
      arch, drivers: don't include <asm/io.h> directly, use <linux/io.h> instead
      arch: unify ioremap prototypes and macro aliases
      cleanup IORESOURCE_CACHEABLE vs ioremap()
      devm: fix ioremap_cache() usage
      arch: introduce strict_ioremap
      arch: introduce memremap()
      pmem: convert to generic memremap

Toshi Kani (3):
      mm, x86: Fix warning in ioremap RAM check
      mm, x86: Remove region_is_ram() call from ioremap
      mm: Fix bugs in region_is_ram()


 arch/alpha/include/asm/io.h                 |    7 ++
 arch/arc/include/asm/io.h                   |    6 --
 arch/arm/Kconfig                            |    1 
 arch/arm/include/asm/io.h                   |    8 +--
 arch/arm/mach-clps711x/board-cdb89712.c     |    2 -
 arch/arm/mach-shmobile/pm-rcar.c            |    2 -
 arch/arm/mm/ioremap.c                       |    6 +-
 arch/arm/mm/nommu.c                         |    6 +-
 arch/arm64/Kconfig                          |    1 
 arch/arm64/include/asm/io.h                 |   23 ++++++--
 arch/arm64/kernel/efi.c                     |    7 +-
 arch/arm64/kernel/smp_spin_table.c          |   17 +++---
 arch/avr32/include/asm/io.h                 |   22 ++++---
 arch/avr32/mm/ioremap.c                     |    2 -
 arch/cris/include/asm/io.h                  |    8 +--
 arch/cris/mm/ioremap.c                      |    2 -
 arch/frv/Kconfig                            |    1 
 arch/frv/include/asm/io.h                   |   23 +++-----
 arch/hexagon/include/asm/io.h               |    5 +-
 arch/ia64/include/asm/io.h                  |   10 +--
 arch/ia64/kernel/cyclone.c                  |    2 -
 arch/ia64/mm/ioremap.c                      |    4 +
 arch/m32r/include/asm/io.h                  |    9 +--
 arch/m68k/Kconfig                           |    1 
 arch/m68k/include/asm/io_mm.h               |   21 ++++---
 arch/m68k/include/asm/io_no.h               |   34 +++++++----
 arch/m68k/include/asm/raw_io.h              |    3 +
 arch/m68k/mm/kmap.c                         |    2 -
 arch/metag/Kconfig                          |    1 
 arch/metag/include/asm/io.h                 |   35 +++++++-----
 arch/microblaze/include/asm/io.h            |    6 --
 arch/microblaze/mm/pgtable.c                |    2 -
 arch/mips/Kconfig                           |    1 
 arch/mips/include/asm/io.h                  |   42 +++++---------
 arch/mn10300/include/asm/io.h               |   10 ++-
 arch/nios2/include/asm/io.h                 |   15 +----
 arch/openrisc/include/asm/io.h              |    3 +
 arch/openrisc/mm/ioremap.c                  |    2 -
 arch/parisc/include/asm/io.h                |    6 +-
 arch/parisc/mm/ioremap.c                    |    2 -
 arch/powerpc/Kconfig                        |    1 
 arch/powerpc/include/asm/io.h               |    7 +-
 arch/powerpc/kernel/pci_of_scan.c           |    2 -
 arch/s390/include/asm/io.h                  |    8 +--
 arch/sh/include/asm/io.h                    |    9 ++-
 arch/sparc/include/asm/io_32.h              |    7 +-
 arch/sparc/include/asm/io_64.h              |    8 +--
 arch/sparc/kernel/ioport.c                  |    2 -
 arch/sparc/kernel/pci.c                     |    3 -
 arch/tile/include/asm/io.h                  |   17 ++++--
 arch/unicore32/include/asm/io.h             |   25 +++++++-
 arch/x86/Kconfig                            |    1 
 arch/x86/include/asm/io.h                   |   17 +++---
 arch/x86/kernel/crash_dump_64.c             |    6 +-
 arch/x86/kernel/kdebugfs.c                  |    8 +--
 arch/x86/kernel/ksysfs.c                    |   28 +++++----
 arch/x86/mm/ioremap.c                       |   53 ++++++++---------
 arch/xtensa/Kconfig                         |    1 
 arch/xtensa/include/asm/io.h                |   13 ++--
 drivers/acpi/apei/einj.c                    |    9 ++-
 drivers/acpi/apei/erst.c                    |    6 +-
 drivers/firmware/google/memconsole.c        |    5 +-
 drivers/isdn/icn/icn.h                      |    2 -
 drivers/mtd/devices/slram.c                 |    2 -
 drivers/mtd/nand/diskonchip.c               |    2 -
 drivers/mtd/onenand/generic.c               |    2 -
 drivers/net/ethernet/sfc/io.h               |    2 -
 drivers/nvdimm/pmem.c                       |    2 -
 drivers/pci/probe.c                         |    3 -
 drivers/pnp/manager.c                       |    2 -
 drivers/scsi/aic94xx/aic94xx_init.c         |    7 --
 drivers/scsi/arcmsr/arcmsr_hba.c            |    5 --
 drivers/scsi/mvsas/mv_init.c                |   15 +----
 drivers/scsi/sun3x_esp.c                    |    2 -
 drivers/staging/comedi/drivers/ii_pci20kc.c |    1 
 drivers/tty/serial/8250/8250_core.c         |    2 -
 drivers/video/fbdev/ocfb.c                  |    1 
 drivers/video/fbdev/s1d13xxxfb.c            |    3 -
 drivers/video/fbdev/stifb.c                 |    1 
 include/asm-generic/io.h                    |   15 +++--
 include/asm-generic/iomap.h                 |    8 ---
 include/linux/device.h                      |    5 ++
 include/linux/io-mapping.h                  |    2 -
 include/linux/io.h                          |   82 +++++++++++++++++++++++++++
 include/linux/mtd/map.h                     |    2 -
 include/linux/pmem.h                        |   29 +++++-----
 include/video/vga.h                         |    2 -
 kernel/resource.c                           |   57 +++++++++++++++++--
 lib/Kconfig                                 |    5 +-
 lib/devres.c                                |   68 ++++++++++++++--------
 lib/pci_iomap.c                             |    7 +-
 tools/testing/nvdimm/Kbuild                 |    4 +
 tools/testing/nvdimm/test/iomap.c           |   34 ++++++++---
 93 files changed, 565 insertions(+), 405 deletions(-)

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 01/10] mm, x86: Fix warning in ioremap RAM check
  2015-07-20  0:17 [PATCH 00/10] unify ioremap definitions and introduce memremap Dan Williams
@ 2015-07-20  0:17 ` Dan Williams
  2015-07-20  0:17 ` [PATCH 02/10] mm, x86: Remove region_is_ram() call from ioremap Dan Williams
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Dan Williams @ 2015-07-20  0:17 UTC (permalink / raw)
  To: tglx, mingo, hpa
  Cc: linux-arch, tony.luck, toshi.kani, arnd, benh, mcgrof, x86,
	linux-kernel, ralf, geert, Roland Dreier, Ingo Molnar,
	Borislav Petkov, linux, ross.zwisler, kbuild test robot, hch,
	linux-arm-kernel

From: Toshi Kani <toshi.kani@hp.com>

__ioremap_caller() calls __ioremap_check_ram() through
walk_system_ram_range() to check if a target range is in RAM.
__ioremap_check_ram() has WARN_ONCE() in a wrong place where it warns
when the given range is not RAM.  This misplaced warning is not exposed
since walk_system_ram_range() only calls __ioremap_check_ram() for RAM
ranges.

Move the WARN_ONCE() to __ioremap_caller(), fix up __ioremap_caller to
use the %pa format specifier, and update the message to include the
address range.

Signed-off-by: Toshi Kani <toshi.kani@hp.com>
Cc: Roland Dreier <roland@purestorage.com>
Cc: Luis R. Rodriguez <mcgrof@suse.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
[djbw: fix format specifier warnings]
Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/x86/mm/ioremap.c |   17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index cc5ccc415cc0..63da79114fe9 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -63,8 +63,6 @@ static int __ioremap_check_ram(unsigned long start_pfn, unsigned long nr_pages,
 		    !PageReserved(pfn_to_page(start_pfn + i)))
 			return 1;
 
-	WARN_ONCE(1, "ioremap on RAM pfn 0x%lx\n", start_pfn);
-
 	return 0;
 }
 
@@ -102,8 +100,8 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
 		return NULL;
 
 	if (!phys_addr_valid(phys_addr)) {
-		printk(KERN_WARNING "ioremap: invalid physical address %llx\n",
-		       (unsigned long long)phys_addr);
+		printk(KERN_WARNING "ioremap: invalid physical address %pa\n",
+				&phys_addr);
 		WARN_ON_ONCE(1);
 		return NULL;
 	}
@@ -131,8 +129,11 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
 		pfn      = phys_addr >> PAGE_SHIFT;
 		last_pfn = last_addr >> PAGE_SHIFT;
 		if (walk_system_ram_range(pfn, last_pfn - pfn + 1, NULL,
-					  __ioremap_check_ram) == 1)
+					  __ioremap_check_ram) == 1) {
+			WARN_ONCE(1, "ioremap on RAM at %pa - %pa\n",
+					&phys_addr, &last_addr);
 			return NULL;
+		}
 	}
 	/*
 	 * Mappings have to be page-aligned
@@ -151,10 +152,8 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
 	if (pcm != new_pcm) {
 		if (!is_new_memtype_allowed(phys_addr, size, pcm, new_pcm)) {
 			printk(KERN_ERR
-		"ioremap error for 0x%llx-0x%llx, requested 0x%x, got 0x%x\n",
-				(unsigned long long)phys_addr,
-				(unsigned long long)(phys_addr + size),
-				pcm, new_pcm);
+		"ioremap error for %pa - %pa, requested 0x%x, got 0x%x\n",
+				&phys_addr, &last_addr, pcm, new_pcm);
 			goto err_free_memtype;
 		}
 		pcm = new_pcm;


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 02/10] mm, x86: Remove region_is_ram() call from ioremap
  2015-07-20  0:17 [PATCH 00/10] unify ioremap definitions and introduce memremap Dan Williams
  2015-07-20  0:17 ` [PATCH 01/10] mm, x86: Fix warning in ioremap RAM check Dan Williams
@ 2015-07-20  0:17 ` Dan Williams
  2015-07-20  0:17 ` [PATCH 03/10] mm: Fix bugs in region_is_ram() Dan Williams
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Dan Williams @ 2015-07-20  0:17 UTC (permalink / raw)
  To: tglx, mingo, hpa
  Cc: linux-arch, tony.luck, toshi.kani, arnd, benh, mcgrof, x86,
	linux-kernel, geert, Mike Travis, Roland Dreier, Ingo Molnar,
	Borislav Petkov, ralf, linux, ross.zwisler, hch,
	linux-arm-kernel

From: Toshi Kani <toshi.kani@hp.com>

__ioremap_caller() calls region_is_ram() to walk through the
iomem_resource table to check if a target range is in RAM, which
was added to improve the lookup performance over page_is_ram()
(commit 906e36c5c717 "x86: use optimized ioresource lookup in
ioremap function").  page_is_ram() was no longer used when this
change was added, though.

__ioremap_caller() then calls walk_system_ram_range(), which had
replaced page_is_ram() to improve the lookup performance (commit
c81c8a1eeede "x86, ioremap: Speed up check for RAM pages").

Since both checks walk through the same iomem_resource table for
the same purpose, there is no need to call the two functions.
Furthermore, region_is_ram() always returns with -1, which makes
walk_system_ram_range() as the only check being used at this point.

Therefore, this patch changes __ioremap_caller() to call
walk_system_ram_range() only.

Note, removing the call to region_is_ram() is also necessary to
fix bugs in region_is_ram().  walk_system_ram_range() requires
RAM ranges be page-aligned in the iomem_resource table to work
properly.  This restriction has allowed multiple ioremaps to RAM
(setup_data) which are page-unaligned.  Using fixed region_is_ram()
will cause these callers to start failing.  After all ioremap
callers to setup_data are converted, __ioremap_caller() may call
region_is_ram() instead to remove this restriction.

Signed-off-by: Toshi Kani <toshi.kani@hp.com>
Cc: Roland Dreier <roland@purestorage.com>
Cc: Mike Travis <travis@sgi.com>
Cc: Luis R. Rodriguez <mcgrof@suse.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/x86/mm/ioremap.c |   24 ++++++------------------
 1 file changed, 6 insertions(+), 18 deletions(-)

diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 63da79114fe9..ccf5c867b2eb 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -92,7 +92,6 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
 	pgprot_t prot;
 	int retval;
 	void __iomem *ret_addr;
-	int ram_region;
 
 	/* Don't allow wraparound or zero size */
 	last_addr = phys_addr + size - 1;
@@ -115,26 +114,15 @@ static void __iomem *__ioremap_caller(resource_size_t phys_addr,
 	/*
 	 * Don't allow anybody to remap normal RAM that we're using..
 	 */
-	/* First check if whole region can be identified as RAM or not */
-	ram_region = region_is_ram(phys_addr, size);
-	if (ram_region > 0) {
-		WARN_ONCE(1, "ioremap on RAM at 0x%lx - 0x%lx\n",
-				(unsigned long int)phys_addr,
-				(unsigned long int)last_addr);
-		return NULL;
-	}
-
-	/* If could not be identified(-1), check page by page */
-	if (ram_region < 0) {
-		pfn      = phys_addr >> PAGE_SHIFT;
-		last_pfn = last_addr >> PAGE_SHIFT;
-		if (walk_system_ram_range(pfn, last_pfn - pfn + 1, NULL,
+	pfn      = phys_addr >> PAGE_SHIFT;
+	last_pfn = last_addr >> PAGE_SHIFT;
+	if (walk_system_ram_range(pfn, last_pfn - pfn + 1, NULL,
 					  __ioremap_check_ram) == 1) {
-			WARN_ONCE(1, "ioremap on RAM at %pa - %pa\n",
+		WARN_ONCE(1, "ioremap on RAM at %pa - %pa\n",
 					&phys_addr, &last_addr);
-			return NULL;
-		}
+		return NULL;
 	}
+
 	/*
 	 * Mappings have to be page-aligned
 	 */


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 03/10] mm: Fix bugs in region_is_ram()
  2015-07-20  0:17 [PATCH 00/10] unify ioremap definitions and introduce memremap Dan Williams
  2015-07-20  0:17 ` [PATCH 01/10] mm, x86: Fix warning in ioremap RAM check Dan Williams
  2015-07-20  0:17 ` [PATCH 02/10] mm, x86: Remove region_is_ram() call from ioremap Dan Williams
@ 2015-07-20  0:17 ` Dan Williams
  2015-07-20  0:17 ` [PATCH 04/10] arch, drivers: don't include <asm/io.h> directly, use <linux/io.h> instead Dan Williams
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Dan Williams @ 2015-07-20  0:17 UTC (permalink / raw)
  To: tglx, mingo, hpa
  Cc: linux-arch, tony.luck, linux, arnd, benh, mcgrof, x86,
	linux-kernel, ralf, Mike Travis, geert, ross.zwisler, toshi.kani,
	Andrew Morton, hch, linux-arm-kernel

From: Toshi Kani <toshi.kani@hp.com>

region_is_ram() looks up the iomem_resource table to check if
a target range is in RAM.  However, it always returns with -1
due to invalid range checks.  It always breaks the loop at the
first entry of the table.

Another issue is that it compares p->flags and flags, but it
always fails.  The flags is declared as int, which makes it as
a negative value with IORESOURCE_BUSY (0x80000000) set while
p->flags is unsigned long.

Fix the range check and flags so that region_is_ram() works as
advertised.

Signed-off-by: Toshi Kani <toshi.kani@hp.com>
Cc: Mike Travis <travis@sgi.com>
Cc: Luis R. Rodriguez <mcgrof@suse.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 kernel/resource.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/kernel/resource.c b/kernel/resource.c
index 90552aab5f2d..fed052a1bc9f 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -504,13 +504,13 @@ int region_is_ram(resource_size_t start, unsigned long size)
 {
 	struct resource *p;
 	resource_size_t end = start + size - 1;
-	int flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+	unsigned long flags = IORESOURCE_MEM | IORESOURCE_BUSY;
 	const char *name = "System RAM";
 	int ret = -1;
 
 	read_lock(&resource_lock);
 	for (p = iomem_resource.child; p ; p = p->sibling) {
-		if (end < p->start)
+		if (p->end < start)
 			continue;
 
 		if (p->start <= start && end <= p->end) {
@@ -521,7 +521,7 @@ int region_is_ram(resource_size_t start, unsigned long size)
 				ret = 1;
 			break;
 		}
-		if (p->end < start)
+		if (end < p->start)
 			break;	/* not found */
 	}
 	read_unlock(&resource_lock);


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 04/10] arch, drivers: don't include <asm/io.h> directly, use <linux/io.h> instead
  2015-07-20  0:17 [PATCH 00/10] unify ioremap definitions and introduce memremap Dan Williams
                   ` (2 preceding siblings ...)
  2015-07-20  0:17 ` [PATCH 03/10] mm: Fix bugs in region_is_ram() Dan Williams
@ 2015-07-20  0:17 ` Dan Williams
  2015-07-20  0:18 ` [PATCH 05/10] arch: unify ioremap prototypes and macro aliases Dan Williams
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Dan Williams @ 2015-07-20  0:17 UTC (permalink / raw)
  To: tglx, mingo, hpa
  Cc: linux-arch, tony.luck, linux, arnd, benh, mcgrof, x86,
	linux-kernel, ralf, geert, toshi.kani, ross.zwisler, hch,
	linux-arm-kernel

Preparation for uniform definition of ioremap, ioremap_wc, ioremap_wt,
and ioremap_cache, tree-wide.

Acked-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/arm/mach-shmobile/pm-rcar.c            |    2 +-
 arch/ia64/kernel/cyclone.c                  |    2 +-
 drivers/isdn/icn/icn.h                      |    2 +-
 drivers/mtd/devices/slram.c                 |    2 +-
 drivers/mtd/nand/diskonchip.c               |    2 +-
 drivers/mtd/onenand/generic.c               |    2 +-
 drivers/scsi/sun3x_esp.c                    |    2 +-
 drivers/staging/comedi/drivers/ii_pci20kc.c |    1 +
 drivers/tty/serial/8250/8250_core.c         |    2 +-
 drivers/video/fbdev/s1d13xxxfb.c            |    3 +--
 drivers/video/fbdev/stifb.c                 |    1 +
 include/linux/io-mapping.h                  |    2 +-
 include/linux/mtd/map.h                     |    2 +-
 include/video/vga.h                         |    2 +-
 14 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/arch/arm/mach-shmobile/pm-rcar.c b/arch/arm/mach-shmobile/pm-rcar.c
index 00022ee56f80..9d3dde00c2fe 100644
--- a/arch/arm/mach-shmobile/pm-rcar.c
+++ b/arch/arm/mach-shmobile/pm-rcar.c
@@ -12,7 +12,7 @@
 #include <linux/err.h>
 #include <linux/mm.h>
 #include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include "pm-rcar.h"
 
 /* SYSC */
diff --git a/arch/ia64/kernel/cyclone.c b/arch/ia64/kernel/cyclone.c
index 4826ff957a3d..5fa3848ba224 100644
--- a/arch/ia64/kernel/cyclone.c
+++ b/arch/ia64/kernel/cyclone.c
@@ -4,7 +4,7 @@
 #include <linux/errno.h>
 #include <linux/timex.h>
 #include <linux/clocksource.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* IBM Summit (EXA) Cyclone counter code*/
 #define CYCLONE_CBAR_ADDR 0xFEB00CD0
diff --git a/drivers/isdn/icn/icn.h b/drivers/isdn/icn/icn.h
index b713466997a0..f8f2e76d34bf 100644
--- a/drivers/isdn/icn/icn.h
+++ b/drivers/isdn/icn/icn.h
@@ -38,7 +38,7 @@ typedef struct icn_cdef {
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/major.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/slab.h>
diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c
index 2fc4957cbe7f..a70eb83e68f1 100644
--- a/drivers/mtd/devices/slram.c
+++ b/drivers/mtd/devices/slram.c
@@ -41,7 +41,7 @@
 #include <linux/fs.h>
 #include <linux/ioctl.h>
 #include <linux/init.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <linux/mtd/mtd.h>
 
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index 7da266a53979..0802158a3f75 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -24,7 +24,7 @@
 #include <linux/rslib.h>
 #include <linux/moduleparam.h>
 #include <linux/slab.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/nand.h>
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c
index 32a216d31141..ab7bda0bb245 100644
--- a/drivers/mtd/onenand/generic.c
+++ b/drivers/mtd/onenand/generic.c
@@ -18,7 +18,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/onenand.h>
 #include <linux/mtd/partitions.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /*
  * Note: Driver name and platform data format have been updated!
diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c
index e26e81de7c45..d50c5ed8f428 100644
--- a/drivers/scsi/sun3x_esp.c
+++ b/drivers/scsi/sun3x_esp.c
@@ -12,9 +12,9 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 
 #include <asm/sun3x.h>
-#include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/dvma.h>
 
diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c
index 0768bc42a5db..14ef1f67dd42 100644
--- a/drivers/staging/comedi/drivers/ii_pci20kc.c
+++ b/drivers/staging/comedi/drivers/ii_pci20kc.c
@@ -28,6 +28,7 @@
  */
 
 #include <linux/module.h>
+#include <linux/io.h>
 #include "../comedidev.h"
 
 /*
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 37fff12dd4d0..fe902ff52e58 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -38,11 +38,11 @@
 #include <linux/slab.h>
 #include <linux/uaccess.h>
 #include <linux/pm_runtime.h>
+#include <linux/io.h>
 #ifdef CONFIG_SPARC
 #include <linux/sunserialcore.h>
 #endif
 
-#include <asm/io.h>
 #include <asm/irq.h>
 
 #include "8250.h"
diff --git a/drivers/video/fbdev/s1d13xxxfb.c b/drivers/video/fbdev/s1d13xxxfb.c
index 83433cb0dfba..96aa46dc696c 100644
--- a/drivers/video/fbdev/s1d13xxxfb.c
+++ b/drivers/video/fbdev/s1d13xxxfb.c
@@ -32,8 +32,7 @@
 #include <linux/spinlock_types.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include <video/s1d13xxxfb.h>
 
diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c
index 735355b0e023..7df4228e25f0 100644
--- a/drivers/video/fbdev/stifb.c
+++ b/drivers/video/fbdev/stifb.c
@@ -64,6 +64,7 @@
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/io.h>
 
 #include <asm/grfioctl.h>	/* for HP-UX compatibility */
 #include <asm/uaccess.h>
diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h
index c27dde7215b5..e399029b68c5 100644
--- a/include/linux/io-mapping.h
+++ b/include/linux/io-mapping.h
@@ -21,7 +21,7 @@
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/bug.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/page.h>
 
 /*
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index 29975c73a953..366cf77953b5 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -27,9 +27,9 @@
 #include <linux/string.h>
 #include <linux/bug.h>
 #include <linux/kernel.h>
+#include <linux/io.h>
 
 #include <asm/unaligned.h>
-#include <asm/io.h>
 #include <asm/barrier.h>
 
 #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
diff --git a/include/video/vga.h b/include/video/vga.h
index cac567f22e62..d334e64c1c19 100644
--- a/include/video/vga.h
+++ b/include/video/vga.h
@@ -18,7 +18,7 @@
 #define __linux_video_vga_h__
 
 #include <linux/types.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <asm/vga.h>
 #include <asm/byteorder.h>
 


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 05/10] arch: unify ioremap prototypes and macro aliases
  2015-07-20  0:17 [PATCH 00/10] unify ioremap definitions and introduce memremap Dan Williams
                   ` (3 preceding siblings ...)
  2015-07-20  0:17 ` [PATCH 04/10] arch, drivers: don't include <asm/io.h> directly, use <linux/io.h> instead Dan Williams
@ 2015-07-20  0:18 ` Dan Williams
  2015-07-21 13:34   ` Christoph Hellwig
  2015-07-20  0:18 ` [PATCH 06/10] cleanup IORESOURCE_CACHEABLE vs ioremap() Dan Williams
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 24+ messages in thread
From: Dan Williams @ 2015-07-20  0:18 UTC (permalink / raw)
  To: tglx, mingo, hpa
  Cc: linux-arch, tony.luck, linux, arnd, benh, mcgrof, x86,
	linux-kernel, ralf, geert, toshi.kani, ross.zwisler,
	kbuild test robot, hch, linux-arm-kernel

Some archs define the first parameter to ioremap() as unsigned long,
while the balance define it as resource_size_t, similar confusion exists
for the type of the 'size' parameter.  Unify on (resource_size_t,
unsigned long) to enable passing ioremap function pointers.  Also, some
archs use function-like macros for defining ioremap aliases, but
asm-generic/io.h expects object-like macros, unify on the latter.

Move all handling of ioremap aliasing (i.e. ioremap_wt => ioremap) to
include/linux/io.h.  Add a check to lib/devres.c to warn at compile time
if an arch violates type expectations.

Kill ARCH_HAS_IOREMAP_WC and ARCH_HAS_IOREMAP_WT in favor of just
testing for ioremap_wc, and ioremap_wt being defined.  This arrangement
allows drivers to know when ioremap_<foo> are being re-directed to plain
ioremap.  A later patch uses this arrangement to implement support for
strict mappings.

Acked-by: Christoph Hellwig <hch@lst.de>
Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/alpha/include/asm/io.h      |    7 ++++--
 arch/arc/include/asm/io.h        |    6 -----
 arch/arm/include/asm/io.h        |    8 ++----
 arch/arm/mm/ioremap.c            |    6 ++---
 arch/arm/mm/nommu.c              |    6 ++---
 arch/arm64/include/asm/io.h      |   23 ++++++++++++++----
 arch/avr32/include/asm/io.h      |   22 +++++++++--------
 arch/avr32/mm/ioremap.c          |    2 +-
 arch/cris/include/asm/io.h       |    8 +++---
 arch/cris/mm/ioremap.c           |    2 +-
 arch/frv/include/asm/io.h        |   23 ++++++++----------
 arch/hexagon/include/asm/io.h    |    5 +++-
 arch/ia64/include/asm/io.h       |   10 ++------
 arch/ia64/mm/ioremap.c           |    4 ++-
 arch/m32r/include/asm/io.h       |    9 +++----
 arch/m68k/include/asm/io_mm.h    |   21 ++++++++++-------
 arch/m68k/include/asm/io_no.h    |   34 +++++++++++++++++----------
 arch/m68k/include/asm/raw_io.h   |    3 ++
 arch/m68k/mm/kmap.c              |    2 +-
 arch/metag/include/asm/io.h      |   35 +++++++++++++++++-----------
 arch/microblaze/include/asm/io.h |    6 -----
 arch/microblaze/mm/pgtable.c     |    2 +-
 arch/mips/include/asm/io.h       |   42 ++++++++++++---------------------
 arch/mn10300/include/asm/io.h    |   10 +++++---
 arch/nios2/include/asm/io.h      |   15 +++---------
 arch/openrisc/include/asm/io.h   |    3 ++
 arch/openrisc/mm/ioremap.c       |    2 +-
 arch/parisc/include/asm/io.h     |    6 ++---
 arch/parisc/mm/ioremap.c         |    2 +-
 arch/powerpc/include/asm/io.h    |    7 ++----
 arch/s390/include/asm/io.h       |    8 ++----
 arch/sh/include/asm/io.h         |    9 ++++++-
 arch/sparc/include/asm/io_32.h   |    7 ++----
 arch/sparc/include/asm/io_64.h   |    8 ++----
 arch/sparc/kernel/ioport.c       |    2 +-
 arch/tile/include/asm/io.h       |   17 +++++++++----
 arch/unicore32/include/asm/io.h  |   25 ++++++++++++++++----
 arch/x86/include/asm/io.h        |   10 ++++++--
 arch/xtensa/include/asm/io.h     |   13 ++++++----
 drivers/net/ethernet/sfc/io.h    |    2 +-
 include/asm-generic/io.h         |   15 ++++++------
 include/asm-generic/iomap.h      |    8 ------
 include/linux/io.h               |   48 ++++++++++++++++++++++++++++++++++++++
 lib/devres.c                     |   20 ++++++++++++++++
 44 files changed, 303 insertions(+), 220 deletions(-)

diff --git a/arch/alpha/include/asm/io.h b/arch/alpha/include/asm/io.h
index f05bdb4b1cb9..6b63689c27a6 100644
--- a/arch/alpha/include/asm/io.h
+++ b/arch/alpha/include/asm/io.h
@@ -282,10 +282,11 @@ extern inline void ioport_unmap(void __iomem *addr)
 {
 }
 
-static inline void __iomem *ioremap(unsigned long port, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t port, unsigned long size)
 {
 	return IO_CONCAT(__IO_PREFIX,ioremap) (port, size);
 }
+#define ioremap ioremap
 
 static inline void __iomem *__ioremap(unsigned long port, unsigned long size,
 				      unsigned long flags)
@@ -293,16 +294,18 @@ static inline void __iomem *__ioremap(unsigned long port, unsigned long size,
 	return ioremap(port, size);
 }
 
-static inline void __iomem * ioremap_nocache(unsigned long offset,
+static inline void __iomem * ioremap_nocache(resource_size_t offset,
 					     unsigned long size)
 {
 	return ioremap(offset, size);
 } 
+#define ioremap_nocache ioremap_nocache
 
 static inline void iounmap(volatile void __iomem *addr)
 {
 	IO_CONCAT(__IO_PREFIX,iounmap)(addr);
 }
+#define iounmap iounmap
 
 static inline int __is_ioaddr(unsigned long addr)
 {
diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h
index 694ece8a0243..640730d5f3da 100644
--- a/arch/arc/include/asm/io.h
+++ b/arch/arc/include/asm/io.h
@@ -13,14 +13,8 @@
 #include <asm/byteorder.h>
 #include <asm/page.h>
 
-extern void __iomem *ioremap(unsigned long physaddr, unsigned long size);
 extern void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
 				  unsigned long flags);
-extern void iounmap(const void __iomem *addr);
-
-#define ioremap_nocache(phy, sz)	ioremap(phy, sz)
-#define ioremap_wc(phy, sz)		ioremap(phy, sz)
-#define ioremap_wt(phy, sz)		ioremap(phy, sz)
 
 /* Change struct page to physical address */
 #define page_to_phys(page)		(page_to_pfn(page) << PAGE_SHIFT)
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 485982084fe9..ebaac84bd59e 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -388,16 +388,14 @@ static inline void memcpy_toio(volatile void __iomem *to, const void *from,
  * Eg, a CPU not implementing read allocate but implementing write allocate
  * will provide a write allocate mapping instead.
  */
-void __iomem *ioremap(resource_size_t res_cookie, size_t size);
+void __iomem *ioremap(resource_size_t res_cookie, unsigned long size);
 #define ioremap ioremap
-#define ioremap_nocache ioremap
 
-void __iomem *ioremap_cache(resource_size_t res_cookie, size_t size);
+void __iomem *ioremap_cache(resource_size_t res_cookie, unsigned long size);
 #define ioremap_cache ioremap_cache
 
-void __iomem *ioremap_wc(resource_size_t res_cookie, size_t size);
+void __iomem *ioremap_wc(resource_size_t res_cookie, unsigned long size);
 #define ioremap_wc ioremap_wc
-#define ioremap_wt ioremap_wc
 
 void iounmap(volatile void __iomem *iomem_cookie);
 #define iounmap iounmap
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 0c81056c1dd7..db143a3c63c6 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -371,21 +371,21 @@ void __iomem * (*arch_ioremap_caller)(phys_addr_t, size_t,
 				      unsigned int, void *) =
 	__arm_ioremap_caller;
 
-void __iomem *ioremap(resource_size_t res_cookie, size_t size)
+void __iomem *ioremap(resource_size_t res_cookie, unsigned long size)
 {
 	return arch_ioremap_caller(res_cookie, size, MT_DEVICE,
 				   __builtin_return_address(0));
 }
 EXPORT_SYMBOL(ioremap);
 
-void __iomem *ioremap_cache(resource_size_t res_cookie, size_t size)
+void __iomem *ioremap_cache(resource_size_t res_cookie, unsigned long size)
 {
 	return arch_ioremap_caller(res_cookie, size, MT_DEVICE_CACHED,
 				   __builtin_return_address(0));
 }
 EXPORT_SYMBOL(ioremap_cache);
 
-void __iomem *ioremap_wc(resource_size_t res_cookie, size_t size)
+void __iomem *ioremap_wc(resource_size_t res_cookie, unsigned long size)
 {
 	return arch_ioremap_caller(res_cookie, size, MT_DEVICE_WC,
 				   __builtin_return_address(0));
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 1dd10936d68d..13b93eee89da 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -359,21 +359,21 @@ void __iomem *__arm_ioremap_caller(phys_addr_t phys_addr, size_t size,
 
 void __iomem * (*arch_ioremap_caller)(phys_addr_t, size_t, unsigned int, void *);
 
-void __iomem *ioremap(resource_size_t res_cookie, size_t size)
+void __iomem *ioremap(resource_size_t res_cookie, unsigned long size)
 {
 	return __arm_ioremap_caller(res_cookie, size, MT_DEVICE,
 				    __builtin_return_address(0));
 }
 EXPORT_SYMBOL(ioremap);
 
-void __iomem *ioremap_cache(resource_size_t res_cookie, size_t size)
+void __iomem *ioremap_cache(resource_size_t res_cookie, unsigned long size)
 {
 	return __arm_ioremap_caller(res_cookie, size, MT_DEVICE_CACHED,
 				    __builtin_return_address(0));
 }
 EXPORT_SYMBOL(ioremap_cache);
 
-void __iomem *ioremap_wc(resource_size_t res_cookie, size_t size)
+void __iomem *ioremap_wc(resource_size_t res_cookie, unsigned long size)
 {
 	return __arm_ioremap_caller(res_cookie, size, MT_DEVICE_WC,
 				    __builtin_return_address(0));
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 44be1e03ed65..2b56846fc65f 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -166,12 +166,25 @@ extern void __memset_io(volatile void __iomem *, int, size_t);
 extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot);
 extern void __iounmap(volatile void __iomem *addr);
 extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
+#define ioremap_cache ioremap_cache
 
-#define ioremap(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
-#define ioremap_nocache(addr, size)	__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
-#define ioremap_wc(addr, size)		__ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
-#define ioremap_wt(addr, size)		__ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
-#define iounmap				__iounmap
+static inline void __iomem *ioremap(resource_size_t addr, unsigned long size)
+{
+	return __ioremap(addr, size, __pgprot(PROT_DEVICE_nGnRE));
+}
+#define ioremap ioremap
+
+static inline void __iomem *ioremap_wc(resource_size_t addr, unsigned long size)
+{
+	return __ioremap(addr, size, __pgprot(PROT_NORMAL_NC));
+}
+#define ioremap_wc ioremap_wc
+
+static inline void iounmap(volatile void __iomem *addr)
+{
+	return __iounmap(addr);
+}
+#define iounmap iounmap
 
 /*
  * io{read,write}{16,32}be() macros
diff --git a/arch/avr32/include/asm/io.h b/arch/avr32/include/asm/io.h
index e998ff5d8e1a..80af4cb6c5b6 100644
--- a/arch/avr32/include/asm/io.h
+++ b/arch/avr32/include/asm/io.h
@@ -274,7 +274,7 @@ static inline void memset_io(volatile void __iomem *addr, unsigned char val,
 
 extern void __iomem *__ioremap(unsigned long offset, size_t size,
 			       unsigned long flags);
-extern void __iounmap(void __iomem *addr);
+extern void __iounmap(volatile void __iomem *addr);
 
 /*
  * ioremap	-   map bus memory into CPU space
@@ -286,17 +286,17 @@ extern void __iounmap(void __iomem *addr);
  * the other mmio helpers. The returned address is not guaranteed to
  * be usable directly as a virtual address.
  */
-#define ioremap(offset, size)			\
-	__ioremap((offset), (size), 0)
-
-#define ioremap_nocache(offset, size)		\
-	__ioremap((offset), (size), 0)
-
-#define iounmap(addr)				\
-	__iounmap(addr)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
+{
+	return __ioremap(offset, size, 0);
+}
+#define ioremap ioremap
 
-#define ioremap_wc ioremap_nocache
-#define ioremap_wt ioremap_nocache
+static inline void iounmap(volatile void __iomem *addr)
+{
+	return __iounmap(addr);
+}
+#define iounmap iounmap
 
 #define cached(addr) P1SEGADDR(addr)
 #define uncached(addr) P2SEGADDR(addr)
diff --git a/arch/avr32/mm/ioremap.c b/arch/avr32/mm/ioremap.c
index 7def0d84cec6..f3eacbe5dff6 100644
--- a/arch/avr32/mm/ioremap.c
+++ b/arch/avr32/mm/ioremap.c
@@ -73,7 +73,7 @@ void __iomem *__ioremap(unsigned long phys_addr, size_t size,
 }
 EXPORT_SYMBOL(__ioremap);
 
-void __iounmap(void __iomem *addr)
+void __iounmap(volatile void __iomem *addr)
 {
 	struct vm_struct *p;
 
diff --git a/arch/cris/include/asm/io.h b/arch/cris/include/asm/io.h
index 752a3f45df60..cd55a5709433 100644
--- a/arch/cris/include/asm/io.h
+++ b/arch/cris/include/asm/io.h
@@ -37,14 +37,14 @@ static inline void * phys_to_virt(unsigned long address)
 extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
 extern void __iomem * __ioremap_prot(unsigned long phys_addr, unsigned long size, pgprot_t prot);
 
-static inline void __iomem * ioremap (unsigned long offset, unsigned long size)
+static inline void __iomem * ioremap(resource_size_t offset, unsigned long size)
 {
 	return __ioremap(offset, size, 0);
 }
+#define ioremap ioremap
 
-extern void iounmap(volatile void * __iomem addr);
-
-extern void __iomem * ioremap_nocache(unsigned long offset, unsigned long size);
+extern void __iomem * ioremap_nocache(resource_size_t offset, unsigned long size);
+#define ioremap_nocache ioremap_nocache
 
 /*
  * IO bus memory addresses are also 1:1 with the physical address
diff --git a/arch/cris/mm/ioremap.c b/arch/cris/mm/ioremap.c
index 80fdb995a8ce..13cef92df503 100644
--- a/arch/cris/mm/ioremap.c
+++ b/arch/cris/mm/ioremap.c
@@ -76,7 +76,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
  * Must be freed with iounmap.
  */
 
-void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size)
+void __iomem *ioremap_nocache(resource_size_t phys_addr, unsigned long size)
 {
         return __ioremap(phys_addr | MEM_NON_CACHEABLE, size, 0);
 }
diff --git a/arch/frv/include/asm/io.h b/arch/frv/include/asm/io.h
index a31b63ec4930..bde570d29c89 100644
--- a/arch/frv/include/asm/io.h
+++ b/arch/frv/include/asm/io.h
@@ -17,8 +17,6 @@
 
 #ifdef __KERNEL__
 
-#define ARCH_HAS_IOREMAP_WT
-
 #include <linux/types.h>
 #include <asm/virtconvert.h>
 #include <asm/string.h>
@@ -257,29 +255,28 @@ static inline void writel(uint32_t datum, volatile void __iomem *addr)
 
 extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
 
-static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
-{
-	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
-}
-
-static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
 }
+#define ioremap ioremap
 
-static inline void __iomem *ioremap_wt(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap_wt(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
 }
+#define ioremap_wt ioremap_wt
 
-static inline void __iomem *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap_fullcache(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
 }
 
-#define ioremap_wc ioremap_nocache
-
-extern void iounmap(void volatile __iomem *addr);
+static inline void __iomem *ioremap_cache(resource_size_t physaddr, unsigned long size)
+{
+	return ioremap_fullcache(physaddr, size);
+}
+#define ioremap_cache ioremap_cache
 
 static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
 {
diff --git a/arch/hexagon/include/asm/io.h b/arch/hexagon/include/asm/io.h
index 66f5e9a61efc..e5ecc08b7627 100644
--- a/arch/hexagon/include/asm/io.h
+++ b/arch/hexagon/include/asm/io.h
@@ -191,16 +191,19 @@ static inline void writel(u32 data, volatile void __iomem *addr)
  * This is probably too long for an inline.
  */
 void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size);
+#define ioremap_nocache ioremap_nocache
 
-static inline void __iomem *ioremap(unsigned long phys_addr, unsigned long size)
+static inline void __iomem *ioremap(resouce_size_t phys_addr, unsigned long size)
 {
 	return ioremap_nocache(phys_addr, size);
 }
+#define ioremap ioremap
 
 static inline void iounmap(volatile void __iomem *addr)
 {
 	__iounmap(addr);
 }
+#define iounmap iounmap
 
 #define __raw_writel writel
 
diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h
index 80a7e34be009..ea4c7a243973 100644
--- a/arch/ia64/include/asm/io.h
+++ b/arch/ia64/include/asm/io.h
@@ -424,18 +424,12 @@ __writeq (unsigned long val, volatile void __iomem *addr)
 
 # ifdef __KERNEL__
 
-extern void __iomem * ioremap(unsigned long offset, unsigned long size);
-extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size);
-extern void iounmap (volatile void __iomem *addr);
+extern void __iomem * ioremap_nocache (resource_size_t offset, unsigned long size);
+#define ioremap_nocache ioremap_nocache
 extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size);
 #define early_memremap(phys_addr, size)        early_ioremap(phys_addr, size)
 extern void early_iounmap (volatile void __iomem *addr, unsigned long size);
 #define early_memunmap(addr, size)             early_iounmap(addr, size)
-static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size)
-{
-	return ioremap(phys_addr, size);
-}
-
 
 /*
  * String version of IO memory access ops:
diff --git a/arch/ia64/mm/ioremap.c b/arch/ia64/mm/ioremap.c
index 43964cde6214..205d71445f06 100644
--- a/arch/ia64/mm/ioremap.c
+++ b/arch/ia64/mm/ioremap.c
@@ -32,7 +32,7 @@ early_ioremap (unsigned long phys_addr, unsigned long size)
 }
 
 void __iomem *
-ioremap (unsigned long phys_addr, unsigned long size)
+ioremap (resource_size_t phys_addr, unsigned long size)
 {
 	void __iomem *addr;
 	struct vm_struct *area;
@@ -102,7 +102,7 @@ ioremap (unsigned long phys_addr, unsigned long size)
 EXPORT_SYMBOL(ioremap);
 
 void __iomem *
-ioremap_nocache (unsigned long phys_addr, unsigned long size)
+ioremap_nocache (resource_size_t phys_addr, unsigned long size)
 {
 	if (kern_mem_attribute(phys_addr, size) & EFI_MEMORY_WB)
 		return NULL;
diff --git a/arch/m32r/include/asm/io.h b/arch/m32r/include/asm/io.h
index 0c3f25ee3381..d7f96a542816 100644
--- a/arch/m32r/include/asm/io.h
+++ b/arch/m32r/include/asm/io.h
@@ -60,15 +60,14 @@ __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
  *	address.
  */
 
-static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return __ioremap(offset, size, 0);
 }
+#define ioremap ioremap
 
-extern void iounmap(volatile void __iomem *addr);
-#define ioremap_nocache(off,size) ioremap(off,size)
-#define ioremap_wc ioremap_nocache
-#define ioremap_wt ioremap_nocache
+void iounmap(volatile void __iomem *addr);
+#define iounmap iounmap
 
 /*
  * IO bus memory addresses are also 1:1 with the physical address
diff --git a/arch/m68k/include/asm/io_mm.h b/arch/m68k/include/asm/io_mm.h
index f55cad529400..4119295c6631 100644
--- a/arch/m68k/include/asm/io_mm.h
+++ b/arch/m68k/include/asm/io_mm.h
@@ -20,8 +20,6 @@
 
 #ifdef __KERNEL__
 
-#define ARCH_HAS_IOREMAP_WT
-
 #include <linux/compiler.h>
 #include <asm/raw_io.h>
 #include <asm/virtconvert.h>
@@ -460,25 +458,32 @@ static inline void isa_delay(void)
 
 #define mmiowb()
 
-static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
 }
-static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned long size)
-{
-	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
-}
-static inline void __iomem *ioremap_wt(unsigned long physaddr,
+#define ioremap ioremap
+
+static inline void __iomem *ioremap_wt(resource_size_t physaddr,
 					 unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
 }
+#define ioremap_wt ioremap_wt
+
 static inline void __iomem *ioremap_fullcache(unsigned long physaddr,
 				      unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
 }
 
+static inline void __iomem *ioremap_cache(resource_size_t physaddr,
+		unsigned long size)
+{
+	return ioremap_fullcache(physaddr, size);
+}
+#define ioremap_cache ioremap_cache
+
 static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
 {
 	__builtin_memset((void __force *) addr, val, count);
diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h
index ad7bd40e6742..ea9b280ebc33 100644
--- a/arch/m68k/include/asm/io_no.h
+++ b/arch/m68k/include/asm/io_no.h
@@ -3,8 +3,6 @@
 
 #ifdef __KERNEL__
 
-#define ARCH_HAS_IOREMAP_WT
-
 #include <asm/virtconvert.h>
 #include <asm-generic/iomap.h>
 
@@ -143,28 +141,40 @@ static inline void io_insl(unsigned int addr, void *buf, int len)
 #define IOMAP_NOCACHE_NONSER		2
 #define IOMAP_WRITETHROUGH		3
 
-static inline void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
-{
-	return (void *) physaddr;
-}
-static inline void *ioremap(unsigned long physaddr, unsigned long size)
+static inline void __iomem *__ioremap(unsigned long physaddr,
+		unsigned long size, int cacheflag)
 {
-	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
+	return (void __iomem *) physaddr;
 }
-static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
 }
-static inline void *ioremap_wt(unsigned long physaddr, unsigned long size)
+#define ioremap ioremap
+
+static inline void __iomem *ioremap_wt(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
 }
-static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+#define ioremap_wt ioremap_wt
+
+static inline void __iomem *ioremap_fullcache(unsigned long physaddr,
+		unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
 }
 
-#define	iounmap(addr)	do { } while(0)
+static inline void __iomem *ioremap_cache(resource_size_t physaddr,
+		unsigned long size)
+{
+	return ioremap_fullcache(physaddr, size);
+}
+#define ioremap_cache ioremap_cache
+
+static inline void iounmap(volatile void __iomem *addr)
+{
+}
+#define iounmap iounmap
 
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
diff --git a/arch/m68k/include/asm/raw_io.h b/arch/m68k/include/asm/raw_io.h
index 932faa35655b..abb7708f02ed 100644
--- a/arch/m68k/include/asm/raw_io.h
+++ b/arch/m68k/include/asm/raw_io.h
@@ -19,7 +19,8 @@
 #define IOMAP_NOCACHE_NONSER		2
 #define IOMAP_WRITETHROUGH		3
 
-extern void iounmap(void __iomem *addr);
+extern void iounmap(volatile void __iomem *addr);
+#define iounmap iounmap
 
 extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size,
 		       int cacheflag);
diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c
index 6e4955bc542b..f0d76d9f0643 100644
--- a/arch/m68k/mm/kmap.c
+++ b/arch/m68k/mm/kmap.c
@@ -226,7 +226,7 @@ EXPORT_SYMBOL(__ioremap);
 /*
  * Unmap an ioremap()ed region again
  */
-void iounmap(void __iomem *addr)
+void iounmap(volatile void __iomem *addr)
 {
 #ifdef CONFIG_AMIGA
 	if ((!MACH_IS_AMIGA) ||
diff --git a/arch/metag/include/asm/io.h b/arch/metag/include/asm/io.h
index 9890f21eadbe..50e95ecb4bc2 100644
--- a/arch/metag/include/asm/io.h
+++ b/arch/metag/include/asm/io.h
@@ -148,22 +148,29 @@ extern void __iounmap(void __iomem *addr);
  *	address is not guaranteed to be usable directly as a virtual
  *	address.
  */
-#define ioremap(offset, size)                   \
-	__ioremap((offset), (size), 0)
-
-#define ioremap_nocache(offset, size)           \
-	__ioremap((offset), (size), 0)
-
-#define ioremap_cached(offset, size)            \
-	__ioremap((offset), (size), _PAGE_CACHEABLE)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
+{
+	return __ioremap(offset, size, 0);
+}
+#define ioremap ioremap
 
-#define ioremap_wc(offset, size)                \
-	__ioremap((offset), (size), _PAGE_WR_COMBINE)
+static inline void __iomem *ioremap_cache(resource_size_t offset, unsigned long size)
+{
+	return __ioremap(offset, size, _PAGE_CACHEABLE);
+}
+#define ioremap_cache ioremap_cache
+#define ioremap_cached ioremap_cache
 
-#define ioremap_wt(offset, size)                \
-	__ioremap((offset), (size), 0)
+static inline void __iomem *ioremap_wc(resource_size_t offset, unsigned long size)
+{
+	return __ioremap(offset, size, _PAGE_WR_COMBINE);
+}
+#define ioremap_wc ioremap_wc
 
-#define iounmap(addr)                           \
-	__iounmap(addr)
+static inline void iounmap(volatile void __iomem *addr)
+{
+	return __iounmap(addr);
+}
+#define iounmap iounmap
 
 #endif  /* _ASM_METAG_IO_H */
diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h
index 39b6315db82e..60ca27d7dd1f 100644
--- a/arch/microblaze/include/asm/io.h
+++ b/arch/microblaze/include/asm/io.h
@@ -36,13 +36,7 @@ extern resource_size_t isa_mem_base;
 #ifdef CONFIG_MMU
 #define page_to_bus(page)	(page_to_phys(page))
 
-extern void iounmap(void __iomem *addr);
-
-extern void __iomem *ioremap(phys_addr_t address, unsigned long size);
-#define ioremap_nocache(addr, size)		ioremap((addr), (size))
 #define ioremap_fullcache(addr, size)		ioremap((addr), (size))
-#define ioremap_wc(addr, size)			ioremap((addr), (size))
-#define ioremap_wt(addr, size)			ioremap((addr), (size))
 
 #endif /* CONFIG_MMU */
 
diff --git a/arch/microblaze/mm/pgtable.c b/arch/microblaze/mm/pgtable.c
index 4f4520e779a5..2b47b34ff26c 100644
--- a/arch/microblaze/mm/pgtable.c
+++ b/arch/microblaze/mm/pgtable.c
@@ -126,7 +126,7 @@ void __iomem *ioremap(phys_addr_t addr, unsigned long size)
 }
 EXPORT_SYMBOL(ioremap);
 
-void iounmap(void __iomem *addr)
+void iounmap(volatile void __iomem *addr)
 {
 	if ((__force void *)addr > high_memory &&
 					(unsigned long) addr < ioremap_bot)
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 9e777cd42b67..a907e634f914 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -232,30 +232,11 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si
  * address is not guaranteed to be usable directly as a virtual
  * address.
  */
-#define ioremap(offset, size)						\
-	__ioremap_mode((offset), (size), _CACHE_UNCACHED)
-
-/*
- * ioremap_nocache     -   map bus memory into CPU space
- * @offset:    bus address of the memory
- * @size:      size of the resource to map
- *
- * ioremap_nocache performs a platform specific sequence of operations to
- * make bus memory CPU accessible via the readb/readw/readl/writeb/
- * writew/writel functions and the other mmio helpers. The returned
- * address is not guaranteed to be usable directly as a virtual
- * address.
- *
- * This version of ioremap ensures that the memory is marked uncachable
- * on the CPU as well as honouring existing caching rules from things like
- * the PCI bus. Note that there are other caches and buffers on many
- * busses. In particular driver authors should read up on PCI writes
- *
- * It's useful if some control registers are in such an area and
- * write combining or read caching is not desirable:
- */
-#define ioremap_nocache(offset, size)					\
-	__ioremap_mode((offset), (size), _CACHE_UNCACHED)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
+{
+	return __ioremap_mode(offset, size, _CACHE_UNCACHED);
+}
+#define ioremap ioremap
 
 /*
  * ioremap_cachable -	map bus memory into CPU space
@@ -272,8 +253,14 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si
  * the CPU.  Also enables full write-combining.	 Useful for some
  * memory-like regions on I/O busses.
  */
-#define ioremap_cachable(offset, size)					\
-	__ioremap_mode((offset), (size), _page_cachable_default)
+#define ioremap_cachable ioremap_cache
+extern unsigned long _page_cachable_default;
+static inline void __iomem *ioremap_cache(resource_size_t offset,
+		unsigned long size)
+{
+	return __ioremap_mode(offset, size, _page_cachable_default);
+}
+#define ioremap_cache ioremap_cache
 
 /*
  * These two are MIPS specific ioremap variant.	 ioremap_cacheable_cow
@@ -286,7 +273,7 @@ static inline void __iomem * __ioremap_mode(phys_addr_t offset, unsigned long si
 #define ioremap_uncached_accelerated(offset, size)			\
 	__ioremap_mode((offset), (size), _CACHE_UNCACHED_ACCELERATED)
 
-static inline void iounmap(const volatile void __iomem *addr)
+static inline void iounmap(volatile void __iomem *addr)
 {
 	if (plat_iounmap(addr))
 		return;
@@ -301,6 +288,7 @@ static inline void iounmap(const volatile void __iomem *addr)
 
 #undef __IS_KSEG1
 }
+#define iounmap iounmap
 
 #ifdef CONFIG_CPU_CAVIUM_OCTEON
 #define war_octeon_io_reorder_wmb()		wmb()
diff --git a/arch/mn10300/include/asm/io.h b/arch/mn10300/include/asm/io.h
index 07c5b4a3903b..48629631f718 100644
--- a/arch/mn10300/include/asm/io.h
+++ b/arch/mn10300/include/asm/io.h
@@ -266,27 +266,29 @@ static inline void __iomem *__ioremap(unsigned long offset, unsigned long size,
 	return (void __iomem *) offset;
 }
 
-static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return (void __iomem *)(offset & ~0x20000000);
 }
+#define ioremap ioremap
 
 /*
  * This one maps high address device memory and turns off caching for that
  * area.  it's useful if some control registers are in such an area and write
  * combining or read caching is not desirable:
  */
-static inline void __iomem *ioremap_nocache(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size)
 {
 	return (void __iomem *) (offset | 0x20000000);
 }
-
+#define ioremap_nocache ioremap_nocache
 #define ioremap_wc ioremap_nocache
 #define ioremap_wt ioremap_nocache
 
-static inline void iounmap(void __iomem *addr)
+static inline void iounmap(volatile void __iomem *addr)
 {
 }
+#define iounmap iounmap
 
 static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
 {
diff --git a/arch/nios2/include/asm/io.h b/arch/nios2/include/asm/io.h
index c5a62da22cd2..161a63265813 100644
--- a/arch/nios2/include/asm/io.h
+++ b/arch/nios2/include/asm/io.h
@@ -29,24 +29,17 @@ extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size,
 			unsigned long cacheflag);
 extern void __iounmap(void __iomem *addr);
 
-static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, 0);
 }
+#define ioremap ioremap
 
-static inline void __iomem *ioremap_nocache(unsigned long physaddr,
-						unsigned long size)
-{
-	return __ioremap(physaddr, size, 0);
-}
-
-static inline void iounmap(void __iomem *addr)
+static inline void iounmap(volatile void __iomem *addr)
 {
 	__iounmap(addr);
 }
-
-#define ioremap_wc ioremap_nocache
-#define ioremap_wt ioremap_nocache
+#define iounmap iounmap
 
 /* Pages to physical address... */
 #define page_to_phys(page)	virt_to_phys(page_to_virt(page))
diff --git a/arch/openrisc/include/asm/io.h b/arch/openrisc/include/asm/io.h
index 7c691399da3f..4f7636e7901d 100644
--- a/arch/openrisc/include/asm/io.h
+++ b/arch/openrisc/include/asm/io.h
@@ -39,6 +39,7 @@ static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
 {
 	return __ioremap(offset, size, PAGE_KERNEL);
 }
+#define ioremap ioremap
 
 /* #define _PAGE_CI       0x002 */
 static inline void __iomem *ioremap_nocache(phys_addr_t offset,
@@ -47,6 +48,6 @@ static inline void __iomem *ioremap_nocache(phys_addr_t offset,
 	return __ioremap(offset, size,
 			 __pgprot(pgprot_val(PAGE_KERNEL) | _PAGE_CI));
 }
+#define ioremap_nocache ioremap_nocache
 
-extern void iounmap(void *addr);
 #endif
diff --git a/arch/openrisc/mm/ioremap.c b/arch/openrisc/mm/ioremap.c
index 62b08ef392be..2af1bbe5f80c 100644
--- a/arch/openrisc/mm/ioremap.c
+++ b/arch/openrisc/mm/ioremap.c
@@ -81,7 +81,7 @@ __ioremap(phys_addr_t addr, unsigned long size, pgprot_t prot)
 	return (void __iomem *)(offset + (char *)v);
 }
 
-void iounmap(void *addr)
+void iounmap(volatile void __iomem *addr)
 {
 	/* If the page is from the fixmap pool then we just clear out
 	 * the fixmap mapping.
diff --git a/arch/parisc/include/asm/io.h b/arch/parisc/include/asm/io.h
index 8cd0abf28ffb..8a4ecb47f960 100644
--- a/arch/parisc/include/asm/io.h
+++ b/arch/parisc/include/asm/io.h
@@ -132,13 +132,11 @@ extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsign
 /* Most machines react poorly to I/O-space being cacheable... Instead let's
  * define ioremap() in terms of ioremap_nocache().
  */
-static inline void __iomem * ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem * ioremap(resource_size_t offset, unsigned long size)
 {
 	return __ioremap(offset, size, _PAGE_NO_CACHE);
 }
-#define ioremap_nocache(off, sz)	ioremap((off), (sz))
-
-extern void iounmap(const volatile void __iomem *addr);
+#define ioremap ioremap
 
 static inline unsigned char __raw_readb(const volatile void __iomem *addr)
 {
diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c
index 838d0259cd27..3830d8af80a4 100644
--- a/arch/parisc/mm/ioremap.c
+++ b/arch/parisc/mm/ioremap.c
@@ -91,7 +91,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
 }
 EXPORT_SYMBOL(__ioremap);
 
-void iounmap(const volatile void __iomem *addr)
+void iounmap(volatile void __iomem *addr)
 {
 	if (addr > high_memory)
 		return vfree((void *) (PAGE_MASK & (unsigned long __force) addr));
diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h
index a8d2ef30d473..081f7d3d8913 100644
--- a/arch/powerpc/include/asm/io.h
+++ b/arch/powerpc/include/asm/io.h
@@ -2,8 +2,6 @@
 #define _ASM_POWERPC_IO_H
 #ifdef __KERNEL__
 
-#define ARCH_HAS_IOREMAP_WC
-
 /*
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -25,7 +23,6 @@ extern struct pci_dev *isa_bridge_pcidev;
 #endif
 
 #include <linux/device.h>
-#include <linux/io.h>
 
 #include <linux/compiler.h>
 #include <asm/page.h>
@@ -717,12 +714,14 @@ static inline void iosync(void)
  *
  */
 extern void __iomem *ioremap(phys_addr_t address, unsigned long size);
+#define ioremap ioremap
 extern void __iomem *ioremap_prot(phys_addr_t address, unsigned long size,
 				  unsigned long flags);
 extern void __iomem *ioremap_wc(phys_addr_t address, unsigned long size);
-#define ioremap_nocache(addr, size)	ioremap((addr), (size))
+#define ioremap_wc ioremap_wc
 
 extern void iounmap(volatile void __iomem *addr);
+#define iounmap iounmap
 
 extern void __iomem *__ioremap(phys_addr_t, unsigned long size,
 			       unsigned long flags);
diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h
index cb5fdf3a78fc..1cb32250d12b 100644
--- a/arch/s390/include/asm/io.h
+++ b/arch/s390/include/asm/io.h
@@ -27,18 +27,16 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);
 
 #ifdef CONFIG_PCI
 
-#define ioremap_nocache(addr, size)	ioremap(addr, size)
-#define ioremap_wc			ioremap_nocache
-#define ioremap_wt			ioremap_nocache
-
-static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return (void __iomem *) offset;
 }
+#define ioremap ioremap
 
 static inline void iounmap(volatile void __iomem *addr)
 {
 }
+#define iounmap iounmap
 
 static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
 {
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 728c4c571f40..fddd71512ee1 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -336,12 +336,14 @@ static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
 {
 	return __ioremap_mode(offset, size, PAGE_KERNEL_NOCACHE);
 }
+#define ioremap ioremap
 
 static inline void __iomem *
 ioremap_cache(phys_addr_t offset, unsigned long size)
 {
 	return __ioremap_mode(offset, size, PAGE_KERNEL);
 }
+#define ioremap_cache ioremap_cache
 
 #ifdef CONFIG_HAVE_IOREMAP_PROT
 static inline void __iomem *
@@ -367,8 +369,11 @@ static inline void ioremap_fixed_init(void) { }
 static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
 #endif
 
-#define ioremap_nocache	ioremap
-#define iounmap		__iounmap
+static inline void iounmap(volatile void __iomem *addr)
+{
+	__iounmap((void __force __iomem *) addr);
+}
+#define iounmap	iounmap
 
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h
index 57f26c398dc9..138e47e0c7d2 100644
--- a/arch/sparc/include/asm/io_32.h
+++ b/arch/sparc/include/asm/io_32.h
@@ -126,11 +126,8 @@ static inline void sbus_memcpy_toio(volatile void __iomem *dst,
  * Bus number may be embedded in the higher bits of the physical address.
  * This is why we have no bus number argument to ioremap().
  */
-void __iomem *ioremap(unsigned long offset, unsigned long size);
-#define ioremap_nocache(X,Y)	ioremap((X),(Y))
-#define ioremap_wc(X,Y)		ioremap((X),(Y))
-#define ioremap_wt(X,Y)		ioremap((X),(Y))
-void iounmap(volatile void __iomem *addr);
+void __iomem *ioremap(resource_size_t offset, unsigned long size);
+#define ioremap ioremap
 
 /* Create a virtual mapping cookie for an IO port range */
 void __iomem *ioport_map(unsigned long port, unsigned int nr);
diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h
index c32fa3f752c8..47e90988b562 100644
--- a/arch/sparc/include/asm/io_64.h
+++ b/arch/sparc/include/asm/io_64.h
@@ -395,18 +395,16 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src,
 /* On sparc64 we have the whole physical IO address space accessible
  * using physically addressed loads and stores, so this does nothing.
  */
-static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return (void __iomem *)offset;
 }
-
-#define ioremap_nocache(X,Y)		ioremap((X),(Y))
-#define ioremap_wc(X,Y)			ioremap((X),(Y))
-#define ioremap_wt(X,Y)			ioremap((X),(Y))
+#define ioremap ioremap
 
 static inline void iounmap(volatile void __iomem *addr)
 {
 }
+#define iounmap iounmap
 
 #define ioread8			readb
 #define ioread16		readw
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 28fed53b13a0..b8c999f5b821 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -121,7 +121,7 @@ static void xres_free(struct xresource *xrp) {
  *
  * Bus type is always zero on IIep.
  */
-void __iomem *ioremap(unsigned long offset, unsigned long size)
+void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	char name[14];
 
diff --git a/arch/tile/include/asm/io.h b/arch/tile/include/asm/io.h
index dc61de15c1f9..bf7f0fffb8db 100644
--- a/arch/tile/include/asm/io.h
+++ b/arch/tile/include/asm/io.h
@@ -48,14 +48,19 @@ extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size,
 	pgprot_t pgprot);
 extern void iounmap(volatile void __iomem *addr);
 #else
-#define ioremap(physaddr, size)	((void __iomem *)(unsigned long)(physaddr))
-#define iounmap(addr)		((void)0)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
+{
+	return (void __force __iomem *) offset;
+}
+
+static inline void iounmap(volatile void __iomem *addr)
+{
+}
 #endif
+#define ioremap ioremap
+#define iounmap iounmap
 
-#define ioremap_nocache(physaddr, size)		ioremap(physaddr, size)
-#define ioremap_wc(physaddr, size)		ioremap(physaddr, size)
-#define ioremap_wt(physaddr, size)		ioremap(physaddr, size)
-#define ioremap_fullcache(physaddr, size)	ioremap(physaddr, size)
+#define ioremap_fullcache ioremap
 
 #define mmiowb()
 
diff --git a/arch/unicore32/include/asm/io.h b/arch/unicore32/include/asm/io.h
index cb1d8fd2b16b..1088450fabfd 100644
--- a/arch/unicore32/include/asm/io.h
+++ b/arch/unicore32/include/asm/io.h
@@ -18,7 +18,6 @@
 #include <asm/memory.h>
 
 #define PCI_IOBASE	PKUNITY_PCILIO_BASE
-#include <asm-generic/io.h>
 
 /*
  * __uc32_ioremap and __uc32_ioremap_cached takes CPU physical address.
@@ -34,10 +33,26 @@ extern void __uc32_iounmap(volatile void __iomem *addr);
  * Documentation/io-mapping.txt.
  *
  */
-#define ioremap(cookie, size)		__uc32_ioremap(cookie, size)
-#define ioremap_cached(cookie, size)	__uc32_ioremap_cached(cookie, size)
-#define ioremap_nocache(cookie, size)	__uc32_ioremap(cookie, size)
-#define iounmap(cookie)			__uc32_iounmap(cookie)
+static inline void __iomem *ioremap(resource_size_t cookie, unsigned long size)
+{
+	return __uc32_ioremap(cookie, size);
+}
+#define ioremap ioremap
+
+static inline void __iomem *ioremap_cache(resource_size_t cookie, unsigned long size)
+{
+	return __uc32_ioremap_cached(cookie, size);
+}
+#define ioremap_cache ioremap_cache
+#define ioremap_cached ioremap_cached
+
+static inline void iounmap(volatile void __iomem *addr)
+{
+	return __uc32_iounmap(addr);
+}
+#define iounmap iounmap
+
+#include <asm-generic/io.h>
 
 #define readb_relaxed readb
 #define readw_relaxed readw
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index cc9c61bc1abe..d0817f2762ab 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -34,9 +34,6 @@
   *  - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
   */
 
-#define ARCH_HAS_IOREMAP_WC
-#define ARCH_HAS_IOREMAP_WT
-
 #include <linux/string.h>
 #include <linux/compiler.h>
 #include <asm/page.h>
@@ -179,8 +176,11 @@ static inline unsigned int isa_virt_to_bus(volatile void *address)
  * look at pci_iomap().
  */
 extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size);
+#define ioremap_nocache ioremap_nocache
 extern void __iomem *ioremap_uc(resource_size_t offset, unsigned long size);
+#define ioremap_uc ioremap_uc
 extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
+#define ioremap_cache ioremap_cache
 extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size,
 				unsigned long prot_val);
 
@@ -191,8 +191,10 @@ static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return ioremap_nocache(offset, size);
 }
+#define ioremap ioremap
 
 extern void iounmap(volatile void __iomem *addr);
+#define iounmap iounmap
 
 extern void set_iounmap_nonlazy(void);
 
@@ -327,7 +329,9 @@ extern void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);
 extern int ioremap_change_attr(unsigned long vaddr, unsigned long size,
 				enum page_cache_mode pcm);
 extern void __iomem *ioremap_wc(resource_size_t offset, unsigned long size);
+#define ioremap_wc ioremap_wc
 extern void __iomem *ioremap_wt(resource_size_t offset, unsigned long size);
+#define ioremap_wt ioremap_wt
 
 extern bool is_early_ioremap_ptep(pte_t *ptep);
 
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index c39bb6e61911..ae20fc5a1b5f 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -38,7 +38,7 @@ static inline unsigned long xtensa_get_kio_paddr(void)
  * Return the virtual address for the specified bus memory.
  * Note that we currently don't support any address outside the KIO segment.
  */
-static inline void __iomem *ioremap_nocache(unsigned long offset,
+static inline void __iomem *ioremap_nocache(resource_size_t offset,
 		unsigned long size)
 {
 	if (offset >= XCHAL_KIO_PADDR
@@ -47,8 +47,9 @@ static inline void __iomem *ioremap_nocache(unsigned long offset,
 	else
 		BUG();
 }
+#define ioremap_nocache ioremap_nocache
 
-static inline void __iomem *ioremap_cache(unsigned long offset,
+static inline void __iomem *ioremap_cache(resource_size_t offset,
 		unsigned long size)
 {
 	if (offset >= XCHAL_KIO_PADDR
@@ -57,18 +58,18 @@ static inline void __iomem *ioremap_cache(unsigned long offset,
 	else
 		BUG();
 }
+#define ioremap_cache ioremap_cache
 
-#define ioremap_wc ioremap_nocache
-#define ioremap_wt ioremap_nocache
-
-static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
 {
 	return ioremap_nocache(offset, size);
 }
+#define ioremap ioremap
 
 static inline void iounmap(volatile void __iomem *addr)
 {
 }
+#define iounmap iounmap
 
 #define virt_to_bus     virt_to_phys
 #define bus_to_virt     phys_to_virt
diff --git a/drivers/net/ethernet/sfc/io.h b/drivers/net/ethernet/sfc/io.h
index afb94aa2c15e..9d54dd7f4c72 100644
--- a/drivers/net/ethernet/sfc/io.h
+++ b/drivers/net/ethernet/sfc/io.h
@@ -73,7 +73,7 @@
  */
 #ifdef CONFIG_X86_64
 /* PIO is a win only if write-combining is possible */
-#ifdef ARCH_HAS_IOREMAP_WC
+#ifdef ioremap_wc
 #define EFX_USE_PIO 1
 #endif
 #endif
diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index f56094cfdeff..92ac72c988ef 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -746,7 +746,7 @@ static inline void *phys_to_virt(unsigned long address)
 #ifndef CONFIG_MMU
 #ifndef ioremap
 #define ioremap ioremap
-static inline void __iomem *ioremap(phys_addr_t offset, size_t size)
+static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
 {
 	return (void __iomem *)(unsigned long)offset;
 }
@@ -754,7 +754,7 @@ static inline void __iomem *ioremap(phys_addr_t offset, size_t size)
 
 #ifndef __ioremap
 #define __ioremap __ioremap
-static inline void __iomem *__ioremap(phys_addr_t offset, size_t size,
+static inline void __iomem *__ioremap(phys_addr_t offset, unsigned long size,
 				      unsigned long flags)
 {
 	return ioremap(offset, size);
@@ -763,7 +763,8 @@ static inline void __iomem *__ioremap(phys_addr_t offset, size_t size,
 
 #ifndef ioremap_nocache
 #define ioremap_nocache ioremap_nocache
-static inline void __iomem *ioremap_nocache(phys_addr_t offset, size_t size)
+static inline void __iomem *ioremap_nocache(phys_addr_t offset,
+		unsigned long size)
 {
 	return ioremap(offset, size);
 }
@@ -771,7 +772,7 @@ static inline void __iomem *ioremap_nocache(phys_addr_t offset, size_t size)
 
 #ifndef ioremap_uc
 #define ioremap_uc ioremap_uc
-static inline void __iomem *ioremap_uc(phys_addr_t offset, size_t size)
+static inline void __iomem *ioremap_uc(phys_addr_t offset, unsigned long size)
 {
 	return ioremap_nocache(offset, size);
 }
@@ -779,7 +780,7 @@ static inline void __iomem *ioremap_uc(phys_addr_t offset, size_t size)
 
 #ifndef ioremap_wc
 #define ioremap_wc ioremap_wc
-static inline void __iomem *ioremap_wc(phys_addr_t offset, size_t size)
+static inline void __iomem *ioremap_wc(phys_addr_t offset, unsigned long size)
 {
 	return ioremap_nocache(offset, size);
 }
@@ -787,7 +788,7 @@ static inline void __iomem *ioremap_wc(phys_addr_t offset, size_t size)
 
 #ifndef ioremap_wt
 #define ioremap_wt ioremap_wt
-static inline void __iomem *ioremap_wt(phys_addr_t offset, size_t size)
+static inline void __iomem *ioremap_wt(phys_addr_t offset, unsigned long size)
 {
 	return ioremap_nocache(offset, size);
 }
@@ -796,7 +797,7 @@ static inline void __iomem *ioremap_wt(phys_addr_t offset, size_t size)
 #ifndef iounmap
 #define iounmap iounmap
 
-static inline void iounmap(void __iomem *addr)
+static inline void iounmap(volatile void __iomem *addr)
 {
 }
 #endif
diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h
index d8f8622fa044..4789b1cec313 100644
--- a/include/asm-generic/iomap.h
+++ b/include/asm-generic/iomap.h
@@ -62,14 +62,6 @@ extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
 extern void ioport_unmap(void __iomem *);
 #endif
 
-#ifndef ARCH_HAS_IOREMAP_WC
-#define ioremap_wc ioremap_nocache
-#endif
-
-#ifndef ARCH_HAS_IOREMAP_WT
-#define ioremap_wt ioremap_nocache
-#endif
-
 #ifdef CONFIG_PCI
 /* Destroy a virtual mapping cookie for a PCI BAR (memory or IO) */
 struct pci_dev;
diff --git a/include/linux/io.h b/include/linux/io.h
index fb5a99800e77..a4b2c1b2aaee 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -80,6 +80,54 @@ int check_signature(const volatile void __iomem *io_addr,
 			const unsigned char *signature, int length);
 void devm_ioremap_release(struct device *dev, void *res);
 
+#ifndef ioremap
+void __iomem *ioremap(resource_size_t offset, unsigned long size);
+#endif
+
+#ifndef iounmap
+void iounmap(volatile void __iomem *addr);
+#endif
+
+#ifndef ioremap_nocache
+static inline void __iomem *ioremap_nocache(resource_size_t offset,
+		unsigned long size)
+{
+	return ioremap(offset, size);
+}
+#endif
+
+#ifndef ioremap_wc
+static inline void __iomem *ioremap_wc(resource_size_t offset,
+		unsigned long size)
+{
+	return ioremap(offset, size);
+}
+#endif
+
+#ifndef ioremap_wt
+static inline void __iomem *ioremap_wt(resource_size_t offset,
+		unsigned long size)
+{
+	return ioremap(offset, size);
+}
+#endif
+
+#ifndef ioremap_cache
+static inline void __iomem *ioremap_cache(resource_size_t offset,
+		unsigned long size)
+{
+	return ioremap(offset, size);
+}
+#endif
+
+#ifndef ioremap_uc
+static inline void __iomem *ioremap_uc(resource_size_t offset,
+		unsigned long size)
+{
+	return ioremap(offset, size);
+}
+#endif
+
 /*
  * Some systems do not have legacy ISA devices.
  * /dev/port is not a valid interface on these systems.
diff --git a/lib/devres.c b/lib/devres.c
index fbe2aac522e6..e265b74ebbaa 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -4,6 +4,26 @@
 #include <linux/gfp.h>
 #include <linux/export.h>
 
+/*
+ * Throw warnings if an arch fails to define an ioremap symbol or uses an
+ * unexpected declaration.
+ */
+static void __always_unused ioremap_test(void)
+{
+	void __iomem *(*map)(resource_size_t offset, unsigned long size)
+		__always_unused;
+	void (*unmap)(volatile void __iomem *addr) __always_unused;
+
+	map = ioremap_nocache;
+	map = ioremap_cache;
+	map = ioremap_wc;
+	map = ioremap_wt;
+	map = ioremap_uc;
+	map = ioremap;
+
+	unmap = iounmap;
+}
+
 void devm_ioremap_release(struct device *dev, void *res)
 {
 	iounmap(*(void __iomem **)res);


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 06/10] cleanup IORESOURCE_CACHEABLE vs ioremap()
  2015-07-20  0:17 [PATCH 00/10] unify ioremap definitions and introduce memremap Dan Williams
                   ` (4 preceding siblings ...)
  2015-07-20  0:18 ` [PATCH 05/10] arch: unify ioremap prototypes and macro aliases Dan Williams
@ 2015-07-20  0:18 ` Dan Williams
  2015-07-20  0:18 ` [PATCH 07/10] devm: fix ioremap_cache() usage Dan Williams
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Dan Williams @ 2015-07-20  0:18 UTC (permalink / raw)
  To: tglx, mingo, hpa
  Cc: linux-arch, tony.luck, linux, arnd, benh, mcgrof, x86,
	linux-kernel, ralf, geert, toshi.kani, ross.zwisler, hch,
	linux-arm-kernel

Quoting Arnd:
    I was thinking the opposite approach and basically removing all uses
    of IORESOURCE_CACHEABLE from the kernel. There are only a handful of
    them.and we can probably replace them all with hardcoded
    ioremap_cached() calls in the cases they are actually useful.

All existing usages of IORESOURCE_CACHEABLE call ioremap() instead of
ioremap_nocache() if the resource is cacheable, however ioremap() is
uncached by default.  Clearly none of the existing usages care about the
cacheability, so let's clean that up before introducing generic
ioremap_cache() support across architectures.

Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/arm/mach-clps711x/board-cdb89712.c |    2 +-
 arch/powerpc/kernel/pci_of_scan.c       |    2 +-
 arch/sparc/kernel/pci.c                 |    3 +--
 drivers/pci/probe.c                     |    3 +--
 drivers/pnp/manager.c                   |    2 --
 drivers/scsi/aic94xx/aic94xx_init.c     |    7 +------
 drivers/scsi/arcmsr/arcmsr_hba.c        |    5 +----
 drivers/scsi/mvsas/mv_init.c            |   15 ++++-----------
 drivers/video/fbdev/ocfb.c              |    1 -
 lib/devres.c                            |    7 ++-----
 lib/pci_iomap.c                         |    7 ++-----
 11 files changed, 14 insertions(+), 40 deletions(-)

diff --git a/arch/arm/mach-clps711x/board-cdb89712.c b/arch/arm/mach-clps711x/board-cdb89712.c
index 1ec378c334e5..972abdb10028 100644
--- a/arch/arm/mach-clps711x/board-cdb89712.c
+++ b/arch/arm/mach-clps711x/board-cdb89712.c
@@ -95,7 +95,7 @@ static struct physmap_flash_data cdb89712_bootrom_pdata __initdata = {
 
 static struct resource cdb89712_bootrom_resources[] __initdata = {
 	DEFINE_RES_NAMED(CS7_PHYS_BASE, SZ_128, "BOOTROM", IORESOURCE_MEM |
-			 IORESOURCE_CACHEABLE | IORESOURCE_READONLY),
+			 IORESOURCE_READONLY),
 };
 
 static struct platform_device cdb89712_bootrom_pdev __initdata = {
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c
index 42e02a2d570b..d4726addff0b 100644
--- a/arch/powerpc/kernel/pci_of_scan.c
+++ b/arch/powerpc/kernel/pci_of_scan.c
@@ -102,7 +102,7 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev)
 			res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
 		} else if (i == dev->rom_base_reg) {
 			res = &dev->resource[PCI_ROM_RESOURCE];
-			flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE;
+			flags |= IORESOURCE_READONLY;
 		} else {
 			printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
 			continue;
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index c928bc64b4ba..04da147e0712 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -231,8 +231,7 @@ static void pci_parse_of_addrs(struct platform_device *op,
 			res = &dev->resource[(i - PCI_BASE_ADDRESS_0) >> 2];
 		} else if (i == dev->rom_base_reg) {
 			res = &dev->resource[PCI_ROM_RESOURCE];
-			flags |= IORESOURCE_READONLY | IORESOURCE_CACHEABLE
-			      | IORESOURCE_SIZEALIGN;
+			flags |= IORESOURCE_READONLY | IORESOURCE_SIZEALIGN;
 		} else {
 			printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i);
 			continue;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index cefd636681b6..8ed37dd04056 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -326,8 +326,7 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
 		struct resource *res = &dev->resource[PCI_ROM_RESOURCE];
 		dev->rom_base_reg = rom;
 		res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH |
-				IORESOURCE_READONLY | IORESOURCE_CACHEABLE |
-				IORESOURCE_SIZEALIGN;
+				IORESOURCE_READONLY | IORESOURCE_SIZEALIGN;
 		__pci_read_base(dev, pci_bar_mem32, res, rom);
 	}
 }
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c
index 9357aa779048..7ad3295752ef 100644
--- a/drivers/pnp/manager.c
+++ b/drivers/pnp/manager.c
@@ -97,8 +97,6 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx)
 	/* ??? rule->flags restricted to 8 bits, all tests bogus ??? */
 	if (!(rule->flags & IORESOURCE_MEM_WRITEABLE))
 		res->flags |= IORESOURCE_READONLY;
-	if (rule->flags & IORESOURCE_MEM_CACHEABLE)
-		res->flags |= IORESOURCE_CACHEABLE;
 	if (rule->flags & IORESOURCE_MEM_RANGELENGTH)
 		res->flags |= IORESOURCE_RANGELENGTH;
 	if (rule->flags & IORESOURCE_MEM_SHADOWABLE)
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c
index 4b135cca42a1..140cb8e6fea2 100644
--- a/drivers/scsi/aic94xx/aic94xx_init.c
+++ b/drivers/scsi/aic94xx/aic94xx_init.c
@@ -100,12 +100,7 @@ static int asd_map_memio(struct asd_ha_struct *asd_ha)
 				   pci_name(asd_ha->pcidev));
 			goto Err;
 		}
-		if (io_handle->flags & IORESOURCE_CACHEABLE)
-			io_handle->addr = ioremap(io_handle->start,
-						  io_handle->len);
-		else
-			io_handle->addr = ioremap_nocache(io_handle->start,
-							  io_handle->len);
+		io_handle->addr = ioremap(io_handle->start, io_handle->len);
 		if (!io_handle->addr) {
 			asd_printk("couldn't map MBAR%d of %s\n", i==0?0:1,
 				   pci_name(asd_ha->pcidev));
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index 914c39f9f388..e4f77cad9fd8 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -259,10 +259,7 @@ static bool arcmsr_remap_pciregion(struct AdapterControlBlock *acb)
 		addr = (unsigned long)pci_resource_start(pdev, 0);
 		range = pci_resource_len(pdev, 0);
 		flags = pci_resource_flags(pdev, 0);
-		if (flags & IORESOURCE_CACHEABLE)
-			mem_base0 = ioremap(addr, range);
-		else
-			mem_base0 = ioremap_nocache(addr, range);
+		mem_base0 = ioremap(addr, range);
 		if (!mem_base0) {
 			pr_notice("arcmsr%d: memory mapping region fail\n",
 				acb->host->host_no);
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
index d40d734aa53a..e654b5cec69e 100644
--- a/drivers/scsi/mvsas/mv_init.c
+++ b/drivers/scsi/mvsas/mv_init.c
@@ -324,13 +324,9 @@ int mvs_ioremap(struct mvs_info *mvi, int bar, int bar_ex)
 			goto err_out;
 
 		res_flag_ex = pci_resource_flags(pdev, bar_ex);
-		if (res_flag_ex & IORESOURCE_MEM) {
-			if (res_flag_ex & IORESOURCE_CACHEABLE)
-				mvi->regs_ex = ioremap(res_start, res_len);
-			else
-				mvi->regs_ex = ioremap_nocache(res_start,
-						res_len);
-		} else
+		if (res_flag_ex & IORESOURCE_MEM)
+			mvi->regs_ex = ioremap(res_start, res_len);
+		else
 			mvi->regs_ex = (void *)res_start;
 		if (!mvi->regs_ex)
 			goto err_out;
@@ -342,10 +338,7 @@ int mvs_ioremap(struct mvs_info *mvi, int bar, int bar_ex)
 		goto err_out;
 
 	res_flag = pci_resource_flags(pdev, bar);
-	if (res_flag & IORESOURCE_CACHEABLE)
-		mvi->regs = ioremap(res_start, res_len);
-	else
-		mvi->regs = ioremap_nocache(res_start, res_len);
+	mvi->regs = ioremap(res_start, res_len);
 
 	if (!mvi->regs) {
 		if (mvi->regs_ex && (res_flag_ex & IORESOURCE_MEM))
diff --git a/drivers/video/fbdev/ocfb.c b/drivers/video/fbdev/ocfb.c
index de9819660ca0..c9293aea8ec3 100644
--- a/drivers/video/fbdev/ocfb.c
+++ b/drivers/video/fbdev/ocfb.c
@@ -325,7 +325,6 @@ static int ocfb_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "I/O resource request failed\n");
 		return -ENXIO;
 	}
-	res->flags &= ~IORESOURCE_CACHEABLE;
 	fbdev->regs = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(fbdev->regs))
 		return PTR_ERR(fbdev->regs);
diff --git a/lib/devres.c b/lib/devres.c
index e265b74ebbaa..dafbad21bfab 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -173,11 +173,8 @@ void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res)
 		return IOMEM_ERR_PTR(-EBUSY);
 	}
 
-	if (res->flags & IORESOURCE_CACHEABLE)
-		dest_ptr = devm_ioremap(dev, res->start, size);
-	else
-		dest_ptr = devm_ioremap_nocache(dev, res->start, size);
-
+	/* FIXME: add devm_ioremap_cache support */
+	dest_ptr = devm_ioremap(dev, res->start, size);
 	if (!dest_ptr) {
 		dev_err(dev, "ioremap failed for resource %pR\n", res);
 		devm_release_mem_region(dev, res->start, size);
diff --git a/lib/pci_iomap.c b/lib/pci_iomap.c
index bcce5f149310..e1930dbab2da 100644
--- a/lib/pci_iomap.c
+++ b/lib/pci_iomap.c
@@ -41,11 +41,8 @@ void __iomem *pci_iomap_range(struct pci_dev *dev,
 		len = maxlen;
 	if (flags & IORESOURCE_IO)
 		return __pci_ioport_map(dev, start, len);
-	if (flags & IORESOURCE_MEM) {
-		if (flags & IORESOURCE_CACHEABLE)
-			return ioremap(start, len);
-		return ioremap_nocache(start, len);
-	}
+	if (flags & IORESOURCE_MEM)
+		return ioremap(start, len);
 	/* What? */
 	return NULL;
 }


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 07/10] devm: fix ioremap_cache() usage
  2015-07-20  0:17 [PATCH 00/10] unify ioremap definitions and introduce memremap Dan Williams
                   ` (5 preceding siblings ...)
  2015-07-20  0:18 ` [PATCH 06/10] cleanup IORESOURCE_CACHEABLE vs ioremap() Dan Williams
@ 2015-07-20  0:18 ` Dan Williams
  2015-07-20  0:18 ` [PATCH 08/10] arch: introduce strict_ioremap Dan Williams
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 24+ messages in thread
From: Dan Williams @ 2015-07-20  0:18 UTC (permalink / raw)
  To: tglx, mingo, hpa
  Cc: linux-arch, tony.luck, linux, arnd, benh, mcgrof, x86,
	linux-kernel, ralf, geert, toshi.kani, ross.zwisler, hch,
	linux-arm-kernel

Provide devm_ioremap_cache() and fix up devm_ioremap_resource() to
actually provide cacheable mappings.  On archs that implement
ioremap_cache() devm_ioremap_resource() is always silently falling back
to uncached when IORESOURCE_CACHEABLE is specified.

Cc: Toshi Kani <toshi.kani@hp.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 include/linux/io.h |    2 ++
 lib/devres.c       |   53 +++++++++++++++++++++++++---------------------------
 2 files changed, 27 insertions(+), 28 deletions(-)

diff --git a/include/linux/io.h b/include/linux/io.h
index a4b2c1b2aaee..58482241c95c 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -71,6 +71,8 @@ static inline void devm_ioport_unmap(struct device *dev, void __iomem *addr)
 
 void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
 			   resource_size_t size);
+void __iomem *devm_ioremap_cache(struct device *dev, resource_size_t offset,
+			   resource_size_t size);
 void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
 				   resource_size_t size);
 void __iomem *devm_ioremap_wc(struct device *dev, resource_size_t offset,
diff --git a/lib/devres.c b/lib/devres.c
index dafbad21bfab..eefdebd9f903 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -34,6 +34,8 @@ static int devm_ioremap_match(struct device *dev, void *res, void *match_data)
 	return *(void **)res == match_data;
 }
 
+typedef void __iomem *(*ioremap_fn)(resource_size_t offset, unsigned long size);
+
 /**
  * devm_ioremap - Managed ioremap()
  * @dev: Generic device to remap IO address for
@@ -42,8 +44,9 @@ static int devm_ioremap_match(struct device *dev, void *res, void *match_data)
  *
  * Managed ioremap().  Map is automatically unmapped on driver detach.
  */
-void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
-			   resource_size_t size)
+static void __iomem *devm_ioremap_type(struct device *dev,
+		resource_size_t offset, resource_size_t size,
+		ioremap_fn ioremap_type)
 {
 	void __iomem **ptr, *addr;
 
@@ -51,7 +54,7 @@ void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
 	if (!ptr)
 		return NULL;
 
-	addr = ioremap(offset, size);
+	addr = ioremap_type(offset, size);
 	if (addr) {
 		*ptr = addr;
 		devres_add(dev, ptr);
@@ -60,34 +63,25 @@ void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
 
 	return addr;
 }
+
+void __iomem *devm_ioremap(struct device *dev, resource_size_t offset,
+			   resource_size_t size)
+{
+	return devm_ioremap_type(dev, offset, size, ioremap);
+}
 EXPORT_SYMBOL(devm_ioremap);
 
-/**
- * devm_ioremap_nocache - Managed ioremap_nocache()
- * @dev: Generic device to remap IO address for
- * @offset: BUS offset to map
- * @size: Size of map
- *
- * Managed ioremap_nocache().  Map is automatically unmapped on driver
- * detach.
- */
+void __iomem *devm_ioremap_cache(struct device *dev, resource_size_t offset,
+			   resource_size_t size)
+{
+	return devm_ioremap_type(dev, offset, size, ioremap_cache);
+}
+EXPORT_SYMBOL(devm_ioremap_cache);
+
 void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
 				   resource_size_t size)
 {
-	void __iomem **ptr, *addr;
-
-	ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
-	if (!ptr)
-		return NULL;
-
-	addr = ioremap_nocache(offset, size);
-	if (addr) {
-		*ptr = addr;
-		devres_add(dev, ptr);
-	} else
-		devres_free(ptr);
-
-	return addr;
+	return devm_ioremap_type(dev, offset, size, ioremap_nocache);
 }
 EXPORT_SYMBOL(devm_ioremap_nocache);
 
@@ -173,8 +167,11 @@ void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res)
 		return IOMEM_ERR_PTR(-EBUSY);
 	}
 
-	/* FIXME: add devm_ioremap_cache support */
-	dest_ptr = devm_ioremap(dev, res->start, size);
+	if (res->flags & IORESOURCE_CACHEABLE)
+		dest_ptr = devm_ioremap_cache(dev, res->start, size);
+	else
+		dest_ptr = devm_ioremap_nocache(dev, res->start, size);
+
 	if (!dest_ptr) {
 		dev_err(dev, "ioremap failed for resource %pR\n", res);
 		devm_release_mem_region(dev, res->start, size);


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 08/10] arch: introduce strict_ioremap
  2015-07-20  0:17 [PATCH 00/10] unify ioremap definitions and introduce memremap Dan Williams
                   ` (6 preceding siblings ...)
  2015-07-20  0:18 ` [PATCH 07/10] devm: fix ioremap_cache() usage Dan Williams
@ 2015-07-20  0:18 ` Dan Williams
  2015-07-21 13:30   ` Christoph Hellwig
  2015-07-20  0:18 ` [PATCH 09/10] arch: introduce memremap() Dan Williams
  2015-07-20  0:18 ` [PATCH 10/10] pmem: convert to generic memremap Dan Williams
  9 siblings, 1 reply; 24+ messages in thread
From: Dan Williams @ 2015-07-20  0:18 UTC (permalink / raw)
  To: tglx, mingo, hpa
  Cc: linux-arch, tony.luck, linux, arnd, benh, mcgrof, x86,
	linux-kernel, ralf, geert, toshi.kani, ross.zwisler, hch,
	linux-arm-kernel

In preparation for enabling memremap(), add support for strict mappings.
strict_ioremap_<type>() returns NULL if the arch does not implement the
mapping type, rather than falling back silently to ioremap().

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 include/linux/io.h |   21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/include/linux/io.h b/include/linux/io.h
index 58482241c95c..080a4fbf2ba4 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -130,6 +130,27 @@ static inline void __iomem *ioremap_uc(resource_size_t offset,
 }
 #endif
 
+static inline void __iomem *strict_ioremap_cache(resource_size_t offset,
+		unsigned long size)
+{
+#ifdef ioremap_cache
+	return ioremap_cache(offset, size);
+#else
+	return (void __force __iomem *) NULL;
+#endif
+}
+
+static inline void __iomem *strict_ioremap_wt(resource_size_t offset,
+		unsigned long size)
+{
+#ifdef ioremap_wt
+	return ioremap_wt(offset, size);
+#else
+	return (void __force __iomem *) NULL;
+#endif
+}
+
+
 /*
  * Some systems do not have legacy ISA devices.
  * /dev/port is not a valid interface on these systems.


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 09/10] arch: introduce memremap()
  2015-07-20  0:17 [PATCH 00/10] unify ioremap definitions and introduce memremap Dan Williams
                   ` (7 preceding siblings ...)
  2015-07-20  0:18 ` [PATCH 08/10] arch: introduce strict_ioremap Dan Williams
@ 2015-07-20  0:18 ` Dan Williams
  2015-07-20 12:00   ` Mark Rutland
  2015-07-21 23:58   ` Luis R. Rodriguez
  2015-07-20  0:18 ` [PATCH 10/10] pmem: convert to generic memremap Dan Williams
  9 siblings, 2 replies; 24+ messages in thread
From: Dan Williams @ 2015-07-20  0:18 UTC (permalink / raw)
  To: tglx, mingo, hpa
  Cc: linux-arch, tony.luck, linux, arnd, benh, mcgrof, x86,
	linux-kernel, ralf, Andy Shevchenko, geert, toshi.kani,
	ross.zwisler, hch, linux-arm-kernel

Existing users of ioremap_cache() are mapping memory that is known in
advance to not have i/o side effects.  These users are forced to cast
away the __iomem annotation, or otherwise neglect to fix the sparse
errors thrown when dereferencing pointers to this memory.  Provide
memremap() as a non __iomem annotated ioremap_*() in the case when
ioremap is otherwise a pointer to memory.

The ARCH_HAS_MEMREMAP kconfig symbol is introduced for archs to assert
that it is safe to recast / reuse the return value from ioremap as a
normal pointer to memory.  In other words, archs that mandate specific
accessors for __iomem are not memremap() capable and drivers that care,
like pmem, can add a dependency to disable themselves on these archs.

Note, that memremap is a break from the ioremap implementation pattern
of adding a new memremap_<type>() for each mapping type.  Instead,
the implementation defines flags that are passed to the central
memremap() implementation.

Outside of ioremap() and ioremap_nocache(), the expectation is that most
calls to ioremap_<type>() are seeking memory-like semantics (e.g.
speculative reads, and prefetching permitted).  These callsites can be
moved to memremap() over time.

Cc: Arnd Bergmann <arnd@arndb.de>
Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/arm/Kconfig                     |    1 +
 arch/arm64/Kconfig                   |    1 +
 arch/arm64/kernel/efi.c              |    7 ++---
 arch/arm64/kernel/smp_spin_table.c   |   17 +++++------
 arch/frv/Kconfig                     |    1 +
 arch/m68k/Kconfig                    |    1 +
 arch/metag/Kconfig                   |    1 +
 arch/mips/Kconfig                    |    1 +
 arch/powerpc/Kconfig                 |    1 +
 arch/x86/Kconfig                     |    1 +
 arch/x86/kernel/crash_dump_64.c      |    6 ++--
 arch/x86/kernel/kdebugfs.c           |    8 +++--
 arch/x86/kernel/ksysfs.c             |   28 +++++++++----------
 arch/x86/mm/ioremap.c                |   10 +++----
 arch/xtensa/Kconfig                  |    1 +
 drivers/acpi/apei/einj.c             |    9 +++---
 drivers/acpi/apei/erst.c             |    6 ++--
 drivers/firmware/google/memconsole.c |    5 ++-
 include/linux/device.h               |    5 +++
 include/linux/io.h                   |   11 +++++++
 kernel/resource.c                    |   51 +++++++++++++++++++++++++++++++++-
 lib/Kconfig                          |    5 +++
 22 files changed, 126 insertions(+), 51 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 1c5021002fe4..1d64aae0a226 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -3,6 +3,7 @@ config ARM
 	default y
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select ARCH_HAS_ELF_RANDOMIZE
+	select ARCH_HAS_MEMREMAP
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_HAVE_CUSTOM_GPIO_H
 	select ARCH_HAS_GCOV_PROFILE_ALL
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 318175f62c24..305def28385f 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -6,6 +6,7 @@ config ARM64
 	select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_GCOV_PROFILE_ALL
+	select ARCH_HAS_MEMREMAP
 	select ARCH_HAS_SG_CHAIN
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_USE_CMPXCHG_LOCKREF
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 9d4aa18f2a82..ed363a0202b9 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -290,8 +290,7 @@ static int __init arm64_enable_runtime_services(void)
 	pr_info("Remapping and enabling EFI services.\n");
 
 	mapsize = memmap.map_end - memmap.map;
-	memmap.map = (__force void *)ioremap_cache((phys_addr_t)memmap.phys_map,
-						   mapsize);
+	memmap.map = memremap(memmap.phys_map, mapsize, MEMREMAP_CACHE);
 	if (!memmap.map) {
 		pr_err("Failed to remap EFI memory map\n");
 		return -1;
@@ -299,8 +298,8 @@ static int __init arm64_enable_runtime_services(void)
 	memmap.map_end = memmap.map + mapsize;
 	efi.memmap = &memmap;
 
-	efi.systab = (__force void *)ioremap_cache(efi_system_table,
-						   sizeof(efi_system_table_t));
+	efi.systab = memremap(efi_system_table, sizeof(efi_system_table_t),
+			MEMREMAP_CACHE);
 	if (!efi.systab) {
 		pr_err("Failed to remap EFI System Table\n");
 		return -1;
diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c
index aef3605a8c47..b9caf6cd44e6 100644
--- a/arch/arm64/kernel/smp_spin_table.c
+++ b/arch/arm64/kernel/smp_spin_table.c
@@ -73,19 +73,19 @@ static int smp_spin_table_cpu_init(unsigned int cpu)
 
 static int smp_spin_table_cpu_prepare(unsigned int cpu)
 {
-	__le64 __iomem *release_addr;
+	__le64 *release_addr;
 
 	if (!cpu_release_addr[cpu])
 		return -ENODEV;
 
 	/*
 	 * The cpu-release-addr may or may not be inside the linear mapping.
-	 * As ioremap_cache will either give us a new mapping or reuse the
-	 * existing linear mapping, we can use it to cover both cases. In
-	 * either case the memory will be MT_NORMAL.
+	 * As memremap will either give us a new mapping or reuse the existing
+	 * linear mapping, we can use it to cover both cases. In either case
+	 * the memory will be MT_NORMAL.
 	 */
-	release_addr = ioremap_cache(cpu_release_addr[cpu],
-				     sizeof(*release_addr));
+	release_addr = memremap(cpu_release_addr[cpu], sizeof(*release_addr),
+			MEMREMAP_CACHE);
 	if (!release_addr)
 		return -ENOMEM;
 
@@ -97,15 +97,14 @@ static int smp_spin_table_cpu_prepare(unsigned int cpu)
 	 * the boot protocol.
 	 */
 	writeq_relaxed(__pa(secondary_holding_pen), release_addr);
-	__flush_dcache_area((__force void *)release_addr,
-			    sizeof(*release_addr));
+	__flush_dcache_area(release_addr, sizeof(*release_addr));
 
 	/*
 	 * Send an event to wake up the secondary CPU.
 	 */
 	sev();
 
-	iounmap(release_addr);
+	memunmap(release_addr);
 
 	return 0;
 }
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index 34aa19352dc1..2373bf183527 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -14,6 +14,7 @@ config FRV
 	select OLD_SIGSUSPEND3
 	select OLD_SIGACTION
 	select HAVE_DEBUG_STACKOVERFLOW
+	select ARCH_HAS_MEMREMAP
 
 config ZONE_DMA
 	bool
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 2dd8f63bfbbb..831b1be8c43d 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -23,6 +23,7 @@ config M68K
 	select MODULES_USE_ELF_RELA
 	select OLD_SIGSUSPEND3
 	select OLD_SIGACTION
+	select ARCH_HAS_MEMREMAP
 
 config RWSEM_GENERIC_SPINLOCK
 	bool
diff --git a/arch/metag/Kconfig b/arch/metag/Kconfig
index 0b389a81c43a..5669fe3eb807 100644
--- a/arch/metag/Kconfig
+++ b/arch/metag/Kconfig
@@ -24,6 +24,7 @@ config METAG
 	select HAVE_PERF_EVENTS
 	select HAVE_SYSCALL_TRACEPOINTS
 	select HAVE_UNDERSCORE_SYMBOL_PREFIX
+	select ARCH_HAS_MEMREMAP
 	select IRQ_DOMAIN
 	select MODULES_USE_ELF_RELA
 	select OF
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index aab7e46cadd5..ac9da90931b9 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -59,6 +59,7 @@ config MIPS
 	select SYSCTL_EXCEPTION_TRACE
 	select HAVE_VIRT_CPU_ACCOUNTING_GEN
 	select HAVE_IRQ_TIME_ACCOUNTING
+	select ARCH_HAS_MEMREMAP
 
 menu "Machine selection"
 
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 5ef27113b898..50889c7b5c81 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -89,6 +89,7 @@ config PPC
 	select ARCH_MIGHT_HAVE_PC_SERIO
 	select BINFMT_ELF
 	select ARCH_HAS_ELF_RANDOMIZE
+	select ARCH_HAS_MEMREMAP
 	select OF
 	select OF_EARLY_FLATTREE
 	select OF_RESERVED_MEM
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 3dbb7e7909ca..80eb19c8b62d 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -27,6 +27,7 @@ config X86
 	select ARCH_HAS_ELF_RANDOMIZE
 	select ARCH_HAS_FAST_MULTIPLIER
 	select ARCH_HAS_GCOV_PROFILE_ALL
+	select ARCH_HAS_MEMREMAP
 	select ARCH_HAS_PMEM_API
 	select ARCH_HAS_SG_CHAIN
 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c
index afa64adb75ee..b87ca059e5fc 100644
--- a/arch/x86/kernel/crash_dump_64.c
+++ b/arch/x86/kernel/crash_dump_64.c
@@ -31,19 +31,19 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
 	if (!csize)
 		return 0;
 
-	vaddr = ioremap_cache(pfn << PAGE_SHIFT, PAGE_SIZE);
+	vaddr = memremap(pfn << PAGE_SHIFT, PAGE_SIZE, MEMREMAP_CACHE);
 	if (!vaddr)
 		return -ENOMEM;
 
 	if (userbuf) {
 		if (copy_to_user(buf, vaddr + offset, csize)) {
-			iounmap(vaddr);
+			memunmap(vaddr);
 			return -EFAULT;
 		}
 	} else
 		memcpy(buf, vaddr + offset, csize);
 
 	set_iounmap_nonlazy();
-	iounmap(vaddr);
+	memunmap(vaddr);
 	return csize;
 }
diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c
index dc1404bf8e4b..a2248482c14b 100644
--- a/arch/x86/kernel/kdebugfs.c
+++ b/arch/x86/kernel/kdebugfs.c
@@ -49,7 +49,7 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf,
 	pa = node->paddr + sizeof(struct setup_data) + pos;
 	pg = pfn_to_page((pa + count - 1) >> PAGE_SHIFT);
 	if (PageHighMem(pg)) {
-		p = ioremap_cache(pa, count);
+		p = memremap(pa, count, MEMREMAP_CACHE);
 		if (!p)
 			return -ENXIO;
 	} else
@@ -58,7 +58,7 @@ static ssize_t setup_data_read(struct file *file, char __user *user_buf,
 	remain = copy_to_user(user_buf, p, count);
 
 	if (PageHighMem(pg))
-		iounmap(p);
+		memunmap(p);
 
 	if (remain)
 		return -EFAULT;
@@ -128,7 +128,7 @@ static int __init create_setup_data_nodes(struct dentry *parent)
 
 		pg = pfn_to_page((pa_data+sizeof(*data)-1) >> PAGE_SHIFT);
 		if (PageHighMem(pg)) {
-			data = ioremap_cache(pa_data, sizeof(*data));
+			data = memremap(pa_data, sizeof(*data), MEMREMAP_CACHE);
 			if (!data) {
 				kfree(node);
 				error = -ENXIO;
@@ -144,7 +144,7 @@ static int __init create_setup_data_nodes(struct dentry *parent)
 		pa_data = data->next;
 
 		if (PageHighMem(pg))
-			iounmap(data);
+			memunmap(data);
 		if (error)
 			goto err_dir;
 		no++;
diff --git a/arch/x86/kernel/ksysfs.c b/arch/x86/kernel/ksysfs.c
index c2bedaea11f7..d2670bb75a08 100644
--- a/arch/x86/kernel/ksysfs.c
+++ b/arch/x86/kernel/ksysfs.c
@@ -16,8 +16,8 @@
 #include <linux/stat.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
+#include <linux/io.h>
 
-#include <asm/io.h>
 #include <asm/setup.h>
 
 static ssize_t version_show(struct kobject *kobj,
@@ -79,12 +79,12 @@ static int get_setup_data_paddr(int nr, u64 *paddr)
 			*paddr = pa_data;
 			return 0;
 		}
-		data = ioremap_cache(pa_data, sizeof(*data));
+		data = memremap(pa_data, sizeof(*data), MEMREMAP_CACHE);
 		if (!data)
 			return -ENOMEM;
 
 		pa_data = data->next;
-		iounmap(data);
+		memunmap(data);
 		i++;
 	}
 	return -EINVAL;
@@ -97,17 +97,17 @@ static int __init get_setup_data_size(int nr, size_t *size)
 	u64 pa_data = boot_params.hdr.setup_data;
 
 	while (pa_data) {
-		data = ioremap_cache(pa_data, sizeof(*data));
+		data = memremap(pa_data, sizeof(*data), MEMREMAP_CACHE);
 		if (!data)
 			return -ENOMEM;
 		if (nr == i) {
 			*size = data->len;
-			iounmap(data);
+			memunmap(data);
 			return 0;
 		}
 
 		pa_data = data->next;
-		iounmap(data);
+		memunmap(data);
 		i++;
 	}
 	return -EINVAL;
@@ -127,12 +127,12 @@ static ssize_t type_show(struct kobject *kobj,
 	ret = get_setup_data_paddr(nr, &paddr);
 	if (ret)
 		return ret;
-	data = ioremap_cache(paddr, sizeof(*data));
+	data = memremap(paddr, sizeof(*data), MEMREMAP_CACHE);
 	if (!data)
 		return -ENOMEM;
 
 	ret = sprintf(buf, "0x%x\n", data->type);
-	iounmap(data);
+	memunmap(data);
 	return ret;
 }
 
@@ -154,7 +154,7 @@ static ssize_t setup_data_data_read(struct file *fp,
 	ret = get_setup_data_paddr(nr, &paddr);
 	if (ret)
 		return ret;
-	data = ioremap_cache(paddr, sizeof(*data));
+	data = memremap(paddr, sizeof(*data), MEMREMAP_CACHE);
 	if (!data)
 		return -ENOMEM;
 
@@ -170,15 +170,15 @@ static ssize_t setup_data_data_read(struct file *fp,
 		goto out;
 
 	ret = count;
-	p = ioremap_cache(paddr + sizeof(*data), data->len);
+	p = memremap(paddr + sizeof(*data), data->len, MEMREMAP_CACHE);
 	if (!p) {
 		ret = -ENOMEM;
 		goto out;
 	}
 	memcpy(buf, p + off, count);
-	iounmap(p);
+	memunmap(p);
 out:
-	iounmap(data);
+	memunmap(data);
 	return ret;
 }
 
@@ -250,13 +250,13 @@ static int __init get_setup_data_total_num(u64 pa_data, int *nr)
 	*nr = 0;
 	while (pa_data) {
 		*nr += 1;
-		data = ioremap_cache(pa_data, sizeof(*data));
+		data = memremap(pa_data, sizeof(*data), MEMREMAP_CACHE);
 		if (!data) {
 			ret = -ENOMEM;
 			goto out;
 		}
 		pa_data = data->next;
-		iounmap(data);
+		memunmap(data);
 	}
 
 out:
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index ccf5c867b2eb..4920f735f551 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -401,12 +401,10 @@ void *xlate_dev_mem_ptr(phys_addr_t phys)
 	if (page_is_ram(start >> PAGE_SHIFT))
 		return __va(phys);
 
-	vaddr = ioremap_cache(start, PAGE_SIZE);
-	/* Only add the offset on success and return NULL if the ioremap() failed: */
+	vaddr = memremap(start, PAGE_SIZE, MEMREMAP_CACHE);
 	if (vaddr)
-		vaddr += offset;
-
-	return vaddr;
+		return vaddr + offset;
+	return NULL;
 }
 
 void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr)
@@ -414,7 +412,7 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr)
 	if (page_is_ram(phys >> PAGE_SHIFT))
 		return;
 
-	iounmap((void __iomem *)((unsigned long)addr & PAGE_MASK));
+	memunmap((void *)((unsigned long)addr & PAGE_MASK));
 }
 
 static pte_t bm_pte[PAGE_SIZE/sizeof(pte_t)] __page_aligned_bss;
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index e5b872ba2484..da1078692c41 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -3,6 +3,7 @@ config ZONE_DMA
 
 config XTENSA
 	def_bool y
+	select ARCH_HAS_MEMREMAP
 	select ARCH_WANT_FRAME_POINTERS
 	select ARCH_WANT_IPC_PARSE_VERSION
 	select ARCH_WANT_OPTIONAL_GPIOLIB
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index a095d4f858da..d4992fea6994 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -318,7 +318,8 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type,
 			    sizeof(*trigger_tab) - 1);
 		goto out;
 	}
-	trigger_tab = ioremap_cache(trigger_paddr, sizeof(*trigger_tab));
+	trigger_tab = memremap(trigger_paddr, sizeof(*trigger_tab),
+			MEMREMAP_CACHE);
 	if (!trigger_tab) {
 		pr_err(EINJ_PFX "Failed to map trigger table!\n");
 		goto out_rel_header;
@@ -346,8 +347,8 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type,
 		       (unsigned long long)trigger_paddr + table_size - 1);
 		goto out_rel_header;
 	}
-	iounmap(trigger_tab);
-	trigger_tab = ioremap_cache(trigger_paddr, table_size);
+	memunmap(trigger_tab);
+	trigger_tab = memremap(trigger_paddr, table_size, MEMREMAP_CACHE);
 	if (!trigger_tab) {
 		pr_err(EINJ_PFX "Failed to map trigger table!\n");
 		goto out_rel_entry;
@@ -409,7 +410,7 @@ out_rel_header:
 	release_mem_region(trigger_paddr, sizeof(*trigger_tab));
 out:
 	if (trigger_tab)
-		iounmap(trigger_tab);
+		memunmap(trigger_tab);
 
 	return rc;
 }
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index 3670bbab57a3..dc49b0b42d65 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -77,7 +77,7 @@ static struct acpi_table_erst *erst_tab;
 static struct erst_erange {
 	u64 base;
 	u64 size;
-	void __iomem *vaddr;
+	void *vaddr;
 	u32 attr;
 } erst_erange;
 
@@ -1185,8 +1185,8 @@ static int __init erst_init(void)
 		goto err_unmap_reg;
 	}
 	rc = -ENOMEM;
-	erst_erange.vaddr = ioremap_cache(erst_erange.base,
-					  erst_erange.size);
+	erst_erange.vaddr = memremap(erst_erange.base, erst_erange.size,
+			MEMREMAP_CACHE);
 	if (!erst_erange.vaddr)
 		goto err_release_erange;
 
diff --git a/drivers/firmware/google/memconsole.c b/drivers/firmware/google/memconsole.c
index 2f569aaed4c7..2b8160d12ad6 100644
--- a/drivers/firmware/google/memconsole.c
+++ b/drivers/firmware/google/memconsole.c
@@ -52,14 +52,15 @@ static ssize_t memconsole_read(struct file *filp, struct kobject *kobp,
 	char *memconsole;
 	ssize_t ret;
 
-	memconsole = ioremap_cache(memconsole_baseaddr, memconsole_length);
+	memconsole = memremap(memconsole_baseaddr, memconsole_length,
+			MEMREMAP_CACHE);
 	if (!memconsole) {
 		pr_err("memconsole: ioremap_cache failed\n");
 		return -ENOMEM;
 	}
 	ret = memory_read_from_buffer(buf, count, &pos, memconsole,
 				      memconsole_length);
-	iounmap(memconsole);
+	memunmap(memconsole);
 	return ret;
 }
 
diff --git a/include/linux/device.h b/include/linux/device.h
index 5a31bf3a4024..04e53eab71c5 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -668,6 +668,11 @@ extern void devm_free_pages(struct device *dev, unsigned long addr);
 
 void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res);
 
+static inline void *devm_memremap_resource(struct device *dev, struct resource *res)
+{
+	return (void __force *) devm_ioremap_resource(dev, res);
+}
+
 /* allows to add/remove a custom action to devres stack */
 int devm_add_action(struct device *dev, void (*action)(void *), void *data);
 void devm_remove_action(struct device *dev, void (*action)(void *), void *data);
diff --git a/include/linux/io.h b/include/linux/io.h
index 080a4fbf2ba4..2983b6e63970 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -192,4 +192,15 @@ static inline int arch_phys_wc_index(int handle)
 #endif
 #endif
 
+enum {
+	MEMREMAP_WB = 1 << 0,
+	MEMREMAP_WT = 1 << 1,
+	MEMREMAP_WC = 1 << 2,
+	MEMREMAP_STRICT = 1 << 3,
+	MEMREMAP_CACHE = MEMREMAP_WB,
+};
+
+extern void *memremap(resource_size_t offset, size_t size, unsigned long flags);
+extern void memunmap(void *addr);
+
 #endif /* _LINUX_IO_H */
diff --git a/kernel/resource.c b/kernel/resource.c
index fed052a1bc9f..a96376be513a 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -23,7 +23,7 @@
 #include <linux/pfn.h>
 #include <linux/mm.h>
 #include <linux/resource_ext.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 
 struct resource ioport_resource = {
@@ -528,6 +528,55 @@ int region_is_ram(resource_size_t start, unsigned long size)
 	return ret;
 }
 
+#ifdef CONFIG_ARCH_HAS_MEMREMAP
+/*
+ * memremap() is "ioremap" for cases where it is known that the resource
+ * being mapped does not have i/o side effects and the __iomem
+ * annotation is not applicable.
+ */
+static bool memremap_valid(resource_size_t offset, size_t size)
+{
+	if (region_is_ram(offset, size) != 0) {
+		WARN_ONCE(1, "memremap attempted on ram %pa size: %zu\n",
+				&offset, size);
+		return false;
+	}
+	return true;
+}
+
+void *memremap(resource_size_t offset, size_t size, unsigned long flags)
+{
+	void __iomem *addr = NULL;
+
+	if (!memremap_valid(offset, size))
+		return NULL;
+
+	/* try all mapping types requested until one returns non-NULL */
+	if (flags & MEMREMAP_CACHE) {
+		if (flags & MEMREMAP_STRICT)
+			addr = strict_ioremap_cache(offset, size);
+		else
+			addr = ioremap_cache(offset, size);
+	}
+
+	if (!addr && (flags & MEMREMAP_WT)) {
+		if (flags & MEMREMAP_STRICT)
+			addr = strict_ioremap_wt(offset, size);
+		else
+			addr = ioremap_wt(offset, size);
+	}
+
+	return (void __force *) addr;
+}
+EXPORT_SYMBOL(memremap);
+
+void memunmap(void *addr)
+{
+	iounmap((void __iomem __force *) addr);
+}
+EXPORT_SYMBOL(memunmap);
+#endif /* CONFIG_ARCH_HAS_MEMREMAP */
+
 void __weak arch_remove_reservations(struct resource *avail)
 {
 }
diff --git a/lib/Kconfig b/lib/Kconfig
index 3a2ef67db6c7..097b99073924 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -526,7 +526,10 @@ source "lib/fonts/Kconfig"
 #
 
 config ARCH_HAS_SG_CHAIN
-	def_bool n
+	bool
+
+config ARCH_HAS_MEMREMAP
+	bool
 
 config ARCH_HAS_PMEM_API
 	bool


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 10/10] pmem: convert to generic memremap
  2015-07-20  0:17 [PATCH 00/10] unify ioremap definitions and introduce memremap Dan Williams
                   ` (8 preceding siblings ...)
  2015-07-20  0:18 ` [PATCH 09/10] arch: introduce memremap() Dan Williams
@ 2015-07-20  0:18 ` Dan Williams
  9 siblings, 0 replies; 24+ messages in thread
From: Dan Williams @ 2015-07-20  0:18 UTC (permalink / raw)
  To: tglx, mingo, hpa
  Cc: linux-arch, tony.luck, linux, arnd, benh, mcgrof, x86,
	linux-kernel, ralf, geert, toshi.kani, ross.zwisler, hch,
	linux-arm-kernel

Update memremap_pmem() to query the architecture for the mapping type of
the given persistent memory range  and then pass those flags to generic
memremap().  arch_memremap_pmem_flags() is provided an address range to
evaluate in the event an arch has a need for different mapping types by
address range.  For example the ACPI NFIT carries EFI mapping types in
its memory range description table.

Cc: Ross Zwisler <ross.zwisler@linux.intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 arch/x86/include/asm/io.h         |    7 +------
 arch/x86/mm/ioremap.c             |   10 ++++++++++
 drivers/nvdimm/pmem.c             |    2 +-
 include/linux/pmem.h              |   29 ++++++++++++++---------------
 tools/testing/nvdimm/Kbuild       |    4 ++--
 tools/testing/nvdimm/test/iomap.c |   34 +++++++++++++++++++++++++---------
 6 files changed, 53 insertions(+), 33 deletions(-)

diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index d0817f2762ab..3ca5d45b52b8 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -250,12 +250,7 @@ static inline void flush_write_buffers(void)
 #endif
 }
 
-static inline void __pmem *arch_memremap_pmem(resource_size_t offset,
-	unsigned long size)
-{
-	return (void __force __pmem *) ioremap_cache(offset, size);
-}
-
+unsigned long arch_memremap_pmem_flags(resource_size_t offset, size_t size);
 #endif /* __KERNEL__ */
 
 extern void native_io_delay(void);
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 4920f735f551..640e4c334836 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -203,6 +203,16 @@ err_free_memtype:
 	return NULL;
 }
 
+unsigned long arch_memremap_pmem_flags(resource_size_t offset, size_t size)
+{
+	/*
+	 * TODO: check the mapping type provided by platform firmware,
+	 * per range.
+	 */
+	return MEMREMAP_CACHE | MEMREMAP_STRICT;
+}
+EXPORT_SYMBOL(arch_memremap_pmem_flags);
+
 /**
  * ioremap_nocache     -   map bus memory into CPU space
  * @phys_addr:    bus address of the memory
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index ade9eb917a4d..bdc35110783f 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -211,7 +211,7 @@ static int pmem_rw_bytes(struct nd_namespace_common *ndns,
 
 static void pmem_free(struct pmem_device *pmem)
 {
-	memunmap_pmem(pmem->virt_addr);
+	memunmap(pmem->virt_addr);
 	release_mem_region(pmem->phys_addr, pmem->size);
 	kfree(pmem);
 }
diff --git a/include/linux/pmem.h b/include/linux/pmem.h
index d2114045a6c4..28a0b989f46d 100644
--- a/include/linux/pmem.h
+++ b/include/linux/pmem.h
@@ -28,10 +28,10 @@ static inline bool __arch_has_wmb_pmem(void)
 	return false;
 }
 
-static inline void __pmem *arch_memremap_pmem(resource_size_t offset,
+static inline unsigned long arch_memremap_pmem_flags(resource_size_t offset,
 		unsigned long size)
 {
-	return NULL;
+	return 0;
 }
 
 static inline void arch_memcpy_to_pmem(void __pmem *dst, const void *src,
@@ -43,8 +43,8 @@ static inline void arch_memcpy_to_pmem(void __pmem *dst, const void *src,
 
 /*
  * Architectures that define ARCH_HAS_PMEM_API must provide
- * implementations for arch_memremap_pmem(), arch_memcpy_to_pmem(),
- * arch_wmb_pmem(), and __arch_has_wmb_pmem().
+ * implementations for arch_memremap_pmem_flags(),
+ * arch_memcpy_to_pmem(), arch_wmb_pmem(), and __arch_has_wmb_pmem().
  */
 
 static inline void memcpy_from_pmem(void *dst, void __pmem const *src, size_t size)
@@ -52,11 +52,6 @@ static inline void memcpy_from_pmem(void *dst, void __pmem const *src, size_t si
 	memcpy(dst, (void __force const *) src, size);
 }
 
-static inline void memunmap_pmem(void __pmem *addr)
-{
-	iounmap((void __force __iomem *) addr);
-}
-
 /**
  * arch_has_wmb_pmem - true if wmb_pmem() ensures durability
  *
@@ -85,16 +80,15 @@ static inline bool arch_has_pmem_api(void)
  * default_memremap_pmem + default_memcpy_to_pmem is sufficient for
  * making data durable relative to i/o completion.
  */
-static void default_memcpy_to_pmem(void __pmem *dst, const void *src,
+static inline void default_memcpy_to_pmem(void __pmem *dst, const void *src,
 		size_t size)
 {
 	memcpy((void __force *) dst, src, size);
 }
 
-static void __pmem *default_memremap_pmem(resource_size_t offset,
-		unsigned long size)
+static inline unsigned long default_memremap_pmem_flags(void)
 {
-	return (void __pmem __force *)ioremap_wt(offset, size);
+	return MEMREMAP_WT | MEMREMAP_STRICT;
 }
 
 /**
@@ -112,9 +106,14 @@ static void __pmem *default_memremap_pmem(resource_size_t offset,
 static inline void __pmem *memremap_pmem(resource_size_t offset,
 		unsigned long size)
 {
+	unsigned long flags;
+
 	if (arch_has_pmem_api())
-		return arch_memremap_pmem(offset, size);
-	return default_memremap_pmem(offset, size);
+		flags = arch_memremap_pmem_flags(offset, size);
+	else
+		flags = default_memremap_pmem_flags();
+
+	return (void __pmem *) memremap(offset, size, flags);
 }
 
 /**
diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild
index f56914c7929b..8c0f9fc72d6e 100644
--- a/tools/testing/nvdimm/Kbuild
+++ b/tools/testing/nvdimm/Kbuild
@@ -1,9 +1,9 @@
-ldflags-y += --wrap=ioremap_wt
 ldflags-y += --wrap=ioremap_wc
 ldflags-y += --wrap=devm_ioremap_nocache
-ldflags-y += --wrap=ioremap_cache
 ldflags-y += --wrap=ioremap_nocache
 ldflags-y += --wrap=iounmap
+ldflags-y += --wrap=memremap
+ldflags-y += --wrap=memunmap
 ldflags-y += --wrap=__request_region
 ldflags-y += --wrap=__release_region
 
diff --git a/tools/testing/nvdimm/test/iomap.c b/tools/testing/nvdimm/test/iomap.c
index 64bfaa50831c..21288f34a5ca 100644
--- a/tools/testing/nvdimm/test/iomap.c
+++ b/tools/testing/nvdimm/test/iomap.c
@@ -80,11 +80,20 @@ void __iomem *__wrap_devm_ioremap_nocache(struct device *dev,
 }
 EXPORT_SYMBOL(__wrap_devm_ioremap_nocache);
 
-void __iomem *__wrap_ioremap_cache(resource_size_t offset, unsigned long size)
+void *__wrap_memremap(resource_size_t offset, size_t size,
+		unsigned long flags)
 {
-	return __nfit_test_ioremap(offset, size, ioremap_cache);
+	struct nfit_test_resource *nfit_res;
+
+	rcu_read_lock();
+	nfit_res = get_nfit_res(offset);
+	rcu_read_unlock();
+	if (nfit_res)
+		return (void __iomem *) nfit_res->buf + offset
+			- nfit_res->res->start;
+	return memremap(offset, size, flags);
 }
-EXPORT_SYMBOL(__wrap_ioremap_cache);
+EXPORT_SYMBOL(__wrap_memremap);
 
 void __iomem *__wrap_ioremap_nocache(resource_size_t offset, unsigned long size)
 {
@@ -92,12 +101,6 @@ void __iomem *__wrap_ioremap_nocache(resource_size_t offset, unsigned long size)
 }
 EXPORT_SYMBOL(__wrap_ioremap_nocache);
 
-void __iomem *__wrap_ioremap_wt(resource_size_t offset, unsigned long size)
-{
-	return __nfit_test_ioremap(offset, size, ioremap_wt);
-}
-EXPORT_SYMBOL(__wrap_ioremap_wt);
-
 void __iomem *__wrap_ioremap_wc(resource_size_t offset, unsigned long size)
 {
 	return __nfit_test_ioremap(offset, size, ioremap_wc);
@@ -117,6 +120,19 @@ void __wrap_iounmap(volatile void __iomem *addr)
 }
 EXPORT_SYMBOL(__wrap_iounmap);
 
+void __wrap_memunmap(void *addr)
+{
+	struct nfit_test_resource *nfit_res;
+
+	rcu_read_lock();
+	nfit_res = get_nfit_res((unsigned long) addr);
+	rcu_read_unlock();
+	if (nfit_res)
+		return;
+	return memunmap(addr);
+}
+EXPORT_SYMBOL(__wrap_memunmap);
+
 struct resource *__wrap___request_region(struct resource *parent,
 		resource_size_t start, resource_size_t n, const char *name,
 		int flags)


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH 09/10] arch: introduce memremap()
  2015-07-20  0:18 ` [PATCH 09/10] arch: introduce memremap() Dan Williams
@ 2015-07-20 12:00   ` Mark Rutland
  2015-07-20 14:39     ` Dan Williams
  2015-07-21 23:58   ` Luis R. Rodriguez
  1 sibling, 1 reply; 24+ messages in thread
From: Mark Rutland @ 2015-07-20 12:00 UTC (permalink / raw)
  To: Dan Williams
  Cc: tglx, mingo, hpa, linux-arch, tony.luck, linux, arnd, benh,
	mcgrof, x86, linux-kernel, ralf, Andy Shevchenko, geert,
	toshi.kani, ross.zwisler, hch, linux-arm-kernel, will.deacon,
	catalin.marinas

Hi,

On Mon, Jul 20, 2015 at 01:18:23AM +0100, Dan Williams wrote:
> Existing users of ioremap_cache() are mapping memory that is known in
> advance to not have i/o side effects.  These users are forced to cast
> away the __iomem annotation, or otherwise neglect to fix the sparse
> errors thrown when dereferencing pointers to this memory.  Provide
> memremap() as a non __iomem annotated ioremap_*() in the case when
> ioremap is otherwise a pointer to memory.
> 
> The ARCH_HAS_MEMREMAP kconfig symbol is introduced for archs to assert
> that it is safe to recast / reuse the return value from ioremap as a
> normal pointer to memory.  In other words, archs that mandate specific
> accessors for __iomem are not memremap() capable and drivers that care,
> like pmem, can add a dependency to disable themselves on these archs.
> 
> Note, that memremap is a break from the ioremap implementation pattern
> of adding a new memremap_<type>() for each mapping type.  Instead,
> the implementation defines flags that are passed to the central
> memremap() implementation.
> 
> Outside of ioremap() and ioremap_nocache(), the expectation is that most
> calls to ioremap_<type>() are seeking memory-like semantics (e.g.
> speculative reads, and prefetching permitted).  These callsites can be
> moved to memremap() over time.
> 
> Cc: Arnd Bergmann <arnd@arndb.de>
> Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> ---
>  arch/arm/Kconfig                     |    1 +
>  arch/arm64/Kconfig                   |    1 +
>  arch/arm64/kernel/efi.c              |    7 ++---
>  arch/arm64/kernel/smp_spin_table.c   |   17 +++++------

These last two files weren't updated in patch 2 to use <linux/io.h>, nor are
they updated here, so this patch breaks the build for arm64.

[...]

> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 318175f62c24..305def28385f 100644
> --- a/arch/arm64/Kconfig
> +++ b/arch/arm64/Kconfig
> @@ -6,6 +6,7 @@ config ARM64
>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>         select ARCH_HAS_ELF_RANDOMIZE
>         select ARCH_HAS_GCOV_PROFILE_ALL
> +       select ARCH_HAS_MEMREMAP
>         select ARCH_HAS_SG_CHAIN
>         select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
>         select ARCH_USE_CMPXCHG_LOCKREF
> diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
> index 9d4aa18f2a82..ed363a0202b9 100644
> --- a/arch/arm64/kernel/efi.c
> +++ b/arch/arm64/kernel/efi.c
> @@ -290,8 +290,7 @@ static int __init arm64_enable_runtime_services(void)
>         pr_info("Remapping and enabling EFI services.\n");
> 
>         mapsize = memmap.map_end - memmap.map;
> -       memmap.map = (__force void *)ioremap_cache((phys_addr_t)memmap.phys_map,
> -                                                  mapsize);
> +       memmap.map = memremap(memmap.phys_map, mapsize, MEMREMAP_CACHE);

memmap.phys_map is a void*, so we need to retain a cast to a numeric type or
we'll get splats like:

arch/arm64/kernel/efi.c: In function ‘arm64_enable_runtime_services’:
arch/arm64/kernel/efi.c:294:24: warning: passing argument 1 of ‘memremap’ makes integer from pointer without a cast
  memmap.map = memremap(memmap.phys_map, mapsize, MEMREMAP_CACHE);
                        ^
In file included from arch/arm64/kernel/efi.c:18:0:
include/linux/io.h:203:14: note: expected ‘resource_size_t’ but argument is of type ‘void *’
 extern void *memremap(resource_size_t offset, size_t size, unsigned long flags);
              ^
Unfortunately, even with that fixed this patch breaks boot due to the
memremap_valid check. It's extremely likely that (portions of) the
tables are already in the linear mapping, and so page_is_ram will be
true.

At boot time I get the following:

Remapping and enabling EFI services.
------------[ cut here ]------------
WARNING: CPU: 0 PID: 1 at kernel/resource.c:541 memremap+0xb0/0xbc()
memremap attempted on ram 0x00000009f9e4a018 size: 1200
Modules linked in:
CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.2.0-rc3+ #201
Hardware name: ARM Juno development board (r0) (DT)
Call trace:
[<ffffffc000089954>] dump_backtrace+0x0/0x124
[<ffffffc000089a88>] show_stack+0x10/0x1c
[<ffffffc0005d15c8>] dump_stack+0x84/0xc8
[<ffffffc0000b3f44>] warn_slowpath_common+0x98/0xd0
[<ffffffc0000b3fc8>] warn_slowpath_fmt+0x4c/0x58
[<ffffffc0000b9470>] memremap+0xac/0xbc
[<ffffffc000814fe8>] arm64_enable_runtime_services+0x90/0x208
[<ffffffc000082864>] do_one_initcall+0x88/0x1a0
[<ffffffc000811a20>] kernel_init_freeable+0x8c/0x1f8
[<ffffffc0005ce370>] kernel_init+0xc/0xd8
---[ end trace cb88537fdc8fa200 ]---
Failed to remap EFI memory map

>         if (!memmap.map) {
>                 pr_err("Failed to remap EFI memory map\n");
>                 return -1;
> @@ -299,8 +298,8 @@ static int __init arm64_enable_runtime_services(void)
>         memmap.map_end = memmap.map + mapsize;
>         efi.memmap = &memmap;
> 
> -       efi.systab = (__force void *)ioremap_cache(efi_system_table,
> -                                                  sizeof(efi_system_table_t));
> +       efi.systab = memremap(efi_system_table, sizeof(efi_system_table_t),
> +                       MEMREMAP_CACHE);
>         if (!efi.systab) {
>                 pr_err("Failed to remap EFI System Table\n");
>                 return -1;
> diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c
> index aef3605a8c47..b9caf6cd44e6 100644
> --- a/arch/arm64/kernel/smp_spin_table.c
> +++ b/arch/arm64/kernel/smp_spin_table.c
> @@ -73,19 +73,19 @@ static int smp_spin_table_cpu_init(unsigned int cpu)
> 
>  static int smp_spin_table_cpu_prepare(unsigned int cpu)
>  {
> -       __le64 __iomem *release_addr;
> +       __le64 *release_addr;
> 
>         if (!cpu_release_addr[cpu])
>                 return -ENODEV;
> 
>         /*
>          * The cpu-release-addr may or may not be inside the linear mapping.
> -        * As ioremap_cache will either give us a new mapping or reuse the
> -        * existing linear mapping, we can use it to cover both cases. In
> -        * either case the memory will be MT_NORMAL.
> +        * As memremap will either give us a new mapping or reuse the existing
> +        * linear mapping, we can use it to cover both cases. In either case
> +        * the memory will be MT_NORMAL.
>          */
> -       release_addr = ioremap_cache(cpu_release_addr[cpu],
> -                                    sizeof(*release_addr));
> +       release_addr = memremap(cpu_release_addr[cpu], sizeof(*release_addr),
> +                       MEMREMAP_CACHE);

Likewise, the comment here is contradicted by the code in memremap_valid
(below). We'll fail to bring up secondaries if the release address fell
in the linear mapping.

> +#ifdef CONFIG_ARCH_HAS_MEMREMAP
> +/*
> + * memremap() is "ioremap" for cases where it is known that the resource
> + * being mapped does not have i/o side effects and the __iomem
> + * annotation is not applicable.
> + */
> +static bool memremap_valid(resource_size_t offset, size_t size)
> +{
> +       if (region_is_ram(offset, size) != 0) {
> +               WARN_ONCE(1, "memremap attempted on ram %pa size: %zu\n",
> +                               &offset, size);
> +               return false;
> +       }
> +       return true;
> +}
> +
> +void *memremap(resource_size_t offset, size_t size, unsigned long flags)
> +{
> +       void __iomem *addr = NULL;
> +
> +       if (!memremap_valid(offset, size))
> +               return NULL;
> +
> +       /* try all mapping types requested until one returns non-NULL */
> +       if (flags & MEMREMAP_CACHE) {
> +               if (flags & MEMREMAP_STRICT)
> +                       addr = strict_ioremap_cache(offset, size);
> +               else
> +                       addr = ioremap_cache(offset, size);
> +       }
> +
> +       if (!addr && (flags & MEMREMAP_WT)) {
> +               if (flags & MEMREMAP_STRICT)
> +                       addr = strict_ioremap_wt(offset, size);
> +               else
> +                       addr = ioremap_wt(offset, size);
> +       }
> +
> +       return (void __force *) addr;
> +}
> +EXPORT_SYMBOL(memremap);

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 09/10] arch: introduce memremap()
  2015-07-20 12:00   ` Mark Rutland
@ 2015-07-20 14:39     ` Dan Williams
  2015-07-20 15:56       ` Mark Rutland
  0 siblings, 1 reply; 24+ messages in thread
From: Dan Williams @ 2015-07-20 14:39 UTC (permalink / raw)
  To: Mark Rutland
  Cc: tglx, mingo, hpa, linux-arch, tony.luck, linux, arnd, benh,
	mcgrof, x86, linux-kernel, ralf, Andy Shevchenko, geert,
	toshi.kani, ross.zwisler, hch, linux-arm-kernel, Will Deacon,
	catalin.marinas

On Mon, Jul 20, 2015 at 5:00 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> Hi,
>
> On Mon, Jul 20, 2015 at 01:18:23AM +0100, Dan Williams wrote:
>> Existing users of ioremap_cache() are mapping memory that is known in
>> advance to not have i/o side effects.  These users are forced to cast
>> away the __iomem annotation, or otherwise neglect to fix the sparse
>> errors thrown when dereferencing pointers to this memory.  Provide
>> memremap() as a non __iomem annotated ioremap_*() in the case when
>> ioremap is otherwise a pointer to memory.
>>
>> The ARCH_HAS_MEMREMAP kconfig symbol is introduced for archs to assert
>> that it is safe to recast / reuse the return value from ioremap as a
>> normal pointer to memory.  In other words, archs that mandate specific
>> accessors for __iomem are not memremap() capable and drivers that care,
>> like pmem, can add a dependency to disable themselves on these archs.
>>
>> Note, that memremap is a break from the ioremap implementation pattern
>> of adding a new memremap_<type>() for each mapping type.  Instead,
>> the implementation defines flags that are passed to the central
>> memremap() implementation.
>>
>> Outside of ioremap() and ioremap_nocache(), the expectation is that most
>> calls to ioremap_<type>() are seeking memory-like semantics (e.g.
>> speculative reads, and prefetching permitted).  These callsites can be
>> moved to memremap() over time.
>>
>> Cc: Arnd Bergmann <arnd@arndb.de>
>> Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
>> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
>> ---
>>  arch/arm/Kconfig                     |    1 +
>>  arch/arm64/Kconfig                   |    1 +
>>  arch/arm64/kernel/efi.c              |    7 ++---
>>  arch/arm64/kernel/smp_spin_table.c   |   17 +++++------
>
> These last two files weren't updated in patch 2 to use <linux/io.h>, nor are
> they updated here, so this patch breaks the build for arm64.

Thanks for testing!  I'll follow up and see why this failure wasn't
reported by 0day-kbuild.

> [...]
>
>> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
>> index 318175f62c24..305def28385f 100644
>> --- a/arch/arm64/Kconfig
>> +++ b/arch/arm64/Kconfig
>> @@ -6,6 +6,7 @@ config ARM64
>>         select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
>>         select ARCH_HAS_ELF_RANDOMIZE
>>         select ARCH_HAS_GCOV_PROFILE_ALL
>> +       select ARCH_HAS_MEMREMAP
>>         select ARCH_HAS_SG_CHAIN
>>         select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
>>         select ARCH_USE_CMPXCHG_LOCKREF
>> diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
>> index 9d4aa18f2a82..ed363a0202b9 100644
>> --- a/arch/arm64/kernel/efi.c
>> +++ b/arch/arm64/kernel/efi.c
>> @@ -290,8 +290,7 @@ static int __init arm64_enable_runtime_services(void)
>>         pr_info("Remapping and enabling EFI services.\n");
>>
>>         mapsize = memmap.map_end - memmap.map;
>> -       memmap.map = (__force void *)ioremap_cache((phys_addr_t)memmap.phys_map,
>> -                                                  mapsize);
>> +       memmap.map = memremap(memmap.phys_map, mapsize, MEMREMAP_CACHE);
>
> memmap.phys_map is a void*, so we need to retain a cast to a numeric type or
> we'll get splats like:
>
> arch/arm64/kernel/efi.c: In function ‘arm64_enable_runtime_services’:
> arch/arm64/kernel/efi.c:294:24: warning: passing argument 1 of ‘memremap’ makes integer from pointer without a cast
>   memmap.map = memremap(memmap.phys_map, mapsize, MEMREMAP_CACHE);
>                         ^
> In file included from arch/arm64/kernel/efi.c:18:0:
> include/linux/io.h:203:14: note: expected ‘resource_size_t’ but argument is of type ‘void *’
>  extern void *memremap(resource_size_t offset, size_t size, unsigned long flags);
>               ^

Again, I need to check my compile scripts.

> Unfortunately, even with that fixed this patch breaks boot due to the
> memremap_valid check. It's extremely likely that (portions of) the
> tables are already in the linear mapping, and so page_is_ram will be
> true.

Really, "portions of", not the entire table?  Is it too early to use
the direct mapping like pfn_to_page(memmap.phys_map >> PAGE_SHIFT)?

In any event this splat mandates splitting this memremap() enabling
patch into per-instance conversions of ioremap_cache().

> At boot time I get the following:
>
> Remapping and enabling EFI services.
> ------------[ cut here ]------------
> WARNING: CPU: 0 PID: 1 at kernel/resource.c:541 memremap+0xb0/0xbc()
> memremap attempted on ram 0x00000009f9e4a018 size: 1200
> Modules linked in:
> CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.2.0-rc3+ #201
> Hardware name: ARM Juno development board (r0) (DT)
> Call trace:
> [<ffffffc000089954>] dump_backtrace+0x0/0x124
> [<ffffffc000089a88>] show_stack+0x10/0x1c
> [<ffffffc0005d15c8>] dump_stack+0x84/0xc8
> [<ffffffc0000b3f44>] warn_slowpath_common+0x98/0xd0
> [<ffffffc0000b3fc8>] warn_slowpath_fmt+0x4c/0x58
> [<ffffffc0000b9470>] memremap+0xac/0xbc
> [<ffffffc000814fe8>] arm64_enable_runtime_services+0x90/0x208
> [<ffffffc000082864>] do_one_initcall+0x88/0x1a0
> [<ffffffc000811a20>] kernel_init_freeable+0x8c/0x1f8
> [<ffffffc0005ce370>] kernel_init+0xc/0xd8
> ---[ end trace cb88537fdc8fa200 ]---
> Failed to remap EFI memory map
>
>>         if (!memmap.map) {
>>                 pr_err("Failed to remap EFI memory map\n");
>>                 return -1;
>> @@ -299,8 +298,8 @@ static int __init arm64_enable_runtime_services(void)
>>         memmap.map_end = memmap.map + mapsize;
>>         efi.memmap = &memmap;
>>
>> -       efi.systab = (__force void *)ioremap_cache(efi_system_table,
>> -                                                  sizeof(efi_system_table_t));
>> +       efi.systab = memremap(efi_system_table, sizeof(efi_system_table_t),
>> +                       MEMREMAP_CACHE);
>>         if (!efi.systab) {
>>                 pr_err("Failed to remap EFI System Table\n");
>>                 return -1;
>> diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c
>> index aef3605a8c47..b9caf6cd44e6 100644
>> --- a/arch/arm64/kernel/smp_spin_table.c
>> +++ b/arch/arm64/kernel/smp_spin_table.c
>> @@ -73,19 +73,19 @@ static int smp_spin_table_cpu_init(unsigned int cpu)
>>
>>  static int smp_spin_table_cpu_prepare(unsigned int cpu)
>>  {
>> -       __le64 __iomem *release_addr;
>> +       __le64 *release_addr;
>>
>>         if (!cpu_release_addr[cpu])
>>                 return -ENODEV;
>>
>>         /*
>>          * The cpu-release-addr may or may not be inside the linear mapping.
>> -        * As ioremap_cache will either give us a new mapping or reuse the
>> -        * existing linear mapping, we can use it to cover both cases. In
>> -        * either case the memory will be MT_NORMAL.
>> +        * As memremap will either give us a new mapping or reuse the existing
>> +        * linear mapping, we can use it to cover both cases. In either case
>> +        * the memory will be MT_NORMAL.
>>          */
>> -       release_addr = ioremap_cache(cpu_release_addr[cpu],
>> -                                    sizeof(*release_addr));
>> +       release_addr = memremap(cpu_release_addr[cpu], sizeof(*release_addr),
>> +                       MEMREMAP_CACHE);
>
> Likewise, the comment here is contradicted by the code in memremap_valid
> (below). We'll fail to bring up secondaries if the release address fell
> in the linear mapping.

Ah, so ARM's ioremap_cache() silently handles calls to remap RAM with
a pointer to the direct mapping.  It think that's a useful property to
carry in the generic implementation.  Especially if the direct mapping
has established greater than PAGE_SIZE mappings.

>
>> +#ifdef CONFIG_ARCH_HAS_MEMREMAP
>> +/*
>> + * memremap() is "ioremap" for cases where it is known that the resource
>> + * being mapped does not have i/o side effects and the __iomem
>> + * annotation is not applicable.
>> + */
>> +static bool memremap_valid(resource_size_t offset, size_t size)
>> +{
>> +       if (region_is_ram(offset, size) != 0) {
>> +               WARN_ONCE(1, "memremap attempted on ram %pa size: %zu\n",
>> +                               &offset, size);
>> +               return false;
>> +       }
>> +       return true;
>> +}
>> +
>> +void *memremap(resource_size_t offset, size_t size, unsigned long flags)
>> +{
>> +       void __iomem *addr = NULL;
>> +
>> +       if (!memremap_valid(offset, size))
>> +               return NULL;
>> +
>> +       /* try all mapping types requested until one returns non-NULL */
>> +       if (flags & MEMREMAP_CACHE) {
>> +               if (flags & MEMREMAP_STRICT)
>> +                       addr = strict_ioremap_cache(offset, size);
>> +               else
>> +                       addr = ioremap_cache(offset, size);
>> +       }
>> +
>> +       if (!addr && (flags & MEMREMAP_WT)) {
>> +               if (flags & MEMREMAP_STRICT)
>> +                       addr = strict_ioremap_wt(offset, size);
>> +               else
>> +                       addr = ioremap_wt(offset, size);
>> +       }
>> +
>> +       return (void __force *) addr;
>> +}
>> +EXPORT_SYMBOL(memremap);
>
> Thanks,
> Mark.

Thanks Mark!

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 09/10] arch: introduce memremap()
  2015-07-20 14:39     ` Dan Williams
@ 2015-07-20 15:56       ` Mark Rutland
  0 siblings, 0 replies; 24+ messages in thread
From: Mark Rutland @ 2015-07-20 15:56 UTC (permalink / raw)
  To: Dan Williams
  Cc: tglx, mingo, hpa, linux-arch, tony.luck, linux, arnd, benh,
	mcgrof, x86, linux-kernel, ralf, Andy Shevchenko, geert,
	toshi.kani, ross.zwisler, hch, linux-arm-kernel, Will Deacon,
	Catalin Marinas, leif.lindholm, ard.biesheuvel

On Mon, Jul 20, 2015 at 03:39:44PM +0100, Dan Williams wrote:
> On Mon, Jul 20, 2015 at 5:00 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> > Hi,
> >
> > On Mon, Jul 20, 2015 at 01:18:23AM +0100, Dan Williams wrote:
> >> Existing users of ioremap_cache() are mapping memory that is known in
> >> advance to not have i/o side effects.  These users are forced to cast
> >> away the __iomem annotation, or otherwise neglect to fix the sparse
> >> errors thrown when dereferencing pointers to this memory.  Provide
> >> memremap() as a non __iomem annotated ioremap_*() in the case when
> >> ioremap is otherwise a pointer to memory.
> >>
> >> The ARCH_HAS_MEMREMAP kconfig symbol is introduced for archs to assert
> >> that it is safe to recast / reuse the return value from ioremap as a
> >> normal pointer to memory.  In other words, archs that mandate specific
> >> accessors for __iomem are not memremap() capable and drivers that care,
> >> like pmem, can add a dependency to disable themselves on these archs.
> >>
> >> Note, that memremap is a break from the ioremap implementation pattern
> >> of adding a new memremap_<type>() for each mapping type.  Instead,
> >> the implementation defines flags that are passed to the central
> >> memremap() implementation.
> >>
> >> Outside of ioremap() and ioremap_nocache(), the expectation is that most
> >> calls to ioremap_<type>() are seeking memory-like semantics (e.g.
> >> speculative reads, and prefetching permitted).  These callsites can be
> >> moved to memremap() over time.
> >>
> >> Cc: Arnd Bergmann <arnd@arndb.de>
> >> Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
> >> Signed-off-by: Dan Williams <dan.j.williams@intel.com>

[...]

> > Unfortunately, even with that fixed this patch breaks boot due to the
> > memremap_valid check. It's extremely likely that (portions of) the
> > tables are already in the linear mapping, and so page_is_ram will be
> > true.
> 
> Really, "portions of", not the entire table?

Yes, if a table straddles a page boundary (the spec doesn't seem to
disallow this). We might not map all of the required pages, e.g.

* If the kernel was loaded more than TEXT_OFFSET bytes above the table
  (the arm64 linear/direct mapping is currently tied to our text
  mapping, and we can't currently address anything below that).

  In this case the start isn't in the direct mapping, and we'll try to
  create a new mapping. That should work.

* If the kernel is built with a small VA range, and we have just the
  right amount of memory before the table begins (this is absurdly
  unlikely).

  In this case if the start is in the direct mapping, but the end isn't,
  we'll explode when accessing it.

* If the 'mem=' parameter is used, the direct mapping can be truncated.

  In this case if the start is in the direct mapping, but the end isn't,
  we'll explode when accessing it.

In the arm64 ioremap_cache we only check
pfn_valid(__phys_to_pfn(phys_addr)), and assume that if the start was
mapped, then the whole region is. In the cases above that's clearly not
true, so we should probably see about handling that.

> Is it too early to use the direct mapping like
> pfn_to_page(memmap.phys_map >> PAGE_SHIFT)?

I believe it's too early, as we haven't initialised the memmap yet. For
the cases above we will never have a page for the portion of the region
not in the direct mapping anyway.

> In any event this splat mandates splitting this memremap() enabling
> patch into per-instance conversions of ioremap_cache().
> 
> > At boot time I get the following:
> >
> > Remapping and enabling EFI services.
> > ------------[ cut here ]------------
> > WARNING: CPU: 0 PID: 1 at kernel/resource.c:541 memremap+0xb0/0xbc()
> > memremap attempted on ram 0x00000009f9e4a018 size: 1200
> > Modules linked in:
> > CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.2.0-rc3+ #201
> > Hardware name: ARM Juno development board (r0) (DT)
> > Call trace:
> > [<ffffffc000089954>] dump_backtrace+0x0/0x124
> > [<ffffffc000089a88>] show_stack+0x10/0x1c
> > [<ffffffc0005d15c8>] dump_stack+0x84/0xc8
> > [<ffffffc0000b3f44>] warn_slowpath_common+0x98/0xd0
> > [<ffffffc0000b3fc8>] warn_slowpath_fmt+0x4c/0x58
> > [<ffffffc0000b9470>] memremap+0xac/0xbc
> > [<ffffffc000814fe8>] arm64_enable_runtime_services+0x90/0x208
> > [<ffffffc000082864>] do_one_initcall+0x88/0x1a0
> > [<ffffffc000811a20>] kernel_init_freeable+0x8c/0x1f8
> > [<ffffffc0005ce370>] kernel_init+0xc/0xd8
> > ---[ end trace cb88537fdc8fa200 ]---
> > Failed to remap EFI memory map
> >
> >>         if (!memmap.map) {
> >>                 pr_err("Failed to remap EFI memory map\n");
> >>                 return -1;
> >> @@ -299,8 +298,8 @@ static int __init arm64_enable_runtime_services(void)
> >>         memmap.map_end = memmap.map + mapsize;
> >>         efi.memmap = &memmap;
> >>
> >> -       efi.systab = (__force void *)ioremap_cache(efi_system_table,
> >> -                                                  sizeof(efi_system_table_t));
> >> +       efi.systab = memremap(efi_system_table, sizeof(efi_system_table_t),
> >> +                       MEMREMAP_CACHE);
> >>         if (!efi.systab) {
> >>                 pr_err("Failed to remap EFI System Table\n");
> >>                 return -1;
> >> diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c
> >> index aef3605a8c47..b9caf6cd44e6 100644
> >> --- a/arch/arm64/kernel/smp_spin_table.c
> >> +++ b/arch/arm64/kernel/smp_spin_table.c
> >> @@ -73,19 +73,19 @@ static int smp_spin_table_cpu_init(unsigned int cpu)
> >>
> >>  static int smp_spin_table_cpu_prepare(unsigned int cpu)
> >>  {
> >> -       __le64 __iomem *release_addr;
> >> +       __le64 *release_addr;
> >>
> >>         if (!cpu_release_addr[cpu])
> >>                 return -ENODEV;
> >>
> >>         /*
> >>          * The cpu-release-addr may or may not be inside the linear mapping.
> >> -        * As ioremap_cache will either give us a new mapping or reuse the
> >> -        * existing linear mapping, we can use it to cover both cases. In
> >> -        * either case the memory will be MT_NORMAL.
> >> +        * As memremap will either give us a new mapping or reuse the existing
> >> +        * linear mapping, we can use it to cover both cases. In either case
> >> +        * the memory will be MT_NORMAL.
> >>          */
> >> -       release_addr = ioremap_cache(cpu_release_addr[cpu],
> >> -                                    sizeof(*release_addr));
> >> +       release_addr = memremap(cpu_release_addr[cpu], sizeof(*release_addr),
> >> +                       MEMREMAP_CACHE);
> >
> > Likewise, the comment here is contradicted by the code in memremap_valid
> > (below). We'll fail to bring up secondaries if the release address fell
> > in the linear mapping.
> 
> Ah, so ARM's ioremap_cache() silently handles calls to remap RAM with
> a pointer to the direct mapping.  It think that's a useful property to
> carry in the generic implementation.  Especially if the direct mapping
> has established greater than PAGE_SIZE mappings.

That sounds good to me.

As mentioned above, I think we should test that the entire region we're
trying to map falls within the direct mapping before assuming we can use
it, though I'm not sure what the best way of doing that is.

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 08/10] arch: introduce strict_ioremap
  2015-07-20  0:18 ` [PATCH 08/10] arch: introduce strict_ioremap Dan Williams
@ 2015-07-21 13:30   ` Christoph Hellwig
  2015-07-21 16:11     ` Dan Williams
  0 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2015-07-21 13:30 UTC (permalink / raw)
  To: Dan Williams
  Cc: tglx, mingo, hpa, linux-arch, tony.luck, linux, arnd, benh,
	mcgrof, x86, linux-kernel, ralf, geert, toshi.kani, ross.zwisler,
	hch, linux-arm-kernel

On Sun, Jul 19, 2015 at 08:18:17PM -0400, Dan Williams wrote:
> In preparation for enabling memremap(), add support for strict mappings.
> strict_ioremap_<type>() returns NULL if the arch does not implement the
> mapping type, rather than falling back silently to ioremap().

Please don't introduce another large number of ioremap variants.

I think we should go straight to the ioremap_flags variant, although
I wonder if we should even bother with ioremap_flags for this use
case, given that we really want memremap-like semantics for anything
that isn't plain ioremap (and maybe ioremap_nocache).

Sorry or being the downer, but I really think we need to clean up this
mess deeply insted of trying to paper over it.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 05/10] arch: unify ioremap prototypes and macro aliases
  2015-07-20  0:18 ` [PATCH 05/10] arch: unify ioremap prototypes and macro aliases Dan Williams
@ 2015-07-21 13:34   ` Christoph Hellwig
  2015-07-21 16:08     ` Dan Williams
  0 siblings, 1 reply; 24+ messages in thread
From: Christoph Hellwig @ 2015-07-21 13:34 UTC (permalink / raw)
  To: Dan Williams
  Cc: tglx, mingo, hpa, linux-arch, tony.luck, linux, arnd, benh,
	mcgrof, x86, linux-kernel, ralf, geert, toshi.kani, ross.zwisler,
	kbuild test robot, hch, linux-arm-kernel

On Sun, Jul 19, 2015 at 08:18:00PM -0400, Dan Williams wrote:
> Some archs define the first parameter to ioremap() as unsigned long,
> while the balance define it as resource_size_t, similar confusion exists
> for the type of the 'size' parameter.  Unify on (resource_size_t,
> unsigned long) to enable passing ioremap function pointers.  Also, some
> archs use function-like macros for defining ioremap aliases, but
> asm-generic/io.h expects object-like macros, unify on the latter.
> 
> Move all handling of ioremap aliasing (i.e. ioremap_wt => ioremap) to
> include/linux/io.h.  Add a check to lib/devres.c to warn at compile time
> if an arch violates type expectations.

I don't think devres really has aything to do with this code.

> Kill ARCH_HAS_IOREMAP_WC and ARCH_HAS_IOREMAP_WT in favor of just
> testing for ioremap_wc, and ioremap_wt being defined.  This arrangement
> allows drivers to know when ioremap_<foo> are being re-directed to plain
> ioremap.  A later patch uses this arrangement to implement support for
> strict mappings.
> 
> Acked-by: Christoph Hellwig <hch@lst.de>

I only ACKed this as a band-aid to get the pmem code in.  Now that
we got that in with a less invasive hack I don't see any reasons to
do this over doing the proper common prototypes and per-arch runtime checks
of flags variant.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 05/10] arch: unify ioremap prototypes and macro aliases
  2015-07-21 13:34   ` Christoph Hellwig
@ 2015-07-21 16:08     ` Dan Williams
  0 siblings, 0 replies; 24+ messages in thread
From: Dan Williams @ 2015-07-21 16:08 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, linux-arch,
	Tony Luck, Russell King - ARM Linux, Arnd Bergmann,
	Benjamin Herrenschmidt, Luis Rodriguez, X86 ML, linux-kernel,
	Ralf Baechle, Geert Uytterhoeven, Kani, Toshimitsu, Ross Zwisler,
	kbuild test robot, linux-arm-kernel

On Tue, Jul 21, 2015 at 6:34 AM, Christoph Hellwig <hch@lst.de> wrote:
>
> On Sun, Jul 19, 2015 at 08:18:00PM -0400, Dan Williams wrote:
> > Some archs define the first parameter to ioremap() as unsigned long,
> > while the balance define it as resource_size_t, similar confusion exists
> > for the type of the 'size' parameter.  Unify on (resource_size_t,
> > unsigned long) to enable passing ioremap function pointers.  Also, some
> > archs use function-like macros for defining ioremap aliases, but
> > asm-generic/io.h expects object-like macros, unify on the latter.
> >
> > Move all handling of ioremap aliasing (i.e. ioremap_wt => ioremap) to
> > include/linux/io.h.  Add a check to lib/devres.c to warn at compile time
> > if an arch violates type expectations.
>
> I don't think devres really has aything to do with this code.

It's one of the only cross-arch C files that is built with HAS_IOMEM.
It depends on having a common ioremap prototype later in the series.

> > Kill ARCH_HAS_IOREMAP_WC and ARCH_HAS_IOREMAP_WT in favor of just
> > testing for ioremap_wc, and ioremap_wt being defined.  This arrangement
> > allows drivers to know when ioremap_<foo> are being re-directed to plain
> > ioremap.  A later patch uses this arrangement to implement support for
> > strict mappings.
> >
> > Acked-by: Christoph Hellwig <hch@lst.de>
>
> I only ACKed this as a band-aid to get the pmem code in.  Now that
> we got that in with a less invasive hack I don't see any reasons to
> do this over doing the proper common prototypes and per-arch runtime checks
> of flags variant.

That's not too much of a setback.  I had already started to realize
that nobody really wants the ioremap_<type> variants compared to
memremap.  So rather than introduce this cleanup and deprecate
ioremap_<type> over time, let's just skip a step and start converting
to memremap() with a proper 'flags' parameter for the mapping-type
right away

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 08/10] arch: introduce strict_ioremap
  2015-07-21 13:30   ` Christoph Hellwig
@ 2015-07-21 16:11     ` Dan Williams
  0 siblings, 0 replies; 24+ messages in thread
From: Dan Williams @ 2015-07-21 16:11 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, linux-arch,
	Tony Luck, Russell King - ARM Linux, Arnd Bergmann,
	Benjamin Herrenschmidt, Luis Rodriguez, X86 ML, linux-kernel,
	Ralf Baechle, Geert Uytterhoeven, Kani, Toshimitsu, Ross Zwisler,
	linux-arm-kernel

On Tue, Jul 21, 2015 at 6:30 AM, Christoph Hellwig <hch@lst.de> wrote:
> On Sun, Jul 19, 2015 at 08:18:17PM -0400, Dan Williams wrote:
>> In preparation for enabling memremap(), add support for strict mappings.
>> strict_ioremap_<type>() returns NULL if the arch does not implement the
>> mapping type, rather than falling back silently to ioremap().
>
> Please don't introduce another large number of ioremap variants.
>
> I think we should go straight to the ioremap_flags variant, although
> I wonder if we should even bother with ioremap_flags for this use
> case, given that we really want memremap-like semantics for anything
> that isn't plain ioremap (and maybe ioremap_nocache).
>
> Sorry or being the downer, but I really think we need to clean up this
> mess deeply insted of trying to paper over it.

No worries.  I'll rework the series around the idea that memremap() is
a replacement rather than a wrapper for ioremap_<type>().

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 09/10] arch: introduce memremap()
  2015-07-20  0:18 ` [PATCH 09/10] arch: introduce memremap() Dan Williams
  2015-07-20 12:00   ` Mark Rutland
@ 2015-07-21 23:58   ` Luis R. Rodriguez
  2015-07-22  4:04     ` Dan Williams
  1 sibling, 1 reply; 24+ messages in thread
From: Luis R. Rodriguez @ 2015-07-21 23:58 UTC (permalink / raw)
  To: Dan Williams
  Cc: tglx, mingo, hpa, linux-arch, tony.luck, linux, arnd, benh, x86,
	linux-kernel, ralf, Andy Shevchenko, geert, toshi.kani,
	ross.zwisler, hch, linux-arm-kernel

On Sun, Jul 19, 2015 at 08:18:23PM -0400, Dan Williams wrote:
> diff --git a/include/linux/io.h b/include/linux/io.h
> index 080a4fbf2ba4..2983b6e63970 100644
> --- a/include/linux/io.h
> +++ b/include/linux/io.h
> @@ -192,4 +192,15 @@ static inline int arch_phys_wc_index(int handle)
>  #endif
>  #endif
>  
> +enum {
> +	MEMREMAP_WB = 1 << 0,
> +	MEMREMAP_WT = 1 << 1,
> +	MEMREMAP_WC = 1 << 2,
> +	MEMREMAP_STRICT = 1 << 3,
> +	MEMREMAP_CACHE = MEMREMAP_WB,
> +};

A few things:

1) You'll need MEMREMAP_UC now as well now.

2) as you are doing all this sweep over architectures on this please
also address the lack of ioremap_*() variant implemention to return
NULL, ie not supported, because we've decided for now that so long
as the semantics are not well defined we can't expect architectures
to get it right unless they are doing the work themselves, and the
old strategy of just #defin'ing a variant to iorempa_nocache() which
folks tended to just can lead to issues. In your case since you are
jumping to the flags implementation this might be knocking two birds
with one stone.

3) For the case that architectures have no MMU we currently do a direct
mapping such as what you try to describe to do with memremap(). I wonder
if its worth it to then enable that code to just map to memremap(). That
throws off your usage of CONFIG_ARCH_HAS_MEMREMAP if we want to repurpose
that implementation for no the MMU case, unless of course you just have a
__memremap() which does the default basic direct mapping implementation.

4) Since we are all blaming semantics on our woes I'd like to ask for
some effort on semantics to be well defined. Semantics here sholud cover
some form of Documentation but also sparse annotation checks and perhaps
Coccinelle grammar rules for how things should be done. This should not only
cover general use but also if there are calls which depend on a cache
type to have been set. If we used sparse annotations it  may meen a
different return type for each cache type.  Not sure if we want this.
If we went with grammar rules I'm looking to for instance have in place
rules on scripts/coccinelle which would allow developers to use

make coccicheck M=foo/

to find issues. I can perhaps help with this, but we'd need to do a good
sweep here to not only cover good territory but also get folks to agree
on things.

5) This may be related to 4), not sure. There are aligment requirements we
should probably iron out for architectures. How will we annotate these
requirements or allow architectures to be pedantic over these requirements?

  Luis

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 09/10] arch: introduce memremap()
  2015-07-21 23:58   ` Luis R. Rodriguez
@ 2015-07-22  4:04     ` Dan Williams
  2015-07-22 22:55       ` Luis R. Rodriguez
  0 siblings, 1 reply; 24+ messages in thread
From: Dan Williams @ 2015-07-22  4:04 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, linux-arch,
	Tony Luck, Russell King - ARM Linux, Arnd Bergmann,
	Benjamin Herrenschmidt, X86 ML, linux-kernel, Ralf Baechle,
	Andy Shevchenko, Geert Uytterhoeven, Kani, Toshimitsu,
	Ross Zwisler, Christoph Hellwig, linux-arm-kernel

On Tue, Jul 21, 2015 at 4:58 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote:
> On Sun, Jul 19, 2015 at 08:18:23PM -0400, Dan Williams wrote:
>> diff --git a/include/linux/io.h b/include/linux/io.h
>> index 080a4fbf2ba4..2983b6e63970 100644
>> --- a/include/linux/io.h
>> +++ b/include/linux/io.h
>> @@ -192,4 +192,15 @@ static inline int arch_phys_wc_index(int handle)
>>  #endif
>>  #endif
>>
>> +enum {
>> +     MEMREMAP_WB = 1 << 0,
>> +     MEMREMAP_WT = 1 << 1,
>> +     MEMREMAP_WC = 1 << 2,
>> +     MEMREMAP_STRICT = 1 << 3,
>> +     MEMREMAP_CACHE = MEMREMAP_WB,
>> +};
>
> A few things:
>
> 1) You'll need MEMREMAP_UC now as well now.

Why?  I don't think it fits.  If there are any I/O areas (non-memory)
in the range then it simply is not "memory" and should not be using
memremap().  In other words it seems like you really do need to heed
the __iomem annotation in the return value from ioremap_uc().

> 2) as you are doing all this sweep over architectures on this please
> also address the lack of ioremap_*() variant implemention to return
> NULL, ie not supported, because we've decided for now that so long
> as the semantics are not well defined we can't expect architectures
> to get it right unless they are doing the work themselves, and the
> old strategy of just #defin'ing a variant to iorempa_nocache() which
> folks tended to just can lead to issues. In your case since you are
> jumping to the flags implementation this might be knocking two birds
> with one stone.

I'm not going to do a general sweep for this as the expectation that
ioremap silently falls back if a mapping type is not supported is
buried all over the place.  That said, new usages and conversions to
memremap() can be strict about this. For now, I'm only handling
ioremap_cache() and ioremap_wt() conversions.

> 3) For the case that architectures have no MMU we currently do a direct
> mapping such as what you try to describe to do with memremap(). I wonder
> if its worth it to then enable that code to just map to memremap(). That
> throws off your usage of CONFIG_ARCH_HAS_MEMREMAP if we want to repurpose
> that implementation for no the MMU case, unless of course you just have a
> __memremap() which does the default basic direct mapping implementation.

Yes, in the next rev of this series I am having it fall back to direct
mappings where it makes sense.

> 4) Since we are all blaming semantics on our woes I'd like to ask for
> some effort on semantics to be well defined. Semantics here sholud cover
> some form of Documentation but also sparse annotation checks and perhaps
> Coccinelle grammar rules for how things should be done. This should not only
> cover general use but also if there are calls which depend on a cache
> type to have been set. If we used sparse annotations it  may meen a
> different return type for each cache type.  Not sure if we want this.
> If we went with grammar rules I'm looking to for instance have in place
> rules on scripts/coccinelle which would allow developers to use

memremap() explicitly does not want get into arch semantics debates.
The pointer returned from memremap() is a "void *" that can be used as
normal memory.  If it is a normal pointer I don't see the role for
sparse annotation.

>
> make coccicheck M=foo/
>
> to find issues. I can perhaps help with this, but we'd need to do a good
> sweep here to not only cover good territory but also get folks to agree
> on things.
>
> 5) This may be related to 4), not sure. There are aligment requirements we
> should probably iron out for architectures. How will we annotate these
> requirements or allow architectures to be pedantic over these requirements?

What requirements beyond PAGE_SIZE alignment would we need to worry about?

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 09/10] arch: introduce memremap()
  2015-07-22  4:04     ` Dan Williams
@ 2015-07-22 22:55       ` Luis R. Rodriguez
  2015-07-22 23:15         ` Dan Williams
  0 siblings, 1 reply; 24+ messages in thread
From: Luis R. Rodriguez @ 2015-07-22 22:55 UTC (permalink / raw)
  To: Dan Williams
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, linux-arch,
	Tony Luck, Russell King - ARM Linux, Arnd Bergmann,
	Benjamin Herrenschmidt, X86 ML, linux-kernel, Ralf Baechle,
	Andy Shevchenko, Geert Uytterhoeven, Kani, Toshimitsu,
	Ross Zwisler, Christoph Hellwig, linux-arm-kernel

On Tue, Jul 21, 2015 at 09:04:22PM -0700, Dan Williams wrote:
> On Tue, Jul 21, 2015 at 4:58 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote:
> > On Sun, Jul 19, 2015 at 08:18:23PM -0400, Dan Williams wrote:
> >> diff --git a/include/linux/io.h b/include/linux/io.h
> >> index 080a4fbf2ba4..2983b6e63970 100644
> >> --- a/include/linux/io.h
> >> +++ b/include/linux/io.h
> >> @@ -192,4 +192,15 @@ static inline int arch_phys_wc_index(int handle)
> >>  #endif
> >>  #endif
> >>
> >> +enum {
> >> +     MEMREMAP_WB = 1 << 0,
> >> +     MEMREMAP_WT = 1 << 1,
> >> +     MEMREMAP_WC = 1 << 2,
> >> +     MEMREMAP_STRICT = 1 << 3,
> >> +     MEMREMAP_CACHE = MEMREMAP_WB,
> >> +};
> >
> > A few things:
> >
> > 1) You'll need MEMREMAP_UC now as well now.
> 
> Why?  I don't think it fits.  If there are any I/O areas (non-memory)
> in the range then it simply is not "memory" and should not be using
> memremap().  In other words it seems like you really do need to heed
> the __iomem annotation in the return value from ioremap_uc().

One can use a similar argument for some areas of use of write-combining,
what litmus test are you using to add a flag above? Why would WC be OK
and not UC? WC is a cache hack on x86...

> > 2) as you are doing all this sweep over architectures on this please
> > also address the lack of ioremap_*() variant implemention to return
> > NULL, ie not supported, because we've decided for now that so long
> > as the semantics are not well defined we can't expect architectures
> > to get it right unless they are doing the work themselves, and the
> > old strategy of just #defin'ing a variant to iorempa_nocache() which
> > folks tended to just can lead to issues. In your case since you are
> > jumping to the flags implementation this might be knocking two birds
> > with one stone.
> 
> I'm not going to do a general sweep for this as the expectation that
> ioremap silently falls back if a mapping type is not supported is
> buried all over the place.

But it does not. It cannot. The reason, as I noted in a commit now merged
on tip, is that the default wrappers are nested under #ifndef CONFIG_MMU,
whereas really this should have just been used for ioremap() and iounmap().

That is, the ioremap_*() variants should have a definition even for !CONFIG_MMU,
and since we actually don't want to enable sloppy defines of this the sensible
defaults should be to return NULL on variants -- for both !CONFIG_MMU
and for CONFIG_MMU. The way to fix then then is to move the default variant
definitions out from #ifndef CONFIG_MMU and have them return NULL. We may
be able to have them return something not-null by default always but we
first need to beat to death the topic of semantics with all architecture
folks to each that agreement. Until then the variants shoudl just return
NULL encouraging arch developers to supply a proper implementation.

> That said, new usages and conversions to
> memremap() can be strict about this. For now, I'm only handling
> ioremap_cache() and ioremap_wt() conversions.

OK, if you are not going to do this let me know and I can do it.

> > 3) For the case that architectures have no MMU we currently do a direct
> > mapping such as what you try to describe to do with memremap(). I wonder
> > if its worth it to then enable that code to just map to memremap(). That
> > throws off your usage of CONFIG_ARCH_HAS_MEMREMAP if we want to repurpose
> > that implementation for no the MMU case, unless of course you just have a
> > __memremap() which does the default basic direct mapping implementation.
> 
> Yes, in the next rev of this series I am having it fall back to direct
> mappings where it makes sense.
> 
> > 4) Since we are all blaming semantics on our woes I'd like to ask for
> > some effort on semantics to be well defined. Semantics here sholud cover
> > some form of Documentation but also sparse annotation checks and perhaps
> > Coccinelle grammar rules for how things should be done. This should not only
> > cover general use but also if there are calls which depend on a cache
> > type to have been set. If we used sparse annotations it  may meen a
> > different return type for each cache type.  Not sure if we want this.
> > If we went with grammar rules I'm looking to for instance have in place
> > rules on scripts/coccinelle which would allow developers to use
> 
> memremap() explicitly does not want get into arch semantics debates.

Why? The ioremap() cluster fuck seems like a good example to learn from.

I was also under the impression you are going to provide a new API with flags
to kill / make old ioremap() varaints use this new API with the flags passed?
Is that not the case ?

> The pointer returned from memremap() is a "void *" that can be used as
> normal memory.  If it is a normal pointer I don't see the role for
> sparse annotation.

Hrm, do we want to *prevent* certain to use the memory range when it is direct?

> > make coccicheck M=foo/
> >
> > to find issues. I can perhaps help with this, but we'd need to do a good
> > sweep here to not only cover good territory but also get folks to agree
> > on things.
> >
> > 5) This may be related to 4), not sure. There are aligment requirements we
> > should probably iron out for architectures. How will we annotate these
> > requirements or allow architectures to be pedantic over these requirements?
> 
> What requirements beyond PAGE_SIZE alignment would we need to worry about?

That's a big concern some folks expressed, architecture folks would know more.

One last thing: if you are providing a new API to replace a series of old
symbols that were used before (I though you were working towards this for all
ioremap_*() variants) we have to take care to ensure that any symbol that is
currently exported with EXPORT_SYMBOL_GPL() does not get an EXPORT_SYMBOL()
wrapper-escape since we do not want proprietary drivers to make use these
alternatives.

 Luis

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 09/10] arch: introduce memremap()
  2015-07-22 22:55       ` Luis R. Rodriguez
@ 2015-07-22 23:15         ` Dan Williams
  2015-07-23  0:55           ` Luis R. Rodriguez
  0 siblings, 1 reply; 24+ messages in thread
From: Dan Williams @ 2015-07-22 23:15 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, linux-arch,
	Tony Luck, Russell King - ARM Linux, Arnd Bergmann,
	Benjamin Herrenschmidt, X86 ML, linux-kernel, Ralf Baechle,
	Andy Shevchenko, Geert Uytterhoeven, Kani, Toshimitsu,
	Ross Zwisler, Christoph Hellwig, linux-arm-kernel

On Wed, Jul 22, 2015 at 3:55 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote:
> On Tue, Jul 21, 2015 at 09:04:22PM -0700, Dan Williams wrote:
>> On Tue, Jul 21, 2015 at 4:58 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote:
>> > On Sun, Jul 19, 2015 at 08:18:23PM -0400, Dan Williams wrote:
>> >> diff --git a/include/linux/io.h b/include/linux/io.h
>> >> index 080a4fbf2ba4..2983b6e63970 100644
>> >> --- a/include/linux/io.h
>> >> +++ b/include/linux/io.h
>> >> @@ -192,4 +192,15 @@ static inline int arch_phys_wc_index(int handle)
>> >>  #endif
>> >>  #endif
>> >>
>> >> +enum {
>> >> +     MEMREMAP_WB = 1 << 0,
>> >> +     MEMREMAP_WT = 1 << 1,
>> >> +     MEMREMAP_WC = 1 << 2,
>> >> +     MEMREMAP_STRICT = 1 << 3,
>> >> +     MEMREMAP_CACHE = MEMREMAP_WB,
>> >> +};
>> >
>> > A few things:
>> >
>> > 1) You'll need MEMREMAP_UC now as well now.
>>
>> Why?  I don't think it fits.  If there are any I/O areas (non-memory)
>> in the range then it simply is not "memory" and should not be using
>> memremap().  In other words it seems like you really do need to heed
>> the __iomem annotation in the return value from ioremap_uc().
>
> One can use a similar argument for some areas of use of write-combining,
> what litmus test are you using to add a flag above? Why would WC be OK
> and not UC? WC is a cache hack on x86...

I should remove WC from the list for now, I'm not converting
ioremap_wc() to memremap at this time.

That said it's not the same argument.  A driver calling ioremap_wc()
is explicitly signing up to handle flushing the write-combine buffer
and the expectation is that there are no I/O ranges in the mapping
that would be affected by write combining.  An ioremap_uc() mapping
says "careful there are I/O sensitive registers in this range".

>> > 2) as you are doing all this sweep over architectures on this please
>> > also address the lack of ioremap_*() variant implemention to return
>> > NULL, ie not supported, because we've decided for now that so long
>> > as the semantics are not well defined we can't expect architectures
>> > to get it right unless they are doing the work themselves, and the
>> > old strategy of just #defin'ing a variant to iorempa_nocache() which
>> > folks tended to just can lead to issues. In your case since you are
>> > jumping to the flags implementation this might be knocking two birds
>> > with one stone.
>>
>> I'm not going to do a general sweep for this as the expectation that
>> ioremap silently falls back if a mapping type is not supported is
>> buried all over the place.
>
> But it does not. It cannot. The reason, as I noted in a commit now merged
> on tip, is that the default wrappers are nested under #ifndef CONFIG_MMU,
> whereas really this should have just been used for ioremap() and iounmap().
>
> That is, the ioremap_*() variants should have a definition even for !CONFIG_MMU,
> and since we actually don't want to enable sloppy defines of this the sensible
> defaults should be to return NULL on variants -- for both !CONFIG_MMU
> and for CONFIG_MMU. The way to fix then then is to move the default variant
> definitions out from #ifndef CONFIG_MMU and have them return NULL. We may
> be able to have them return something not-null by default always but we
> first need to beat to death the topic of semantics with all architecture
> folks to each that agreement. Until then the variants shoudl just return
> NULL encouraging arch developers to supply a proper implementation.

That clean up is orthogonal to memremap.  memremap will return NULL
for unsupported mapping types.

>> That said, new usages and conversions to
>> memremap() can be strict about this. For now, I'm only handling
>> ioremap_cache() and ioremap_wt() conversions.
>
> OK, if you are not going to do this let me know and I can do it.

Yes, go ahead.

>> > 3) For the case that architectures have no MMU we currently do a direct
>> > mapping such as what you try to describe to do with memremap(). I wonder
>> > if its worth it to then enable that code to just map to memremap(). That
>> > throws off your usage of CONFIG_ARCH_HAS_MEMREMAP if we want to repurpose
>> > that implementation for no the MMU case, unless of course you just have a
>> > __memremap() which does the default basic direct mapping implementation.
>>
>> Yes, in the next rev of this series I am having it fall back to direct
>> mappings where it makes sense.
>>
>> > 4) Since we are all blaming semantics on our woes I'd like to ask for
>> > some effort on semantics to be well defined. Semantics here sholud cover
>> > some form of Documentation but also sparse annotation checks and perhaps
>> > Coccinelle grammar rules for how things should be done. This should not only
>> > cover general use but also if there are calls which depend on a cache
>> > type to have been set. If we used sparse annotations it  may meen a
>> > different return type for each cache type.  Not sure if we want this.
>> > If we went with grammar rules I'm looking to for instance have in place
>> > rules on scripts/coccinelle which would allow developers to use
>>
>> memremap() explicitly does not want get into arch semantics debates.
>
> Why? The ioremap() cluster fuck seems like a good example to learn from.
>
> I was also under the impression you are going to provide a new API with flags
> to kill / make old ioremap() varaints use this new API with the flags passed?
> Is that not the case ?

Yes, I'll post the new series shortly once 0day says there are no
build regressions.

>> The pointer returned from memremap() is a "void *" that can be used as
>> normal memory.  If it is a normal pointer I don't see the role for
>> sparse annotation.
>
> Hrm, do we want to *prevent* certain to use the memory range when it is direct?

Can you give an example scenario?

>
>> > make coccicheck M=foo/
>> >
>> > to find issues. I can perhaps help with this, but we'd need to do a good
>> > sweep here to not only cover good territory but also get folks to agree
>> > on things.
>> >
>> > 5) This may be related to 4), not sure. There are aligment requirements we
>> > should probably iron out for architectures. How will we annotate these
>> > requirements or allow architectures to be pedantic over these requirements?
>>
>> What requirements beyond PAGE_SIZE alignment would we need to worry about?
>
> That's a big concern some folks expressed, architecture folks would know more.
>
> One last thing: if you are providing a new API to replace a series of old
> symbols that were used before (I though you were working towards this for all
> ioremap_*() variants) we have to take care to ensure that any symbol that is
> currently exported with EXPORT_SYMBOL_GPL() does not get an EXPORT_SYMBOL()
> wrapper-escape since we do not want proprietary drivers to make use these
> alternatives.

Yes, memremap() is inheriting the export level of ioremap_cache.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 09/10] arch: introduce memremap()
  2015-07-22 23:15         ` Dan Williams
@ 2015-07-23  0:55           ` Luis R. Rodriguez
  2015-07-23  1:02             ` Dan Williams
  0 siblings, 1 reply; 24+ messages in thread
From: Luis R. Rodriguez @ 2015-07-23  0:55 UTC (permalink / raw)
  To: Dan Williams
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, linux-arch,
	Tony Luck, Russell King - ARM Linux, Arnd Bergmann,
	Benjamin Herrenschmidt, X86 ML, linux-kernel, Ralf Baechle,
	Andy Shevchenko, Geert Uytterhoeven, Kani, Toshimitsu,
	Ross Zwisler, Christoph Hellwig, linux-arm-kernel

On Wed, Jul 22, 2015 at 04:15:41PM -0700, Dan Williams wrote:
> On Wed, Jul 22, 2015 at 3:55 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote:
> > On Tue, Jul 21, 2015 at 09:04:22PM -0700, Dan Williams wrote:
> >> On Tue, Jul 21, 2015 at 4:58 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote:
> >> > On Sun, Jul 19, 2015 at 08:18:23PM -0400, Dan Williams wrote:
> >> >> diff --git a/include/linux/io.h b/include/linux/io.h
> >> >> index 080a4fbf2ba4..2983b6e63970 100644
> >> >> --- a/include/linux/io.h
> >> >> +++ b/include/linux/io.h
> >> >> @@ -192,4 +192,15 @@ static inline int arch_phys_wc_index(int handle)
> >> >>  #endif
> >> >>  #endif
> >> >>
> >> >> +enum {
> >> >> +     MEMREMAP_WB = 1 << 0,
> >> >> +     MEMREMAP_WT = 1 << 1,
> >> >> +     MEMREMAP_WC = 1 << 2,
> >> >> +     MEMREMAP_STRICT = 1 << 3,
> >> >> +     MEMREMAP_CACHE = MEMREMAP_WB,
> >> >> +};
> >> >
> >> > A few things:
> >> >
> >> > 1) You'll need MEMREMAP_UC now as well now.
> >>
> >> Why?  I don't think it fits.  If there are any I/O areas (non-memory)
> >> in the range then it simply is not "memory" and should not be using
> >> memremap().  In other words it seems like you really do need to heed
> >> the __iomem annotation in the return value from ioremap_uc().
> >
> > One can use a similar argument for some areas of use of write-combining,
> > what litmus test are you using to add a flag above? Why would WC be OK
> > and not UC? WC is a cache hack on x86...
> 
> I should remove WC from the list for now, I'm not converting
> ioremap_wc() to memremap at this time.

Do you have plans to do so? If so can you elaborate on such plans ?

> That said it's not the same argument.  A driver calling ioremap_wc()
> is explicitly signing up to handle flushing the write-combine buffer
> and the expectation is that there are no I/O ranges in the mapping
> that would be affected by write combining.

The thing is the semantics even for write-combining need to be discussed
further, write-combining for kernel interfaces are screwed up for at least one
architecture becaues we didn't get things right or document expectations
correctly amongst other things, so the above is not sufficient to define
write-combining for now.

> An ioremap_uc() mapping says "careful there are I/O sensitive registers in this range".

Yes but we have ioremap_nocache(). I added ioremap_uc() and the goal behind ioremap_uc()
was to enable efficient use of absolutely no cache at all, and this was particularly
aimed at taking advantage of strong UC on PAT. This was also a compromise to help
with the transition over on x86 from UC- to UC in the long term as we also convert
all write-combining variant API users to (old mtrr_add(), now arch_phys_wc_add())
over from ioremap_nocache() to ioremap_wc() and ensure its MMIO registers use
keep using ioremap_nocache() -- but for corner cases with old MTRR hacks we need
ioremap_uc() to also avoid regressions when we do the flip on x86 fromr UC- to
UC. How we want to map this to other architectures remaisn to be discovered, but
perhaps they don't care.

Anyway so why is WB and WT allowed if you are going to remove WC and not add UC?

> >> > 2) as you are doing all this sweep over architectures on this please
> >> > also address the lack of ioremap_*() variant implemention to return
> >> > NULL, ie not supported, because we've decided for now that so long
> >> > as the semantics are not well defined we can't expect architectures
> >> > to get it right unless they are doing the work themselves, and the
> >> > old strategy of just #defin'ing a variant to iorempa_nocache() which
> >> > folks tended to just can lead to issues. In your case since you are
> >> > jumping to the flags implementation this might be knocking two birds
> >> > with one stone.
> >>
> >> I'm not going to do a general sweep for this as the expectation that
> >> ioremap silently falls back if a mapping type is not supported is
> >> buried all over the place.
> >
> > But it does not. It cannot. The reason, as I noted in a commit now merged
> > on tip, is that the default wrappers are nested under #ifndef CONFIG_MMU,
> > whereas really this should have just been used for ioremap() and iounmap().
> >
> > That is, the ioremap_*() variants should have a definition even for !CONFIG_MMU,
> > and since we actually don't want to enable sloppy defines of this the sensible
> > defaults should be to return NULL on variants -- for both !CONFIG_MMU
> > and for CONFIG_MMU. The way to fix then then is to move the default variant
> > definitions out from #ifndef CONFIG_MMU and have them return NULL. We may
> > be able to have them return something not-null by default always but we
> > first need to beat to death the topic of semantics with all architecture
> > folks to each that agreement. Until then the variants shoudl just return
> > NULL encouraging arch developers to supply a proper implementation.
> 
> That clean up is orthogonal to memremap.  memremap will return NULL
> for unsupported mapping types.

It can be if you are not doing a major long term cleanup...

> >> That said, new usages and conversions to
> >> memremap() can be strict about this. For now, I'm only handling
> >> ioremap_cache() and ioremap_wt() conversions.
> >
> > OK, if you are not going to do this let me know and I can do it.
> 
> Yes, go ahead.

OK..

> >> > 3) For the case that architectures have no MMU we currently do a direct
> >> > mapping such as what you try to describe to do with memremap(). I wonder
> >> > if its worth it to then enable that code to just map to memremap(). That
> >> > throws off your usage of CONFIG_ARCH_HAS_MEMREMAP if we want to repurpose
> >> > that implementation for no the MMU case, unless of course you just have a
> >> > __memremap() which does the default basic direct mapping implementation.
> >>
> >> Yes, in the next rev of this series I am having it fall back to direct
> >> mappings where it makes sense.
> >>
> >> > 4) Since we are all blaming semantics on our woes I'd like to ask for
> >> > some effort on semantics to be well defined. Semantics here sholud cover
> >> > some form of Documentation but also sparse annotation checks and perhaps
> >> > Coccinelle grammar rules for how things should be done. This should not only
> >> > cover general use but also if there are calls which depend on a cache
> >> > type to have been set. If we used sparse annotations it  may meen a
> >> > different return type for each cache type.  Not sure if we want this.
> >> > If we went with grammar rules I'm looking to for instance have in place
> >> > rules on scripts/coccinelle which would allow developers to use
> >>
> >> memremap() explicitly does not want get into arch semantics debates.
> >
> > Why? The ioremap() cluster fuck seems like a good example to learn from.
> >
> > I was also under the impression you are going to provide a new API with flags
> > to kill / make old ioremap() varaints use this new API with the flags passed?
> > Is that not the case ?
> 
> Yes, I'll post the new series shortly once 0day says there are no
> build regressions.

Then what API was it you intend on using for that ? My point is that semantics
shoudl matter then for that -- strongly.

> >> The pointer returned from memremap() is a "void *" that can be used as
> >> normal memory.  If it is a normal pointer I don't see the role for
> >> sparse annotation.
> >
> > Hrm, do we want to *prevent* certain to use the memory range when it is direct?
> 
> Can you give an example scenario?

arch_phys_wc_add(), set_memory_wc(), set_memory_*(). There may be others. The
mem region API Toshi just fixed is another.

> >> > make coccicheck M=foo/
> >> >
> >> > to find issues. I can perhaps help with this, but we'd need to do a good
> >> > sweep here to not only cover good territory but also get folks to agree
> >> > on things.
> >> >
> >> > 5) This may be related to 4), not sure. There are aligment requirements we
> >> > should probably iron out for architectures. How will we annotate these
> >> > requirements or allow architectures to be pedantic over these requirements?
> >>
> >> What requirements beyond PAGE_SIZE alignment would we need to worry about?
> >
> > That's a big concern some folks expressed, architecture folks would know more.
> >
> > One last thing: if you are providing a new API to replace a series of old
> > symbols that were used before (I though you were working towards this for all
> > ioremap_*() variants) we have to take care to ensure that any symbol that is
> > currently exported with EXPORT_SYMBOL_GPL() does not get an EXPORT_SYMBOL()
> > wrapper-escape since we do not want proprietary drivers to make use these
> > alternatives.
> 
> Yes, memremap() is inheriting the export level of ioremap_cache.

Like I said we need to take care to ensure EXPORT_SYMBOL_GPL() is not used
then by new wrappers to enable proprietary drivers to make use of those
symbosl through the new wrapper. One idea may be to work on symbol namespaces,
if we cannot address this through static inlines for old callers and just
making the new APIs EXPORT_SYMBOL_GPL().

  Luis

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 09/10] arch: introduce memremap()
  2015-07-23  0:55           ` Luis R. Rodriguez
@ 2015-07-23  1:02             ` Dan Williams
  0 siblings, 0 replies; 24+ messages in thread
From: Dan Williams @ 2015-07-23  1:02 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, linux-arch,
	Tony Luck, Russell King - ARM Linux, Arnd Bergmann,
	Benjamin Herrenschmidt, X86 ML, linux-kernel, Ralf Baechle,
	Andy Shevchenko, Geert Uytterhoeven, Kani, Toshimitsu,
	Ross Zwisler, Christoph Hellwig, linux-arm-kernel

On Wed, Jul 22, 2015 at 5:55 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote:
> On Wed, Jul 22, 2015 at 04:15:41PM -0700, Dan Williams wrote:
> Anyway so why is WB and WT allowed if you are going to remove WC and not add UC?
>

Because all existing usages of WB and WT mappings are clearly free of
I/O side effect concerns.  The WC and now UC usages are a muddy mix of
"sometimes there's I/O side effects, but it depends by arch and
driver".

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2015-07-23  1:03 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-20  0:17 [PATCH 00/10] unify ioremap definitions and introduce memremap Dan Williams
2015-07-20  0:17 ` [PATCH 01/10] mm, x86: Fix warning in ioremap RAM check Dan Williams
2015-07-20  0:17 ` [PATCH 02/10] mm, x86: Remove region_is_ram() call from ioremap Dan Williams
2015-07-20  0:17 ` [PATCH 03/10] mm: Fix bugs in region_is_ram() Dan Williams
2015-07-20  0:17 ` [PATCH 04/10] arch, drivers: don't include <asm/io.h> directly, use <linux/io.h> instead Dan Williams
2015-07-20  0:18 ` [PATCH 05/10] arch: unify ioremap prototypes and macro aliases Dan Williams
2015-07-21 13:34   ` Christoph Hellwig
2015-07-21 16:08     ` Dan Williams
2015-07-20  0:18 ` [PATCH 06/10] cleanup IORESOURCE_CACHEABLE vs ioremap() Dan Williams
2015-07-20  0:18 ` [PATCH 07/10] devm: fix ioremap_cache() usage Dan Williams
2015-07-20  0:18 ` [PATCH 08/10] arch: introduce strict_ioremap Dan Williams
2015-07-21 13:30   ` Christoph Hellwig
2015-07-21 16:11     ` Dan Williams
2015-07-20  0:18 ` [PATCH 09/10] arch: introduce memremap() Dan Williams
2015-07-20 12:00   ` Mark Rutland
2015-07-20 14:39     ` Dan Williams
2015-07-20 15:56       ` Mark Rutland
2015-07-21 23:58   ` Luis R. Rodriguez
2015-07-22  4:04     ` Dan Williams
2015-07-22 22:55       ` Luis R. Rodriguez
2015-07-22 23:15         ` Dan Williams
2015-07-23  0:55           ` Luis R. Rodriguez
2015-07-23  1:02             ` Dan Williams
2015-07-20  0:18 ` [PATCH 10/10] pmem: convert to generic memremap Dan Williams

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).