2005-03-18 19:47:12

by Randy.Dunlap

[permalink] [raw]
Subject: [PATCH 0/4] io_remap_pfn_range: intro.


This is a combination of io_remap_pfn_range patches posted in the
last week or so by Keir Fraser and me.

This description is mostly from Keir's original post.


This patch introduces a new interface function for mapping bus/device
memory: io_remap_pfn_range. This accepts the same parameters as
remap_pfn_range and io_remap_page_range but should be used in any
situation where the caller is not simply remapping ordinary RAM.
For example, when mapping device registers the new function should be used.

The distinction between remapping device memory and ordinary RAM is
critical for the Xen hypervisor.

This patch series also cleans up the remaining users of
io_remap_page_range (in particular, the several sparc-specific
sections in various drivers that use a special form of io_remap_page_range:
an extra <iospace> argument for SPARC arch.) by converting them to
use io_remap_pfn_range(), where io_remap_pfn_range() supports
passing <iospace> as part of the pfn argument.

The sparc32 & sparc64 code needs live testing.


(from Keir:)
I have audited the drivers/ and sound/ directories. Most uses of
remap_pfn_range are okay, but there are a small handful that are
remapping device memory (mostly AGP and DRM drivers).

Of particular driver is the HPET driver, whose mmap function is broken
even for native (non-Xen) builds. If nothing else, vmalloc_to_phys
should be used instead of __pa to convert an ioremapped virtual
address to a valid physical address. The fix in this patch is to
remember the original bus address as probed at boot time and to pass
this to io_remap_pfn_range.


---
~Randy


2005-03-18 19:40:00

by Randy.Dunlap

[permalink] [raw]
Subject: [PATCH 3/4] io_remap_pfn_range: fix some callers for XEN


(from Keir:)
I have audited the drivers/ and sound/ directories. Most uses of
remap_pfn_range are okay, but there are a small handful that are
remapping device memory (mostly AGP and DRM drivers).

Of particular driver is the HPET driver, whose mmap function is broken
even for native (non-Xen) builds. If nothing else, vmalloc_to_phys
should be used instead of __pa to convert an ioremapped virtual
address to a valid physical address. The fix in this patch is to
remember the original bus address as probed at boot time and to pass
this to io_remap_pfn_range.

drivers/char/agp/frontend.c | 4 ++--
drivers/char/drm/drm_vm.c | 2 +-
drivers/char/drm/i810_dma.c | 2 +-
drivers/char/drm/i830_dma.c | 2 +-
drivers/char/hpet.c | 6 ++++--
drivers/sbus/char/flash.c | 2 +-
6 files changed, 10 insertions(+), 8 deletions(-)

Signed-off-by: Keir Fraser <[email protected]>


--- linux-2.6-old/drivers/char/agp/frontend.c 2005-03-16 10:30:25 +00:00
+++ linux-2.6-new/drivers/char/agp/frontend.c 2005-03-16 10:34:58 +00:00
@@ -628,7 +628,7 @@
DBG("client vm_ops=%p", kerninfo.vm_ops);
if (kerninfo.vm_ops) {
vma->vm_ops = kerninfo.vm_ops;
- } else if (remap_pfn_range(vma, vma->vm_start,
+ } else if (io_remap_pfn_range(vma, vma->vm_start,
(kerninfo.aper_base + offset) >> PAGE_SHIFT,
size, vma->vm_page_prot)) {
goto out_again;
@@ -644,7 +644,7 @@
DBG("controller vm_ops=%p", kerninfo.vm_ops);
if (kerninfo.vm_ops) {
vma->vm_ops = kerninfo.vm_ops;
- } else if (remap_pfn_range(vma, vma->vm_start,
+ } else if (io_remap_pfn_range(vma, vma->vm_start,
kerninfo.aper_base >> PAGE_SHIFT,
size, vma->vm_page_prot)) {
goto out_again;
--- linux-2.6-old/drivers/char/drm/drm_vm.c 2005-03-16 10:30:25 +00:00
+++ linux-2.6-new/drivers/char/drm/drm_vm.c 2005-03-16 10:34:58 +00:00
@@ -630,7 +630,7 @@
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
#else
- if (remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
+ if (io_remap_pfn_range(vma, vma->vm_start,
(VM_OFFSET(vma) + offset) >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
--- linux-2.6-old/drivers/char/drm/i810_dma.c 2005-03-16 10:30:25 +00:00
+++ linux-2.6-new/drivers/char/drm/i810_dma.c 2005-03-16 10:34:58 +00:00
@@ -119,7 +119,7 @@
buf_priv->currently_mapped = I810_BUF_MAPPED;
unlock_kernel();

- if (remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
+ if (io_remap_pfn_range(vma, vma->vm_start,
VM_OFFSET(vma) >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot)) return -EAGAIN;
--- linux-2.6-old/drivers/char/drm/i830_dma.c 2005-03-16 10:30:25 +00:00
+++ linux-2.6-new/drivers/char/drm/i830_dma.c 2005-03-16 10:34:58 +00:00
@@ -121,7 +121,7 @@
buf_priv->currently_mapped = I830_BUF_MAPPED;
unlock_kernel();

- if (remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
+ if (io_remap_pfn_range(vma, vma->vm_start,
VM_OFFSET(vma) >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot)) return -EAGAIN;
--- linux-2.6-old/drivers/char/hpet.c 2005-03-16 10:30:25 +00:00
+++ linux-2.6-new/drivers/char/hpet.c 2005-03-16 10:34:58 +00:00
@@ -76,6 +76,7 @@
struct hpets {
struct hpets *hp_next;
struct hpet __iomem *hp_hpet;
+ unsigned long hp_hpet_phys;
struct time_interpolator *hp_interpolator;
unsigned long hp_period;
unsigned long hp_delta;
@@ -265,7 +266,7 @@
return -EINVAL;

devp = file->private_data;
- addr = (unsigned long)devp->hd_hpet;
+ addr = devp->hd_hpets->hp_hpet_phys;

if (addr & (PAGE_SIZE - 1))
return -ENOSYS;
@@ -274,7 +275,7 @@
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
addr = __pa(addr);

- if (remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
+ if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
PAGE_SIZE, vma->vm_page_prot)) {
printk(KERN_ERR "remap_pfn_range failed in hpet.c\n");
return -EAGAIN;
@@ -795,6 +796,7 @@

hpetp->hp_which = hpet_nhpet++;
hpetp->hp_hpet = hdp->hd_address;
+ hpetp->hp_hpet_phys = hdp->hd_phys_address;

hpetp->hp_ntimer = hdp->hd_nirqs;

--- linux-2.6-old/drivers/sbus/char/flash.c 2005-03-16 10:30:37 +00:00
+++ linux-2.6-new/drivers/sbus/char/flash.c 2005-03-16 10:34:58 +00:00
@@ -75,7 +75,7 @@
pgprot_val(vma->vm_page_prot) |= _PAGE_E;
vma->vm_flags |= (VM_SHM | VM_LOCKED);

- if (remap_pfn_range(vma, vma->vm_start, addr, size, vma->vm_page_prot))
+ if (io_remap_pfn_range(vma, vma->vm_start, addr, size, vma->vm_page_prot))
return -EAGAIN;

return 0;

---

2005-03-18 19:40:25

by Randy.Dunlap

[permalink] [raw]
Subject: [PATCH 2/4] io_remap_pfn_range: convert sparc callers


io_remap_pfn_range():
convert sparc32/64 callers of io_remap_page_range(with 6 args)
to io_remap_pfn_range(with 5 args);

drivers/char/drm/drm_vm.c | 6 +++---
drivers/sbus/char/vfc_dev.c | 6 ++++--
drivers/video/fbmem.c | 6 +++---
drivers/video/sbuslib.c | 8 +++++---
4 files changed, 15 insertions(+), 11 deletions(-)

Signed-off-by: Randy Dunlap <[email protected]>

diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/drivers/char/drm/drm_vm.c linux-2611-bk3-pfn/drivers/char/drm/drm_vm.c
--- linux-2611-bk3-pv/drivers/char/drm/drm_vm.c 2005-03-01 23:38:33.000000000 -0800
+++ linux-2611-bk3-pfn/drivers/char/drm/drm_vm.c 2005-03-07 11:04:59.000000000 -0800
@@ -625,10 +625,10 @@ int drm_mmap(struct file *filp, struct v
#endif
offset = dev->driver->get_reg_ofs(dev);
#ifdef __sparc__
- if (io_remap_page_range(DRM_RPR_ARG(vma) vma->vm_start,
- VM_OFFSET(vma) + offset,
+ if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
+ (VM_OFFSET(vma) + offset) >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
- vma->vm_page_prot, 0))
+ vma->vm_page_prot))
#else
if (remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
(VM_OFFSET(vma) + offset) >> PAGE_SHIFT,
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/drivers/sbus/char/vfc_dev.c linux-2611-bk3-pfn/drivers/sbus/char/vfc_dev.c
--- linux-2611-bk3-pv/drivers/sbus/char/vfc_dev.c 2005-03-01 23:38:10.000000000 -0800
+++ linux-2611-bk3-pfn/drivers/sbus/char/vfc_dev.c 2005-03-07 11:04:59.000000000 -0800
@@ -626,8 +626,10 @@ static int vfc_mmap(struct file *file, s
vma->vm_flags |=
(VM_SHM | VM_LOCKED | VM_IO | VM_MAYREAD | VM_MAYWRITE | VM_MAYSHARE);
map_offset = (unsigned int) (long)dev->phys_regs;
- ret = io_remap_page_range(vma, vma->vm_start, map_offset, map_size,
- vma->vm_page_prot, dev->which_io);
+ ret = io_remap_pfn_range(vma, vma->vm_start,
+ MK_IOSPACE_PFN(dev->which_io,
+ map_offset >> PAGE_SHIFT),
+ map_size, vma->vm_page_prot);

if(ret)
return -EAGAIN;
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/drivers/video/fbmem.c linux-2611-bk3-pfn/drivers/video/fbmem.c
--- linux-2611-bk3-pv/drivers/video/fbmem.c 2005-03-01 23:37:30.000000000 -0800
+++ linux-2611-bk3-pfn/drivers/video/fbmem.c 2005-03-07 11:04:59.000000000 -0800
@@ -940,8 +940,8 @@ fb_mmap(struct file *file, struct vm_are
/* This is an IO map - tell maydump to skip this VMA */
vma->vm_flags |= VM_IO | VM_RESERVED;
#if defined(__sparc_v9__)
- if (io_remap_page_range(vma, vma->vm_start, off,
- vma->vm_end - vma->vm_start, vma->vm_page_prot, 0))
+ if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot))
return -EAGAIN;
#else
#if defined(__mc68000__)
@@ -977,7 +977,7 @@ fb_mmap(struct file *file, struct vm_are
#else
#warning What do we have to do here??
#endif
- if (io_remap_page_range(vma, vma->vm_start, off,
+ if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
vma->vm_end - vma->vm_start, vma->vm_page_prot))
return -EAGAIN;
#endif /* !__sparc_v9__ */
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/drivers/video/sbuslib.c linux-2611-bk3-pfn/drivers/video/sbuslib.c
--- linux-2611-bk3-pv/drivers/video/sbuslib.c 2005-03-01 23:37:52.000000000 -0800
+++ linux-2611-bk3-pfn/drivers/video/sbuslib.c 2005-03-07 11:04:59.000000000 -0800
@@ -74,10 +74,12 @@ int sbusfb_mmap_helper(struct sbus_mmap_
}
if (page + map_size > size)
map_size = size - page;
- r = io_remap_page_range(vma,
+ r = io_remap_pfn_range(vma,
vma->vm_start + page,
- map_offset, map_size,
- vma->vm_page_prot, iospace);
+ MK_IOSPACE_PFN(iospace,
+ map_offset >> PAGE_SHIFT),
+ map_size,
+ vma->vm_page_prot);
if (r)
return -EAGAIN;
page += map_size;
---

2005-03-18 19:42:55

by Randy.Dunlap

[permalink] [raw]
Subject: [PATCH 4/4] io_remap_pfn_range: convert last callers


io_remap_pfn_range() remaining callers:
convert all remaining callers of io_remap_page_range()
to io_remap_pfn_range();
add io_remap_page_range() to feature-removal-schedule.txt;

Documentation/feature-removal-schedule.txt | 9 +++++++++
arch/sh/kernel/cpu/sh4/sq.c | 2 +-
drivers/video/acornfb.c | 2 +-
drivers/video/au1100fb.c | 2 +-
drivers/video/controlfb.c | 2 +-
drivers/video/sa1100fb.c | 2 +-
sound/core/pcm_native.c | 4 ++--
7 files changed, 16 insertions(+), 7 deletions(-)

Signed-off-by: Randy Dunlap <[email protected]>

diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk10-remap1/arch/sh/kernel/cpu/sh4/sq.c linux-2611-bk10-remap2/arch/sh/kernel/cpu/sh4/sq.c
--- linux-2611-bk10-remap1/arch/sh/kernel/cpu/sh4/sq.c 2005-03-01 23:38:07.000000000 -0800
+++ linux-2611-bk10-remap2/arch/sh/kernel/cpu/sh4/sq.c 2005-03-16 09:46:10.000000000 -0800
@@ -379,7 +379,7 @@ static int sq_mmap(struct file *file, st

map = __sq_alloc_mapping(vma->vm_start, offset, size, "Userspace");

- if (io_remap_page_range(vma, map->sq_addr, map->addr,
+ if (io_remap_pfn_range(vma, map->sq_addr, map->addr >> PAGE_SHIFT,
size, vma->vm_page_prot))
return -EAGAIN;

diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk10-remap1/Documentation/feature-removal-schedule.txt linux-2611-bk10-remap2/Documentation/feature-removal-schedule.txt
--- linux-2611-bk10-remap1/Documentation/feature-removal-schedule.txt 2005-03-16 09:16:26.000000000 -0800
+++ linux-2611-bk10-remap2/Documentation/feature-removal-schedule.txt 2005-03-16 10:01:18.000000000 -0800
@@ -31,9 +31,18 @@ Why: /proc/sys/cpu/* has been deprecated
Both interfaces are superseded by the cpufreq interface in
/sys/devices/system/cpu/cpu%n/cpufreq/.
Who: Dominik Brodowski <[email protected]>
+---------------------------

What: ACPI S4bios support
When: May 2005
Why: Noone uses it, and it probably does not work, anyway. swsusp is
faster, more reliable, and people are actually using it.
Who: Pavel Machek <[email protected]>
+---------------------------
+
+What: io_remap_page_range() (macro or function)
+When: September 2005
+Why: Replaced by io_remap_pfn_range() which allows more memory space
+ addressabilty (by using a pfn) and supports sparc & sparc64
+ iospace as part of the pfn.
+Who: Randy Dunlap <[email protected]>
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk10-remap1/drivers/video/acornfb.c linux-2611-bk10-remap2/drivers/video/acornfb.c
--- linux-2611-bk10-remap1/drivers/video/acornfb.c 2005-03-01 23:38:26.000000000 -0800
+++ linux-2611-bk10-remap2/drivers/video/acornfb.c 2005-03-16 09:38:24.000000000 -0800
@@ -909,7 +909,7 @@ acornfb_mmap(struct fb_info *info, struc
* some updates to the screen occasionally, but process switches
* should cause the caches and buffers to be flushed often enough.
*/
- if (io_remap_page_range(vma, vma->vm_start, off,
+ if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
return -EAGAIN;
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk10-remap1/drivers/video/au1100fb.c linux-2611-bk10-remap2/drivers/video/au1100fb.c
--- linux-2611-bk10-remap1/drivers/video/au1100fb.c 2005-03-01 23:37:48.000000000 -0800
+++ linux-2611-bk10-remap2/drivers/video/au1100fb.c 2005-03-16 09:33:56.000000000 -0800
@@ -408,7 +408,7 @@ au1100fb_mmap(struct fb_info *_fb,
/* This is an IO map - tell maydump to skip this VMA */
vma->vm_flags |= VM_IO;

- if (io_remap_page_range(vma, vma->vm_start, off,
+ if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot)) {
return -EAGAIN;
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk10-remap1/drivers/video/controlfb.c linux-2611-bk10-remap2/drivers/video/controlfb.c
--- linux-2611-bk10-remap1/drivers/video/controlfb.c 2005-03-01 23:37:50.000000000 -0800
+++ linux-2611-bk10-remap2/drivers/video/controlfb.c 2005-03-16 09:37:11.000000000 -0800
@@ -315,7 +315,7 @@ static int controlfb_mmap(struct fb_info
return -EINVAL;
off += start;
vma->vm_pgoff = off >> PAGE_SHIFT;
- if (io_remap_page_range(vma, vma->vm_start, off,
+ if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
vma->vm_end - vma->vm_start, vma->vm_page_prot))
return -EAGAIN;

diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk10-remap1/drivers/video/sa1100fb.c linux-2611-bk10-remap2/drivers/video/sa1100fb.c
--- linux-2611-bk10-remap1/drivers/video/sa1100fb.c 2005-03-01 23:37:50.000000000 -0800
+++ linux-2611-bk10-remap2/drivers/video/sa1100fb.c 2005-03-16 09:37:53.000000000 -0800
@@ -836,7 +836,7 @@ static int sa1100fb_mmap(struct fb_info
vma->vm_pgoff = off >> PAGE_SHIFT;
vma->vm_flags |= VM_IO;
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- return io_remap_page_range(vma, vma->vm_start, off,
+ return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot);
}
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk10-remap1/sound/core/pcm_native.c linux-2611-bk10-remap2/sound/core/pcm_native.c
--- linux-2611-bk10-remap1/sound/core/pcm_native.c 2005-03-16 09:17:08.000000000 -0800
+++ linux-2611-bk10-remap2/sound/core/pcm_native.c 2005-03-16 09:39:41.000000000 -0800
@@ -3097,8 +3097,8 @@ int snd_pcm_lib_mmap_iomem(snd_pcm_subst
area->vm_flags |= VM_IO;
size = area->vm_end - area->vm_start;
offset = area->vm_pgoff << PAGE_SHIFT;
- if (io_remap_page_range(area, area->vm_start,
- substream->runtime->dma_addr + offset,
+ if (io_remap_pfn_range(area, area->vm_start,
+ (substream->runtime->dma_addr + offset) >> PAGE_SHIFT,
size, area->vm_page_prot))
return -EAGAIN;
atomic_inc(&substream->runtime->mmap_count);

---

2005-03-18 19:45:20

by Randy.Dunlap

[permalink] [raw]
Subject: [PATCH 1/4] io_remap_pfn_range: add for all arch-es


io_remap_pfn_range():
add io_remap_pfn_range() for all arches;
add MK_IOSPACE_PFN(), GET_IOSPACE(), and GET_PFN()
for all arches but primarily for sparc32/64's extended IO space,
sparc: kill the hack of using low bit of <offset> to mean
write_combine or set side-effect (_PAGE_E) bit;
(DaveM suggested that I kill it;)
future: convert remaining callers of io_remap_page_range() to
io_remap_pfn_range() and deprecate io_remap_page_range();

arch/sparc/kernel/sparc_ksyms.c | 1
arch/sparc/mm/generic.c | 34 ++++++++++++++++++++++++
arch/sparc64/kernel/pci.c | 15 +++++-----
arch/sparc64/kernel/sparc64_ksyms.c | 6 +++-
arch/sparc64/mm/generic.c | 50 ++++++++++++++++++++++++++++--------
include/asm-alpha/pgtable.h | 7 +++++
include/asm-arm/pgtable.h | 7 +++++
include/asm-arm26/pgtable.h | 7 +++++
include/asm-frv/pgtable.h | 7 +++++
include/asm-h8300/pgtable.h | 7 +++++
include/asm-i386/pgtable.h | 7 +++++
include/asm-ia64/pgtable.h | 7 +++++
include/asm-m32r/pgtable.h | 7 +++++
include/asm-m68k/pgtable.h | 7 +++++
include/asm-m68knommu/pgtable.h | 7 +++++
include/asm-mips/pgtable.h | 18 ++++++++++++
include/asm-parisc/pgtable.h | 7 +++++
include/asm-ppc/pgtable.h | 16 +++++++++++
include/asm-ppc64/pgtable.h | 7 +++++
include/asm-sh/pgtable.h | 7 +++++
include/asm-sh64/pgtable.h | 8 +++++
include/asm-sparc/pgtable.h | 14 +++++++++-
include/asm-sparc64/pgtable.h | 12 ++++++++
include/asm-x86_64/pgtable.h | 7 +++++
24 files changed, 251 insertions(+), 21 deletions(-)

Signed-off-by: Randy Dunlap <[email protected]>

diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/arch/sparc/kernel/sparc_ksyms.c linux-2611-bk3-pfn/arch/sparc/kernel/sparc_ksyms.c
--- linux-2611-bk3-pv/arch/sparc/kernel/sparc_ksyms.c 2005-03-01 23:37:48.000000000 -0800
+++ linux-2611-bk3-pfn/arch/sparc/kernel/sparc_ksyms.c 2005-03-07 11:04:59.000000000 -0800
@@ -164,6 +164,7 @@ EXPORT_SYMBOL(get_auxio);
#endif
EXPORT_SYMBOL(request_fast_irq);
EXPORT_SYMBOL(io_remap_page_range);
+EXPORT_SYMBOL(io_remap_pfn_range);
/* P3: iounit_xxx may be needed, sun4d users */
/* EXPORT_SYMBOL(iounit_map_dma_init); */
/* EXPORT_SYMBOL(iounit_map_dma_page); */
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/arch/sparc/mm/generic.c linux-2611-bk3-pfn/arch/sparc/mm/generic.c
--- linux-2611-bk3-pv/arch/sparc/mm/generic.c 2005-03-07 11:02:16.000000000 -0800
+++ linux-2611-bk3-pfn/arch/sparc/mm/generic.c 2005-03-07 13:23:18.000000000 -0800
@@ -118,3 +118,37 @@ int io_remap_page_range(struct vm_area_s
flush_tlb_range(vma, beg, end);
return error;
}
+
+int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
+ unsigned long pfn, unsigned long size, pgprot_t prot)
+{
+ int error = 0;
+ pgd_t * dir;
+ unsigned long beg = from;
+ unsigned long end = from + size;
+ struct mm_struct *mm = vma->vm_mm;
+ int space = GET_IOSPACE(pfn);
+ unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
+
+ prot = __pgprot(pg_iobits);
+ offset -= from;
+ dir = pgd_offset(mm, from);
+ flush_cache_range(vma, beg, end);
+
+ spin_lock(&mm->page_table_lock);
+ while (from < end) {
+ pmd_t *pmd = pmd_alloc(current->mm, dir, from);
+ error = -ENOMEM;
+ if (!pmd)
+ break;
+ error = io_remap_pmd_range(mm, pmd, from, end - from, offset + from, prot, space);
+ if (error)
+ break;
+ from = (from + PGDIR_SIZE) & PGDIR_MASK;
+ dir++;
+ }
+ spin_unlock(&mm->page_table_lock);
+
+ flush_tlb_range(vma, beg, end);
+ return error;
+}
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/arch/sparc64/kernel/pci.c linux-2611-bk3-pfn/arch/sparc64/kernel/pci.c
--- linux-2611-bk3-pv/arch/sparc64/kernel/pci.c 2005-03-07 11:02:16.000000000 -0800
+++ linux-2611-bk3-pfn/arch/sparc64/kernel/pci.c 2005-03-07 11:04:59.000000000 -0800
@@ -18,6 +18,7 @@

#include <asm/uaccess.h>
#include <asm/pbm.h>
+#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/ebus.h>
#include <asm/isa.h>
@@ -734,12 +735,10 @@ static void __pci_mmap_set_flags(struct
static void __pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma,
enum pci_mmap_state mmap_state)
{
- /* Our io_remap_page_range takes care of this, do nothing. */
+ /* Our io_remap_page_range/io_remap_pfn_range takes care of this,
+ do nothing. */
}

-extern int io_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long offset,
- unsigned long size, pgprot_t prot, int space);
-
/* Perform the actual remap of the pages for a PCI device mapping, as appropriate
* for this architecture. The region in the process to map is described by vm_start
* and vm_end members of VMA, the base physical address is found in vm_pgoff.
@@ -761,10 +760,10 @@ int pci_mmap_page_range(struct pci_dev *
__pci_mmap_set_flags(dev, vma, mmap_state);
__pci_mmap_set_pgprot(dev, vma, mmap_state);

- ret = io_remap_page_range(vma, vma->vm_start,
- (vma->vm_pgoff << PAGE_SHIFT |
- (write_combine ? 0x1UL : 0x0UL)),
- vma->vm_end - vma->vm_start, vma->vm_page_prot, 0);
+ ret = io_remap_pfn_range(vma, vma->vm_start,
+ vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
if (ret)
return ret;

diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/arch/sparc64/kernel/sparc64_ksyms.c linux-2611-bk3-pfn/arch/sparc64/kernel/sparc64_ksyms.c
--- linux-2611-bk3-pv/arch/sparc64/kernel/sparc64_ksyms.c 2005-03-01 23:38:20.000000000 -0800
+++ linux-2611-bk3-pfn/arch/sparc64/kernel/sparc64_ksyms.c 2005-03-07 11:04:59.000000000 -0800
@@ -87,7 +87,10 @@ extern int svr4_setcontext(svr4_ucontext
extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *);
extern long sparc32_open(const char __user * filename, int flags, int mode);
-extern int io_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long offset, unsigned long size, pgprot_t prot, int space);
+extern int io_remap_page_range(struct vm_area_struct *vma, unsigned long from,
+ unsigned long offset, unsigned long size, pgprot_t prot, int space);
+extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
+ unsigned long pfn, unsigned long size, pgprot_t prot);
extern void (*prom_palette)(int);

extern int __ashrdi3(int, int);
@@ -254,6 +257,7 @@ EXPORT_SYMBOL(pci_dma_supported);

/* I/O device mmaping on Sparc64. */
EXPORT_SYMBOL(io_remap_page_range);
+EXPORT_SYMBOL(io_remap_pfn_range);

/* Solaris/SunOS binary compatibility */
EXPORT_SYMBOL(_sigpause_common);
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/arch/sparc64/mm/generic.c linux-2611-bk3-pfn/arch/sparc64/mm/generic.c
--- linux-2611-bk3-pv/arch/sparc64/mm/generic.c 2005-03-07 11:02:16.000000000 -0800
+++ linux-2611-bk3-pfn/arch/sparc64/mm/generic.c 2005-03-07 13:27:06.000000000 -0800
@@ -20,10 +20,6 @@
*
* They use a pgprot that sets PAGE_IO and does not check the
* mem_map table as this is independent of normal memory.
- *
- * As a special hack if the lowest bit of offset is set the
- * side-effect bit will be turned off. This is used as a
- * performance improvement on FFB/AFB. -DaveM
*/
static inline void io_remap_pte_range(struct mm_struct *mm, pte_t * pte,
unsigned long address,
@@ -33,6 +29,8 @@ static inline void io_remap_pte_range(st
{
unsigned long end;

+ /* clear hack bit that was used as a write_combine side-effect flag */
+ offset &= ~0x1UL;
address &= ~PMD_MASK;
end = address + size;
if (end > PMD_SIZE)
@@ -41,22 +39,22 @@ static inline void io_remap_pte_range(st
pte_t entry;
unsigned long curend = address + PAGE_SIZE;

- entry = mk_pte_io((offset & ~(0x1UL)), prot, space);
+ entry = mk_pte_io(offset, prot, space);
if (!(address & 0xffff)) {
if (!(address & 0x3fffff) && !(offset & 0x3ffffe) && end >= address + 0x400000) {
- entry = mk_pte_io((offset & ~(0x1UL)),
+ entry = mk_pte_io(offset,
__pgprot(pgprot_val (prot) | _PAGE_SZ4MB),
space);
curend = address + 0x400000;
offset += 0x400000;
} else if (!(address & 0x7ffff) && !(offset & 0x7fffe) && end >= address + 0x80000) {
- entry = mk_pte_io((offset & ~(0x1UL)),
+ entry = mk_pte_io(offset,
__pgprot(pgprot_val (prot) | _PAGE_SZ512K),
space);
curend = address + 0x80000;
offset += 0x80000;
} else if (!(offset & 0xfffe) && end >= address + 0x10000) {
- entry = mk_pte_io((offset & ~(0x1UL)),
+ entry = mk_pte_io(offset,
__pgprot(pgprot_val (prot) | _PAGE_SZ64K),
space);
curend = address + 0x10000;
@@ -66,8 +64,6 @@ static inline void io_remap_pte_range(st
} else
offset += PAGE_SIZE;

- if (offset & 0x1UL)
- pte_val(entry) &= ~(_PAGE_E);
do {
BUG_ON(!pte_none(*pte));
set_pte_at(mm, address, pte, entry);
@@ -150,3 +146,37 @@ int io_remap_page_range(struct vm_area_s

return error;
}
+
+int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
+ unsigned long pfn, unsigned long size, pgprot_t prot)
+{
+ int error = 0;
+ pgd_t * dir;
+ unsigned long beg = from;
+ unsigned long end = from + size;
+ struct mm_struct *mm = vma->vm_mm;
+ int space = GET_IOSPACE(pfn);
+ unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT;
+
+ prot = __pgprot(pg_iobits);
+ offset -= from;
+ dir = pgd_offset(mm, from);
+ flush_cache_range(vma, beg, end);
+
+ spin_lock(&mm->page_table_lock);
+ while (from < end) {
+ pud_t *pud = pud_alloc(current->mm, dir, from);
+ error = -ENOMEM;
+ if (!pud)
+ break;
+ error = io_remap_pud_range(mm, pud, from, end - from, offset + from, prot, space);
+ if (error)
+ break;
+ from = (from + PGDIR_SIZE) & PGDIR_MASK;
+ dir++;
+ }
+ flush_tlb_range(vma, beg, end);
+ spin_unlock(&mm->page_table_lock);
+
+ return error;
+}
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-alpha/pgtable.h linux-2611-bk3-pfn/include/asm-alpha/pgtable.h
--- linux-2611-bk3-pv/include/asm-alpha/pgtable.h 2005-03-07 11:02:18.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-alpha/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -340,6 +340,13 @@ extern inline pte_t mk_swap_pte(unsigned
remap_pfn_range(vma, start, pfn, size, prot); \
})

+#define io_remap_pfn_range(vma, start, pfn, size, prot) \
+ remap_pfn_range(vma, start, pfn, size, prot)
+
+#define MK_IOSPACE_PFN(space, pfn) (pfn)
+#define GET_IOSPACE(pfn) 0
+#define GET_PFN(pfn) (pfn)
+
#define pte_ERROR(e) \
printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e))
#define pmd_ERROR(e) \
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-arm/pgtable.h linux-2611-bk3-pfn/include/asm-arm/pgtable.h
--- linux-2611-bk3-pv/include/asm-arm/pgtable.h 2005-03-07 11:02:18.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-arm/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -419,6 +419,13 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD
#define io_remap_page_range(vma,from,phys,size,prot) \
remap_pfn_range(vma, from, (phys) >> PAGE_SHIFT, size, prot)

+#define io_remap_pfn_range(vma,from,pfn,size,prot) \
+ remap_pfn_range(vma, from, pfn, size, prot)
+
+#define MK_IOSPACE_PFN(space, pfn) (pfn)
+#define GET_IOSPACE(pfn) 0
+#define GET_PFN(pfn) (pfn)
+
#define pgtable_cache_init() do { } while (0)

#endif /* !__ASSEMBLY__ */
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-arm26/pgtable.h linux-2611-bk3-pfn/include/asm-arm26/pgtable.h
--- linux-2611-bk3-pv/include/asm-arm26/pgtable.h 2005-03-07 11:02:18.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-arm26/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -293,6 +293,13 @@ static inline pte_t mk_pte_phys(unsigned
#define io_remap_page_range(vma,from,phys,size,prot) \
remap_pfn_range(vma, from, (phys) >> PAGE_SHIFT, size, prot)

+#define io_remap_pfn_range(vma,from,pfn,size,prot) \
+ remap_pfn_range(vma, from, pfn, size, prot)
+
+#define MK_IOSPACE_PFN(space, pfn) (pfn)
+#define GET_IOSPACE(pfn) 0
+#define GET_PFN(pfn) (pfn)
+
#endif /* !__ASSEMBLY__ */

#endif /* _ASMARM_PGTABLE_H */
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-frv/pgtable.h linux-2611-bk3-pfn/include/asm-frv/pgtable.h
--- linux-2611-bk3-pv/include/asm-frv/pgtable.h 2005-03-07 11:02:18.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-frv/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -503,6 +503,13 @@ static inline int pte_file(pte_t pte)
#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)

+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define MK_IOSPACE_PFN(space, pfn) (pfn)
+#define GET_IOSPACE(pfn) 0
+#define GET_PFN(pfn) (pfn)
+
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-h8300/pgtable.h linux-2611-bk3-pfn/include/asm-h8300/pgtable.h
--- linux-2611-bk3-pv/include/asm-h8300/pgtable.h 2005-03-01 23:38:07.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-h8300/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -55,6 +55,13 @@ extern int is_in_rom(unsigned long);
#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)

+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define MK_IOSPACE_PFN(space, pfn) (pfn)
+#define GET_IOSPACE(pfn) 0
+#define GET_PFN(pfn) (pfn)
+
/*
* All 32bit addresses are effectively valid for vmalloc...
* Sort of meaningless for non-VM targets.
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-i386/pgtable.h linux-2611-bk3-pfn/include/asm-i386/pgtable.h
--- linux-2611-bk3-pv/include/asm-i386/pgtable.h 2005-03-07 11:02:18.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-i386/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -405,6 +405,13 @@ extern void noexec_setup(const char *str
#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)

+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define MK_IOSPACE_PFN(space, pfn) (pfn)
+#define GET_IOSPACE(pfn) 0
+#define GET_PFN(pfn) (pfn)
+
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-ia64/pgtable.h linux-2611-bk3-pfn/include/asm-ia64/pgtable.h
--- linux-2611-bk3-pv/include/asm-ia64/pgtable.h 2005-03-07 11:02:18.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-ia64/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -447,6 +447,13 @@ extern void paging_init (void);
#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)

+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define MK_IOSPACE_PFN(space, pfn) (pfn)
+#define GET_IOSPACE(pfn) 0
+#define GET_PFN(pfn) (pfn)
+
/*
* ZERO_PAGE is a global shared page that is always zero: used
* for zero-mapped memory areas etc..
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-m32r/pgtable.h linux-2611-bk3-pfn/include/asm-m32r/pgtable.h
--- linux-2611-bk3-pv/include/asm-m32r/pgtable.h 2005-03-07 11:02:18.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-m32r/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -381,6 +381,13 @@ static inline void pmd_set(pmd_t * pmdp,
#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)

+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define MK_IOSPACE_PFN(space, pfn) (pfn)
+#define GET_IOSPACE(pfn) 0
+#define GET_PFN(pfn) (pfn)
+
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-m68k/pgtable.h linux-2611-bk3-pfn/include/asm-m68k/pgtable.h
--- linux-2611-bk3-pv/include/asm-m68k/pgtable.h 2005-03-07 11:02:18.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-m68k/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -144,6 +144,13 @@ static inline void update_mmu_cache(stru
#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)

+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define MK_IOSPACE_PFN(space, pfn) (pfn)
+#define GET_IOSPACE(pfn) 0
+#define GET_PFN(pfn) (pfn)
+
/* MMU-specific headers */

#ifdef CONFIG_SUN3
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-m68knommu/pgtable.h linux-2611-bk3-pfn/include/asm-m68knommu/pgtable.h
--- linux-2611-bk3-pv/include/asm-m68knommu/pgtable.h 2005-03-01 23:38:10.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-m68knommu/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -59,6 +59,13 @@ extern int is_in_rom(unsigned long);
#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)

+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define MK_IOSPACE_PFN(space, pfn) (pfn)
+#define GET_IOSPACE(pfn) 0
+#define GET_PFN(pfn) (pfn)
+
/*
* All 32bit addresses are effectively valid for vmalloc...
* Sort of meaningless for non-VM targets.
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-mips/pgtable.h linux-2611-bk3-pfn/include/asm-mips/pgtable.h
--- linux-2611-bk3-pv/include/asm-mips/pgtable.h 2005-03-07 11:02:18.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-mips/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -367,11 +367,27 @@ static inline int io_remap_page_range(st
phys_t phys_addr_high = fixup_bigphys_addr(paddr, size);
return remap_pfn_range(vma, vaddr, phys_addr_high >> PAGE_SHIFT, size, prot);
}
+
+static inline int io_remap_pfn_range(struct vm_area_struct *vma,
+ unsigned long vaddr,
+ unsigned long pfn,
+ unsigned long size,
+ pgprot_t prot)
+{
+ phys_t phys_addr_high = fixup_bigphys_addr(pfn << PAGE_SHIFT, size);
+ return remap_pfn_range(vma, vaddr, pfn, size, prot);
+}
#else
#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
- remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
+ remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
#endif

+#define MK_IOSPACE_PFN(space, pfn) (pfn)
+#define GET_IOSPACE(pfn) 0
+#define GET_PFN(pfn) (pfn)
+
#include <asm-generic/pgtable.h>

/*
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-parisc/pgtable.h linux-2611-bk3-pfn/include/asm-parisc/pgtable.h
--- linux-2611-bk3-pv/include/asm-parisc/pgtable.h 2005-03-07 11:02:18.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-parisc/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -501,6 +501,13 @@ static inline void ptep_set_wrprotect(st
#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)

+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define MK_IOSPACE_PFN(space, pfn) (pfn)
+#define GET_IOSPACE(pfn) 0
+#define GET_PFN(pfn) (pfn)
+
/* We provide our own get_unmapped_area to provide cache coherency */

#define HAVE_ARCH_UNMAPPED_AREA
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-ppc/pgtable.h linux-2611-bk3-pfn/include/asm-ppc/pgtable.h
--- linux-2611-bk3-pv/include/asm-ppc/pgtable.h 2005-03-07 11:02:18.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-ppc/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -735,11 +735,27 @@ static inline int io_remap_page_range(st
phys_addr_t paddr64 = fixup_bigphys_addr(paddr, size);
return remap_pfn_range(vma, vaddr, paddr64 >> PAGE_SHIFT, size, prot);
}
+
+static inline int io_remap_pfn_range(struct vm_area_struct *vma,
+ unsigned long vaddr,
+ unsigned long pfn,
+ unsigned long size,
+ pgprot_t prot)
+{
+ phys_addr_t paddr64 = fixup_bigphys_addr(pfn << PAGE_SHIFT, size);
+ return remap_pfn_range(vma, vaddr, pfn, size, prot);
+}
#else
#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
#endif

+#define MK_IOSPACE_PFN(space, pfn) (pfn)
+#define GET_IOSPACE(pfn) 0
+#define GET_PFN(pfn) (pfn)
+
/*
* No page table caches to initialise
*/
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-ppc64/pgtable.h linux-2611-bk3-pfn/include/asm-ppc64/pgtable.h
--- linux-2611-bk3-pv/include/asm-ppc64/pgtable.h 2005-03-07 11:02:18.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-ppc64/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -527,6 +527,13 @@ extern void update_mmu_cache(struct vm_a
#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)

+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define MK_IOSPACE_PFN(space, pfn) (pfn)
+#define GET_IOSPACE(pfn) 0
+#define GET_PFN(pfn) (pfn)
+
void pgtable_cache_init(void);

extern void hpte_init_native(void);
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-sh/pgtable.h linux-2611-bk3-pfn/include/asm-sh/pgtable.h
--- linux-2611-bk3-pv/include/asm-sh/pgtable.h 2005-03-07 11:02:18.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-sh/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -279,6 +279,13 @@ typedef pte_t *pte_addr_t;
#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)

+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define MK_IOSPACE_PFN(space, pfn) (pfn)
+#define GET_IOSPACE(pfn) 0
+#define GET_PFN(pfn) (pfn)
+
/*
* No page table caches to initialise
*/
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-sh64/pgtable.h linux-2611-bk3-pfn/include/asm-sh64/pgtable.h
--- linux-2611-bk3-pv/include/asm-sh64/pgtable.h 2005-03-07 11:02:18.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-sh64/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -482,6 +482,14 @@ extern void update_mmu_cache(struct vm_a

#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
+
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define MK_IOSPACE_PFN(space, pfn) (pfn)
+#define GET_IOSPACE(pfn) 0
+#define GET_PFN(pfn) (pfn)
+
#endif /* !__ASSEMBLY__ */

/*
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-sparc/pgtable.h linux-2611-bk3-pfn/include/asm-sparc/pgtable.h
--- linux-2611-bk3-pv/include/asm-sparc/pgtable.h 2005-03-07 11:02:18.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-sparc/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -454,8 +454,20 @@ extern unsigned long *sparc_valid_addr_b
#define kern_addr_valid(addr) \
(test_bit(__pa((unsigned long)(addr))>>20, sparc_valid_addr_bitmap))

-extern int io_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long to,
+extern int io_remap_page_range(struct vm_area_struct *vma,
+ unsigned long from, unsigned long to,
unsigned long size, pgprot_t prot, int space);
+extern int io_remap_pfn_range(struct vm_area_struct *vma,
+ unsigned long from, unsigned long pfn,
+ unsigned long size, pgprot_t prot);
+
+/*
+ * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
+ * its high 4 bits. These macros/functions put it there or get it from there.
+ */
+#define MK_IOSPACE_PFN(space, pfn) (pfn | (space << (BITS_PER_LONG - 4)))
+#define GET_IOSPACE(pfn) (pfn >> (BITS_PER_LONG - 4))
+#define GET_PFN(pfn) (pfn & 0x0fffffffUL)

#include <asm-generic/pgtable.h>

diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-sparc64/pgtable.h linux-2611-bk3-pfn/include/asm-sparc64/pgtable.h
--- linux-2611-bk3-pv/include/asm-sparc64/pgtable.h 2005-03-07 11:02:18.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-sparc64/pgtable.h 2005-03-07 11:08:06.000000000 -0800
@@ -16,6 +16,7 @@

#include <linux/config.h>
#include <linux/compiler.h>
+#include <asm/types.h>
#include <asm/spitfire.h>
#include <asm/asi.h>
#include <asm/system.h>
@@ -431,6 +432,17 @@ extern unsigned long *sparc64_valid_addr
extern int io_remap_page_range(struct vm_area_struct *vma, unsigned long from,
unsigned long offset,
unsigned long size, pgprot_t prot, int space);
+extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
+ unsigned long pfn,
+ unsigned long size, pgprot_t prot);
+
+/*
+ * For sparc32&64, the pfn in io_remap_pfn_range() carries <iospace> in
+ * its high 4 bits. These macros/functions put it there or get it from there.
+ */
+#define MK_IOSPACE_PFN(space, pfn) (pfn | (space << (BITS_PER_LONG - 4)))
+#define GET_IOSPACE(pfn) (pfn >> (BITS_PER_LONG - 4))
+#define GET_PFN(pfn) (pfn & 0x0fffffffffffffffUL)

/* Override for {pgd,pmd}_addr_end() to deal with the virtual address
* space hole. We simply sign extend bit 43.
diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-x86_64/pgtable.h linux-2611-bk3-pfn/include/asm-x86_64/pgtable.h
--- linux-2611-bk3-pv/include/asm-x86_64/pgtable.h 2005-03-07 11:02:18.000000000 -0800
+++ linux-2611-bk3-pfn/include/asm-x86_64/pgtable.h 2005-03-07 11:04:59.000000000 -0800
@@ -407,6 +407,13 @@ extern int kern_addr_valid(unsigned long
#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)

+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+#define MK_IOSPACE_PFN(space, pfn) (pfn)
+#define GET_IOSPACE(pfn) 0
+#define GET_PFN(pfn) (pfn)
+
#define HAVE_ARCH_UNMAPPED_AREA

#define pgtable_cache_init() do { } while (0)
---

2005-03-18 20:56:28

by David Miller

[permalink] [raw]
Subject: Re: [PATCH 0/4] io_remap_pfn_range: intro.

On Fri, 18 Mar 2005 11:25:45 -0800
"Randy.Dunlap" <[email protected]> wrote:

> The sparc32 & sparc64 code needs live testing.

These patches look great Randy. I think they should go in.

If sparc explodes, I'll clean up the mess. Any problem which
crops up should not be difficult to solve.

2005-03-18 23:05:31

by Paul Mackerras

[permalink] [raw]
Subject: Re: [PATCH 1/4] io_remap_pfn_range: add for all arch-es

Randy.Dunlap writes:

> diff -Naurp -X /home/rddunlap/doc/dontdiff-osdl linux-2611-bk3-pv/include/asm-ppc/pgtable.h linux-2611-bk3-pfn/include/asm-ppc/pgtable.h
> --- linux-2611-bk3-pv/include/asm-ppc/pgtable.h 2005-03-07 11:02:18.000000000 -0800
> +++ linux-2611-bk3-pfn/include/asm-ppc/pgtable.h 2005-03-07 11:04:59.000000000 -0800
> @@ -735,11 +735,27 @@ static inline int io_remap_page_range(st
> phys_addr_t paddr64 = fixup_bigphys_addr(paddr, size);
> return remap_pfn_range(vma, vaddr, paddr64 >> PAGE_SHIFT, size, prot);
> }
> +
> +static inline int io_remap_pfn_range(struct vm_area_struct *vma,
> + unsigned long vaddr,
> + unsigned long pfn,
> + unsigned long size,
> + pgprot_t prot)
> +{
> + phys_addr_t paddr64 = fixup_bigphys_addr(pfn << PAGE_SHIFT, size);
> + return remap_pfn_range(vma, vaddr, pfn, size, prot);

Just by inspection, this looks like pfn should be changed to
paddr64 >> PAGE_SHIFT in that last line.

Paul.

2005-03-18 23:25:16

by Randy.Dunlap

[permalink] [raw]
Subject: Re: [PATCH 1/4] io_remap_pfn_range: add for all arch-es

Paul Mackerras wrote:
>
> Just by inspection, this looks like pfn should be changed to
> paddr64 >> PAGE_SHIFT in that last line.
>
> Paul.

Agreed, thank you. Patch is attached.

--
~Randy


Attachments:
ioremap_ppc_shift.patch (792.00 B)

2005-04-20 01:37:18

by William Lee Irwin III

[permalink] [raw]
Subject: Re: [PATCH 0/4] io_remap_pfn_range: intro.

On Fri, Mar 18, 2005 at 11:25:45AM -0800, Randy.Dunlap wrote:
> This is a combination of io_remap_pfn_range patches posted in the
> last week or so by Keir Fraser and me.
> This description is mostly from Keir's original post.
> This patch introduces a new interface function for mapping bus/device
> memory: io_remap_pfn_range. This accepts the same parameters as
> remap_pfn_range and io_remap_page_range but should be used in any
> situation where the caller is not simply remapping ordinary RAM.
> For example, when mapping device registers the new function should be used.
> The distinction between remapping device memory and ordinary RAM is
> critical for the Xen hypervisor.
> This patch series also cleans up the remaining users of
> io_remap_page_range (in particular, the several sparc-specific
> sections in various drivers that use a special form of io_remap_page_range:
> an extra <iospace> argument for SPARC arch.) by converting them to
> use io_remap_pfn_range(), where io_remap_pfn_range() supports
> passing <iospace> as part of the pfn argument.
> The sparc32 & sparc64 code needs live testing.

Thanks for covering this for me (not that I've contributed a line of
code to this). I've got a very limited range of devices to test on
sparc so I'll have to wait for users' reports to come in.


-- wli

2005-04-20 01:39:02

by William Lee Irwin III

[permalink] [raw]
Subject: Re: [PATCH 0/4] io_remap_pfn_range: intro.

On Fri, 18 Mar 2005 11:25:45 -0800 "Randy.Dunlap" <[email protected]> wrote:
>> The sparc32 & sparc64 code needs live testing.

On Fri, Mar 18, 2005 at 12:56:17PM -0800, David S. Miller wrote:
> These patches look great Randy. I think they should go in.
> If sparc explodes, I'll clean up the mess. Any problem which
> crops up should not be difficult to solve.

Thanks for covering for me. My understanding of this area of the code
is very limited, so your help is much appreciated here.


-- wli