aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-11-29 18:51:18 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-11-29 18:51:18 +0000
commit9e34879530f2d1dad18dcbd62ed56a673e6947e3 (patch)
treed7001d72f86a39df19660b758b649cddd61ec198
parent6098b15ac3f7c9435021a2c10fe611b2520b30c0 (diff)
parentcfb60f4ea0474627c26647f300fef046b162ef76 (diff)
downloadxen-9e34879530f2d1dad18dcbd62ed56a673e6947e3.tar.gz
xen-9e34879530f2d1dad18dcbd62ed56a673e6947e3.tar.bz2
xen-9e34879530f2d1dad18dcbd62ed56a673e6947e3.zip
bitkeeper revision 1.1159.187.39 (41ab6fa6Y09a8uLTIgCHmRV5IVqoRA)
Merge scramble.cl.cam.ac.uk:/auto/groups/xeno/BK/xen-2.0-testing.bk into scramble.cl.cam.ac.uk:/local/scratch/kaf24/xen-2.0-testing.bk
-rw-r--r--.rootkeys1
-rw-r--r--linux-2.6.9-xen-sparse/arch/xen/i386/mm/ioremap.c351
-rw-r--r--linux-2.6.9-xen-sparse/arch/xen/kernel/Makefile2
-rw-r--r--linux-2.6.9-xen-sparse/arch/xen/kernel/devmem.c158
-rw-r--r--linux-2.6.9-xen-sparse/drivers/char/mem.c25
-rw-r--r--linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/io.h3
6 files changed, 316 insertions, 224 deletions
diff --git a/.rootkeys b/.rootkeys
index 8bda240f8f..1691f867c4 100644
--- a/.rootkeys
+++ b/.rootkeys
@@ -171,6 +171,7 @@
4107adf1s5u6249DNPUViX1YNagbUQ linux-2.6.9-xen-sparse/arch/xen/i386/pci/irq.c
40f56239zOksGg_H4XD4ye6iZNtoZA linux-2.6.9-xen-sparse/arch/xen/kernel/Makefile
40f56239bvOjuuuViZ0XMlNiREFC0A linux-2.6.9-xen-sparse/arch/xen/kernel/ctrl_if.c
+41ab6fa06JdF7jxUsuDcjN3UhuIAxg linux-2.6.9-xen-sparse/arch/xen/kernel/devmem.c
40f56238xFQe9T7M_U_FItM-bZIpLw linux-2.6.9-xen-sparse/arch/xen/kernel/evtchn.c
4110f478aeQWllIN7J4kouAHiAqrPw linux-2.6.9-xen-sparse/arch/xen/kernel/fixup.c
412dfae9eA3_6e6bCGUtg1mj8b56fQ linux-2.6.9-xen-sparse/arch/xen/kernel/gnttab.c
diff --git a/linux-2.6.9-xen-sparse/arch/xen/i386/mm/ioremap.c b/linux-2.6.9-xen-sparse/arch/xen/i386/mm/ioremap.c
index f97d3f6b4d..d28a636c77 100644
--- a/linux-2.6.9-xen-sparse/arch/xen/i386/mm/ioremap.c
+++ b/linux-2.6.9-xen-sparse/arch/xen/i386/mm/ioremap.c
@@ -16,23 +16,33 @@
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#ifndef CONFIG_XEN_PHYSDEV_ACCESS
-void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
-{ return NULL; }
+void * __ioremap(unsigned long phys_addr, unsigned long size,
+ unsigned long flags)
+{
+ return NULL;
+}
void *ioremap_nocache (unsigned long phys_addr, unsigned long size)
-{ return NULL; }
+{
+ return NULL;
+}
void iounmap(volatile void __iomem *addr)
-{ }
+{
+}
void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
-{ return NULL; }
+{
+ return NULL;
+}
void __init bt_iounmap(void *addr, unsigned long size)
-{ }
+{
+}
#else
@@ -50,86 +60,6 @@ static inline int is_local_lowmem(unsigned long address)
return ((pfn < max_low_pfn) && (pfn_to_mfn(pfn) == mfn));
}
-static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
- unsigned long phys_addr, unsigned long flags)
-{
- unsigned long end;
- unsigned long pfn;
-
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
- if (address >= end)
- BUG();
- pfn = phys_addr >> PAGE_SHIFT;
- do {
- if (!pte_none(*pte)) {
- printk("remap_area_pte: page already exists\n");
- BUG();
- }
- set_pte(pte, pfn_pte_ma(pfn, __pgprot(_PAGE_PRESENT | _PAGE_RW |
- _PAGE_DIRTY | _PAGE_ACCESSED | flags)));
- address += PAGE_SIZE;
- pfn++;
- pte++;
- } while (address && (address < end));
-}
-
-static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
- unsigned long phys_addr, unsigned long flags)
-{
- unsigned long end;
-
- address &= ~PGDIR_MASK;
- end = address + size;
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
- phys_addr -= address;
- if (address >= end)
- BUG();
- do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
- if (!pte)
- return -ENOMEM;
- remap_area_pte(pte, address, end - address, address + phys_addr, flags);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address && (address < end));
- return 0;
-}
-
-static int remap_area_pages(unsigned long address, unsigned long phys_addr,
- unsigned long size, unsigned long flags)
-{
- int error;
- pgd_t * dir;
- unsigned long end = address + size;
-
- phys_addr -= address;
- dir = pgd_offset(&init_mm, address);
- flush_cache_all();
- if (address >= end)
- BUG();
- spin_lock(&init_mm.page_table_lock);
- do {
- pmd_t *pmd;
- pmd = pmd_alloc(&init_mm, dir, address);
- error = -ENOMEM;
- if (!pmd)
- break;
- if (remap_area_pmd(pmd, address, end - address,
- phys_addr + address, flags))
- break;
- error = 0;
- address = (address + PGDIR_SIZE) & PGDIR_MASK;
- dir++;
- } while (address && (address < end));
- spin_unlock(&init_mm.page_table_lock);
- flush_tlb_all();
- return error;
-}
-
/*
* Generic mapping function (not visible outside):
*/
@@ -192,7 +122,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
return NULL;
area->phys_addr = phys_addr;
addr = (void __iomem *) area->addr;
- if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
+ if (direct_remap_area_pages(&init_mm, (unsigned long) addr, phys_addr, size, __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | flags), DOMID_IO)) {
vunmap((void __force *) addr);
return NULL;
}
@@ -360,138 +290,145 @@ void __init bt_iounmap(void *addr, unsigned long size)
#define direct_mk_pte_phys(physpage, pgprot) \
__direct_mk_pte((physpage) >> PAGE_SHIFT, pgprot)
-static inline void direct_remap_area_pte(pte_t *pte,
- unsigned long address,
- unsigned long size,
- mmu_update_t **v)
+static inline void direct_remap_area_pte(
+ pte_t *pte,
+ unsigned long address,
+ unsigned long size,
+ mmu_update_t **v)
{
- unsigned long end;
-
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
- if (address >= end)
- BUG();
-
- do {
- (*v)->ptr = virt_to_machine(pte);
- (*v)++;
- address += PAGE_SIZE;
- pte++;
- } while (address && (address < end));
+ unsigned long end;
+
+ address &= ~PMD_MASK;
+ end = address + size;
+ if (end > PMD_SIZE)
+ end = PMD_SIZE;
+ if (address >= end)
+ BUG();
+
+ do {
+ (*v)->ptr = virt_to_machine(pte);
+ (*v)++;
+ address += PAGE_SIZE;
+ pte++;
+ } while (address && (address < end));
}
-static inline int direct_remap_area_pmd(struct mm_struct *mm,
- pmd_t *pmd,
- unsigned long address,
- unsigned long size,
- mmu_update_t **v)
+static inline int direct_remap_area_pmd(
+ struct mm_struct *mm,
+ pmd_t *pmd,
+ unsigned long address,
+ unsigned long size,
+ mmu_update_t **v)
{
- unsigned long end;
-
- address &= ~PGDIR_MASK;
- end = address + size;
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
- if (address >= end)
- BUG();
- do {
- pte_t *pte = pte_alloc_map(mm, pmd, address);
- if (!pte)
- return -ENOMEM;
- direct_remap_area_pte(pte, address, end - address, v);
- pte_unmap(pte);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address && (address < end));
- return 0;
+ unsigned long end;
+
+ address &= ~PGDIR_MASK;
+ end = address + size;
+ if (end > PGDIR_SIZE)
+ end = PGDIR_SIZE;
+ if (address >= end)
+ BUG();
+ do {
+ pte_t *pte = (mm == &init_mm) ?
+ pte_alloc_kernel(mm, pmd, address) :
+ pte_alloc_map(mm, pmd, address);
+ if (!pte)
+ return -ENOMEM;
+ direct_remap_area_pte(pte, address, end - address, v);
+ pte_unmap(pte);
+ address = (address + PMD_SIZE) & PMD_MASK;
+ pmd++;
+ } while (address && (address < end));
+ return 0;
}
-int __direct_remap_area_pages(struct mm_struct *mm,
- unsigned long address,
- unsigned long size,
- mmu_update_t *v)
+int __direct_remap_area_pages(
+ struct mm_struct *mm,
+ unsigned long address,
+ unsigned long size,
+ mmu_update_t *v)
{
- pgd_t * dir;
- unsigned long end = address + size;
-
- dir = pgd_offset(mm, address);
- flush_cache_all();
- if (address >= end)
- BUG();
- spin_lock(&mm->page_table_lock);
- do {
- pmd_t *pmd = pmd_alloc(mm, dir, address);
- if (!pmd)
- return -ENOMEM;
- direct_remap_area_pmd(mm, pmd, address, end - address, &v);
- address = (address + PGDIR_SIZE) & PGDIR_MASK;
- dir++;
-
- } while (address && (address < end));
- spin_unlock(&mm->page_table_lock);
- flush_tlb_all();
- return 0;
+ pgd_t * dir;
+ unsigned long end = address + size;
+
+ dir = pgd_offset(mm, address);
+ if (address >= end)
+ BUG();
+ spin_lock(&mm->page_table_lock);
+ do {
+ pmd_t *pmd = pmd_alloc(mm, dir, address);
+ if (!pmd)
+ return -ENOMEM;
+ direct_remap_area_pmd(mm, pmd, address, end - address, &v);
+ address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ dir++;
+
+ } while (address && (address < end));
+ spin_unlock(&mm->page_table_lock);
+ return 0;
}
-int direct_remap_area_pages(struct mm_struct *mm,
- unsigned long address,
- unsigned long machine_addr,
- unsigned long size,
- pgprot_t prot,
- domid_t domid)
+int direct_remap_area_pages(
+ struct mm_struct *mm,
+ unsigned long address,
+ unsigned long machine_addr,
+ unsigned long size,
+ pgprot_t prot,
+ domid_t domid)
{
- int i;
- unsigned long start_address;
+ int i;
+ unsigned long start_address;
#define MAX_DIRECTMAP_MMU_QUEUE 130
- mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *w, *v;
-
- u[0].ptr = MMU_EXTENDED_COMMAND;
- u[0].val = MMUEXT_SET_FOREIGNDOM;
- u[0].val |= (unsigned long)domid << 16;
- v = w = &u[1];
-
- start_address = address;
-
- for( i = 0; i < size; i += PAGE_SIZE )
- {
- if ( (v - u) == MAX_DIRECTMAP_MMU_QUEUE )
- {
- /* Fill in the PTE pointers. */
- __direct_remap_area_pages( mm,
- start_address,
- address-start_address,
- w);
-
- if ( HYPERVISOR_mmu_update(u, v - u, NULL) < 0 )
- return -EFAULT;
- v = w;
- start_address = address;
+ mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *w, *v;
+
+ u[0].ptr = MMU_EXTENDED_COMMAND;
+ u[0].val = MMUEXT_SET_FOREIGNDOM;
+ u[0].val |= (unsigned long)domid << 16;
+ v = w = &u[1];
+
+ start_address = address;
+
+ flush_cache_all();
+
+ for (i = 0; i < size; i += PAGE_SIZE) {
+ if ((v - u) == MAX_DIRECTMAP_MMU_QUEUE) {
+ /* Fill in the PTE pointers. */
+ __direct_remap_area_pages(
+ mm,
+ start_address,
+ address-start_address,
+ w);
+
+ if (HYPERVISOR_mmu_update(u, v - u, NULL) < 0)
+ return -EFAULT;
+ v = w;
+ start_address = address;
+ }
+
+ /*
+ * Fill in the machine address: PTE ptr is done later by
+ * __direct_remap_area_pages().
+ */
+ v->val = (machine_addr & PAGE_MASK) | pgprot_val(prot);
+
+ machine_addr += PAGE_SIZE;
+ address += PAGE_SIZE;
+ v++;
}
- /*
- * Fill in the machine address: PTE ptr is done later by
- * __direct_remap_area_pages().
- */
- v->val = (machine_addr & PAGE_MASK) | pgprot_val(prot);
-
- machine_addr += PAGE_SIZE;
- address += PAGE_SIZE;
- v++;
- }
-
- if ( v != w )
- {
- /* get the ptep's filled in */
- __direct_remap_area_pages(mm,
- start_address,
- address-start_address,
- w);
- if ( unlikely(HYPERVISOR_mmu_update(u, v - u, NULL) < 0) )
- return -EFAULT;
- }
-
- return 0;
+ if (v != w) {
+ /* get the ptep's filled in */
+ __direct_remap_area_pages(
+ mm,
+ start_address,
+ address-start_address,
+ w);
+ if (unlikely(HYPERVISOR_mmu_update(u, v - u, NULL) < 0))
+ return -EFAULT;
+ }
+
+ flush_tlb_all();
+
+ return 0;
}
diff --git a/linux-2.6.9-xen-sparse/arch/xen/kernel/Makefile b/linux-2.6.9-xen-sparse/arch/xen/kernel/Makefile
index 3e987bee23..26731eff31 100644
--- a/linux-2.6.9-xen-sparse/arch/xen/kernel/Makefile
+++ b/linux-2.6.9-xen-sparse/arch/xen/kernel/Makefile
@@ -9,4 +9,4 @@ $(obj)/vmlinux.lds:
extra-y += vmlinux.lds
-obj-y := ctrl_if.o evtchn.o fixup.o reboot.o xen_proc.o gnttab.o skbuff.o
+obj-y := ctrl_if.o evtchn.o fixup.o reboot.o xen_proc.o gnttab.o skbuff.o devmem.o
diff --git a/linux-2.6.9-xen-sparse/arch/xen/kernel/devmem.c b/linux-2.6.9-xen-sparse/arch/xen/kernel/devmem.c
new file mode 100644
index 0000000000..ffda098851
--- /dev/null
+++ b/linux-2.6.9-xen-sparse/arch/xen/kernel/devmem.c
@@ -0,0 +1,158 @@
+/*
+ * Originally from linux/drivers/char/mem.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * Added devfs support.
+ * Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
+ * Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mman.h>
+#include <linux/random.h>
+#include <linux/init.h>
+#include <linux/raw.h>
+#include <linux/tty.h>
+#include <linux/capability.h>
+#include <linux/smp_lock.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/ptrace.h>
+#include <linux/device.h>
+#include <asm/pgalloc.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+
+static inline int uncached_access(struct file *file, unsigned long addr)
+{
+ if (file->f_flags & O_SYNC)
+ return 1;
+ /* Xen sets correct MTRR type on non-RAM for us. */
+ return 0;
+}
+
+/*
+ * This funcion reads the *physical* memory. The f_pos points directly to the
+ * memory location.
+ */
+static ssize_t read_mem(struct file * file, char __user * buf,
+ size_t count, loff_t *ppos)
+{
+ unsigned long i, p = *ppos;
+ ssize_t read = 0;
+ void *v;
+
+ if ((v = ioremap(p, count)) == NULL) {
+ /*
+ * Some programs (e.g., dmidecode) groove off into weird RAM
+ * areas where no table scan possibly exist (because Xen will
+ * have stomped on them!). These programs get rather upset if
+ * we let them know that Xen failed their access, so we fake
+ * out a read of all zeroes. :-)
+ */
+ for (i = 0; i < count; i++)
+ if (put_user(0, buf+i))
+ return -EFAULT;
+ return count;
+ }
+ if (copy_to_user(buf, v, count))
+ return -EFAULT;
+ iounmap(v);
+
+ read += count;
+ *ppos += read;
+
+ return read;
+}
+
+static ssize_t write_mem(struct file * file, const char __user * buf,
+ size_t count, loff_t *ppos)
+{
+ unsigned long p = *ppos;
+ ssize_t written = 0;
+ void *v;
+
+ if ((v = ioremap(p, count)) == NULL)
+ return -EFAULT;
+ if (copy_to_user(v, buf, count))
+ return -EFAULT;
+ iounmap(v);
+
+ written += count;
+ *ppos += written;
+
+ return written;
+}
+
+static int mmap_mem(struct file * file, struct vm_area_struct * vma)
+{
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+ int uncached;
+
+ uncached = uncached_access(file, offset);
+ if (uncached)
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+ /* Don't try to swap out physical pages.. */
+ vma->vm_flags |= VM_RESERVED;
+
+ /*
+ * Don't dump addresses that are not real memory to a core file.
+ */
+ if (uncached)
+ vma->vm_flags |= VM_IO;
+
+ if (io_remap_page_range(vma, vma->vm_start, offset,
+ vma->vm_end-vma->vm_start, vma->vm_page_prot))
+ return -EAGAIN;
+
+ return 0;
+}
+
+/*
+ * The memory devices use the full 32/64 bits of the offset, and so we cannot
+ * check against negative addresses: they are ok. The return value is weird,
+ * though, in that case (0).
+ *
+ * also note that seeking relative to the "end of file" isn't supported:
+ * it has no meaning, so it returns -EINVAL.
+ */
+static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
+{
+ loff_t ret;
+
+ down(&file->f_dentry->d_inode->i_sem);
+ switch (orig) {
+ case 0:
+ file->f_pos = offset;
+ ret = file->f_pos;
+ force_successful_syscall_return();
+ break;
+ case 1:
+ file->f_pos += offset;
+ ret = file->f_pos;
+ force_successful_syscall_return();
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ up(&file->f_dentry->d_inode->i_sem);
+ return ret;
+}
+
+static int open_mem(struct inode * inode, struct file * filp)
+{
+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
+}
+
+struct file_operations mem_fops = {
+ .llseek = memory_lseek,
+ .read = read_mem,
+ .write = write_mem,
+ .mmap = mmap_mem,
+ .open = open_mem,
+};
diff --git a/linux-2.6.9-xen-sparse/drivers/char/mem.c b/linux-2.6.9-xen-sparse/drivers/char/mem.c
index 072c5ca761..c805a2ca48 100644
--- a/linux-2.6.9-xen-sparse/drivers/char/mem.c
+++ b/linux-2.6.9-xen-sparse/drivers/char/mem.c
@@ -26,7 +26,6 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-#include <asm/pgalloc.h>
#ifdef CONFIG_IA64
# include <linux/efi.h>
@@ -43,12 +42,7 @@ extern void tapechar_init(void);
*/
static inline int uncached_access(struct file *file, unsigned long addr)
{
-#ifdef CONFIG_XEN
- if (file->f_flags & O_SYNC)
- return 1;
- /* Xen sets correct MTRR type on non-RAM for us. */
- return 0;
-#elif defined(__i386__)
+#if defined(__i386__)
/*
* On the PPro and successors, the MTRRs are used to set
* memory types for physical addresses outside main memory,
@@ -149,7 +143,7 @@ static ssize_t do_write_mem(void *p, unsigned long realp,
return written;
}
-
+#ifndef ARCH_HAS_DEV_MEM
/*
* This funcion reads the *physical* memory. The f_pos points directly to the
* memory location.
@@ -195,8 +189,9 @@ static ssize_t write_mem(struct file * file, const char __user * buf,
return -EFAULT;
return do_write_mem(__va(p), p, buf, count, ppos);
}
+#endif
-static int mmap_mem(struct file * file, struct vm_area_struct * vma)
+static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
{
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
int uncached;
@@ -216,15 +211,9 @@ static int mmap_mem(struct file * file, struct vm_area_struct * vma)
if (uncached)
vma->vm_flags |= VM_IO;
-#if defined(CONFIG_XEN)
- if (io_remap_page_range(vma, vma->vm_start, offset,
- vma->vm_end-vma->vm_start, vma->vm_page_prot))
- return -EAGAIN;
-#else
if (remap_page_range(vma, vma->vm_start, offset, vma->vm_end-vma->vm_start,
vma->vm_page_prot))
return -EAGAIN;
-#endif
return 0;
}
@@ -584,7 +573,7 @@ static int open_port(struct inode * inode, struct file * filp)
return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
}
-#define mmap_kmem mmap_mem
+#define mmap_mem mmap_kmem
#define zero_lseek null_lseek
#define full_lseek null_lseek
#define write_zero write_null
@@ -592,6 +581,7 @@ static int open_port(struct inode * inode, struct file * filp)
#define open_mem open_port
#define open_kmem open_mem
+#ifndef ARCH_HAS_DEV_MEM
static struct file_operations mem_fops = {
.llseek = memory_lseek,
.read = read_mem,
@@ -599,6 +589,9 @@ static struct file_operations mem_fops = {
.mmap = mmap_mem,
.open = open_mem,
};
+#else
+extern struct file_operations mem_fops;
+#endif
static struct file_operations kmem_fops = {
.llseek = memory_lseek,
diff --git a/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/io.h b/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/io.h
index 0837c81cfa..08667ae0f6 100644
--- a/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/io.h
+++ b/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/io.h
@@ -444,4 +444,7 @@ BUILDIO(b,b,char)
BUILDIO(w,w,short)
BUILDIO(l,,int)
+/* We will be supplying our own /dev/mem implementation */
+#define ARCH_HAS_DEV_MEM
+
#endif