2015-07-25 02:43:41

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 00/25] replace ioremap_{cache|wt} with memremap

Changes since v1 [1]:

1/ Drop the attempt at unifying ioremap() prototypes, just focus on
converting ioremap_cache and ioremap_wt over to memremap (Christoph)

2/ Drop the unrelated cleanups to use %pa in __ioremap_caller (Thomas)

3/ Add support for memremap() attempts on "System RAM" to simply return
the kernel virtual address for that range. ARM depends on this
functionality in ioremap_cache() and ACPI was open coding a similar
solution. (Mark)

4/ Split the conversions of ioremap_{cache|wt} into separate patches per
driver / arch.

5/ Fix bisection breakage and other reports from 0day-kbuild

---
While developing the pmem driver we noticed that the __iomem annotation
on the return value from ioremap_cache() was being mishandled by several
callers. We also observed that all of the call sites expected to be
able to treat the return value from ioremap_cache() as normal
(non-__iomem) pointer to memory.

This patchset takes the opportunity to clean up the above confusion as
well as a few issues with the ioremap_{cache|wt} interface, including:

1/ Eliminating the possibility of function prototypes differing between
architectures by defining a central memremap() prototype that takes
flags to determine the mapping type.

2/ Returning NULL rather than falling back silently to a different
mapping-type. This allows drivers to be stricter about the
mapping-type fallbacks that are permissible.

[1]: http://marc.info/?l=linux-arm-kernel&m=143735199029255&w=2

---

Dan Williams (22):
mm: enhance region_is_ram() to distinguish 'unknown' vs 'mixed'
arch, drivers: don't include <asm/io.h> directly, use <linux/io.h> instead
cleanup IORESOURCE_CACHEABLE vs ioremap()
intel_iommu: fix leaked ioremap mapping
arch: introduce memremap()
arm: switch from ioremap_cache to memremap
x86: switch from ioremap_cache to memremap
gma500: switch from acpi_os_ioremap to ioremap
i915: switch from acpi_os_ioremap to ioremap
acpi: switch from ioremap_cache to memremap
toshiba laptop: replace ioremap_cache with ioremap
memconsole: fix __iomem mishandling, switch to memremap
visorbus: switch from ioremap_cache to memremap
intel-iommu: switch from ioremap_cache to memremap
libnvdimm, pmem: switch from ioremap_cache to memremap
pxa2xx-flash: switch from ioremap_cache to memremap
sfi: switch from ioremap_cache to memremap
fbdev: switch from ioremap_wt to memremap
pmem: switch from ioremap_wt to memremap
arch: remove ioremap_cache, replace with arch_memremap
arch: remove ioremap_wt, replace with arch_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/arc/include/asm/io.h | 1
arch/arm/Kconfig | 1
arch/arm/include/asm/io.h | 13 +++-
arch/arm/include/asm/xen/page.h | 4 +
arch/arm/mach-clps711x/board-cdb89712.c | 2 -
arch/arm/mach-shmobile/pm-rcar.c | 2 -
arch/arm/mm/ioremap.c | 12 +++-
arch/arm/mm/nommu.c | 11 ++-
arch/arm64/Kconfig | 1
arch/arm64/include/asm/acpi.h | 10 +--
arch/arm64/include/asm/dmi.h | 8 +--
arch/arm64/include/asm/io.h | 8 ++-
arch/arm64/kernel/efi.c | 9 ++-
arch/arm64/kernel/smp_spin_table.c | 19 +++---
arch/arm64/mm/ioremap.c | 20 ++----
arch/avr32/include/asm/io.h | 1
arch/frv/Kconfig | 1
arch/frv/include/asm/io.h | 17 ++---
arch/frv/mm/kmap.c | 6 ++
arch/ia64/Kconfig | 1
arch/ia64/include/asm/io.h | 11 +++
arch/ia64/kernel/cyclone.c | 2 -
arch/m32r/include/asm/io.h | 1
arch/m68k/Kconfig | 1
arch/m68k/include/asm/io_mm.h | 14 +---
arch/m68k/include/asm/io_no.h | 12 ++--
arch/m68k/include/asm/raw_io.h | 4 +
arch/m68k/mm/kmap.c | 17 +++++
arch/m68k/mm/sun3kmap.c | 6 ++
arch/metag/include/asm/io.h | 3 -
arch/microblaze/include/asm/io.h | 1
arch/mn10300/include/asm/io.h | 1
arch/nios2/include/asm/io.h | 1
arch/powerpc/kernel/pci_of_scan.c | 2 -
arch/s390/include/asm/io.h | 1
arch/sh/Kconfig | 1
arch/sh/include/asm/io.h | 20 ++++--
arch/sh/mm/ioremap.c | 10 +++
arch/sparc/include/asm/io_32.h | 1
arch/sparc/include/asm/io_64.h | 1
arch/sparc/kernel/pci.c | 3 -
arch/tile/include/asm/io.h | 1
arch/x86/Kconfig | 1
arch/x86/include/asm/efi.h | 3 +
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 | 76 ++++++++++--------------
arch/xtensa/Kconfig | 1
arch/xtensa/include/asm/io.h | 9 ++-
drivers/acpi/apei/einj.c | 9 ++-
drivers/acpi/apei/erst.c | 6 +-
drivers/acpi/nvs.c | 6 +-
drivers/acpi/osl.c | 70 ++++++----------------
drivers/char/toshiba.c | 2 -
drivers/firmware/google/memconsole.c | 7 +-
drivers/gpu/drm/gma500/opregion.c | 2 -
drivers/gpu/drm/i915/intel_opregion.c | 2 -
drivers/iommu/intel-iommu.c | 10 ++-
drivers/iommu/intel_irq_remapping.c | 4 +
drivers/isdn/icn/icn.h | 2 -
drivers/mtd/devices/slram.c | 2 -
drivers/mtd/maps/pxa2xx-flash.c | 4 +
drivers/mtd/nand/diskonchip.c | 2 -
drivers/mtd/onenand/generic.c | 2 -
drivers/nvdimm/Kconfig | 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/sfi/sfi_core.c | 4 +
drivers/staging/comedi/drivers/ii_pci20kc.c | 1
drivers/staging/unisys/visorbus/visorchannel.c | 16 +++--
drivers/staging/unisys/visorbus/visorchipset.c | 17 +++--
drivers/tty/serial/8250/8250_core.c | 2 -
drivers/video/fbdev/Kconfig | 2 -
drivers/video/fbdev/amifb.c | 5 +-
drivers/video/fbdev/atafb.c | 5 +-
drivers/video/fbdev/hpfb.c | 6 +-
drivers/video/fbdev/ocfb.c | 1
drivers/video/fbdev/s1d13xxxfb.c | 3 -
drivers/video/fbdev/stifb.c | 1
include/acpi/acpi_io.h | 6 +-
include/asm-generic/io.h | 8 ---
include/asm-generic/iomap.h | 4 -
include/linux/io-mapping.h | 2 -
include/linux/io.h | 9 +++
include/linux/mtd/map.h | 2 -
include/linux/pmem.h | 26 +++++---
include/video/vga.h | 2 -
kernel/Makefile | 2 +
kernel/memremap.c | 74 +++++++++++++++++++++++
kernel/resource.c | 43 +++++++-------
lib/Kconfig | 5 +-
lib/devres.c | 13 +---
lib/pci_iomap.c | 7 +-
tools/testing/nvdimm/Kbuild | 4 +
tools/testing/nvdimm/test/iomap.c | 34 ++++++++---
101 files changed, 482 insertions(+), 398 deletions(-)
create mode 100644 kernel/memremap.c


2015-07-25 02:43:46

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 01/25] mm, x86: Fix warning in ioremap RAM check

From: Toshi Kani <[email protected]>

__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(), and update the message to
include the address range.

Signed-off-by: Toshi Kani <[email protected]>
Cc: Roland Dreier <[email protected]>
Cc: Luis R. Rodriguez <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Borislav Petkov <[email protected]>
[djbw: fix format specifier warnings]
Reported-by: kbuild test robot <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
arch/x86/mm/ioremap.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index cc5ccc415cc0..c13f7fdca142 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;
}

@@ -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

2015-07-25 02:43:56

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 02/25] mm, x86: Remove region_is_ram() call from ioremap

From: Toshi Kani <[email protected]>

__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 <[email protected]>
Cc: Roland Dreier <[email protected]>
Cc: Mike Travis <[email protected]>
Cc: Luis R. Rodriguez <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Borislav Petkov <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
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 c13f7fdca142..12b1eaeab6b9 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
*/

2015-07-25 02:44:00

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 03/25] mm: Fix bugs in region_is_ram()

From: Toshi Kani <[email protected]>

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 <[email protected]>
Cc: Mike Travis <[email protected]>
Cc: Luis R. Rodriguez <[email protected]>
Cc: Dan Williams <[email protected]>
Cc: Andrew Morton <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
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);

2015-07-25 02:44:07

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 04/25] mm: enhance region_is_ram() to distinguish 'unknown' vs 'mixed'

region_is_ram() is used to prevent the establishment of aliased mappings
to physical "System RAM" with incompatible cache settings. However, it
uses "-1" to indicate both "unknown" memory ranges (ranges not described
by platform firmware) and "mixed" ranges (where the parameters describe
a range that partially overlaps "System RAM").

Fix this up by explicitly tracking the "unknown" vs "mixed" resource
cases. In addition to clarifying that "-1" means the requested spanned
RAM and non-RAM resource, this re-write also adds support for detecting
when the requested range completely covers all of a resource.

Finally, the implementation treats overlaps between "unknown" and RAM as
RAM.

Cc: Toshi Kani <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
kernel/resource.c | 43 +++++++++++++++++++++++--------------------
1 file changed, 23 insertions(+), 20 deletions(-)

diff --git a/kernel/resource.c b/kernel/resource.c
index fed052a1bc9f..119b282985f9 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -493,39 +493,42 @@ int __weak page_is_ram(unsigned long pfn)
EXPORT_SYMBOL_GPL(page_is_ram);

/*
- * Search for a resouce entry that fully contains the specified region.
- * If found, return 1 if it is RAM, 0 if not.
- * If not found, or region is not fully contained, return -1
+ * Check if the specified region partially overlaps or fully eclipses "System
+ * RAM". Return '0' if the region does not overlap RAM, return '-1' if the
+ * region overlaps RAM and another resource, and return '1' if the region
+ * overlaps RAM and no other defined resource. Note, that '1' is also returned
+ * in the case when the specified region overlaps RAM and undefined memory
+ * holes.
*
* Used by the ioremap functions to ensure the user is not remapping RAM and is
* a vast speed up over walking through the resource table page by page.
*/
int region_is_ram(resource_size_t start, unsigned long size)
{
- struct resource *p;
- resource_size_t end = start + size - 1;
unsigned long flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ resource_size_t end = start + size - 1;
const char *name = "System RAM";
- int ret = -1;
+ int ram = 0; int other = 0;
+ struct resource *p;

read_lock(&resource_lock);
for (p = iomem_resource.child; p ; p = p->sibling) {
- if (p->end < start)
- continue;
-
- if (p->start <= start && end <= p->end) {
- /* resource fully contains region */
- if ((p->flags != flags) || strcmp(p->name, name))
- ret = 0;
- else
- ret = 1;
- break;
- }
- if (end < p->start)
- break; /* not found */
+ bool is_ram = strcmp(p->name, name) == 0 && p->flags == flags;
+
+ if (start >= p->start && start <= p->end)
+ is_ram ? ram++ : other++;
+ if (end >= p->start && end <= p->end)
+ is_ram ? ram++ : other++;
+ if (p->start >= start && p->end <= end)
+ is_ram ? ram++ : other++;
}
read_unlock(&resource_lock);
- return ret;
+
+ if (other == 0)
+ return !!ram;
+ if (ram)
+ return -1;
+ return 0;
}

void __weak arch_remove_reservations(struct resource *avail)

2015-07-25 02:44:14

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 05/25] arch, drivers: don't include <asm/io.h> directly, use <linux/io.h> instead

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

Acked-by: Christoph Hellwig <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
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>

2015-07-25 02:44:17

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 06/25] cleanup IORESOURCE_CACHEABLE vs ioremap()

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. Particularly devm_ioremap_resource() never worked as
advertised since it always fell back to plain ioremap().

Clean this up as the new direction we want is to convert
ioremap_<type>() usages to memremap(..., flags).

Suggested-by: Arnd Bergmann <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
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 | 13 ++++---------
lib/pci_iomap.c | 7 ++-----
11 files changed, 16 insertions(+), 44 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 fbe2aac522e6..f13a2468ff39 100644
--- a/lib/devres.c
+++ b/lib/devres.c
@@ -119,10 +119,9 @@ EXPORT_SYMBOL(devm_iounmap);
* @dev: generic device to handle the resource for
* @res: resource to be handled
*
- * Checks that a resource is a valid memory region, requests the memory region
- * and ioremaps it either as cacheable or as non-cacheable memory depending on
- * the resource's flags. All operations are managed and will be undone on
- * driver detach.
+ * Checks that a resource is a valid memory region, requests the memory
+ * region and ioremaps it. All operations are managed and will be undone
+ * on driver detach.
*
* Returns a pointer to the remapped memory or an ERR_PTR() encoded error code
* on failure. Usage example:
@@ -153,11 +152,7 @@ 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);
-
+ 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;
}

2015-07-25 02:44:21

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 07/25] intel_iommu: fix leaked ioremap mapping

iommu_load_old_irte() appears to leak the old_irte mapping after use.

Cc: Joerg Roedel <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
drivers/iommu/intel_irq_remapping.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c
index f15692a410c7..27cdfa84ec5b 100644
--- a/drivers/iommu/intel_irq_remapping.c
+++ b/drivers/iommu/intel_irq_remapping.c
@@ -426,6 +426,8 @@ static int iommu_load_old_irte(struct intel_iommu *iommu)
bitmap_set(iommu->ir_table->bitmap, i, 1);
}

+ iounmap(old_ir_table);
+
return 0;
}

2015-07-25 02:44:32

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 08/25] arch: introduce memremap()

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. 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.

memremap() is a break from the ioremap implementation pattern of adding
a new memremap_<type>() for each mapping type and having silent
compatibility fall backs. Instead, the
implementation defines flags that are passed to the central memremap()
and if a mapping type is not supported by an arch memremap returns NULL.

The behavior change to return NULL on an unsupported request is reserved
for a later patch. This initial implementation starts off by using
ioremap_cache() directly. Once all ioremap_cache() and ioremap_wt()
instances have been converted the functionality for establishing these
mappings will be pushed to a per-architecture arch_memremap()
implementation.

Cc: Arnd Bergmann <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
arch/ia64/include/asm/io.h | 1 +
arch/sh/include/asm/io.h | 1 +
arch/xtensa/include/asm/io.h | 1 +
include/linux/io.h | 9 +++++
kernel/Makefile | 2 +
kernel/memremap.c | 82 ++++++++++++++++++++++++++++++++++++++++++
6 files changed, 96 insertions(+)
create mode 100644 kernel/memremap.c

diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h
index 80a7e34be009..9041bbe2b7b4 100644
--- a/arch/ia64/include/asm/io.h
+++ b/arch/ia64/include/asm/io.h
@@ -435,6 +435,7 @@ static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned lo
{
return ioremap(phys_addr, size);
}
+#define ioremap_cache ioremap_cache


/*
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 728c4c571f40..6194e20fccca 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -342,6 +342,7 @@ 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 *
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index c39bb6e61911..867840f5400f 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -57,6 +57,7 @@ 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
diff --git a/include/linux/io.h b/include/linux/io.h
index fb5a99800e77..dfed9d608bb3 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -121,4 +121,13 @@ static inline int arch_phys_wc_index(int handle)
#endif
#endif

+enum {
+ MEMREMAP_WB = 1 << 0,
+ MEMREMAP_WT = 1 << 1,
+ 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/Makefile b/kernel/Makefile
index 43c4c920f30a..92866d36e376 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -99,6 +99,8 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o
obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
obj-$(CONFIG_TORTURE_TEST) += torture.o

+obj-$(CONFIG_HAS_IOMEM) += memremap.o
+
$(obj)/configs.o: $(obj)/config_data.h

# config_data.h contains the same information as ikconfig.h but gzipped.
diff --git a/kernel/memremap.c b/kernel/memremap.c
new file mode 100644
index 000000000000..ba206fd11785
--- /dev/null
+++ b/kernel/memremap.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright(c) 2015 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+#include <linux/types.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+
+#ifndef ioremap_cache
+/* temporary while we convert existing ioremap_cache users to memremap */
+__weak void __iomem *ioremap_cache(resource_size_t offset, unsigned long size)
+{
+ return ioremap(offset, size);
+}
+#endif
+
+/*
+ * 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.
+ */
+void *memremap(resource_size_t offset, size_t size, unsigned long flags)
+{
+ int is_ram = region_is_ram(offset, size);
+ void *addr = NULL;
+
+ if (is_ram < 0) {
+ WARN_ONCE(1, "memremap attempted on mixed range %pa size: %zu\n",
+ &offset, size);
+ return NULL;
+ }
+
+ /* Try all mapping types requested until one returns non-NULL */
+ if (flags & MEMREMAP_CACHE) {
+ flags &= ~MEMREMAP_CACHE;
+ /*
+ * MEMREMAP_CACHE is special in that it can be satisifed
+ * from the direct map. Some archs depend on the
+ * capability of memremap() to autodetect cases where
+ * the requested range is potentially in "System RAM"
+ */
+ if (is_ram)
+ addr = __va(offset);
+ else
+ addr = ioremap_cache(offset, size);
+ }
+
+ /*
+ * If we don't have a mapping yet and more request flags are
+ * pending then we will be attempting to establish a new virtual
+ * address mapping. Enforce that this mapping is not aliasing
+ * "System RAM"
+ */
+ if (!addr && is_ram && flags) {
+ WARN_ONCE(1, "memremap attempted on ram %pa size: %zu\n",
+ &offset, size);
+ return NULL;
+ }
+
+ if (!addr && (flags & MEMREMAP_WT)) {
+ flags &= ~MEMREMAP_WT;
+ addr = ioremap_wt(offset, size);
+ }
+
+ return addr;
+}
+EXPORT_SYMBOL(memremap);
+
+void memunmap(void *addr)
+{
+ if (is_vmalloc_addr(addr))
+ iounmap((void __iomem *) addr);
+}
+EXPORT_SYMBOL(memunmap);

2015-07-25 02:49:49

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 09/25] arm: switch from ioremap_cache to memremap

In preparation for deprecating ioremap_cache() convert its usage in
arch/arm[64]/ to memremap.

Cc: Russell King <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
arch/arm/include/asm/xen/page.h | 4 ++--
arch/arm64/include/asm/acpi.h | 5 +----
arch/arm64/include/asm/dmi.h | 8 ++++----
arch/arm64/kernel/efi.c | 9 +++++----
arch/arm64/kernel/smp_spin_table.c | 19 +++++++++----------
5 files changed, 21 insertions(+), 24 deletions(-)

diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 1bee8ca12494..59c966e51af7 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -103,8 +103,8 @@ static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
return __set_phys_to_machine(pfn, mfn);
}

-#define xen_remap(cookie, size) ioremap_cache((cookie), (size))
-#define xen_unmap(cookie) iounmap((cookie))
+#define xen_remap(cookie, size) memremap((cookie), (size), MEMREMAP_CACHE)
+#define xen_unmap(cookie) memunmap((cookie))

bool xen_arch_need_swiotlb(struct device *dev,
unsigned long pfn,
diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 406485ed110a..5d7e46a1efdb 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -33,10 +33,7 @@
static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
acpi_size size)
{
- if (!page_is_ram(phys >> PAGE_SHIFT))
- return ioremap(phys, size);
-
- return ioremap_cache(phys, size);
+ return memremap(phys, size, MEMREMAP_CACHE);
}
#define acpi_os_ioremap acpi_os_ioremap

diff --git a/arch/arm64/include/asm/dmi.h b/arch/arm64/include/asm/dmi.h
index 69d37d87b159..f3dae56c50da 100644
--- a/arch/arm64/include/asm/dmi.h
+++ b/arch/arm64/include/asm/dmi.h
@@ -22,10 +22,10 @@
* request a virtual mapping for configuration tables such as SMBIOS.
* This means we have to map them before use.
*/
-#define dmi_early_remap(x, l) ioremap_cache(x, l)
-#define dmi_early_unmap(x, l) iounmap(x)
-#define dmi_remap(x, l) ioremap_cache(x, l)
-#define dmi_unmap(x) iounmap(x)
+#define dmi_early_remap(x, l) memremap(x, l, MEMREMAP_CACHE)
+#define dmi_early_unmap(x, l) memunmap(x)
+#define dmi_remap(x, l) memremap(x, l, MEMREMAP_CACHE)
+#define dmi_unmap(x) memunmap(x)
#define dmi_alloc(l) kzalloc(l, GFP_KERNEL)

#endif
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 9d4aa18f2a82..f0d6688cd62c 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -26,6 +26,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
+#include <linux/io.h>

#include <asm/cacheflush.h>
#include <asm/efi.h>
@@ -290,8 +291,8 @@ 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((phys_addr_t) memmap.phys_map, mapsize,
+ MEMREMAP_CACHE);
if (!memmap.map) {
pr_err("Failed to remap EFI memory map\n");
return -1;
@@ -299,8 +300,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..47da614f6215 100644
--- a/arch/arm64/kernel/smp_spin_table.c
+++ b/arch/arm64/kernel/smp_spin_table.c
@@ -21,11 +21,11 @@
#include <linux/of.h>
#include <linux/smp.h>
#include <linux/types.h>
+#include <linux/io.h>

#include <asm/cacheflush.h>
#include <asm/cpu_ops.h>
#include <asm/cputype.h>
-#include <asm/io.h>
#include <asm/smp_plat.h>

extern void secondary_holding_pen(void);
@@ -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;
}

2015-07-25 02:44:40

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 10/25] x86: switch from ioremap_cache to memremap

In preparation for deprecating ioremap_cache() convert its usage in
arch/x86/ to memremap.

Cc: Thomas Gleixner <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Borislav Petkov <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
arch/x86/include/asm/efi.h | 3 ++-
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 ++++------
5 files changed, 27 insertions(+), 28 deletions(-)

diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index 155162ea0e00..755272a8c45f 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -54,7 +54,8 @@ extern unsigned long asmlinkage efi_call_phys(void *, ...);
kernel_fpu_end(); \
})

-#define efi_ioremap(addr, size, type, attr) ioremap_cache(addr, size)
+#define efi_ioremap(addr, size, type, attr) \
+ memremap(addr, size, MEMREMAP_CACHE)

#else /* !CONFIG_X86_32 */

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 12b1eaeab6b9..6f759c7c2ab7 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -403,12 +403,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)
@@ -416,7 +414,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;

2015-07-25 02:44:43

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 11/25] gma500: switch from acpi_os_ioremap to ioremap

acpi_os_ioremap uses cached mappings, however it appears that gma500
wants to read dynamic platform state. Switch to ioremap() to prevent it
reading stale state from cache.

Cc: David Airlie <[email protected]>
Cc: [email protected]
Signed-off-by: Dan Williams <[email protected]>
---
drivers/gpu/drm/gma500/opregion.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/gma500/opregion.c b/drivers/gpu/drm/gma500/opregion.c
index ab696ca7eeec..9809c26ea0cf 100644
--- a/drivers/gpu/drm/gma500/opregion.c
+++ b/drivers/gpu/drm/gma500/opregion.c
@@ -322,7 +322,7 @@ int psb_intel_opregion_setup(struct drm_device *dev)
INIT_WORK(&opregion->asle_work, psb_intel_opregion_asle_work);

DRM_DEBUG("OpRegion detected at 0x%8x\n", opregion_phy);
- base = acpi_os_ioremap(opregion_phy, 8*1024);
+ base = ioremap(opregion_phy, 8*1024);
if (!base)
return -ENOMEM;

2015-07-25 02:44:49

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 12/25] i915: switch from acpi_os_ioremap to ioremap

acpi_os_ioremap uses cached mappings, however it appears that i915
wants to read dynamic platform state. Switch to ioremap() to prevent it
reading stale state from cache.

Cc: Daniel Vetter <[email protected]>
Cc: Jani Nikula <[email protected]>
Cc: [email protected]
Cc: David Airlie <[email protected]>
Cc: [email protected]
Signed-off-by: Dan Williams <[email protected]>
---
drivers/gpu/drm/i915/intel_opregion.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
index 481337436f72..16ba7c67410d 100644
--- a/drivers/gpu/drm/i915/intel_opregion.c
+++ b/drivers/gpu/drm/i915/intel_opregion.c
@@ -863,7 +863,7 @@ int intel_opregion_setup(struct drm_device *dev)
INIT_WORK(&opregion->asle_work, asle_work);
#endif

- base = acpi_os_ioremap(asls, OPREGION_SIZE);
+ base = ioremap(asls, OPREGION_SIZE);
if (!base)
return -ENOMEM;

2015-07-25 02:45:12

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 13/25] acpi: switch from ioremap_cache to memremap

In preparation for deprecating ioremap_cache() convert its usage in
drivers/acpi and include/acpi/ to memremap. This includes dropping the
__iomem annotation throughout ACPI since the memremap can be treated as
a normal memory pointer.

Finally, memremap automatically handles requests to map normal memory
pages, so this also drops the calls to "should_use_kmap()".

Cc: Bob Moore <[email protected]>
Cc: Lv Zheng <[email protected]>
Cc: Rafael J. Wysocki <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
arch/arm64/include/asm/acpi.h | 5 +--
drivers/acpi/apei/einj.c | 9 +++--
drivers/acpi/apei/erst.c | 6 ++--
drivers/acpi/nvs.c | 6 ++--
drivers/acpi/osl.c | 70 +++++++++++------------------------------
include/acpi/acpi_io.h | 6 ++--
6 files changed, 35 insertions(+), 67 deletions(-)

diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
index 5d7e46a1efdb..d12fc0b932b3 100644
--- a/arch/arm64/include/asm/acpi.h
+++ b/arch/arm64/include/asm/acpi.h
@@ -30,12 +30,11 @@
/* Basic configuration for ACPI */
#ifdef CONFIG_ACPI
/* ACPI table mapping after acpi_gbl_permanent_mmap is set */
-static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
- acpi_size size)
+static inline void *acpi_os_memremap(acpi_physical_address phys, acpi_size size)
{
return memremap(phys, size, MEMREMAP_CACHE);
}
-#define acpi_os_ioremap acpi_os_ioremap
+#define acpi_os_memremap acpi_os_memremap

typedef u64 phys_cpuid_t;
#define PHYS_CPUID_INVALID INVALID_HWID
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/acpi/nvs.c b/drivers/acpi/nvs.c
index 85287b8fe3aa..e0e15af93b22 100644
--- a/drivers/acpi/nvs.c
+++ b/drivers/acpi/nvs.c
@@ -136,7 +136,7 @@ void suspend_nvs_free(void)
entry->data = NULL;
if (entry->kaddr) {
if (entry->unmap) {
- iounmap(entry->kaddr);
+ memunmap(entry->kaddr);
entry->unmap = false;
} else {
acpi_os_unmap_iomem(entry->kaddr,
@@ -180,7 +180,7 @@ int suspend_nvs_save(void)

entry->kaddr = acpi_os_get_iomem(phys, size);
if (!entry->kaddr) {
- entry->kaddr = acpi_os_ioremap(phys, size);
+ entry->kaddr = acpi_os_memremap(phys, size);
entry->unmap = !!entry->kaddr;
}
if (!entry->kaddr) {
@@ -197,7 +197,7 @@ int suspend_nvs_save(void)
* suspend_nvs_restore - restore NVS memory regions
*
* This function is going to be called with interrupts disabled, so it
- * cannot iounmap the virtual addresses used to access the NVS region.
+ * cannot memunmap the virtual addresses used to access the NVS region.
*/
void suspend_nvs_restore(void)
{
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 3b8963f21b36..9d5242179b74 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -31,7 +31,6 @@
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mm.h>
-#include <linux/highmem.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/kmod.h>
@@ -44,8 +43,8 @@
#include <linux/list.h>
#include <linux/jiffies.h>
#include <linux/semaphore.h>
+#include <linux/io.h>

-#include <asm/io.h>
#include <asm/uaccess.h>

#include "internal.h"
@@ -90,7 +89,7 @@ static struct workqueue_struct *kacpi_hotplug_wq;
*/
struct acpi_ioremap {
struct list_head list;
- void __iomem *virt;
+ void *virt;
acpi_physical_address phys;
acpi_size size;
unsigned long refcount;
@@ -294,7 +293,7 @@ acpi_map_lookup(acpi_physical_address phys, acpi_size size)
}

/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
-static void __iomem *
+static void *
acpi_map_vaddr_lookup(acpi_physical_address phys, unsigned int size)
{
struct acpi_ioremap *map;
@@ -306,10 +305,10 @@ acpi_map_vaddr_lookup(acpi_physical_address phys, unsigned int size)
return NULL;
}

-void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size)
+void *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size)
{
struct acpi_ioremap *map;
- void __iomem *virt = NULL;
+ void *virt = NULL;

mutex_lock(&acpi_ioremap_lock);
map = acpi_map_lookup(phys, size);
@@ -324,7 +323,7 @@ EXPORT_SYMBOL_GPL(acpi_os_get_iomem);

/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
static struct acpi_ioremap *
-acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
+acpi_map_lookup_virt(void *virt, acpi_size size)
{
struct acpi_ioremap *map;

@@ -336,44 +335,13 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
return NULL;
}

-#if defined(CONFIG_IA64) || defined(CONFIG_ARM64)
-/* ioremap will take care of cache attributes */
-#define should_use_kmap(pfn) 0
-#else
-#define should_use_kmap(pfn) page_is_ram(pfn)
-#endif
-
-static void __iomem *acpi_map(acpi_physical_address pg_off, unsigned long pg_sz)
-{
- unsigned long pfn;
-
- pfn = pg_off >> PAGE_SHIFT;
- if (should_use_kmap(pfn)) {
- if (pg_sz > PAGE_SIZE)
- return NULL;
- return (void __iomem __force *)kmap(pfn_to_page(pfn));
- } else
- return acpi_os_ioremap(pg_off, pg_sz);
-}
-
-static void acpi_unmap(acpi_physical_address pg_off, void __iomem *vaddr)
-{
- unsigned long pfn;
-
- pfn = pg_off >> PAGE_SHIFT;
- if (should_use_kmap(pfn))
- kunmap(pfn_to_page(pfn));
- else
- iounmap(vaddr);
-}
-
-void __iomem *__init_refok
+void *__init_refok
acpi_os_map_iomem(acpi_physical_address phys, acpi_size size)
{
struct acpi_ioremap *map;
- void __iomem *virt;
acpi_physical_address pg_off;
acpi_size pg_sz;
+ void *virt;

if (phys > ULONG_MAX) {
printk(KERN_ERR PREFIX "Cannot map memory that high\n");
@@ -399,7 +367,7 @@ acpi_os_map_iomem(acpi_physical_address phys, acpi_size size)

pg_off = round_down(phys, PAGE_SIZE);
pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
- virt = acpi_map(pg_off, pg_sz);
+ virt = acpi_os_memremap(pg_off, pg_sz);
if (!virt) {
mutex_unlock(&acpi_ioremap_lock);
kfree(map);
@@ -437,7 +405,7 @@ static void acpi_os_map_cleanup(struct acpi_ioremap *map)
{
if (!map->refcount) {
synchronize_rcu_expedited();
- acpi_unmap(map->phys, map->virt);
+ memunmap(map->virt);
kfree(map);
}
}
@@ -965,7 +933,7 @@ static inline u64 read64(const volatile void __iomem *addr)
acpi_status
acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width)
{
- void __iomem *virt_addr;
+ void *virt_addr;
unsigned int size = width / 8;
bool unmap = false;
u64 dummy;
@@ -974,7 +942,7 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width)
virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
if (!virt_addr) {
rcu_read_unlock();
- virt_addr = acpi_os_ioremap(phys_addr, size);
+ virt_addr = acpi_os_memremap(phys_addr, size);
if (!virt_addr)
return AE_BAD_ADDRESS;
unmap = true;
@@ -985,23 +953,23 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u64 *value, u32 width)

switch (width) {
case 8:
- *(u8 *) value = readb(virt_addr);
+ *(u8 *) value = *(u8 *) virt_addr;
break;
case 16:
- *(u16 *) value = readw(virt_addr);
+ *(u16 *) value = *(u16 *) virt_addr;
break;
case 32:
- *(u32 *) value = readl(virt_addr);
+ *(u32 *) value = *(u32 *) virt_addr;
break;
case 64:
- *(u64 *) value = read64(virt_addr);
+ *(u64 *) value = *(u64 *) virt_addr;
break;
default:
BUG();
}

if (unmap)
- iounmap(virt_addr);
+ memunmap(virt_addr);
else
rcu_read_unlock();

@@ -1032,7 +1000,7 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width)
virt_addr = acpi_map_vaddr_lookup(phys_addr, size);
if (!virt_addr) {
rcu_read_unlock();
- virt_addr = acpi_os_ioremap(phys_addr, size);
+ virt_addr = acpi_os_memremap(phys_addr, size);
if (!virt_addr)
return AE_BAD_ADDRESS;
unmap = true;
@@ -1056,7 +1024,7 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u64 value, u32 width)
}

if (unmap)
- iounmap(virt_addr);
+ memunmap(virt_addr);
else
rcu_read_unlock();

diff --git a/include/acpi/acpi_io.h b/include/acpi/acpi_io.h
index dd86c5fc102d..55bb32f375d6 100644
--- a/include/acpi/acpi_io.h
+++ b/include/acpi/acpi_io.h
@@ -5,11 +5,11 @@

#include <asm/acpi.h>

-#ifndef acpi_os_ioremap
-static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
+#ifndef acpi_os_memremap
+static inline void *acpi_os_memremap(acpi_physical_address phys,
acpi_size size)
{
- return ioremap_cache(phys, size);
+ return memremap(phys, size, MEMREMAP_CACHE);
}
#endif

2015-07-25 02:45:10

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 14/25] toshiba laptop: replace ioremap_cache with ioremap

With ioremap_cache being replaced with memremap there is no longer a
guarantee that a mapping will silently fall back to an uncached mapping.
Explicitly use a vanilla ioremap() for this short lived mapping.

Cc: Arnd Bergmann <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Jonathan Buzzard <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
drivers/char/toshiba.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c
index 014c9d90d297..f5a45d887a37 100644
--- a/drivers/char/toshiba.c
+++ b/drivers/char/toshiba.c
@@ -430,7 +430,7 @@ static int tosh_probe(void)
int i,major,minor,day,year,month,flag;
unsigned char signature[7] = { 0x54,0x4f,0x53,0x48,0x49,0x42,0x41 };
SMMRegisters regs;
- void __iomem *bios = ioremap_cache(0xf0000, 0x10000);
+ void __iomem *bios = ioremap(0xf0000, 0x10000);

if (!bios)
return -ENOMEM;

2015-07-25 02:45:08

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 15/25] memconsole: fix __iomem mishandling, switch to memremap

The memconsole driver is not using proper accessors for __iomem. Switch
to memremap to fix this issue, and this also prepares the driver for the
removal of ioremap_cache.

Cc: Mike Waychison <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
drivers/firmware/google/memconsole.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/firmware/google/memconsole.c b/drivers/firmware/google/memconsole.c
index 2f569aaed4c7..1b25fba84f32 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");
+ pr_err("memconsole: memremap failed\n");
return -ENOMEM;
}
ret = memory_read_from_buffer(buf, count, &pos, memconsole,
memconsole_length);
- iounmap(memconsole);
+ memunmap(memconsole);
return ret;
}

2015-07-25 02:45:38

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 16/25] visorbus: switch from ioremap_cache to memremap

In preparation for deprecating ioremap_cache() convert its usage in
visorbus to memremap.

Cc: Benjamin Romer <[email protected]>
Cc: David Kershner <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
drivers/staging/unisys/visorbus/visorchannel.c | 16 +++++++++-------
drivers/staging/unisys/visorbus/visorchipset.c | 17 +++++++++--------
2 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/drivers/staging/unisys/visorbus/visorchannel.c b/drivers/staging/unisys/visorbus/visorchannel.c
index 20b63496e9f2..787e8b98f0b6 100644
--- a/drivers/staging/unisys/visorbus/visorchannel.c
+++ b/drivers/staging/unisys/visorbus/visorchannel.c
@@ -21,6 +21,7 @@
*/

#include <linux/uuid.h>
+#include <linux/io.h>

#include "version.h"
#include "visorbus.h"
@@ -36,7 +37,7 @@ static const uuid_le spar_video_guid = SPAR_CONSOLEVIDEO_CHANNEL_PROTOCOL_GUID;
struct visorchannel {
u64 physaddr;
ulong nbytes;
- void __iomem *mapped;
+ void *mapped;
bool requested;
struct channel_header chan_hdr;
uuid_le guid;
@@ -93,7 +94,7 @@ visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes,
}
}

- channel->mapped = ioremap_cache(physaddr, size);
+ channel->mapped = memremap(physaddr, size, MEMREMAP_CACHE);
if (!channel->mapped) {
release_mem_region(physaddr, size);
goto cleanup;
@@ -113,7 +114,7 @@ visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes,
if (uuid_le_cmp(guid, NULL_UUID_LE) == 0)
guid = channel->chan_hdr.chtype;

- iounmap(channel->mapped);
+ memunmap(channel->mapped);
if (channel->requested)
release_mem_region(channel->physaddr, channel->nbytes);
channel->mapped = NULL;
@@ -126,7 +127,8 @@ visorchannel_create_guts(u64 physaddr, unsigned long channel_bytes,
}
}

- channel->mapped = ioremap_cache(channel->physaddr, channel_bytes);
+ channel->mapped = memremap(channel->physaddr, channel_bytes,
+ MEMREMAP_CACHE);
if (!channel->mapped) {
release_mem_region(channel->physaddr, channel_bytes);
goto cleanup;
@@ -167,7 +169,7 @@ visorchannel_destroy(struct visorchannel *channel)
if (!channel)
return;
if (channel->mapped) {
- iounmap(channel->mapped);
+ memunmap(channel->mapped);
if (channel->requested)
release_mem_region(channel->physaddr, channel->nbytes);
}
@@ -241,7 +243,7 @@ visorchannel_read(struct visorchannel *channel, ulong offset,
if (offset + nbytes > channel->nbytes)
return -EIO;

- memcpy_fromio(local, channel->mapped + offset, nbytes);
+ memcpy(local, channel->mapped + offset, nbytes);

return 0;
}
@@ -262,7 +264,7 @@ visorchannel_write(struct visorchannel *channel, ulong offset,
memcpy(&channel->chan_hdr + offset, local, copy_size);
}

- memcpy_toio(channel->mapped + offset, local, nbytes);
+ memcpy(channel->mapped + offset, local, nbytes);

return 0;
}
diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c
index bb8087e70127..6d2ee282905d 100644
--- a/drivers/staging/unisys/visorbus/visorchipset.c
+++ b/drivers/staging/unisys/visorbus/visorchipset.c
@@ -119,7 +119,7 @@ static struct visorchannel *controlvm_channel;

/* Manages the request payload in the controlvm channel */
struct visor_controlvm_payload_info {
- u8 __iomem *ptr; /* pointer to base address of payload pool */
+ u8 *ptr; /* pointer to base address of payload pool */
u64 offset; /* offset from beginning of controlvm
* channel to beginning of payload * pool */
u32 bytes; /* number of bytes in payload pool */
@@ -401,21 +401,22 @@ parser_init_byte_stream(u64 addr, u32 bytes, bool local, bool *retry)
p = __va((unsigned long) (addr));
memcpy(ctx->data, p, bytes);
} else {
- void __iomem *mapping;
+ void *mapping;

if (!request_mem_region(addr, bytes, "visorchipset")) {
rc = NULL;
goto cleanup;
}

- mapping = ioremap_cache(addr, bytes);
+ mapping = memremap(addr, bytes, MEMREMAP_CACHE);
if (!mapping) {
release_mem_region(addr, bytes);
rc = NULL;
goto cleanup;
}
- memcpy_fromio(ctx->data, mapping, bytes);
+ memcpy(ctx->data, mapping, bytes);
release_mem_region(addr, bytes);
+ memunmap(mapping);
}

ctx->byte_stream = true;
@@ -1327,7 +1328,7 @@ static int
initialize_controlvm_payload_info(u64 phys_addr, u64 offset, u32 bytes,
struct visor_controlvm_payload_info *info)
{
- u8 __iomem *payload = NULL;
+ u8 *payload = NULL;
int rc = CONTROLVM_RESP_SUCCESS;

if (!info) {
@@ -1339,7 +1340,7 @@ initialize_controlvm_payload_info(u64 phys_addr, u64 offset, u32 bytes,
rc = -CONTROLVM_RESP_ERROR_PAYLOAD_INVALID;
goto cleanup;
}
- payload = ioremap_cache(phys_addr + offset, bytes);
+ payload = memremap(phys_addr + offset, bytes, MEMREMAP_CACHE);
if (!payload) {
rc = -CONTROLVM_RESP_ERROR_IOREMAP_FAILED;
goto cleanup;
@@ -1352,7 +1353,7 @@ initialize_controlvm_payload_info(u64 phys_addr, u64 offset, u32 bytes,
cleanup:
if (rc < 0) {
if (payload) {
- iounmap(payload);
+ memunmap(payload);
payload = NULL;
}
}
@@ -1363,7 +1364,7 @@ static void
destroy_controlvm_payload_info(struct visor_controlvm_payload_info *info)
{
if (info->ptr) {
- iounmap(info->ptr);
+ memunmap(info->ptr);
info->ptr = NULL;
}
memset(info, 0, sizeof(struct visor_controlvm_payload_info));

2015-07-25 02:45:20

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 17/25] intel-iommu: switch from ioremap_cache to memremap

In preparation for deprecating ioremap_cache() convert its usage in
intel-iommu to memremap. This also eliminates the mishandling of the
__iomem annotation in the implementation.

Cc: David Woodhouse <[email protected]>
Cc: Joerg Roedel <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
drivers/iommu/intel-iommu.c | 10 ++++++----
drivers/iommu/intel_irq_remapping.c | 4 ++--
2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index a98a7b27aca1..028ad0ff6abb 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -34,6 +34,7 @@
#include <linux/mempool.h>
#include <linux/memory.h>
#include <linux/timer.h>
+#include <linux/io.h>
#include <linux/iova.h>
#include <linux/iommu.h>
#include <linux/intel-iommu.h>
@@ -2871,7 +2872,8 @@ static int copy_context_table(struct intel_iommu *iommu,
}

ret = -ENOMEM;
- old_ce = ioremap_cache(old_ce_phys, PAGE_SIZE);
+ old_ce = memremap(old_ce_phys, PAGE_SIZE,
+ MEMREMAP_CACHE);
if (!old_ce)
goto out;

@@ -2919,7 +2921,7 @@ static int copy_context_table(struct intel_iommu *iommu,
__iommu_flush_cache(iommu, new_ce, VTD_PAGE_SIZE);

out_unmap:
- iounmap(old_ce);
+ memunmap(old_ce);

out:
return ret;
@@ -2953,7 +2955,7 @@ static int copy_translation_tables(struct intel_iommu *iommu)
if (!old_rt_phys)
return -EINVAL;

- old_rt = ioremap_cache(old_rt_phys, PAGE_SIZE);
+ old_rt = memremap(old_rt_phys, PAGE_SIZE, MEMREMAP_CACHE);
if (!old_rt)
return -ENOMEM;

@@ -3002,7 +3004,7 @@ static int copy_translation_tables(struct intel_iommu *iommu)
ret = 0;

out_unmap:
- iounmap(old_rt);
+ memunmap(old_rt);

return ret;
}
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c
index 27cdfa84ec5b..1da158d3b3ce 100644
--- a/drivers/iommu/intel_irq_remapping.c
+++ b/drivers/iommu/intel_irq_remapping.c
@@ -408,7 +408,7 @@ static int iommu_load_old_irte(struct intel_iommu *iommu)
size = INTR_REMAP_TABLE_ENTRIES*sizeof(struct irte);

/* Map the old IR table */
- old_ir_table = ioremap_cache(irt_phys, size);
+ old_ir_table = memremap(irt_phys, size, MEMREMAP_CACHE);
if (!old_ir_table)
return -ENOMEM;

@@ -426,7 +426,7 @@ static int iommu_load_old_irte(struct intel_iommu *iommu)
bitmap_set(iommu->ir_table->bitmap, i, 1);
}

- iounmap(old_ir_table);
+ memunmap(old_ir_table);

return 0;
}

2015-07-25 02:45:24

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 18/25] libnvdimm, pmem: switch from ioremap_cache to memremap

In preparation for deprecating ioremap_cache() convert its usage in
libnvdimm and the PMEM API to memremap.

Signed-off-by: Dan Williams <[email protected]>
---
arch/x86/include/asm/io.h | 7 +------
arch/x86/mm/ioremap.c | 6 ++++++
tools/testing/nvdimm/Kbuild | 2 +-
tools/testing/nvdimm/test/iomap.c | 6 +++---
4 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index cc9c61bc1abe..8aeb6456188a 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -248,12 +248,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);
-}
-
+void __pmem *arch_memremap_pmem(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 6f759c7c2ab7..7b422e7574b1 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -317,6 +317,12 @@ void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
}
EXPORT_SYMBOL(ioremap_cache);

+void __pmem *arch_memremap_pmem(resource_size_t offset, size_t size)
+{
+ return (void __force __pmem *) ioremap_cache(offset, size);
+}
+EXPORT_SYMBOL(arch_memremap_pmem);
+
void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
unsigned long prot_val)
{
diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild
index f56914c7929b..de2912ea78e8 100644
--- a/tools/testing/nvdimm/Kbuild
+++ b/tools/testing/nvdimm/Kbuild
@@ -1,7 +1,7 @@
ldflags-y += --wrap=ioremap_wt
ldflags-y += --wrap=ioremap_wc
ldflags-y += --wrap=devm_ioremap_nocache
-ldflags-y += --wrap=ioremap_cache
+ldflags-y += --wrap=arch_memremap_pmem
ldflags-y += --wrap=ioremap_nocache
ldflags-y += --wrap=iounmap
ldflags-y += --wrap=__request_region
diff --git a/tools/testing/nvdimm/test/iomap.c b/tools/testing/nvdimm/test/iomap.c
index 64bfaa50831c..f8486f98f860 100644
--- a/tools/testing/nvdimm/test/iomap.c
+++ b/tools/testing/nvdimm/test/iomap.c
@@ -80,11 +80,11 @@ 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_arch_memremap_pmem(resource_size_t offset, size_t size)
{
- return __nfit_test_ioremap(offset, size, ioremap_cache);
+ return __nfit_test_ioremap(offset, size, arch_memremap_pmem);
}
-EXPORT_SYMBOL(__wrap_ioremap_cache);
+EXPORT_SYMBOL(__wrap_arch_memremap_pmem);

void __iomem *__wrap_ioremap_nocache(resource_size_t offset, unsigned long size)
{

2015-07-25 02:47:50

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 19/25] pxa2xx-flash: switch from ioremap_cache to memremap

In preparation for deprecating ioremap_cache() convert its usage in
pxa2xx-flash to memremap.

Cc: David Woodhouse <[email protected]>
Cc: Brian Norris <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
drivers/mtd/maps/pxa2xx-flash.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
index 12fa75df5008..758a8a7f86d9 100644
--- a/drivers/mtd/maps/pxa2xx-flash.c
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -71,8 +71,8 @@ static int pxa2xx_flash_probe(struct platform_device *pdev)
info->map.name);
return -ENOMEM;
}
- info->map.cached =
- ioremap_cache(info->map.phys, info->map.size);
+ info->map.cached = memremap(info->map.phys, info->map.size,
+ MEMREMAP_CACHE);
if (!info->map.cached)
printk(KERN_WARNING "Failed to ioremap cached %s\n",
info->map.name);

2015-07-25 02:45:40

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 20/25] sfi: switch from ioremap_cache to memremap

In preparation for deprecating ioremap_cache() convert its usage in sfi
to memremap. It's a bit awkward that we go and add back a fake __iomem
annotation, but this is to keep consistency with early_ioremap() which
does not have a 'memremap' flavor.

Cc: Len Brown <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
drivers/sfi/sfi_core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/sfi/sfi_core.c b/drivers/sfi/sfi_core.c
index 296db7a69c27..1cccf31dfccc 100644
--- a/drivers/sfi/sfi_core.c
+++ b/drivers/sfi/sfi_core.c
@@ -101,7 +101,7 @@ static void __iomem * __ref sfi_map_memory(u64 phys, u32 size)
return NULL;

if (sfi_use_ioremap)
- return ioremap_cache(phys, size);
+ return (void __iomem *) memremap(phys, size, MEMREMAP_CACHE);
else
return early_ioremap(phys, size);
}
@@ -112,7 +112,7 @@ static void __ref sfi_unmap_memory(void __iomem *virt, u32 size)
return;

if (sfi_use_ioremap)
- iounmap(virt);
+ memunmap((void __force *) virt);
else
early_iounmap(virt, size);
}

2015-07-25 02:46:58

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 21/25] fbdev: switch from ioremap_wt to memremap

In preparation for deprecating ioremap_wt() convert its usage in
drivers/video/fbdev to memremap.

Cc: Jean-Christophe Plagniol-Villard <[email protected]>
Cc: Tomi Valkeinen <[email protected]>
Cc: [email protected]
Signed-off-by: Dan Williams <[email protected]>
---
drivers/video/fbdev/amifb.c | 5 +++--
drivers/video/fbdev/atafb.c | 5 +++--
drivers/video/fbdev/hpfb.c | 6 +++---
3 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/drivers/video/fbdev/amifb.c b/drivers/video/fbdev/amifb.c
index 1d702e13aaff..0cde451046d0 100644
--- a/drivers/video/fbdev/amifb.c
+++ b/drivers/video/fbdev/amifb.c
@@ -52,6 +52,7 @@
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h>
+#include <linux/io.h>

#include <asm/irq.h>
#include <asm/amigahw.h>
@@ -3705,8 +3706,8 @@ default_chipset:
* access the videomem with writethrough cache
*/
info->fix.smem_start = (u_long)ZTWO_PADDR(videomemory);
- videomemory = (u_long)ioremap_wt(info->fix.smem_start,
- info->fix.smem_len);
+ videomemory = (u_long)memremap(info->fix.smem_start, info->fix.smem_len,
+ MEMREMAP_WT);
if (!videomemory) {
dev_warn(&pdev->dev,
"Unable to map videomem cached writethrough\n");
diff --git a/drivers/video/fbdev/atafb.c b/drivers/video/fbdev/atafb.c
index d6ce613e12ad..5615e8c31ea2 100644
--- a/drivers/video/fbdev/atafb.c
+++ b/drivers/video/fbdev/atafb.c
@@ -55,12 +55,12 @@
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/io.h>

#include <asm/setup.h>
#include <linux/uaccess.h>
#include <asm/pgtable.h>
#include <asm/irq.h>
-#include <asm/io.h>

#include <asm/atarihw.h>
#include <asm/atariints.h>
@@ -3185,7 +3185,8 @@ int __init atafb_init(void)
/* Map the video memory (physical address given) to somewhere
* in the kernel address space.
*/
- external_screen_base = ioremap_wt(external_addr, external_len);
+ external_screen_base = memremap(external_addr, external_len,
+ MEMREMAP_WT);
if (external_vgaiobase)
external_vgaiobase =
(unsigned long)ioremap(external_vgaiobase, 0x10000);
diff --git a/drivers/video/fbdev/hpfb.c b/drivers/video/fbdev/hpfb.c
index 9476d196f510..d08c320b06fc 100644
--- a/drivers/video/fbdev/hpfb.c
+++ b/drivers/video/fbdev/hpfb.c
@@ -14,8 +14,8 @@
#include <linux/init.h>
#include <linux/fb.h>
#include <linux/dio.h>
+#include <linux/io.h>

-#include <asm/io.h>
#include <asm/uaccess.h>

static struct fb_info fb_info = {
@@ -241,8 +241,8 @@ static int hpfb_init_one(unsigned long phys_base, unsigned long virt_base)
fb_info.fix.line_length = fb_width;
fb_height = (in_8(fb_regs + HPFB_FBHMSB) << 8) | in_8(fb_regs + HPFB_FBHLSB);
fb_info.fix.smem_len = fb_width * fb_height;
- fb_start = (unsigned long)ioremap_wt(fb_info.fix.smem_start,
- fb_info.fix.smem_len);
+ fb_start = (unsigned long) memremap(fb_info.fix.smem_start,
+ fb_info.fix.smem_len, MEMREMAP_WT);
hpfb_defined.xres = (in_8(fb_regs + HPFB_DWMSB) << 8) | in_8(fb_regs + HPFB_DWLSB);
hpfb_defined.yres = (in_8(fb_regs + HPFB_DHMSB) << 8) | in_8(fb_regs + HPFB_DHLSB);
hpfb_defined.xres_virtual = hpfb_defined.xres;

2015-07-25 02:45:48

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 22/25] pmem: switch from ioremap_wt to memremap

In preparation for deprecating ioremap_wt() convert its usage in
the PMEM API to memremap.

Cc: Ross Zwisler <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
include/linux/pmem.h | 2 +-
tools/testing/nvdimm/Kbuild | 4 ++--
tools/testing/nvdimm/test/iomap.c | 34 +++++++++++++++++++++++++---------
3 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/include/linux/pmem.h b/include/linux/pmem.h
index d2114045a6c4..1bf74c735fa0 100644
--- a/include/linux/pmem.h
+++ b/include/linux/pmem.h
@@ -94,7 +94,7 @@ static void default_memcpy_to_pmem(void __pmem *dst, const void *src,
static void __pmem *default_memremap_pmem(resource_size_t offset,
unsigned long size)
{
- return (void __pmem __force *)ioremap_wt(offset, size);
+ return (void __pmem *) memremap(offset, size, MEMREMAP_WT);
}

/**
diff --git a/tools/testing/nvdimm/Kbuild b/tools/testing/nvdimm/Kbuild
index de2912ea78e8..8032a49f7873 100644
--- a/tools/testing/nvdimm/Kbuild
+++ b/tools/testing/nvdimm/Kbuild
@@ -1,7 +1,7 @@
-ldflags-y += --wrap=ioremap_wt
ldflags-y += --wrap=ioremap_wc
ldflags-y += --wrap=devm_ioremap_nocache
-ldflags-y += --wrap=arch_memremap_pmem
+ldflags-y += --wrap=memremap
+ldflags-y += --wrap=memunmap
ldflags-y += --wrap=ioremap_nocache
ldflags-y += --wrap=iounmap
ldflags-y += --wrap=__request_region
diff --git a/tools/testing/nvdimm/test/iomap.c b/tools/testing/nvdimm/test/iomap.c
index f8486f98f860..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 *__wrap_arch_memremap_pmem(resource_size_t offset, size_t size)
+void *__wrap_memremap(resource_size_t offset, size_t size,
+ unsigned long flags)
{
- return __nfit_test_ioremap(offset, size, arch_memremap_pmem);
+ 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_arch_memremap_pmem);
+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)

2015-07-25 02:45:56

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 23/25] arch: remove ioremap_cache, replace with arch_memremap

Now that all call sites for ioremap_cache() have been converted to
memremap(MEMREMAP_CACHE) we can now proceed with removing the
implementation in the archs. This amounts to replacing the per-arch
ioremap_cache() implementation with arch_memremap.

Cc: Arnd Bergmann <[email protected]>
Cc: Russell King <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Borislav Petkov <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
arch/arm/Kconfig | 1 +
arch/arm/include/asm/io.h | 11 ++++++++---
arch/arm/mm/ioremap.c | 12 ++++++++----
arch/arm/mm/nommu.c | 11 +++++++----
arch/arm64/Kconfig | 1 +
arch/arm64/include/asm/io.h | 7 ++++++-
arch/arm64/mm/ioremap.c | 20 +++++++-------------
arch/ia64/Kconfig | 1 +
arch/ia64/include/asm/io.h | 12 +++++++++---
arch/sh/Kconfig | 1 +
arch/sh/include/asm/io.h | 21 ++++++++++++++-------
arch/sh/mm/ioremap.c | 10 ++++++++++
arch/x86/Kconfig | 1 +
arch/x86/include/asm/io.h | 8 +++++++-
arch/x86/mm/ioremap.c | 20 +++++++++++++++-----
arch/xtensa/Kconfig | 1 +
arch/xtensa/include/asm/io.h | 9 ++++++---
drivers/nvdimm/Kconfig | 2 +-
kernel/Makefile | 2 +-
kernel/memremap.c | 14 +++-----------
lib/Kconfig | 5 ++++-
21 files changed, 112 insertions(+), 58 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/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 485982084fe9..989eeaa8dd84 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -355,7 +355,7 @@ static inline void memcpy_toio(volatile void __iomem *to, const void *from,
* Function Memory type Cacheability Cache hint
* ioremap() Device n/a n/a
* ioremap_nocache() Device n/a n/a
- * ioremap_cache() Normal Writeback Read allocate
+ * memremap(CACHE) Normal Writeback Read allocate
* ioremap_wc() Normal Non-cacheable n/a
* ioremap_wt() Normal Non-cacheable n/a
*
@@ -392,8 +392,8 @@ void __iomem *ioremap(resource_size_t res_cookie, size_t size);
#define ioremap ioremap
#define ioremap_nocache ioremap

-void __iomem *ioremap_cache(resource_size_t res_cookie, size_t size);
-#define ioremap_cache ioremap_cache
+void __iomem *arch_memremap(resource_size_t res_cookie, size_t size,
+ unsigned long flags);

void __iomem *ioremap_wc(resource_size_t res_cookie, size_t size);
#define ioremap_wc ioremap_wc
@@ -402,6 +402,11 @@ void __iomem *ioremap_wc(resource_size_t res_cookie, size_t size);
void iounmap(volatile void __iomem *iomem_cookie);
#define iounmap iounmap

+static inline void arch_memunmap(void *addr)
+{
+ iounmap((volatile void __iomem *) addr);
+}
+
/*
* io{read,write}{16,32}be() macros
*/
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 0c81056c1dd7..4e64247ba083 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -378,12 +378,16 @@ void __iomem *ioremap(resource_size_t res_cookie, size_t size)
}
EXPORT_SYMBOL(ioremap);

-void __iomem *ioremap_cache(resource_size_t res_cookie, size_t size)
+void *arch_memremap(resource_size_t res_cookie, size_t size,
+ unsigned long flags)
{
- return arch_ioremap_caller(res_cookie, size, MT_DEVICE_CACHED,
- __builtin_return_address(0));
+ if ((flags & MEMREMAP_CACHE) == 0)
+ return NULL;
+
+ return (void __force *) arch_ioremap_caller(res_cookie, size,
+ MT_DEVICE_CACHED, __builtin_return_address(0));
}
-EXPORT_SYMBOL(ioremap_cache);
+EXPORT_SYMBOL(arch_memremap);

void __iomem *ioremap_wc(resource_size_t res_cookie, size_t size)
{
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 1dd10936d68d..ec42be4d6e6e 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -366,12 +366,15 @@ void __iomem *ioremap(resource_size_t res_cookie, size_t size)
}
EXPORT_SYMBOL(ioremap);

-void __iomem *ioremap_cache(resource_size_t res_cookie, size_t size)
+void *arch_memremap(resource_size_t res_cookie, size_t size, unsigned long flags)
{
- return __arm_ioremap_caller(res_cookie, size, MT_DEVICE_CACHED,
- __builtin_return_address(0));
+ if ((flags & MEMREMAP_CACHE) == 0)
+ return NULL;
+
+ return (void __force *) __arm_ioremap_caller(res_cookie, size,
+ MT_DEVICE_CACHED, __builtin_return_address(0));
}
-EXPORT_SYMBOL(ioremap_cache);
+EXPORT_SYMBOL(arch_memremap);

void __iomem *ioremap_wc(resource_size_t res_cookie, size_t size)
{
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/include/asm/io.h b/arch/arm64/include/asm/io.h
index 44be1e03ed65..305d1c9b3352 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -165,7 +165,7 @@ 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);
+extern void *arch_memremap(phys_addr_t phys_addr, size_t size, unsigned long flags);

#define ioremap(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
#define ioremap_nocache(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
@@ -173,6 +173,11 @@ extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
#define ioremap_wt(addr, size) __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
#define iounmap __iounmap

+static inline void memunmap(void *addr)
+{
+ iounmap((volatile void __iomem *) addr);
+}
+
/*
* io{read,write}{16,32}be() macros
*/
diff --git a/arch/arm64/mm/ioremap.c b/arch/arm64/mm/ioremap.c
index 01e88c8bcab0..dc408d8db938 100644
--- a/arch/arm64/mm/ioremap.c
+++ b/arch/arm64/mm/ioremap.c
@@ -84,25 +84,19 @@ void __iounmap(volatile void __iomem *io_addr)
{
unsigned long addr = (unsigned long)io_addr & PAGE_MASK;

- /*
- * We could get an address outside vmalloc range in case
- * of ioremap_cache() reusing a RAM mapping.
- */
- if (VMALLOC_START <= addr && addr < VMALLOC_END)
- vunmap((void *)addr);
+ vunmap((void *)addr);
}
EXPORT_SYMBOL(__iounmap);

-void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size)
+void *arch_memremap(phys_addr_t phys_addr, size_t size, unsigned long flags)
{
- /* For normal memory we already have a cacheable mapping. */
- if (pfn_valid(__phys_to_pfn(phys_addr)))
- return (void __iomem *)__phys_to_virt(phys_addr);
+ if ((flags & MEMREMAP_CACHE) == 0)
+ return NULL;

- return __ioremap_caller(phys_addr, size, __pgprot(PROT_NORMAL),
- __builtin_return_address(0));
+ return (void __force *) __ioremap_caller(phys_addr, size,
+ __pgprot(PROT_NORMAL), __builtin_return_address(0));
}
-EXPORT_SYMBOL(ioremap_cache);
+EXPORT_SYMBOL(arch_memremap);

/*
* Must be called after early_fixmap_init
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 42a91a7aa2b0..aa83a5da1c99 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -52,6 +52,7 @@ config IA64
select HAVE_MOD_ARCH_SPECIFIC
select MODULES_USE_ELF_RELA
select ARCH_USE_CMPXCHG_LOCKREF
+ select ARCH_HAS_MEMREMAP
select HAVE_ARCH_AUDITSYSCALL
default y
help
diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h
index 9041bbe2b7b4..64e8e2fbf2b0 100644
--- a/arch/ia64/include/asm/io.h
+++ b/arch/ia64/include/asm/io.h
@@ -431,12 +431,18 @@ 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)
+
+/* caching type is determined internal to ioremap */
+static inline void *arch_memremap(resource_size_t offset, size_t size,
+ unsigned long flags)
{
- return ioremap(phys_addr, size);
+ return (void __force *) ioremap(offset, size);
}
-#define ioremap_cache ioremap_cache

+static inline void arch_memunmap(void *addr)
+{
+ iounmap((volatile void __iomem *) addr);
+}

/*
* String version of IO memory access ops:
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 50057fed819d..78d2bd6531cc 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -54,6 +54,7 @@ config SUPERH32
def_bool ARCH = "sh"
select HAVE_KPROBES
select HAVE_KRETPROBES
+ select ARCH_HAS_MEMREMAP
select HAVE_IOREMAP_PROT if MMU && !X2TLB
select HAVE_FUNCTION_TRACER
select HAVE_FTRACE_MCOUNT_RECORD
diff --git a/arch/sh/include/asm/io.h b/arch/sh/include/asm/io.h
index 6194e20fccca..aec5f5f8cde6 100644
--- a/arch/sh/include/asm/io.h
+++ b/arch/sh/include/asm/io.h
@@ -326,10 +326,19 @@ __ioremap_mode(phys_addr_t offset, unsigned long size, pgprot_t prot)

return __ioremap(offset, size, prot);
}
+
+void *arch_memremap(resource_size_t offset, unsigned long size,
+ unsigned long flags);
+
#else
#define __ioremap(offset, size, prot) ((void __iomem *)(offset))
#define __ioremap_mode(offset, size, prot) ((void __iomem *)(offset))
#define __iounmap(addr) do { } while (0)
+static inline void *arch_memremap(resource_size_t offset, size_t size,
+ unsigned long flags)
+{
+ return (void *) offset;
+}
#endif /* CONFIG_MMU */

static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
@@ -337,13 +346,6 @@ static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
return __ioremap_mode(offset, size, PAGE_KERNEL_NOCACHE);
}

-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 *
ioremap_prot(phys_addr_t offset, unsigned long size, unsigned long flags)
@@ -371,6 +373,11 @@ static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
#define ioremap_nocache ioremap
#define iounmap __iounmap

+static inline void arch_memunmap(void *addr)
+{
+ iounmap((void __iomem *) addr);
+}
+
/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
* access
diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c
index 0c99ec2e7ed8..40414bca4241 100644
--- a/arch/sh/mm/ioremap.c
+++ b/arch/sh/mm/ioremap.c
@@ -86,6 +86,16 @@ __ioremap_caller(phys_addr_t phys_addr, unsigned long size,
}
EXPORT_SYMBOL(__ioremap_caller);

+void *arch_memremap(resource_size_t offset, unsigned long size,
+ unsigned long flags)
+{
+ if ((flags & MEMREMAP_CACHE) == 0)
+ return NULL;
+
+ return (void __force *) __ioremap_mode(offset, size, PAGE_KERNEL);
+}
+EXPORT_SYMBOL(arch_memremap);
+
/*
* Simple checks for non-translatable mappings.
*/
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index b3a1a5d77d92..9c2fb6b896aa 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/include/asm/io.h b/arch/x86/include/asm/io.h
index 8aeb6456188a..d13ac9cbdc30 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -180,9 +180,10 @@ static inline unsigned int isa_virt_to_bus(volatile void *address)
*/
extern void __iomem *ioremap_nocache(resource_size_t offset, unsigned long size);
extern void __iomem *ioremap_uc(resource_size_t offset, unsigned long size);
-extern void __iomem *ioremap_cache(resource_size_t offset, unsigned long size);
extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size,
unsigned long prot_val);
+extern void *arch_memremap(resource_size_t offset, size_t size,
+ unsigned long flags);

/*
* The default ioremap() behavior is non-cached:
@@ -194,6 +195,11 @@ static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)

extern void iounmap(volatile void __iomem *addr);

+static inline void arch_memunmap(void *addr)
+{
+ iounmap((volatile void __iomem *) addr);
+}
+
extern void set_iounmap_nonlazy(void);

#ifdef __KERNEL__
diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 7b422e7574b1..8d5c88bcd09b 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -310,16 +310,26 @@ void __iomem *ioremap_wt(resource_size_t phys_addr, unsigned long size)
}
EXPORT_SYMBOL(ioremap_wt);

-void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
+void *arch_memremap(resource_size_t phys_addr, size_t size,
+ unsigned long flags)
{
- return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WB,
- __builtin_return_address(0));
+ int prot;
+
+ if (flags & MEMREMAP_CACHE)
+ prot = _PAGE_CACHE_MODE_WB;
+ else if (flags & MEMREMAP_WT)
+ prot = _PAGE_CACHE_MODE_WT;
+ else
+ return NULL;
+
+ return (void __force *) __ioremap_caller(phys_addr, size, prot,
+ __builtin_return_address(0));
}
-EXPORT_SYMBOL(ioremap_cache);
+EXPORT_SYMBOL(arch_memremap);

void __pmem *arch_memremap_pmem(resource_size_t offset, size_t size)
{
- return (void __force __pmem *) ioremap_cache(offset, size);
+ return (void __pmem *) arch_memremap(offset, size, MEMREMAP_CACHE);
}
EXPORT_SYMBOL(arch_memremap_pmem);

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/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index 867840f5400f..da6c8290e432 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -48,8 +48,8 @@ static inline void __iomem *ioremap_nocache(unsigned long offset,
BUG();
}

-static inline void __iomem *ioremap_cache(unsigned long offset,
- unsigned long size)
+static inline void *arch_memremap(resource_size_t offset, size_t size,
+ unsigned long flags)
{
if (offset >= XCHAL_KIO_PADDR
&& offset - XCHAL_KIO_PADDR < XCHAL_KIO_SIZE)
@@ -57,7 +57,6 @@ 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
@@ -71,6 +70,10 @@ static inline void iounmap(volatile void __iomem *addr)
{
}

+static inline void memunmap(void *addr)
+{
+}
+
#define virt_to_bus virt_to_phys
#define bus_to_virt phys_to_virt

diff --git a/drivers/nvdimm/Kconfig b/drivers/nvdimm/Kconfig
index 72226acb5c0f..1c249926b6d0 100644
--- a/drivers/nvdimm/Kconfig
+++ b/drivers/nvdimm/Kconfig
@@ -1,5 +1,6 @@
menuconfig LIBNVDIMM
tristate "NVDIMM (Non-Volatile Memory Device) Support"
+ depends on ARCH_HAS_MEMREMAP
depends on PHYS_ADDR_T_64BIT
depends on BLK_DEV
help
@@ -19,7 +20,6 @@ if LIBNVDIMM
config BLK_DEV_PMEM
tristate "PMEM: Persistent memory block device support"
default LIBNVDIMM
- depends on HAS_IOMEM
select ND_BTT if BTT
help
Memory ranges for PMEM are described by either an NFIT
diff --git a/kernel/Makefile b/kernel/Makefile
index 92866d36e376..6d12e8006150 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -99,7 +99,7 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o
obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
obj-$(CONFIG_TORTURE_TEST) += torture.o

-obj-$(CONFIG_HAS_IOMEM) += memremap.o
+obj-$(CONFIG_ARCH_HAS_MEMREMAP) += memremap.o

$(obj)/configs.o: $(obj)/config_data.h

diff --git a/kernel/memremap.c b/kernel/memremap.c
index ba206fd11785..c99aa4f12e2b 100644
--- a/kernel/memremap.c
+++ b/kernel/memremap.c
@@ -14,14 +14,6 @@
#include <linux/io.h>
#include <linux/mm.h>

-#ifndef ioremap_cache
-/* temporary while we convert existing ioremap_cache users to memremap */
-__weak void __iomem *ioremap_cache(resource_size_t offset, unsigned long size)
-{
- return ioremap(offset, size);
-}
-#endif
-
/*
* memremap() is "ioremap" for cases where it is known that the resource
* being mapped does not have i/o side effects and the __iomem
@@ -50,7 +42,7 @@ void *memremap(resource_size_t offset, size_t size, unsigned long flags)
if (is_ram)
addr = __va(offset);
else
- addr = ioremap_cache(offset, size);
+ addr = arch_memremap(offset, size, MEMREMAP_CACHE);
}

/*
@@ -67,7 +59,7 @@ void *memremap(resource_size_t offset, size_t size, unsigned long flags)

if (!addr && (flags & MEMREMAP_WT)) {
flags &= ~MEMREMAP_WT;
- addr = ioremap_wt(offset, size);
+ addr = arch_memremap(offset, size, MEMREMAP_WT);
}

return addr;
@@ -77,6 +69,6 @@ EXPORT_SYMBOL(memremap);
void memunmap(void *addr)
{
if (is_vmalloc_addr(addr))
- iounmap((void __iomem *) addr);
+ arch_memunmap(addr);
}
EXPORT_SYMBOL(memunmap);
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

2015-07-25 02:46:01

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 24/25] arch: remove ioremap_wt, replace with arch_memremap

Now that all call sites for ioremap_wt() have been converted to
memremap(MEMREMAP_WT) we can now proceed with removing the
implementation in the archs. This amounts to replacing the per-arch
ioremap_wt() implementation with arch_memremap.

Cc: Arnd Bergmann <[email protected]>
Cc: Russell King <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Borislav Petkov <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
arch/arc/include/asm/io.h | 1 -
arch/arm/include/asm/io.h | 2 --
arch/arm64/include/asm/io.h | 1 -
arch/avr32/include/asm/io.h | 1 -
arch/frv/Kconfig | 1 +
arch/frv/include/asm/io.h | 17 ++++++-----------
arch/frv/mm/kmap.c | 6 ++++++
arch/m32r/include/asm/io.h | 1 -
arch/m68k/Kconfig | 1 +
arch/m68k/include/asm/io_mm.h | 14 ++------------
arch/m68k/include/asm/io_no.h | 12 ++++++------
arch/m68k/include/asm/raw_io.h | 4 ++++
arch/m68k/mm/kmap.c | 17 ++++++++++++++++-
arch/m68k/mm/sun3kmap.c | 6 ++++++
arch/metag/include/asm/io.h | 3 ---
arch/microblaze/include/asm/io.h | 1 -
arch/mn10300/include/asm/io.h | 1 -
arch/nios2/include/asm/io.h | 1 -
arch/s390/include/asm/io.h | 1 -
arch/sparc/include/asm/io_32.h | 1 -
arch/sparc/include/asm/io_64.h | 1 -
arch/tile/include/asm/io.h | 1 -
arch/x86/include/asm/io.h | 2 --
arch/x86/mm/ioremap.c | 17 -----------------
arch/xtensa/include/asm/io.h | 1 -
drivers/video/fbdev/Kconfig | 2 +-
include/asm-generic/io.h | 8 --------
include/asm-generic/iomap.h | 4 ----
28 files changed, 49 insertions(+), 79 deletions(-)

diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h
index 694ece8a0243..00f97a2f5fa6 100644
--- a/arch/arc/include/asm/io.h
+++ b/arch/arc/include/asm/io.h
@@ -20,7 +20,6 @@ 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 989eeaa8dd84..89114571cf11 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -357,7 +357,6 @@ static inline void memcpy_toio(volatile void __iomem *to, const void *from,
* ioremap_nocache() Device n/a n/a
* memremap(CACHE) Normal Writeback Read allocate
* ioremap_wc() Normal Non-cacheable n/a
- * ioremap_wt() Normal Non-cacheable n/a
*
* All device mappings have the following properties:
* - no access speculation
@@ -397,7 +396,6 @@ void __iomem *arch_memremap(resource_size_t res_cookie, size_t size,

void __iomem *ioremap_wc(resource_size_t res_cookie, size_t 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/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 305d1c9b3352..a03157daeb1c 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -170,7 +170,6 @@ extern void *arch_memremap(phys_addr_t phys_addr, size_t size, unsigned long fla
#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 memunmap(void *addr)
diff --git a/arch/avr32/include/asm/io.h b/arch/avr32/include/asm/io.h
index e998ff5d8e1a..4f5ec2bb7172 100644
--- a/arch/avr32/include/asm/io.h
+++ b/arch/avr32/include/asm/io.h
@@ -296,7 +296,6 @@ extern void __iounmap(void __iomem *addr);
__iounmap(addr)

#define ioremap_wc ioremap_nocache
-#define ioremap_wt ioremap_nocache

#define cached(addr) P1SEGADDR(addr)
#define uncached(addr) P2SEGADDR(addr)
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index 34aa19352dc1..b1b4000807fb 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -7,6 +7,7 @@ config FRV
select HAVE_UID16
select VIRT_TO_BUS
select GENERIC_IRQ_SHOW
+ select ARCH_HAS_MEMREMAP
select HAVE_DEBUG_BUGVERBOSE
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_CPU_DEVICES
diff --git a/arch/frv/include/asm/io.h b/arch/frv/include/asm/io.h
index a31b63ec4930..3e908abc41cd 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>
@@ -267,20 +265,17 @@ static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned lon
return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
}

-static inline void __iomem *ioremap_wt(unsigned long physaddr, unsigned long size)
-{
- return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
-}
-
-static inline void __iomem *ioremap_fullcache(unsigned long physaddr, unsigned long size)
-{
- return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
-}
+void *arch_memremap(resource_size_t offset, size_t size, unsigned long flags);

#define ioremap_wc ioremap_nocache

extern void iounmap(void volatile __iomem *addr);

+static inline void arch_memunmap(void *addr)
+{
+ iounmap((volatile void __force *) addr);
+}
+
static inline void __iomem *ioport_map(unsigned long port, unsigned int nr)
{
return (void __iomem *) port;
diff --git a/arch/frv/mm/kmap.c b/arch/frv/mm/kmap.c
index e9217e605aa8..ba7d73383c10 100644
--- a/arch/frv/mm/kmap.c
+++ b/arch/frv/mm/kmap.c
@@ -34,6 +34,12 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cachefla
return (void __iomem *)physaddr;
}

+void *arch_memremap(resource_size_t offset, size_t size, unsigned long flags)
+{
+ return (void *) offset;
+}
+EXPORT_SYMBOL(arch_memremap);
+
/*
* Unmap a ioremap()ed region again
*/
diff --git a/arch/m32r/include/asm/io.h b/arch/m32r/include/asm/io.h
index 0c3f25ee3381..9cc00dbd59ce 100644
--- a/arch/m32r/include/asm/io.h
+++ b/arch/m32r/include/asm/io.h
@@ -68,7 +68,6 @@ static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
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

/*
* IO bus memory addresses are also 1:1 with the physical address
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 2dd8f63bfbbb..693d06dc0a40 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -9,6 +9,7 @@ config M68K
select GENERIC_ATOMIC64
select HAVE_UID16
select VIRT_TO_BUS
+ select ARCH_HAS_MEMREMAP
select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
select GENERIC_CPU_DEVICES
select GENERIC_IOMAP
diff --git a/arch/m68k/include/asm/io_mm.h b/arch/m68k/include/asm/io_mm.h
index f55cad529400..c91872e62dc3 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>
@@ -468,16 +466,8 @@ static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned lon
{
return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
}
-static inline void __iomem *ioremap_wt(unsigned long physaddr,
- unsigned long size)
-{
- return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
-}
-static inline void __iomem *ioremap_fullcache(unsigned long physaddr,
- unsigned long size)
-{
- return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
-}
+
+void *arch_memremap(resource_size_t offset, size_t size, unsigned long flags);

static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
{
diff --git a/arch/m68k/include/asm/io_no.h b/arch/m68k/include/asm/io_no.h
index ad7bd40e6742..008633ba49ce 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>

@@ -155,13 +153,15 @@ static inline void *ioremap_nocache(unsigned long physaddr, unsigned long size)
{
return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
}
-static inline void *ioremap_wt(unsigned long physaddr, unsigned long size)
+
+static inline void *arch_memremap(resource_size_t offset, size_t size,
+ unsigned long flags)
{
- return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
+ return (void *) offset;
}
-static inline void *ioremap_fullcache(unsigned long physaddr, unsigned long size)
+
+static inline void arch_memunmap(void *addr)
{
- return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
}

#define iounmap(addr) do { } while(0)
diff --git a/arch/m68k/include/asm/raw_io.h b/arch/m68k/include/asm/raw_io.h
index 932faa35655b..f6f1448407d9 100644
--- a/arch/m68k/include/asm/raw_io.h
+++ b/arch/m68k/include/asm/raw_io.h
@@ -25,6 +25,10 @@ extern void __iomem *__ioremap(unsigned long physaddr, unsigned long size,
int cacheflag);
extern void __iounmap(void *addr, unsigned long size);

+static inline void arch_memunmap(void *addr)
+{
+ iounmap((void __iomem *) addr);
+}

/* ++roman: The assignments to temp. vars avoid that gcc sometimes generates
* two accesses to memory, which may be undesirable for some devices.
diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c
index 6e4955bc542b..94f334af9a63 100644
--- a/arch/m68k/mm/kmap.c
+++ b/arch/m68k/mm/kmap.c
@@ -14,12 +14,12 @@
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#include <linux/io.h>

#include <asm/setup.h>
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/pgalloc.h>
-#include <asm/io.h>

#undef DEBUG

@@ -223,6 +223,21 @@ void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cachefla
}
EXPORT_SYMBOL(__ioremap);

+void *arch_memremap(resource_size_t offset, size_t size, unsigned long flags)
+{
+ int mode;
+
+ if (flags & MEMREMAP_CACHE)
+ mode = IOMAP_FULL_CACHING;
+ else if (flags & MEMREMAP_WT)
+ mode = IOMAP_WRITETHROUGH;
+ else
+ return NULL;
+
+ return (void __force *) __ioremap(offset, size, mode);
+}
+EXPORT_SYMBOL(arch_memremap);
+
/*
* Unmap an ioremap()ed region again
*/
diff --git a/arch/m68k/mm/sun3kmap.c b/arch/m68k/mm/sun3kmap.c
index 3dc41158c05e..46af60b7f0c7 100644
--- a/arch/m68k/mm/sun3kmap.c
+++ b/arch/m68k/mm/sun3kmap.c
@@ -116,6 +116,12 @@ void __iomem *__ioremap(unsigned long phys, unsigned long size, int cache)
}
EXPORT_SYMBOL(__ioremap);

+void *arch_memremap(resource_size_t offset, size_t size, unsigned long flags)
+{
+ return (void __force *) sun3_ioremap(offset, size, SUN3_PAGE_TYPE_IO);
+}
+EXPORT_SYMBOL(arch_memremap);
+
void iounmap(void __iomem *addr)
{
vfree((void *)(PAGE_MASK & (unsigned long)addr));
diff --git a/arch/metag/include/asm/io.h b/arch/metag/include/asm/io.h
index 9890f21eadbe..d5779b0ec573 100644
--- a/arch/metag/include/asm/io.h
+++ b/arch/metag/include/asm/io.h
@@ -160,9 +160,6 @@ extern void __iounmap(void __iomem *addr);
#define ioremap_wc(offset, size) \
__ioremap((offset), (size), _PAGE_WR_COMBINE)

-#define ioremap_wt(offset, size) \
- __ioremap((offset), (size), 0)
-
#define iounmap(addr) \
__iounmap(addr)

diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h
index 39b6315db82e..4efa4fd023bd 100644
--- a/arch/microblaze/include/asm/io.h
+++ b/arch/microblaze/include/asm/io.h
@@ -42,7 +42,6 @@ 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/mn10300/include/asm/io.h b/arch/mn10300/include/asm/io.h
index 07c5b4a3903b..cc4a2ba9e228 100644
--- a/arch/mn10300/include/asm/io.h
+++ b/arch/mn10300/include/asm/io.h
@@ -282,7 +282,6 @@ static inline void __iomem *ioremap_nocache(unsigned long offset, unsigned long
}

#define ioremap_wc ioremap_nocache
-#define ioremap_wt ioremap_nocache

static inline void iounmap(void __iomem *addr)
{
diff --git a/arch/nios2/include/asm/io.h b/arch/nios2/include/asm/io.h
index c5a62da22cd2..6e24d7cceb0c 100644
--- a/arch/nios2/include/asm/io.h
+++ b/arch/nios2/include/asm/io.h
@@ -46,7 +46,6 @@ static inline void iounmap(void __iomem *addr)
}

#define ioremap_wc ioremap_nocache
-#define ioremap_wt ioremap_nocache

/* Pages to physical address... */
#define page_to_phys(page) virt_to_phys(page_to_virt(page))
diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h
index cb5fdf3a78fc..30fd5c84680e 100644
--- a/arch/s390/include/asm/io.h
+++ b/arch/s390/include/asm/io.h
@@ -29,7 +29,6 @@ void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr);

#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)
{
diff --git a/arch/sparc/include/asm/io_32.h b/arch/sparc/include/asm/io_32.h
index 57f26c398dc9..407ac14295f4 100644
--- a/arch/sparc/include/asm/io_32.h
+++ b/arch/sparc/include/asm/io_32.h
@@ -129,7 +129,6 @@ static inline void sbus_memcpy_toio(volatile void __iomem *dst,
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);

/* Create a virtual mapping cookie for an IO port range */
diff --git a/arch/sparc/include/asm/io_64.h b/arch/sparc/include/asm/io_64.h
index c32fa3f752c8..50d4840d9aeb 100644
--- a/arch/sparc/include/asm/io_64.h
+++ b/arch/sparc/include/asm/io_64.h
@@ -402,7 +402,6 @@ static inline 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))

static inline void iounmap(volatile void __iomem *addr)
{
diff --git a/arch/tile/include/asm/io.h b/arch/tile/include/asm/io.h
index dc61de15c1f9..eece4fc730e4 100644
--- a/arch/tile/include/asm/io.h
+++ b/arch/tile/include/asm/io.h
@@ -54,7 +54,6 @@ extern void iounmap(volatile void __iomem *addr);

#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 mmiowb()
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index d13ac9cbdc30..bba4e8968bc7 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -35,7 +35,6 @@
*/

#define ARCH_HAS_IOREMAP_WC
-#define ARCH_HAS_IOREMAP_WT

#include <linux/string.h>
#include <linux/compiler.h>
@@ -328,7 +327,6 @@ 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);
-extern void __iomem *ioremap_wt(resource_size_t offset, unsigned long size);

extern bool is_early_ioremap_ptep(pte_t *ptep);

diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c
index 8d5c88bcd09b..987a58e84e2f 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -293,23 +293,6 @@ void __iomem *ioremap_wc(resource_size_t phys_addr, unsigned long size)
}
EXPORT_SYMBOL(ioremap_wc);

-/**
- * ioremap_wt - map memory into CPU space write through
- * @phys_addr: bus address of the memory
- * @size: size of the resource to map
- *
- * This version of ioremap ensures that the memory is marked write through.
- * Write through stores data into memory while keeping the cache up-to-date.
- *
- * Must be freed with iounmap.
- */
-void __iomem *ioremap_wt(resource_size_t phys_addr, unsigned long size)
-{
- return __ioremap_caller(phys_addr, size, _PAGE_CACHE_MODE_WT,
- __builtin_return_address(0));
-}
-EXPORT_SYMBOL(ioremap_wt);
-
void *arch_memremap(resource_size_t phys_addr, size_t size,
unsigned long flags)
{
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index da6c8290e432..b9fdd90e89da 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -59,7 +59,6 @@ static inline void *arch_memremap(resource_size_t offset, size_t size,
}

#define ioremap_wc ioremap_nocache
-#define ioremap_wt ioremap_nocache

static inline void __iomem *ioremap(unsigned long offset, unsigned long size)
{
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 2d98de535e0f..b76ec47c6810 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -699,7 +699,7 @@ config FB_MAC

config FB_HP300
bool
- depends on (FB = y) && DIO
+ depends on (FB = y) && DIO && ARCH_HAS_MEMREMAP
select FB_CFB_IMAGEBLIT
default y

diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h
index f56094cfdeff..f5abd5540249 100644
--- a/include/asm-generic/io.h
+++ b/include/asm-generic/io.h
@@ -785,14 +785,6 @@ static inline void __iomem *ioremap_wc(phys_addr_t offset, size_t size)
}
#endif

-#ifndef ioremap_wt
-#define ioremap_wt ioremap_wt
-static inline void __iomem *ioremap_wt(phys_addr_t offset, size_t size)
-{
- return ioremap_nocache(offset, size);
-}
-#endif
-
#ifndef iounmap
#define iounmap iounmap

diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h
index d8f8622fa044..1b41011643a5 100644
--- a/include/asm-generic/iomap.h
+++ b/include/asm-generic/iomap.h
@@ -66,10 +66,6 @@ extern void ioport_unmap(void __iomem *);
#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;

2015-07-25 02:46:09

by Dan Williams

[permalink] [raw]
Subject: [PATCH v2 25/25] pmem: convert to generic memremap

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 <[email protected]>
Signed-off-by: Dan Williams <[email protected]>
---
arch/x86/include/asm/io.h | 2 +-
arch/x86/mm/ioremap.c | 16 ++++++++++------
include/linux/pmem.h | 26 +++++++++++++++-----------
3 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index bba4e8968bc7..1388d7d27775 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -253,7 +253,7 @@ static inline void flush_write_buffers(void)
#endif
}

-void __pmem *arch_memremap_pmem(resource_size_t offset, size_t 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 987a58e84e2f..d4a67223f6e9 100644
--- a/arch/x86/mm/ioremap.c
+++ b/arch/x86/mm/ioremap.c
@@ -205,6 +205,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;
+}
+EXPORT_SYMBOL(arch_memremap_pmem_flags);
+
/**
* ioremap_nocache - map bus memory into CPU space
* @phys_addr: bus address of the memory
@@ -310,12 +320,6 @@ void *arch_memremap(resource_size_t phys_addr, size_t size,
}
EXPORT_SYMBOL(arch_memremap);

-void __pmem *arch_memremap_pmem(resource_size_t offset, size_t size)
-{
- return (void __pmem *) arch_memremap(offset, size, MEMREMAP_CACHE);
-}
-EXPORT_SYMBOL(arch_memremap_pmem);
-
void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
unsigned long prot_val)
{
diff --git a/include/linux/pmem.h b/include/linux/pmem.h
index 1bf74c735fa0..03f9d73f3e13 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)
@@ -54,7 +54,7 @@ static inline void memcpy_from_pmem(void *dst, void __pmem const *src, size_t si

static inline void memunmap_pmem(void __pmem *addr)
{
- iounmap((void __force __iomem *) addr);
+ memunmap((void __force *) addr);
}

/**
@@ -85,16 +85,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 *) memremap(offset, size, MEMREMAP_WT);
+ return MEMREMAP_WT;
}

/**
@@ -112,9 +111,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);
}

/**

2015-07-25 22:02:39

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [PATCH v2 15/25] memconsole: fix __iomem mishandling, switch to memremap

Hello.

On 07/25/2015 05:39 AM, Dan Williams wrote:

> The memconsole driver is not using proper accessors for __iomem. Switch
> to memremap to fix this issue, and this also prepares the driver for the
> removal of ioremap_cache.

> Cc: Mike Waychison <[email protected]>
> Signed-off-by: Dan Williams <[email protected]>
> ---
> drivers/firmware/google/memconsole.c | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)

> diff --git a/drivers/firmware/google/memconsole.c b/drivers/firmware/google/memconsole.c
> index 2f569aaed4c7..1b25fba84f32 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);

Could you maintain the existing style of the broken line alignment in this
file?

> if (!memconsole) {
> - pr_err("memconsole: ioremap_cache failed\n");
> + pr_err("memconsole: memremap failed\n");
> return -ENOMEM;
> }
> ret = memory_read_from_buffer(buf, count, &pos, memconsole,
> memconsole_length);

Here's an example...

> - iounmap(memconsole);
> + memunmap(memconsole);
> return ret;
> }

MBR, Sergei

2015-07-25 23:29:06

by Rafael J. Wysocki

[permalink] [raw]
Subject: Re: [PATCH v2 13/25] acpi: switch from ioremap_cache to memremap

On Friday, July 24, 2015 10:39:09 PM Dan Williams wrote:
> In preparation for deprecating ioremap_cache() convert its usage in
> drivers/acpi and include/acpi/ to memremap. This includes dropping the
> __iomem annotation throughout ACPI since the memremap can be treated as
> a normal memory pointer.
>
> Finally, memremap automatically handles requests to map normal memory
> pages, so this also drops the calls to "should_use_kmap()".
>
> Cc: Bob Moore <[email protected]>
> Cc: Lv Zheng <[email protected]>
> Cc: Rafael J. Wysocki <[email protected]>
> Signed-off-by: Dan Williams <[email protected]>
> ---
> arch/arm64/include/asm/acpi.h | 5 +--
> drivers/acpi/apei/einj.c | 9 +++--
> drivers/acpi/apei/erst.c | 6 ++--
> drivers/acpi/nvs.c | 6 ++--
> drivers/acpi/osl.c | 70 +++++++++++------------------------------
> include/acpi/acpi_io.h | 6 ++--
> 6 files changed, 35 insertions(+), 67 deletions(-)

Need to talk to Bob/Lv about the name change in acpi_io.h.

Apart from that I have no objections.

Thanks,
Rafael

2015-07-26 17:25:30

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Fri, Jul 24, 2015 at 10:38:42PM -0400, Dan Williams wrote:
> The behavior change to return NULL on an unsupported request is reserved
> for a later patch.

Why?

> +enum {
> + MEMREMAP_WB = 1 << 0,
> + MEMREMAP_WT = 1 << 1,
> + MEMREMAP_CACHE = MEMREMAP_WB,

What's the point of having this MEMREMAP_CACHE alias?

Also please document the meaning of the flags for the poor users.

2015-07-26 17:31:18

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH v2 23/25] arch: remove ioremap_cache, replace with arch_memremap

On Fri, Jul 24, 2015 at 10:40:07PM -0400, Dan Williams wrote:
> Now that all call sites for ioremap_cache() have been converted to
> memremap(MEMREMAP_CACHE) we can now proceed with removing the
> implementation in the archs. This amounts to replacing the per-arch
> ioremap_cache() implementation with arch_memremap.

Please have prototypes for arch_memremap and arch_memunmap in
linux/io.h so that we enforce common prototypes. This also
forces arch_memunmap to be out of line which makes sense for such
a slow patch API.

Also while you're at it please convert the ioremap_cached implementations
on metag and unicore32 which looks like misspellings, fix up the comment
in arch/arm/mm/mmu.c and the documentation in Documentation/x86/pat.txt
to not longer refer to ioremap_cache.

2015-07-26 17:31:44

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH v2 24/25] arch: remove ioremap_wt, replace with arch_memremap

Documentation/x86/pat.txt needs to be updated for this change as well.

2015-07-26 17:33:20

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH v2 25/25] pmem: convert to generic memremap

On Fri, Jul 24, 2015 at 10:40:20PM -0400, Dan Williams wrote:
> 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.

I don't think the pmem driver should look at a arch hook here, please
communicate this through the nvdimm subsystem.

Btw, looking at these changes I also think the __pmem annotations
are mistake. We might have all kinds of ways to write to pmem,
and as long as we properly flush it we don't need to force it
through the special accessors. This becomes really interesting
for PCI DMA access.

2015-07-26 17:49:42

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Sun, Jul 26, 2015 at 10:25 AM, Christoph Hellwig <[email protected]> wrote:
> On Fri, Jul 24, 2015 at 10:38:42PM -0400, Dan Williams wrote:
>> The behavior change to return NULL on an unsupported request is reserved
>> for a later patch.
>
> Why?

This is for drivers like pmem that care about the mapping type. For
example, if pmem can't get a cache-enabled mapping it is potentially
putting the write durability of the persistent media at risk.

>> +enum {
>> + MEMREMAP_WB = 1 << 0,
>> + MEMREMAP_WT = 1 << 1,
>> + MEMREMAP_CACHE = MEMREMAP_WB,
>
> What's the point of having this MEMREMAP_CACHE alias?

For developers that are used to seeing ioremap_cache()...

> Also please document the meaning of the flags for the poor users.

Will do. I'll mostly borrow from the x86 mapping type definitions,
but these will also have architecture specific semantics /
constraints.

2015-07-26 18:11:47

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH v2 25/25] pmem: convert to generic memremap

On Sun, Jul 26, 2015 at 10:33 AM, Christoph Hellwig <[email protected]> wrote:
> On Fri, Jul 24, 2015 at 10:40:20PM -0400, Dan Williams wrote:
>> 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.
>
> I don't think the pmem driver should look at a arch hook here, please
> communicate this through the nvdimm subsystem.
>
> Btw, looking at these changes I also think the __pmem annotations
> are mistake. We might have all kinds of ways to write to pmem,
> and as long as we properly flush it we don't need to force it
> through the special accessors. This becomes really interesting
> for PCI DMA access.

I don't follow. We have __iomem for the cpu mapping of a resource and
dma_map() for a PCI device. __pmem works the same and is there to
make sure someone doesn't simply de-reference a pointer to pmem and
hope that the write is persistent.

2015-07-27 05:12:20

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Sun, Jul 26, 2015 at 10:49:39AM -0700, Dan Williams wrote:
> > What's the point of having this MEMREMAP_CACHE alias?
>
> For developers that are used to seeing ioremap_cache()...

Meh. We've got git logs that show clearly what replaced a previous API.
Duplicate names for the same API are highly confusing.

2015-07-27 05:13:02

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Sun, Jul 26, 2015 at 10:49:39AM -0700, Dan Williams wrote:
> On Sun, Jul 26, 2015 at 10:25 AM, Christoph Hellwig <[email protected]> wrote:
> > On Fri, Jul 24, 2015 at 10:38:42PM -0400, Dan Williams wrote:
> >> The behavior change to return NULL on an unsupported request is reserved
> >> for a later patch.
> >
> > Why?
>
> This is for drivers like pmem that care about the mapping type. For
> example, if pmem can't get a cache-enabled mapping it is potentially
> putting the write durability of the persistent media at risk.

I understand that part, but the question is why the old behavior
is retained for now and only changed later.

2015-07-27 05:14:17

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH v2 25/25] pmem: convert to generic memremap

On Sun, Jul 26, 2015 at 11:11:44AM -0700, Dan Williams wrote:
> I don't follow. We have __iomem for the cpu mapping of a resource and
> dma_map() for a PCI device. __pmem works the same and is there to
> make sure someone doesn't simply de-reference a pointer to pmem and
> hope that the write is persistent.

But no deference of a kernel pointer is magily persistent, so I'm
not really worried about that. It just means whenever we want to
pass it to anything we'll need to cast. And anything that does
I/O falls into that category.

2015-07-27 07:48:14

by Daniel Vetter

[permalink] [raw]
Subject: Re: [Intel-gfx] [PATCH v2 12/25] i915: switch from acpi_os_ioremap to ioremap

On Fri, Jul 24, 2015 at 10:39:04PM -0400, Dan Williams wrote:
> acpi_os_ioremap uses cached mappings, however it appears that i915
> wants to read dynamic platform state. Switch to ioremap() to prevent it
> reading stale state from cache.
>
> Cc: Daniel Vetter <[email protected]>
> Cc: Jani Nikula <[email protected]>
> Cc: [email protected]
> Cc: David Airlie <[email protected]>
> Cc: [email protected]
> Signed-off-by: Dan Williams <[email protected]>
> ---
> drivers/gpu/drm/i915/intel_opregion.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c
> index 481337436f72..16ba7c67410d 100644
> --- a/drivers/gpu/drm/i915/intel_opregion.c
> +++ b/drivers/gpu/drm/i915/intel_opregion.c
> @@ -863,7 +863,7 @@ int intel_opregion_setup(struct drm_device *dev)
> INIT_WORK(&opregion->asle_work, asle_work);
> #endif
>
> - base = acpi_os_ioremap(asls, OPREGION_SIZE);
> + base = ioremap(asls, OPREGION_SIZE);

OpRegion is cached memory shared with the firmware afaik, we probably want
a memremap here and switch away from the ioread/write stuff. We have a
similar confusion going on for the vbt parsing (which on anything but
really old machines is also just normal memory).

Same holds for gma500, which is just a copy of i915 for some special
platforms.
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

2015-07-27 08:03:53

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH v2 24/25] arch: remove ioremap_wt, replace with arch_memremap

> +++ 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>
> @@ -267,20 +265,17 @@ static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned lon
> return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
> }
>
> -static inline void __iomem *ioremap_wt(unsigned long physaddr, unsigned long size)
> -{
> - return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
> -}
> -
> -static inline void __iomem *ioremap_fullcache(unsigned long physaddr, unsigned long size)
> -{
> - return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
> -}


> +void *arch_memremap(resource_size_t offset, size_t size, unsigned long flags)
> +{
> + return (void *) offset;
> +}
> +EXPORT_SYMBOL(arch_memremap);

This doesn't look like a correct replacement.

Also shouldn't the replacements of ioremap_fullcache or ioremap_wc be
in the previous patch?

A few more similar issues pop up for other architectures as well.

2015-07-27 22:50:20

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH v2 04/25] mm: enhance region_is_ram() to distinguish 'unknown' vs 'mixed'

On Fri, Jul 24, 2015 at 10:38:21PM -0400, Dan Williams wrote:
> region_is_ram() is used to prevent the establishment of aliased mappings
> to physical "System RAM" with incompatible cache settings. However, it
> uses "-1" to indicate both "unknown" memory ranges (ranges not described
> by platform firmware) and "mixed" ranges (where the parameters describe
> a range that partially overlaps "System RAM").
>
> Fix this up by explicitly tracking the "unknown" vs "mixed" resource
> cases. In addition to clarifying that "-1" means the requested spanned
> RAM and non-RAM resource, this re-write also adds support for detecting
> when the requested range completely covers all of a resource.
>
> Finally, the implementation treats overlaps between "unknown" and RAM as
> RAM.
>
> Cc: Toshi Kani <[email protected]>
> Signed-off-by: Dan Williams <[email protected]>
> ---
> kernel/resource.c | 43 +++++++++++++++++++++++--------------------
> 1 file changed, 23 insertions(+), 20 deletions(-)
>
> diff --git a/kernel/resource.c b/kernel/resource.c
> index fed052a1bc9f..119b282985f9 100644
> --- a/kernel/resource.c
> +++ b/kernel/resource.c
> @@ -493,39 +493,42 @@ int __weak page_is_ram(unsigned long pfn)
> EXPORT_SYMBOL_GPL(page_is_ram);
>
> /*
> - * Search for a resouce entry that fully contains the specified region.
> - * If found, return 1 if it is RAM, 0 if not.
> - * If not found, or region is not fully contained, return -1
> + * Check if the specified region partially overlaps or fully eclipses "System
> + * RAM". Return '0' if the region does not overlap RAM, return '-1' if the
> + * region overlaps RAM and another resource, and return '1' if the region
> + * overlaps RAM and no other defined resource. Note, that '1' is also returned
> + * in the case when the specified region overlaps RAM and undefined memory
> + * holes.
> *
> * Used by the ioremap functions to ensure the user is not remapping RAM and is
> * a vast speed up over walking through the resource table page by page.
> */
> int region_is_ram(resource_size_t start, unsigned long size)
> {

There not many user of region_is_ram() so changing region_is_ram() to return an
enum and thereby making it easier to both extend this documention and read the
code exactly what it is returning would be of large value here and would not be
much work.

Luis

2015-07-27 23:18:03

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Fri, Jul 24, 2015 at 10:38:42PM -0400, 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.

Ok so a special use case.

> 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.

Such memory-like smantics are not well defined yet and this has caused
issues over expectations over a slew of APIs. As you note above
your own defined 'semantics' so far for memremap are just that there are
no i/o side effects, when the mapped memory is just a pointer to memory,
as such I do not think its fair to set the excpectations that we'll
switch all other ioremap_*() callers to the same memremap() API. Now,
it may be a good idea to use something similar, ie, to pass flags,
but setting the expectations outright to move to memremap() without having
any agreement having been made over semantics seems uncalled for at this
point in time, specially when you are noting that the expectations for
both sets of calls are different.

So perhaps:

"
Outside of ioremap() and ioremap_nocache(), all other ioremap_<type>()
variant calls are seeking memory-like semantics (e.g. speculative
reads, and prefetching permitted) and all calls expecations currently
differ depending on architecture. Once and if we get agreement on such
semantics we may be able to move such ioremap_*() variant calls to
a similar API where the semantics required are clearly spelled out
and well defined and passed as arguments.
"

> diff --git a/kernel/memremap.c b/kernel/memremap.c
> new file mode 100644
> index 000000000000..ba206fd11785
> --- /dev/null
> +++ b/kernel/memremap.c
> @@ -0,0 +1,82 @@
> +/*
> + * Copyright(c) 2015 Intel Corporation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of version 2 of the GNU General Public License as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + */
> +#include <linux/types.h>
> +#include <linux/io.h>
> +#include <linux/mm.h>
> +
> +#ifndef ioremap_cache
> +/* temporary while we convert existing ioremap_cache users to memremap */
> +__weak void __iomem *ioremap_cache(resource_size_t offset, unsigned long size)
> +{
> + return ioremap(offset, size);
> +}
> +#endif
> +
> +/*
> + * 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.
> + */
> +void *memremap(resource_size_t offset, size_t size, unsigned long flags)
> +{
> + int is_ram = region_is_ram(offset, size);
> + void *addr = NULL;
> +
> + if (is_ram < 0) {
> + WARN_ONCE(1, "memremap attempted on mixed range %pa size: %zu\n",
> + &offset, size);
> + return NULL;
> + }
> +
> + /* Try all mapping types requested until one returns non-NULL */
> + if (flags & MEMREMAP_CACHE) {
> + flags &= ~MEMREMAP_CACHE;
> + /*
> + * MEMREMAP_CACHE is special in that it can be satisifed
> + * from the direct map. Some archs depend on the
> + * capability of memremap() to autodetect cases where
> + * the requested range is potentially in "System RAM"
> + */
> + if (is_ram)
> + addr = __va(offset);

The no MMU case seems to match this, can that be switch to this?

Luis

2015-07-27 23:26:07

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Sun, Jul 26, 2015 at 10:12 PM, Christoph Hellwig <[email protected]> wrote:
> On Sun, Jul 26, 2015 at 10:49:39AM -0700, Dan Williams wrote:
>> On Sun, Jul 26, 2015 at 10:25 AM, Christoph Hellwig <[email protected]> wrote:
>> > On Fri, Jul 24, 2015 at 10:38:42PM -0400, Dan Williams wrote:
>> >> The behavior change to return NULL on an unsupported request is reserved
>> >> for a later patch.
>> >
>> > Why?
>>
>> This is for drivers like pmem that care about the mapping type. For
>> example, if pmem can't get a cache-enabled mapping it is potentially
>> putting the write durability of the persistent media at risk.
>
> I understand that part, but the question is why the old behavior
> is retained for now and only changed later.

Oh, because all we have at this point is ioremap_cache() which
silently falls back. It's not until the introduction of
arch_memremp() where we update the arch code to break that behavior.

That said, I think it may be beneficial to allow a fallback if the
user cares. So maybe memremap() can call plain ioremap() if
MEMREMAP_STRICT is not set and none of the other mapping types are
satisfied.

2015-07-27 23:49:14

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Mon, Jul 27, 2015 at 4:17 PM, Luis R. Rodriguez <[email protected]> wrote:
> On Fri, Jul 24, 2015 at 10:38:42PM -0400, 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.
>
> Ok so a special use case.
>
>> 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.
>
> Such memory-like smantics are not well defined yet and this has caused
> issues over expectations over a slew of APIs. As you note above
> your own defined 'semantics' so far for memremap are just that there are
> no i/o side effects, when the mapped memory is just a pointer to memory,
> as such I do not think its fair to set the excpectations that we'll
> switch all other ioremap_*() callers to the same memremap() API. Now,
> it may be a good idea to use something similar, ie, to pass flags,
> but setting the expectations outright to move to memremap() without having
> any agreement having been made over semantics seems uncalled for at this
> point in time, specially when you are noting that the expectations for
> both sets of calls are different.
>
> So perhaps:
>
> "
> Outside of ioremap() and ioremap_nocache(), all other ioremap_<type>()
> variant calls are seeking memory-like semantics (e.g. speculative
> reads, and prefetching permitted) and all calls expecations currently
> differ depending on architecture. Once and if we get agreement on such
> semantics we may be able to move such ioremap_*() variant calls to
> a similar API where the semantics required are clearly spelled out
> and well defined and passed as arguments.

I still think ioremap_wc(), and now ioremap_uc(), are special and are
not obvious candidates for conversion to memremap().

> "
>
>> diff --git a/kernel/memremap.c b/kernel/memremap.c
>> new file mode 100644
>> index 000000000000..ba206fd11785
>> --- /dev/null
>> +++ b/kernel/memremap.c
>> @@ -0,0 +1,82 @@
>> +/*
>> + * Copyright(c) 2015 Intel Corporation. All rights reserved.
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of version 2 of the GNU General Public License as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful, but
>> + * WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
>> + * General Public License for more details.
>> + */
>> +#include <linux/types.h>
>> +#include <linux/io.h>
>> +#include <linux/mm.h>
>> +
>> +#ifndef ioremap_cache
>> +/* temporary while we convert existing ioremap_cache users to memremap */
>> +__weak void __iomem *ioremap_cache(resource_size_t offset, unsigned long size)
>> +{
>> + return ioremap(offset, size);
>> +}
>> +#endif
>> +
>> +/*
>> + * 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.
>> + */
>> +void *memremap(resource_size_t offset, size_t size, unsigned long flags)
>> +{
>> + int is_ram = region_is_ram(offset, size);
>> + void *addr = NULL;
>> +
>> + if (is_ram < 0) {
>> + WARN_ONCE(1, "memremap attempted on mixed range %pa size: %zu\n",
>> + &offset, size);
>> + return NULL;
>> + }
>> +
>> + /* Try all mapping types requested until one returns non-NULL */
>> + if (flags & MEMREMAP_CACHE) {
>> + flags &= ~MEMREMAP_CACHE;
>> + /*
>> + * MEMREMAP_CACHE is special in that it can be satisifed
>> + * from the direct map. Some archs depend on the
>> + * capability of memremap() to autodetect cases where
>> + * the requested range is potentially in "System RAM"
>> + */
>> + if (is_ram)
>> + addr = __va(offset);
>
> The no MMU case seems to match this, can that be switch to this?

Hmm, it may be possible to consolidate all the NOMMU cases here.
That's a good incremental cleanup once these base patches are merged.

2015-07-27 23:43:56

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Mon, Jul 27, 2015 at 04:31:09PM -0700, Dan Williams wrote:
> On Mon, Jul 27, 2015 at 4:17 PM, Luis R. Rodriguez <[email protected]> wrote:
> > On Fri, Jul 24, 2015 at 10:38:42PM -0400, 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.
> >
> > Ok so a special use case.
> >
> >> 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.
> >
> > Such memory-like smantics are not well defined yet and this has caused
> > issues over expectations over a slew of APIs. As you note above
> > your own defined 'semantics' so far for memremap are just that there are
> > no i/o side effects, when the mapped memory is just a pointer to memory,
> > as such I do not think its fair to set the excpectations that we'll
> > switch all other ioremap_*() callers to the same memremap() API. Now,
> > it may be a good idea to use something similar, ie, to pass flags,
> > but setting the expectations outright to move to memremap() without having
> > any agreement having been made over semantics seems uncalled for at this
> > point in time, specially when you are noting that the expectations for
> > both sets of calls are different.
> >
> > So perhaps:
> >
> > "
> > Outside of ioremap() and ioremap_nocache(), all other ioremap_<type>()
> > variant calls are seeking memory-like semantics (e.g. speculative
> > reads, and prefetching permitted) and all calls expecations currently
> > differ depending on architecture. Once and if we get agreement on such
> > semantics we may be able to move such ioremap_*() variant calls to
> > a similar API where the semantics required are clearly spelled out
> > and well defined and passed as arguments.
>
> I still think ioremap_wc(), and now ioremap_uc(), are special and are
> not obvious candidates for conversion to memremap().

OK great, then we're in strong agreement, so removing the "Outside of
ioremap() and... over time" might be best then? Otherwise what I posted
seems to reflect the state of affairs better?

> >> +void *memremap(resource_size_t offset, size_t size, unsigned long flags)
> >> +{
> >> + int is_ram = region_is_ram(offset, size);
> >> + void *addr = NULL;
> >> +
> >> + if (is_ram < 0) {
> >> + WARN_ONCE(1, "memremap attempted on mixed range %pa size: %zu\n",
> >> + &offset, size);
> >> + return NULL;
> >> + }
> >> +
> >> + /* Try all mapping types requested until one returns non-NULL */
> >> + if (flags & MEMREMAP_CACHE) {
> >> + flags &= ~MEMREMAP_CACHE;
> >> + /*
> >> + * MEMREMAP_CACHE is special in that it can be satisifed
> >> + * from the direct map. Some archs depend on the
> >> + * capability of memremap() to autodetect cases where
> >> + * the requested range is potentially in "System RAM"
> >> + */
> >> + if (is_ram)
> >> + addr = __va(offset);
> >
> > The no MMU case seems to match this, can that be switch to this?
>
> Hmm, it may be possible to consolidate all the NOMMU cases here.
> That's a good incremental cleanup once these base patches are merged.

Sure fine by me.

Luis

2015-07-28 00:32:58

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Mon, Jul 27, 2015 at 4:43 PM, Luis R. Rodriguez <[email protected]> wrote:
> On Mon, Jul 27, 2015 at 04:31:09PM -0700, Dan Williams wrote:
>> On Mon, Jul 27, 2015 at 4:17 PM, Luis R. Rodriguez <[email protected]> wrote:
>> > On Fri, Jul 24, 2015 at 10:38:42PM -0400, 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.
>> >
>> > Ok so a special use case.
>> >
>> >> 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.
>> >
>> > Such memory-like smantics are not well defined yet and this has caused
>> > issues over expectations over a slew of APIs. As you note above
>> > your own defined 'semantics' so far for memremap are just that there are
>> > no i/o side effects, when the mapped memory is just a pointer to memory,
>> > as such I do not think its fair to set the excpectations that we'll
>> > switch all other ioremap_*() callers to the same memremap() API. Now,
>> > it may be a good idea to use something similar, ie, to pass flags,
>> > but setting the expectations outright to move to memremap() without having
>> > any agreement having been made over semantics seems uncalled for at this
>> > point in time, specially when you are noting that the expectations for
>> > both sets of calls are different.
>> >
>> > So perhaps:
>> >
>> > "
>> > Outside of ioremap() and ioremap_nocache(), all other ioremap_<type>()
>> > variant calls are seeking memory-like semantics (e.g. speculative
>> > reads, and prefetching permitted) and all calls expecations currently
>> > differ depending on architecture. Once and if we get agreement on such
>> > semantics we may be able to move such ioremap_*() variant calls to
>> > a similar API where the semantics required are clearly spelled out
>> > and well defined and passed as arguments.
>>
>> I still think ioremap_wc(), and now ioremap_uc(), are special and are
>> not obvious candidates for conversion to memremap().
>
> OK great, then we're in strong agreement, so removing the "Outside of
> ioremap() and... over time" might be best then? Otherwise what I posted
> seems to reflect the state of affairs better?
>

Ah yes, I need to clean that up. Thanks!

2015-07-28 21:34:45

by Toshi Kani

[permalink] [raw]
Subject: Re: [PATCH v2 04/25] mm: enhance region_is_ram() to distinguish 'unknown' vs 'mixed'

On Fri, 2015-07-24 at 22:38 -0400, Dan Williams wrote:
> region_is_ram() is used to prevent the establishment of aliased mappings
> to physical "System RAM" with incompatible cache settings. However, it
> uses "-1" to indicate both "unknown" memory ranges (ranges not described
> by platform firmware) and "mixed" ranges (where the parameters describe
> a range that partially overlaps "System RAM").
>
> Fix this up by explicitly tracking the "unknown" vs "mixed" resource
> cases. In addition to clarifying that "-1" means the requested spanned
> RAM and non-RAM resource, this re-write also adds support for detecting
> when the requested range completely covers all of a resource.

Agreed - this is a good enhancement.

> Finally, the implementation treats overlaps between "unknown" and RAM as
> RAM.

This sounds right for this interface. iomem_map_sanity_check() checks the
boundary condition with the resource table.

> Cc: Toshi Kani <[email protected]>
> Signed-off-by: Dan Williams <[email protected]>

The changes look good as well.

Reviewed-by: Toshi Kani <[email protected]>

Thanks,
-Toshi

2015-07-28 22:51:38

by Ross Zwisler

[permalink] [raw]
Subject: Re: [PATCH v2 18/25] libnvdimm, pmem: switch from ioremap_cache to memremap

On Fri, 2015-07-24 at 22:39 -0400, Dan Williams wrote:
> In preparation for deprecating ioremap_cache() convert its usage in
> libnvdimm and the PMEM API to memremap.
>
> Signed-off-by: Dan Williams <[email protected]>
> ---
> arch/x86/include/asm/io.h | 7 +------
> arch/x86/mm/ioremap.c | 6 ++++++
> tools/testing/nvdimm/Kbuild | 2 +-
> tools/testing/nvdimm/test/iomap.c | 6 +++---
> 4 files changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
> index cc9c61bc1abe..8aeb6456188a 100644
> --- a/arch/x86/include/asm/io.h
> +++ b/arch/x86/include/asm/io.h
> @@ -248,12 +248,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);
> -}
> -
> +void __pmem *arch_memremap_pmem(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 6f759c7c2ab7..7b422e7574b1 100644
> --- a/arch/x86/mm/ioremap.c
> +++ b/arch/x86/mm/ioremap.c
> @@ -317,6 +317,12 @@ void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
> }
> EXPORT_SYMBOL(ioremap_cache);
>
> +void __pmem *arch_memremap_pmem(resource_size_t offset, size_t size)
> +{
> + return (void __force __pmem *) ioremap_cache(offset, size);

Did you mean for this to be a call to memremap() instead of ioremap_cache()?

2015-07-28 23:06:57

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH v2 18/25] libnvdimm, pmem: switch from ioremap_cache to memremap

On Tue, Jul 28, 2015 at 3:51 PM, Ross Zwisler
<[email protected]> wrote:
> On Fri, 2015-07-24 at 22:39 -0400, Dan Williams wrote:
>> In preparation for deprecating ioremap_cache() convert its usage in
>> libnvdimm and the PMEM API to memremap.
>>
>> Signed-off-by: Dan Williams <[email protected]>
>> ---
>> arch/x86/include/asm/io.h | 7 +------
>> arch/x86/mm/ioremap.c | 6 ++++++
>> tools/testing/nvdimm/Kbuild | 2 +-
>> tools/testing/nvdimm/test/iomap.c | 6 +++---
>> 4 files changed, 11 insertions(+), 10 deletions(-)
>>
>> diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
>> index cc9c61bc1abe..8aeb6456188a 100644
>> --- a/arch/x86/include/asm/io.h
>> +++ b/arch/x86/include/asm/io.h
>> @@ -248,12 +248,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);
>> -}
>> -
>> +void __pmem *arch_memremap_pmem(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 6f759c7c2ab7..7b422e7574b1 100644
>> --- a/arch/x86/mm/ioremap.c
>> +++ b/arch/x86/mm/ioremap.c
>> @@ -317,6 +317,12 @@ void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
>> }
>> EXPORT_SYMBOL(ioremap_cache);
>>
>> +void __pmem *arch_memremap_pmem(resource_size_t offset, size_t size)
>> +{
>> + return (void __force __pmem *) ioremap_cache(offset, size);
>
> Did you mean for this to be a call to memremap() instead of ioremap_cache()?

The ioremap_cache elimination comes in "[PATCH v2 25/25] pmem: convert
to generic memremap", but yeah I should update the changelog to
reflect this is more about pushing the calls to ioremap_cache() out of
line. It would be circular at this point in the series to call back
out to memremap to have it turn around and call ioremap_cache again.

2015-07-29 06:50:08

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Mon, Jul 27, 2015 at 04:26:03PM -0700, Dan Williams wrote:
> Oh, because all we have at this point is ioremap_cache() which
> silently falls back. It's not until the introduction of
> arch_memremp() where we update the arch code to break that behavior.

Ok, makes sense. Might be worth to document in the changelog.

> That said, I think it may be beneficial to allow a fallback if the
> user cares. So maybe memremap() can call plain ioremap() if
> MEMREMAP_STRICT is not set and none of the other mapping types are
> satisfied.

Is there a real use case for it? Fallback APIs always seem confusing
and it might make more sense to do this in the caller(s) that actually
need it.

2015-07-29 18:27:20

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Wed, Jul 29, 2015 at 08:50:04AM +0200, Christoph Hellwig wrote:
> On Mon, Jul 27, 2015 at 04:26:03PM -0700, Dan Williams wrote:
> > Oh, because all we have at this point is ioremap_cache() which
> > silently falls back. It's not until the introduction of
> > arch_memremp() where we update the arch code to break that behavior.
>
> Ok, makes sense. Might be worth to document in the changelog.
>
> > That said, I think it may be beneficial to allow a fallback if the
> > user cares. So maybe memremap() can call plain ioremap() if
> > MEMREMAP_STRICT is not set and none of the other mapping types are
> > satisfied.
>
> Is there a real use case for it? Fallback APIs always seem confusing
> and it might make more sense to do this in the caller(s) that actually
> need it.

It seems semantics-wise we are trying to separate these two really, so I agree
with this. Having a fallback would onloy make things more complicated for any
sanitizer / checker / etc, and I don't think the practical gains of having a
fallback outweight the gains of having a clear semantic separation on intended
memory type and interactions with it.

Luis

2015-07-29 18:33:27

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Wed, Jul 29, 2015 at 11:27 AM, Luis R. Rodriguez <[email protected]> wrote:
> On Wed, Jul 29, 2015 at 08:50:04AM +0200, Christoph Hellwig wrote:
>> On Mon, Jul 27, 2015 at 04:26:03PM -0700, Dan Williams wrote:
>> > Oh, because all we have at this point is ioremap_cache() which
>> > silently falls back. It's not until the introduction of
>> > arch_memremp() where we update the arch code to break that behavior.
>>
>> Ok, makes sense. Might be worth to document in the changelog.
>>
>> > That said, I think it may be beneficial to allow a fallback if the
>> > user cares. So maybe memremap() can call plain ioremap() if
>> > MEMREMAP_STRICT is not set and none of the other mapping types are
>> > satisfied.
>>
>> Is there a real use case for it? Fallback APIs always seem confusing
>> and it might make more sense to do this in the caller(s) that actually
>> need it.
>
> It seems semantics-wise we are trying to separate these two really, so I agree
> with this. Having a fallback would onloy make things more complicated for any
> sanitizer / checker / etc, and I don't think the practical gains of having a
> fallback outweight the gains of having a clear semantic separation on intended
> memory type and interactions with it.
>

Yup, consider it dropped. Drivers that want fallback behavior can do
it explicitly.

2015-07-29 19:12:38

by Ross Zwisler

[permalink] [raw]
Subject: Re: [PATCH v2 22/25] pmem: switch from ioremap_wt to memremap

On Fri, 2015-07-24 at 22:40 -0400, Dan Williams wrote:
> In preparation for deprecating ioremap_wt() convert its usage in
> the PMEM API to memremap.
>
> Cc: Ross Zwisler <[email protected]>
> Signed-off-by: Dan Williams <[email protected]>

Acked-by: Ross Zwisler <[email protected]>

2015-07-29 21:01:59

by Toshi Kani

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Wed, 2015-07-29 at 11:33 -0700, Dan Williams wrote:
> On Wed, Jul 29, 2015 at 11:27 AM, Luis R. Rodriguez <[email protected]>
> wrote:
> > On Wed, Jul 29, 2015 at 08:50:04AM +0200, Christoph Hellwig wrote:
> > > On Mon, Jul 27, 2015 at 04:26:03PM -0700, Dan Williams wrote:
> > > > Oh, because all we have at this point is ioremap_cache() which
> > > > silently falls back. It's not until the introduction of
> > > > arch_memremp() where we update the arch code to break that
> > > > behavior.
> > >
> > > Ok, makes sense. Might be worth to document in the changelog.
> > >
> > > > That said, I think it may be beneficial to allow a fallback if the
> > > > user cares. So maybe memremap() can call plain ioremap() if
> > > > MEMREMAP_STRICT is not set and none of the other mapping types are
> > > > satisfied.
> > >
> > > Is there a real use case for it? Fallback APIs always seem confusing
> > > and it might make more sense to do this in the caller(s) that
> > > actually
> > > need it.
> >
> > It seems semantics-wise we are trying to separate these two really, so
> > I agree
> > with this. Having a fallback would onloy make things more complicated
> > for any
> > sanitizer / checker / etc, and I don't think the practical gains of
> > having a
> > fallback outweight the gains of having a clear semantic separation on
> > intended
> > memory type and interactions with it.
> >
>
> Yup, consider it dropped. Drivers that want fallback behavior can do
> it explicitly.

I agree in general. However, for the drivers to be able to fall back
properly, they will need to know the cache type they can fall back with.
ioremap() falls back to the cache type of an existing mapping to avoid
aliasing.

Thanks,
-Toshi

2015-07-29 21:12:35

by Toshi Kani

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Wed, 2015-07-29 at 15:00 -0600, Toshi Kani wrote:
> On Wed, 2015-07-29 at 11:33 -0700, Dan Williams wrote:
> > On Wed, Jul 29, 2015 at 11:27 AM, Luis R. Rodriguez <[email protected]>
> > wrote:
> > > On Wed, Jul 29, 2015 at 08:50:04AM +0200, Christoph Hellwig wrote:
> > > > On Mon, Jul 27, 2015 at 04:26:03PM -0700, Dan Williams wrote:
> > > > > Oh, because all we have at this point is ioremap_cache() which
> > > > > silently falls back. It's not until the introduction of
> > > > > arch_memremp() where we update the arch code to break that
> > > > > behavior.
> > > >
> > > > Ok, makes sense. Might be worth to document in the changelog.
> > > >
> > > > > That said, I think it may be beneficial to allow a fallback if
> > > > > the
> > > > > user cares. So maybe memremap() can call plain ioremap() if
> > > > > MEMREMAP_STRICT is not set and none of the other mapping types
> > > > > are
> > > > > satisfied.
> > > >
> > > > Is there a real use case for it? Fallback APIs always seem
> > > > confusing
> > > > and it might make more sense to do this in the caller(s) that
> > > > actually
> > > > need it.
> > >
> > > It seems semantics-wise we are trying to separate these two really,
> > > so
> > > I agree
> > > with this. Having a fallback would onloy make things more complicated
> > >
> > > for any
> > > sanitizer / checker / etc, and I don't think the practical gains of
> > > having a
> > > fallback outweight the gains of having a clear semantic separation on
> > >
> > > intended
> > > memory type and interactions with it.
> > >
> >
> > Yup, consider it dropped. Drivers that want fallback behavior can do
> > it explicitly.
>
> I agree in general. However, for the drivers to be able to fall back
> properly, they will need to know the cache type they can fall back with.
> ioremap() falls back to the cache type of an existing mapping to avoid
> aliasing.

Never mind... In this context, we are talking about fallback in case of "
API not implemented" on arch. I was talking about fallback in case of
aliasing.

Thanks,
-Toshi




2015-07-29 21:44:06

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Wed, Jul 29, 2015 at 03:00:38PM -0600, Toshi Kani wrote:
> On Wed, 2015-07-29 at 11:33 -0700, Dan Williams wrote:
> > On Wed, Jul 29, 2015 at 11:27 AM, Luis R. Rodriguez <[email protected]>
> > wrote:
> > > On Wed, Jul 29, 2015 at 08:50:04AM +0200, Christoph Hellwig wrote:
> > > > On Mon, Jul 27, 2015 at 04:26:03PM -0700, Dan Williams wrote:
> > > > > Oh, because all we have at this point is ioremap_cache() which
> > > > > silently falls back. It's not until the introduction of
> > > > > arch_memremp() where we update the arch code to break that
> > > > > behavior.
> > > >
> > > > Ok, makes sense. Might be worth to document in the changelog.
> > > >
> > > > > That said, I think it may be beneficial to allow a fallback if the
> > > > > user cares. So maybe memremap() can call plain ioremap() if
> > > > > MEMREMAP_STRICT is not set and none of the other mapping types are
> > > > > satisfied.
> > > >
> > > > Is there a real use case for it? Fallback APIs always seem confusing
> > > > and it might make more sense to do this in the caller(s) that
> > > > actually
> > > > need it.
> > >
> > > It seems semantics-wise we are trying to separate these two really, so
> > > I agree
> > > with this. Having a fallback would onloy make things more complicated
> > > for any
> > > sanitizer / checker / etc, and I don't think the practical gains of
> > > having a
> > > fallback outweight the gains of having a clear semantic separation on
> > > intended
> > > memory type and interactions with it.
> > >
> >
> > Yup, consider it dropped. Drivers that want fallback behavior can do
> > it explicitly.
>
> I agree in general. However, for the drivers to be able to fall back
> properly, they will need to know the cache type they can fall back with.

That would depend on the purpose of the region and the driver developer should
in theory know best. One issue with this of course is that, as we've
discovered, the semantics of on the ioremap*() variant front regarding cache
types is not clearly well defined, or at least it may be only well defined
implicitly on x86 only, so the driver developer can only *hope* for the best
across architectures. Our ambiguity on our semantics on ioremap*() variants
therefore means driver developers can resonably be puzzled by what fallbacks to
use. That also means architectures maintainers should not whip driver developers
for any misuse. Such considerations are why although we're now revisiting
semantics for ioremap*() variants I was in hopes we could be at least somewhat
pedantic about memremap() semantics.

For instance since memremap() only has 2 types right now can a respective
fallback be documented as an alternative to help with this ? Or can we not
generalize this ? One for MEMREMAP_WB and one for MEMREMAP_WT ?

> ioremap() falls back to the cache type of an existing mapping to avoid
> aliasing.

Does that assume an existing ioremap*() call was used on a bigger range?
Do you know if that happens to only be the case for x86 (I'd think so)
or if its the same for other architectures ?

While at it, Dan, will / should memremap() support overlapping calls ?
What is the expectation on behaviour ?

PS: I did see you reply about this being about lacking an arch implementation
for a memremap() type, not a cache type, but as the driver uses one memremap()
type the goal for a region is just as important as the resulting type.

Luis

2015-07-29 21:47:43

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Wed, Jul 29, 2015 at 2:43 PM, Luis R. Rodriguez <[email protected]> wrote:
> While at it, Dan, will / should memremap() support overlapping calls ?
> What is the expectation on behaviour ?

It will be the same as ioremap(). Each mapping gets its own virtual
address and overlapping calls are permitted. The only protection is
that RAM is never mapped with an alias.

2015-07-29 21:52:33

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Wed, Jul 29, 2015 at 02:47:40PM -0700, Dan Williams wrote:
> On Wed, Jul 29, 2015 at 2:43 PM, Luis R. Rodriguez <[email protected]> wrote:
> > While at it, Dan, will / should memremap() support overlapping calls ?
> > What is the expectation on behaviour ?
>
> It will be the same as ioremap(). Each mapping gets its own virtual
> address and overlapping calls are permitted. The only protection is
> that RAM is never mapped with an alias.

If you could document this as part of your next respin that'd be
highly appreciated.

Luis

2015-07-29 22:22:00

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH v2 24/25] arch: remove ioremap_wt, replace with arch_memremap

On Mon, Jul 27, 2015 at 1:03 AM, Christoph Hellwig <[email protected]> wrote:
>> +++ 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>
>> @@ -267,20 +265,17 @@ static inline void __iomem *ioremap_nocache(unsigned long physaddr, unsigned lon
>> return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
>> }
>>
>> -static inline void __iomem *ioremap_wt(unsigned long physaddr, unsigned long size)
>> -{
>> - return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
>> -}
>> -
>> -static inline void __iomem *ioremap_fullcache(unsigned long physaddr, unsigned long size)
>> -{
>> - return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
>> -}
>
>
>> +void *arch_memremap(resource_size_t offset, size_t size, unsigned long flags)
>> +{
>> + return (void *) offset;
>> +}
>> +EXPORT_SYMBOL(arch_memremap);
>
> This doesn't look like a correct replacement.

It doesn't, but frv jumps through a lot of hoops to give the illusion
it actually supports different mapping types only to do this simple
case in the end. Given we don't want fallback semantics I will simply
remove these false wrappers in the next revision of the patches.

> Also shouldn't the replacements of ioremap_fullcache or ioremap_wc be
> in the previous patch?
>
> A few more similar issues pop up for other architectures as well.

I went ahead and moved the deletion of ioremap_cached() and
ioremap_fullcache() to their own patches.

2015-07-30 00:01:28

by Toshi Kani

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Wed, 2015-07-29 at 23:43 +0200, Luis R. Rodriguez wrote:
> On Wed, Jul 29, 2015 at 03:00:38PM -0600, Toshi Kani wrote:
> > On Wed, 2015-07-29 at 11:33 -0700, Dan Williams wrote:
> > > On Wed, Jul 29, 2015 at 11:27 AM, Luis R. Rodriguez <[email protected]>
> > > wrote:
> > > > On Wed, Jul 29, 2015 at 08:50:04AM +0200, Christoph Hellwig wrote:
> > > > > On Mon, Jul 27, 2015 at 04:26:03PM -0700, Dan Williams wrote:
> > > > > > Oh, because all we have at this point is ioremap_cache() which
> > > > > > silently falls back. It's not until the introduction of
> > > > > > arch_memremp() where we update the arch code to break that
> > > > > > behavior.
> > > > >
> > > > > Ok, makes sense. Might be worth to document in the changelog.
> > > > >
> > > > > > That said, I think it may be beneficial to allow a fallback if
> > > > > > the user cares. So maybe memremap() can call plain ioremap() if
> > > > > > MEMREMAP_STRICT is not set and none of the other mapping types
> > > > > > are satisfied.
> > > > >
> > > > > Is there a real use case for it? Fallback APIs always seem
> > > > > confusing and it might make more sense to do this in the caller(s)
> > > > > that actually need it.
> > > >
> > > > It seems semantics-wise we are trying to separate these two really,
> > > > so I agree with this. Having a fallback would onloy make things more
> > > > complicated for any sanitizer / checker / etc, and I don't think the
> > > > practical gains of having a fallback outweight the gains of having a
> > > > clear semantic separation on intended memory type and interactions
> > > > with it.
> > > >
> > >
> > > Yup, consider it dropped. Drivers that want fallback behavior can do
> > > it explicitly.
> >
> > I agree in general. However, for the drivers to be able to fall back
> > properly, they will need to know the cache type they can fall back with.
> >
>
> That would depend on the purpose of the region and the driver developer
> should in theory know best. One issue with this of course is that, as
> we've discovered, the semantics of on the ioremap*() variant front
> regarding cache types is not clearly well defined, or at least it may be
> only well defined implicitly on x86 only, so the driver developer can only
> *hope* for the best across architectures. Our ambiguity on our semantics
> on ioremap*() variants therefore means driver developers can resonably be
> puzzled by what fallbacks to use. That also means architectures
> maintainers should not whip driver developers for any misuse. Such
> considerations are why although we're now revisiting semantics for
> ioremap*() variants I was in hopes we could be at least somewhat
> pedantic about memremap() semantics.

I agree. However, there are a few exceptions like /dev/mem, which can map a
target range without knowledge.

> For instance since memremap() only has 2 types right now can a respective
> fallback be documented as an alternative to help with this ? Or can we not
> generalize this ? One for MEMREMAP_WB and one for MEMREMAP_WT ?

Yes, if a target range can be only mapped by memremap(). However, there is
no restriction that a range can be mapped with a single interface alone.
For example, a range can be mapped with remap_pfn_range() to user space
with any cache type. So, in theory, memremap() can overlap with any other
types.

> > ioremap() falls back to the cache type of an existing mapping to avoid
> > aliasing.
>
> Does that assume an existing ioremap*() call was used on a bigger range?
> Do you know if that happens to only be the case for x86 (I'd think so)
> or if its the same for other architectures ?

In the /dev/mem example, it is remap_pfn_range(). I think other archs have
the same issue, but I do not know if they fall back in case of overlapping
call.

> While at it, Dan, will / should memremap() support overlapping calls ?
> What is the expectation on behaviour ?
>
> PS: I did see you reply about this being about lacking an arch
> implementation for a memremap() type, not a cache type, but as the driver
> uses one memremap() type the goal for a region is just as important as the
> resulting type.

Agreed. Drivers cannot tell if a fallback is due to lacking implementation
of overlapping, unless they check with #ifdef ioremap_xxx.

Thanks,
-Toshi

2015-08-03 14:27:20

by Joerg Roedel

[permalink] [raw]
Subject: Re: [PATCH v2 17/25] intel-iommu: switch from ioremap_cache to memremap

On Fri, Jul 24, 2015 at 10:39:33PM -0400, Dan Williams wrote:
> In preparation for deprecating ioremap_cache() convert its usage in
> intel-iommu to memremap. This also eliminates the mishandling of the
> __iomem annotation in the implementation.
>
> Cc: David Woodhouse <[email protected]>
> Cc: Joerg Roedel <[email protected]>
> Signed-off-by: Dan Williams <[email protected]>
> ---
> drivers/iommu/intel-iommu.c | 10 ++++++----
> drivers/iommu/intel_irq_remapping.c | 4 ++--
> 2 files changed, 8 insertions(+), 6 deletions(-)

Acked-by: Joerg Roedel <[email protected]>

2015-08-11 21:30:30

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Wed, Jul 29, 2015 at 06:00:04PM -0600, Toshi Kani wrote:
> On Wed, 2015-07-29 at 23:43 +0200, Luis R. Rodriguez wrote:
> > On Wed, Jul 29, 2015 at 03:00:38PM -0600, Toshi Kani wrote:
> > > On Wed, 2015-07-29 at 11:33 -0700, Dan Williams wrote:
> > > > On Wed, Jul 29, 2015 at 11:27 AM, Luis R. Rodriguez <[email protected]>
> > > > wrote:
> > > > > On Wed, Jul 29, 2015 at 08:50:04AM +0200, Christoph Hellwig wrote:
> > > > > > On Mon, Jul 27, 2015 at 04:26:03PM -0700, Dan Williams wrote:
> > > > > > > Oh, because all we have at this point is ioremap_cache() which
> > > > > > > silently falls back. It's not until the introduction of
> > > > > > > arch_memremp() where we update the arch code to break that
> > > > > > > behavior.
> > > > > >
> > > > > > Ok, makes sense. Might be worth to document in the changelog.
> > > > > >
> > > > > > > That said, I think it may be beneficial to allow a fallback if
> > > > > > > the user cares. So maybe memremap() can call plain ioremap() if
> > > > > > > MEMREMAP_STRICT is not set and none of the other mapping types
> > > > > > > are satisfied.
> > > > > >
> > > > > > Is there a real use case for it? Fallback APIs always seem
> > > > > > confusing and it might make more sense to do this in the caller(s)
> > > > > > that actually need it.
> > > > >
> > > > > It seems semantics-wise we are trying to separate these two really,
> > > > > so I agree with this. Having a fallback would onloy make things more
> > > > > complicated for any sanitizer / checker / etc, and I don't think the
> > > > > practical gains of having a fallback outweight the gains of having a
> > > > > clear semantic separation on intended memory type and interactions
> > > > > with it.
> > > > >
> > > >
> > > > Yup, consider it dropped. Drivers that want fallback behavior can do
> > > > it explicitly.
> > >
> > > I agree in general. However, for the drivers to be able to fall back
> > > properly, they will need to know the cache type they can fall back with.
> > >
> >
> > That would depend on the purpose of the region and the driver developer
> > should in theory know best. One issue with this of course is that, as
> > we've discovered, the semantics of on the ioremap*() variant front
> > regarding cache types is not clearly well defined, or at least it may be
> > only well defined implicitly on x86 only, so the driver developer can only
> > *hope* for the best across architectures. Our ambiguity on our semantics
> > on ioremap*() variants therefore means driver developers can resonably be
> > puzzled by what fallbacks to use. That also means architectures
> > maintainers should not whip driver developers for any misuse. Such
> > considerations are why although we're now revisiting semantics for
> > ioremap*() variants I was in hopes we could be at least somewhat
> > pedantic about memremap() semantics.
>
> I agree. However, there are a few exceptions like /dev/mem, which can map a
> target range without knowledge.

Still, the expectation to require support for overlapping ioremap() calls would
seem to be more of an exception than the norm, so I'd argue that requiring
callers who know they do need overlapping support to be explicit about it may
help us simplify expecations on semantics in other areas of the kernel.

> > For instance since memremap() only has 2 types right now can a respective
> > fallback be documented as an alternative to help with this ? Or can we not
> > generalize this ? One for MEMREMAP_WB and one for MEMREMAP_WT ?
>
> Yes, if a target range can be only mapped by memremap(). However, there is
> no restriction that a range can be mapped with a single interface alone.
> For example, a range can be mapped with remap_pfn_range() to user space
> with any cache type. So, in theory, memremap() can overlap with any other
> types.

Shouldn't that be an issue or area of concern ? It seems the flakiness on
ioremap() and its wide array flexibility would spill over the any semantics
which folks would be trying to set out with memremap(). That should not stop
the evolution of memremap() though, just pointing out that perhaps we should be
a bit more restrictive over how things can criss-cross and who areas can do it.

> > > ioremap() falls back to the cache type of an existing mapping to avoid
> > > aliasing.
> >
> > Does that assume an existing ioremap*() call was used on a bigger range?
> > Do you know if that happens to only be the case for x86 (I'd think so)
> > or if its the same for other architectures ?
>
> In the /dev/mem example, it is remap_pfn_range(). I think other archs have
> the same issue, but I do not know if they fall back in case of overlapping
> call.

What should happen if remap_pfn_range() was used with pgprot_writecombine()
and later memremap() is used for instance with a smaller overlappin section,
or perhaps bigger?

Luis

2015-08-11 22:42:52

by Toshi Kani

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Tue, 2015-08-11 at 23:30 +0200, Luis R. Rodriguez wrote:
> On Wed, Jul 29, 2015 at 06:00:04PM -0600, Toshi Kani wrote:
> > On Wed, 2015-07-29 at 23:43 +0200, Luis R. Rodriguez wrote:
> > > On Wed, Jul 29, 2015 at 03:00:38PM -0600, Toshi Kani wrote:
> > > > On Wed, 2015-07-29 at 11:33 -0700, Dan Williams wrote:
:
> > > That would depend on the purpose of the region and the driver
> > > developer should in theory know best. One issue with this of course is
> > > that, as we've discovered, the semantics of on the ioremap*() variant
> > > front regarding cache types is not clearly well defined, or at least
> > > it may be only well defined implicitly on x86 only, so the driver
> > > developer can only *hope* for the best across architectures. Our
> > > ambiguity on our semantics on ioremap*() variants therefore means
> > > driver developers can resonably be puzzled by what fallbacks to use.
> > > That also means architectures maintainers should not whip driver
> > > developers for any misuse. Such considerations are why although we're
> > > now revisiting semantics for ioremap*() variants I was in hopes we
> > > could be at least somewhat pedantic about memremap() semantics.
> >
> > I agree. However, there are a few exceptions like /dev/mem, which can
> > map a target range without knowledge.
>
> Still, the expectation to require support for overlapping ioremap() calls
> would seem to be more of an exception than the norm, so I'd argue that
> requiring callers who know they do need overlapping support to be explicit
> about it may help us simplify expecations on semantics in other areas of
> the kernel.

Again, I agree. I am simply saying that the fallback in an overlapping case
may need to remain supported for such exceptional cases, possibly with a
separate interface.

> > > For instance since memremap() only has 2 types right now can a
> > > respective fallback be documented as an alternative to help with this
> > > ? Or can we not generalize this ? One for MEMREMAP_WB and one for
> > > MEMREMAP_WT ?
> >
> > Yes, if a target range can be only mapped by memremap(). However, there
> > is no restriction that a range can be mapped with a single interface
> > alone. For example, a range can be mapped with remap_pfn_range() to
> > user space with any cache type. So, in theory, memremap() can overlap
> > with any other types.
>
> Shouldn't that be an issue or area of concern ? It seems the flakiness on
> ioremap() and its wide array flexibility would spill over the any
> semantics which folks would be trying to set out with memremap(). That
> should not stop the evolution of memremap() though, just pointing out that
> perhaps we should be a bit more restrictive over how things can criss
> -cross and who areas can do it.

reserve_pfn_range() allows the caller to specify if the fallback needs to be
enabled or disabled with 'strict_prot'. track_pfn_remap() called from
remap_pfn_range() enables it, and track_pfn_copy() disables it. I think we
can do similar for the memremap and ioremap families as well. The fallback
could be set disabled in the regular interfaces, and enabled in some
interface as necessary. This also allows gradual transition, ex. disable in
memremap while ioremap remains enabled for now.

> > > > ioremap() falls back to the cache type of an existing mapping to
> > > > avoid aliasing.
> > >
> > > Does that assume an existing ioremap*() call was used on a bigger
> > > range? Do you know if that happens to only be the case for x86 (I'd
> > > think so) or if its the same for other architectures ?
> >
> > In the /dev/mem example, it is remap_pfn_range(). I think other archs
> > have the same issue, but I do not know if they fall back in case of
> > overlapping call.
>
> What should happen if remap_pfn_range() was used with
> pgprot_writecombine() and later memremap() is used for instance with a
> smaller overlappin section, or perhaps bigger?

With the fallback disabled, memremap() should fail in this case.

Thanks,
-Toshi

2015-08-11 22:53:14

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Tue, Aug 11, 2015 at 3:40 PM, Toshi Kani <[email protected]> wrote:
> On Tue, 2015-08-11 at 23:30 +0200, Luis R. Rodriguez wrote:
>> On Wed, Jul 29, 2015 at 06:00:04PM -0600, Toshi Kani wrote:
>> > On Wed, 2015-07-29 at 23:43 +0200, Luis R. Rodriguez wrote:
>> > > On Wed, Jul 29, 2015 at 03:00:38PM -0600, Toshi Kani wrote:
>> > > > On Wed, 2015-07-29 at 11:33 -0700, Dan Williams wrote:
> :
>> > > That would depend on the purpose of the region and the driver
>> > > developer should in theory know best. One issue with this of course is
>> > > that, as we've discovered, the semantics of on the ioremap*() variant
>> > > front regarding cache types is not clearly well defined, or at least
>> > > it may be only well defined implicitly on x86 only, so the driver
>> > > developer can only *hope* for the best across architectures. Our
>> > > ambiguity on our semantics on ioremap*() variants therefore means
>> > > driver developers can resonably be puzzled by what fallbacks to use.
>> > > That also means architectures maintainers should not whip driver
>> > > developers for any misuse. Such considerations are why although we're
>> > > now revisiting semantics for ioremap*() variants I was in hopes we
>> > > could be at least somewhat pedantic about memremap() semantics.
>> >
>> > I agree. However, there are a few exceptions like /dev/mem, which can
>> > map a target range without knowledge.
>>
>> Still, the expectation to require support for overlapping ioremap() calls
>> would seem to be more of an exception than the norm, so I'd argue that
>> requiring callers who know they do need overlapping support to be explicit
>> about it may help us simplify expecations on semantics in other areas of
>> the kernel.
>
> Again, I agree. I am simply saying that the fallback in an overlapping case
> may need to remain supported for such exceptional cases, possibly with a
> separate interface.

Great.

>> > > For instance since memremap() only has 2 types right now can a
>> > > respective fallback be documented as an alternative to help with this
>> > > ? Or can we not generalize this ? One for MEMREMAP_WB and one for
>> > > MEMREMAP_WT ?
>> >
>> > Yes, if a target range can be only mapped by memremap(). However, there
>> > is no restriction that a range can be mapped with a single interface
>> > alone. For example, a range can be mapped with remap_pfn_range() to
>> > user space with any cache type. So, in theory, memremap() can overlap
>> > with any other types.
>>
>> Shouldn't that be an issue or area of concern ? It seems the flakiness on
>> ioremap() and its wide array flexibility would spill over the any
>> semantics which folks would be trying to set out with memremap(). That
>> should not stop the evolution of memremap() though, just pointing out that
>> perhaps we should be a bit more restrictive over how things can criss
>> -cross and who areas can do it.
>
> reserve_pfn_range() allows the caller to specify if the fallback needs to be
> enabled or disabled with 'strict_prot'. track_pfn_remap() called from
> remap_pfn_range() enables it, and track_pfn_copy() disables it. I think we
> can do similar for the memremap and ioremap families as well. The fallback
> could be set disabled in the regular interfaces, and enabled in some
> interface as necessary. This also allows gradual transition, ex. disable in
> memremap while ioremap remains enabled for now.

Sounds sexy to me.

>> > > > ioremap() falls back to the cache type of an existing mapping to
>> > > > avoid aliasing.
>> > >
>> > > Does that assume an existing ioremap*() call was used on a bigger
>> > > range? Do you know if that happens to only be the case for x86 (I'd
>> > > think so) or if its the same for other architectures ?
>> >
>> > In the /dev/mem example, it is remap_pfn_range(). I think other archs
>> > have the same issue, but I do not know if they fall back in case of
>> > overlapping call.
>>
>> What should happen if remap_pfn_range() was used with
>> pgprot_writecombine() and later memremap() is used for instance with a
>> smaller overlappin section, or perhaps bigger?
>
> With the fallback disabled, memremap() should fail in this case.

Excellent.

Luis

2015-08-11 23:13:48

by Dan Williams

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Tue, Aug 11, 2015 at 3:52 PM, Luis R. Rodriguez <[email protected]> wrote:
> On Tue, Aug 11, 2015 at 3:40 PM, Toshi Kani <[email protected]> wrote:
>> On Tue, 2015-08-11 at 23:30 +0200, Luis R. Rodriguez wrote:
>>> On Wed, Jul 29, 2015 at 06:00:04PM -0600, Toshi Kani wrote:
>>> > On Wed, 2015-07-29 at 23:43 +0200, Luis R. Rodriguez wrote:
>>> > > On Wed, Jul 29, 2015 at 03:00:38PM -0600, Toshi Kani wrote:
>>> > > > On Wed, 2015-07-29 at 11:33 -0700, Dan Williams wrote:
>> :
>>> > > That would depend on the purpose of the region and the driver
>>> > > developer should in theory know best. One issue with this of course is
>>> > > that, as we've discovered, the semantics of on the ioremap*() variant
>>> > > front regarding cache types is not clearly well defined, or at least
>>> > > it may be only well defined implicitly on x86 only, so the driver
>>> > > developer can only *hope* for the best across architectures. Our
>>> > > ambiguity on our semantics on ioremap*() variants therefore means
>>> > > driver developers can resonably be puzzled by what fallbacks to use.
>>> > > That also means architectures maintainers should not whip driver
>>> > > developers for any misuse. Such considerations are why although we're
>>> > > now revisiting semantics for ioremap*() variants I was in hopes we
>>> > > could be at least somewhat pedantic about memremap() semantics.
>>> >
>>> > I agree. However, there are a few exceptions like /dev/mem, which can
>>> > map a target range without knowledge.
>>>
>>> Still, the expectation to require support for overlapping ioremap() calls
>>> would seem to be more of an exception than the norm, so I'd argue that
>>> requiring callers who know they do need overlapping support to be explicit
>>> about it may help us simplify expecations on semantics in other areas of
>>> the kernel.
>>
>> Again, I agree. I am simply saying that the fallback in an overlapping case
>> may need to remain supported for such exceptional cases, possibly with a
>> separate interface.
>
> Great.
>
>>> > > For instance since memremap() only has 2 types right now can a
>>> > > respective fallback be documented as an alternative to help with this
>>> > > ? Or can we not generalize this ? One for MEMREMAP_WB and one for
>>> > > MEMREMAP_WT ?
>>> >
>>> > Yes, if a target range can be only mapped by memremap(). However, there
>>> > is no restriction that a range can be mapped with a single interface
>>> > alone. For example, a range can be mapped with remap_pfn_range() to
>>> > user space with any cache type. So, in theory, memremap() can overlap
>>> > with any other types.
>>>
>>> Shouldn't that be an issue or area of concern ? It seems the flakiness on
>>> ioremap() and its wide array flexibility would spill over the any
>>> semantics which folks would be trying to set out with memremap(). That
>>> should not stop the evolution of memremap() though, just pointing out that
>>> perhaps we should be a bit more restrictive over how things can criss
>>> -cross and who areas can do it.
>>
>> reserve_pfn_range() allows the caller to specify if the fallback needs to be
>> enabled or disabled with 'strict_prot'. track_pfn_remap() called from
>> remap_pfn_range() enables it, and track_pfn_copy() disables it. I think we
>> can do similar for the memremap and ioremap families as well. The fallback
>> could be set disabled in the regular interfaces, and enabled in some
>> interface as necessary. This also allows gradual transition, ex. disable in
>> memremap while ioremap remains enabled for now.
>
> Sounds sexy to me.

Cool, sounds like something we can tackle in 4.4 along with the
ioremap_cache removal cleanups.

2016-04-21 12:47:58

by Luis Chamberlain

[permalink] [raw]
Subject: Re: [PATCH v2 08/25] arch: introduce memremap()

On Wed, Aug 12, 2015 at 12:13 AM, Dan Williams <[email protected]> wrote:
> On Tue, Aug 11, 2015 at 3:52 PM, Luis R. Rodriguez <[email protected]> wrote:
>> On Tue, Aug 11, 2015 at 3:40 PM, Toshi Kani <[email protected]> wrote:
>>> On Tue, 2015-08-11 at 23:30 +0200, Luis R. Rodriguez wrote:
>>>> On Wed, Jul 29, 2015 at 06:00:04PM -0600, Toshi Kani wrote:
>>>> > On Wed, 2015-07-29 at 23:43 +0200, Luis R. Rodriguez wrote:
>>>> > > On Wed, Jul 29, 2015 at 03:00:38PM -0600, Toshi Kani wrote:
>>>> > > > On Wed, 2015-07-29 at 11:33 -0700, Dan Williams wrote:
>>> :
>>>> > > That would depend on the purpose of the region and the driver
>>>> > > developer should in theory know best. One issue with this of course is
>>>> > > that, as we've discovered, the semantics of on the ioremap*() variant
>>>> > > front regarding cache types is not clearly well defined, or at least
>>>> > > it may be only well defined implicitly on x86 only, so the driver
>>>> > > developer can only *hope* for the best across architectures. Our
>>>> > > ambiguity on our semantics on ioremap*() variants therefore means
>>>> > > driver developers can resonably be puzzled by what fallbacks to use.
>>>> > > That also means architectures maintainers should not whip driver
>>>> > > developers for any misuse. Such considerations are why although we're
>>>> > > now revisiting semantics for ioremap*() variants I was in hopes we
>>>> > > could be at least somewhat pedantic about memremap() semantics.
>>>> >
>>>> > I agree. However, there are a few exceptions like /dev/mem, which can
>>>> > map a target range without knowledge.
>>>>
>>>> Still, the expectation to require support for overlapping ioremap() calls
>>>> would seem to be more of an exception than the norm, so I'd argue that
>>>> requiring callers who know they do need overlapping support to be explicit
>>>> about it may help us simplify expecations on semantics in other areas of
>>>> the kernel.
>>>
>>> Again, I agree. I am simply saying that the fallback in an overlapping case
>>> may need to remain supported for such exceptional cases, possibly with a
>>> separate interface.
>>
>> Great.
>>
>>>> > > For instance since memremap() only has 2 types right now can a
>>>> > > respective fallback be documented as an alternative to help with this
>>>> > > ? Or can we not generalize this ? One for MEMREMAP_WB and one for
>>>> > > MEMREMAP_WT ?
>>>> >
>>>> > Yes, if a target range can be only mapped by memremap(). However, there
>>>> > is no restriction that a range can be mapped with a single interface
>>>> > alone. For example, a range can be mapped with remap_pfn_range() to
>>>> > user space with any cache type. So, in theory, memremap() can overlap
>>>> > with any other types.
>>>>
>>>> Shouldn't that be an issue or area of concern ? It seems the flakiness on
>>>> ioremap() and its wide array flexibility would spill over the any
>>>> semantics which folks would be trying to set out with memremap(). That
>>>> should not stop the evolution of memremap() though, just pointing out that
>>>> perhaps we should be a bit more restrictive over how things can criss
>>>> -cross and who areas can do it.
>>>
>>> reserve_pfn_range() allows the caller to specify if the fallback needs to be
>>> enabled or disabled with 'strict_prot'. track_pfn_remap() called from
>>> remap_pfn_range() enables it, and track_pfn_copy() disables it. I think we
>>> can do similar for the memremap and ioremap families as well. The fallback
>>> could be set disabled in the regular interfaces, and enabled in some
>>> interface as necessary. This also allows gradual transition, ex. disable in
>>> memremap while ioremap remains enabled for now.
>>
>> Sounds sexy to me.
>
> Cool, sounds like something we can tackle in 4.4 along with the
> ioremap_cache removal cleanups.

Just a reminder that we should expect some of these changes soon :D

Luis