ia64/xen-unstable

changeset 3215:2b48e77a7c4f

bitkeeper revision 1.1159.183.33 (41ab710dnDIS6x1aWD1XoSvpY_9ZcQ)

Merge scramble.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-2.0-testing.bk
into scramble.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-unstable.bk
author kaf24@scramble.cl.cam.ac.uk
date Mon Nov 29 18:57:17 2004 +0000 (2004-11-29)
parents ded80647d9fc b58b2017b318
children d7e53f4de825
files .rootkeys linux-2.6.9-xen-sparse/arch/xen/i386/mm/ioremap.c linux-2.6.9-xen-sparse/arch/xen/kernel/Makefile linux-2.6.9-xen-sparse/arch/xen/kernel/devmem.c linux-2.6.9-xen-sparse/drivers/char/mem.c linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/io.h
line diff
     1.1 --- a/.rootkeys	Mon Nov 29 16:47:47 2004 +0000
     1.2 +++ b/.rootkeys	Mon Nov 29 18:57:17 2004 +0000
     1.3 @@ -171,6 +171,7 @@ 4107adf1WcCgkhsdLTRGX52cOG1vJg linux-2.6
     1.4  4107adf1s5u6249DNPUViX1YNagbUQ linux-2.6.9-xen-sparse/arch/xen/i386/pci/irq.c
     1.5  40f56239zOksGg_H4XD4ye6iZNtoZA linux-2.6.9-xen-sparse/arch/xen/kernel/Makefile
     1.6  40f56239bvOjuuuViZ0XMlNiREFC0A linux-2.6.9-xen-sparse/arch/xen/kernel/ctrl_if.c
     1.7 +41ab6fa06JdF7jxUsuDcjN3UhuIAxg linux-2.6.9-xen-sparse/arch/xen/kernel/devmem.c
     1.8  40f56238xFQe9T7M_U_FItM-bZIpLw linux-2.6.9-xen-sparse/arch/xen/kernel/evtchn.c
     1.9  4110f478aeQWllIN7J4kouAHiAqrPw linux-2.6.9-xen-sparse/arch/xen/kernel/fixup.c
    1.10  412dfae9eA3_6e6bCGUtg1mj8b56fQ linux-2.6.9-xen-sparse/arch/xen/kernel/gnttab.c
     2.1 --- a/linux-2.6.9-xen-sparse/arch/xen/i386/mm/ioremap.c	Mon Nov 29 16:47:47 2004 +0000
     2.2 +++ b/linux-2.6.9-xen-sparse/arch/xen/i386/mm/ioremap.c	Mon Nov 29 18:57:17 2004 +0000
     2.3 @@ -16,23 +16,33 @@
     2.4  #include <asm/cacheflush.h>
     2.5  #include <asm/tlbflush.h>
     2.6  #include <asm/pgtable.h>
     2.7 +#include <asm/pgalloc.h>
     2.8  
     2.9  #ifndef CONFIG_XEN_PHYSDEV_ACCESS
    2.10  
    2.11 -void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
    2.12 -{ return NULL; }
    2.13 +void * __ioremap(unsigned long phys_addr, unsigned long size,
    2.14 +		unsigned long flags)
    2.15 +{
    2.16 +	return NULL;
    2.17 +}
    2.18  
    2.19  void *ioremap_nocache (unsigned long phys_addr, unsigned long size)
    2.20 -{ return NULL; }
    2.21 +{
    2.22 +	return NULL;
    2.23 +}
    2.24  
    2.25  void iounmap(volatile void __iomem *addr)
    2.26 -{ }
    2.27 +{
    2.28 +}
    2.29  
    2.30  void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
    2.31 -{ return NULL; }
    2.32 +{
    2.33 +	return NULL;
    2.34 +}
    2.35  
    2.36  void __init bt_iounmap(void *addr, unsigned long size)
    2.37 -{ }
    2.38 +{
    2.39 +}
    2.40  
    2.41  #else
    2.42  
    2.43 @@ -50,86 +60,6 @@ static inline int is_local_lowmem(unsign
    2.44  	return ((pfn < max_low_pfn) && (pfn_to_mfn(pfn) == mfn));
    2.45  }
    2.46  
    2.47 -static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
    2.48 -	unsigned long phys_addr, unsigned long flags)
    2.49 -{
    2.50 -	unsigned long end;
    2.51 -	unsigned long pfn;
    2.52 -
    2.53 -	address &= ~PMD_MASK;
    2.54 -	end = address + size;
    2.55 -	if (end > PMD_SIZE)
    2.56 -		end = PMD_SIZE;
    2.57 -	if (address >= end)
    2.58 -		BUG();
    2.59 -	pfn = phys_addr >> PAGE_SHIFT;
    2.60 -	do {
    2.61 -		if (!pte_none(*pte)) {
    2.62 -			printk("remap_area_pte: page already exists\n");
    2.63 -			BUG();
    2.64 -		}
    2.65 -		set_pte(pte, pfn_pte_ma(pfn, __pgprot(_PAGE_PRESENT | _PAGE_RW | 
    2.66 -					_PAGE_DIRTY | _PAGE_ACCESSED | flags)));
    2.67 -		address += PAGE_SIZE;
    2.68 -		pfn++;
    2.69 -		pte++;
    2.70 -	} while (address && (address < end));
    2.71 -}
    2.72 -
    2.73 -static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
    2.74 -	unsigned long phys_addr, unsigned long flags)
    2.75 -{
    2.76 -	unsigned long end;
    2.77 -
    2.78 -	address &= ~PGDIR_MASK;
    2.79 -	end = address + size;
    2.80 -	if (end > PGDIR_SIZE)
    2.81 -		end = PGDIR_SIZE;
    2.82 -	phys_addr -= address;
    2.83 -	if (address >= end)
    2.84 -		BUG();
    2.85 -	do {
    2.86 -		pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
    2.87 -		if (!pte)
    2.88 -			return -ENOMEM;
    2.89 -		remap_area_pte(pte, address, end - address, address + phys_addr, flags);
    2.90 -		address = (address + PMD_SIZE) & PMD_MASK;
    2.91 -		pmd++;
    2.92 -	} while (address && (address < end));
    2.93 -	return 0;
    2.94 -}
    2.95 -
    2.96 -static int remap_area_pages(unsigned long address, unsigned long phys_addr,
    2.97 -				 unsigned long size, unsigned long flags)
    2.98 -{
    2.99 -	int error;
   2.100 -	pgd_t * dir;
   2.101 -	unsigned long end = address + size;
   2.102 -
   2.103 -	phys_addr -= address;
   2.104 -	dir = pgd_offset(&init_mm, address);
   2.105 -	flush_cache_all();
   2.106 -	if (address >= end)
   2.107 -		BUG();
   2.108 -	spin_lock(&init_mm.page_table_lock);
   2.109 -	do {
   2.110 -		pmd_t *pmd;
   2.111 -		pmd = pmd_alloc(&init_mm, dir, address);
   2.112 -		error = -ENOMEM;
   2.113 -		if (!pmd)
   2.114 -			break;
   2.115 -		if (remap_area_pmd(pmd, address, end - address,
   2.116 -					 phys_addr + address, flags))
   2.117 -			break;
   2.118 -		error = 0;
   2.119 -		address = (address + PGDIR_SIZE) & PGDIR_MASK;
   2.120 -		dir++;
   2.121 -	} while (address && (address < end));
   2.122 -	spin_unlock(&init_mm.page_table_lock);
   2.123 -	flush_tlb_all();
   2.124 -	return error;
   2.125 -}
   2.126 -
   2.127  /*
   2.128   * Generic mapping function (not visible outside):
   2.129   */
   2.130 @@ -192,7 +122,7 @@ void __iomem * __ioremap(unsigned long p
   2.131  		return NULL;
   2.132  	area->phys_addr = phys_addr;
   2.133  	addr = (void __iomem *) area->addr;
   2.134 -	if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
   2.135 +	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)) {
   2.136  		vunmap((void __force *) addr);
   2.137  		return NULL;
   2.138  	}
   2.139 @@ -360,138 +290,145 @@ void __init bt_iounmap(void *addr, unsig
   2.140  #define direct_mk_pte_phys(physpage, pgprot) \
   2.141    __direct_mk_pte((physpage) >> PAGE_SHIFT, pgprot)
   2.142  
   2.143 -static inline void direct_remap_area_pte(pte_t *pte, 
   2.144 -                                        unsigned long address, 
   2.145 -                                        unsigned long size,
   2.146 -					mmu_update_t **v)
   2.147 +static inline void direct_remap_area_pte(
   2.148 +	pte_t *pte, 
   2.149 +	unsigned long address, 
   2.150 +	unsigned long size,
   2.151 +	mmu_update_t **v)
   2.152  {
   2.153 -    unsigned long end;
   2.154 +	unsigned long end;
   2.155  
   2.156 -    address &= ~PMD_MASK;
   2.157 -    end = address + size;
   2.158 -    if (end > PMD_SIZE)
   2.159 -        end = PMD_SIZE;
   2.160 -    if (address >= end)
   2.161 -        BUG();
   2.162 +	address &= ~PMD_MASK;
   2.163 +	end = address + size;
   2.164 +	if (end > PMD_SIZE)
   2.165 +		end = PMD_SIZE;
   2.166 +	if (address >= end)
   2.167 +		BUG();
   2.168  
   2.169 -    do {
   2.170 -        (*v)->ptr = virt_to_machine(pte);
   2.171 -        (*v)++;
   2.172 -        address += PAGE_SIZE;
   2.173 -        pte++;
   2.174 -    } while (address && (address < end));
   2.175 +	do {
   2.176 +		(*v)->ptr = virt_to_machine(pte);
   2.177 +		(*v)++;
   2.178 +		address += PAGE_SIZE;
   2.179 +		pte++;
   2.180 +	} while (address && (address < end));
   2.181  }
   2.182  
   2.183 -static inline int direct_remap_area_pmd(struct mm_struct *mm,
   2.184 -                                        pmd_t *pmd, 
   2.185 -                                        unsigned long address, 
   2.186 -                                        unsigned long size,
   2.187 -					mmu_update_t **v)
   2.188 +static inline int direct_remap_area_pmd(
   2.189 +	struct mm_struct *mm,
   2.190 +	pmd_t *pmd, 
   2.191 +	unsigned long address, 
   2.192 +	unsigned long size,
   2.193 +	mmu_update_t **v)
   2.194  {
   2.195 -    unsigned long end;
   2.196 +	unsigned long end;
   2.197  
   2.198 -    address &= ~PGDIR_MASK;
   2.199 -    end = address + size;
   2.200 -    if (end > PGDIR_SIZE)
   2.201 -        end = PGDIR_SIZE;
   2.202 -    if (address >= end)
   2.203 -        BUG();
   2.204 -    do {
   2.205 -        pte_t *pte = pte_alloc_map(mm, pmd, address);
   2.206 -        if (!pte)
   2.207 -            return -ENOMEM;
   2.208 -        direct_remap_area_pte(pte, address, end - address, v);
   2.209 -	pte_unmap(pte);
   2.210 -        address = (address + PMD_SIZE) & PMD_MASK;
   2.211 -        pmd++;
   2.212 -    } while (address && (address < end));
   2.213 -    return 0;
   2.214 +	address &= ~PGDIR_MASK;
   2.215 +	end = address + size;
   2.216 +	if (end > PGDIR_SIZE)
   2.217 +		end = PGDIR_SIZE;
   2.218 +	if (address >= end)
   2.219 +		BUG();
   2.220 +	do {
   2.221 +		pte_t *pte = (mm == &init_mm) ? 
   2.222 +			pte_alloc_kernel(mm, pmd, address) :
   2.223 +			pte_alloc_map(mm, pmd, address);
   2.224 +		if (!pte)
   2.225 +			return -ENOMEM;
   2.226 +		direct_remap_area_pte(pte, address, end - address, v);
   2.227 +		pte_unmap(pte);
   2.228 +		address = (address + PMD_SIZE) & PMD_MASK;
   2.229 +		pmd++;
   2.230 +	} while (address && (address < end));
   2.231 +	return 0;
   2.232  }
   2.233   
   2.234 -int __direct_remap_area_pages(struct mm_struct *mm,
   2.235 -			      unsigned long address, 
   2.236 -			      unsigned long size, 
   2.237 -			      mmu_update_t *v)
   2.238 +int __direct_remap_area_pages(
   2.239 +	struct mm_struct *mm,
   2.240 +	unsigned long address, 
   2.241 +	unsigned long size, 
   2.242 +	mmu_update_t *v)
   2.243  {
   2.244 -    pgd_t * dir;
   2.245 -    unsigned long end = address + size;
   2.246 +	pgd_t * dir;
   2.247 +	unsigned long end = address + size;
   2.248  
   2.249 -    dir = pgd_offset(mm, address);
   2.250 -    flush_cache_all();
   2.251 -    if (address >= end)
   2.252 -        BUG();
   2.253 -    spin_lock(&mm->page_table_lock);
   2.254 -    do {
   2.255 -        pmd_t *pmd = pmd_alloc(mm, dir, address);
   2.256 -        if (!pmd)
   2.257 -	    return -ENOMEM;
   2.258 -        direct_remap_area_pmd(mm, pmd, address, end - address, &v);
   2.259 -        address = (address + PGDIR_SIZE) & PGDIR_MASK;
   2.260 -        dir++;
   2.261 +	dir = pgd_offset(mm, address);
   2.262 +	if (address >= end)
   2.263 +		BUG();
   2.264 +	spin_lock(&mm->page_table_lock);
   2.265 +	do {
   2.266 +		pmd_t *pmd = pmd_alloc(mm, dir, address);
   2.267 +		if (!pmd)
   2.268 +			return -ENOMEM;
   2.269 +		direct_remap_area_pmd(mm, pmd, address, end - address, &v);
   2.270 +		address = (address + PGDIR_SIZE) & PGDIR_MASK;
   2.271 +		dir++;
   2.272  
   2.273 -    } while (address && (address < end));
   2.274 -    spin_unlock(&mm->page_table_lock);
   2.275 -    flush_tlb_all();
   2.276 -    return 0;
   2.277 +	} while (address && (address < end));
   2.278 +	spin_unlock(&mm->page_table_lock);
   2.279 +	return 0;
   2.280  }
   2.281  
   2.282  
   2.283 -int direct_remap_area_pages(struct mm_struct *mm,
   2.284 -                            unsigned long address, 
   2.285 -                            unsigned long machine_addr,
   2.286 -                            unsigned long size, 
   2.287 -                            pgprot_t prot,
   2.288 -                            domid_t  domid)
   2.289 +int direct_remap_area_pages(
   2.290 +	struct mm_struct *mm,
   2.291 +	unsigned long address, 
   2.292 +	unsigned long machine_addr,
   2.293 +	unsigned long size, 
   2.294 +	pgprot_t prot,
   2.295 +	domid_t  domid)
   2.296  {
   2.297 -    int i;
   2.298 -    unsigned long start_address;
   2.299 +	int i;
   2.300 +	unsigned long start_address;
   2.301  #define MAX_DIRECTMAP_MMU_QUEUE 130
   2.302 -    mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *w, *v;
   2.303 +	mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *w, *v;
   2.304  
   2.305 -    u[0].ptr  = MMU_EXTENDED_COMMAND;
   2.306 -    u[0].val  = MMUEXT_SET_FOREIGNDOM;
   2.307 -    u[0].val |= (unsigned long)domid << 16;
   2.308 -    v = w = &u[1];
   2.309 +	u[0].ptr  = MMU_EXTENDED_COMMAND;
   2.310 +	u[0].val  = MMUEXT_SET_FOREIGNDOM;
   2.311 +	u[0].val |= (unsigned long)domid << 16;
   2.312 +	v = w = &u[1];
   2.313 +
   2.314 +	start_address = address;
   2.315 +
   2.316 +	flush_cache_all();
   2.317  
   2.318 -    start_address = address;
   2.319 +	for (i = 0; i < size; i += PAGE_SIZE) {
   2.320 +		if ((v - u) == MAX_DIRECTMAP_MMU_QUEUE) {
   2.321 +			/* Fill in the PTE pointers. */
   2.322 +			__direct_remap_area_pages(
   2.323 +				mm,
   2.324 +				start_address, 
   2.325 +				address-start_address, 
   2.326 +				w);
   2.327 +	
   2.328 +			if (HYPERVISOR_mmu_update(u, v - u, NULL) < 0)
   2.329 +				return -EFAULT;
   2.330 +			v = w;
   2.331 +			start_address = address;
   2.332 +		}
   2.333  
   2.334 -    for( i = 0; i < size; i += PAGE_SIZE )
   2.335 -    {
   2.336 -	if ( (v - u) == MAX_DIRECTMAP_MMU_QUEUE )
   2.337 -	{
   2.338 -	    /* Fill in the PTE pointers. */
   2.339 -	    __direct_remap_area_pages( mm,
   2.340 -				       start_address, 
   2.341 -				       address-start_address, 
   2.342 -				       w);
   2.343 -	    
   2.344 -	    if ( HYPERVISOR_mmu_update(u, v - u, NULL) < 0 )
   2.345 -		return -EFAULT;	    
   2.346 -	    v = w;
   2.347 -	    start_address = address;
   2.348 +		/*
   2.349 +		 * Fill in the machine address: PTE ptr is done later by
   2.350 +		 * __direct_remap_area_pages(). 
   2.351 +		 */
   2.352 +		v->val = (machine_addr & PAGE_MASK) | pgprot_val(prot);
   2.353 +
   2.354 +		machine_addr += PAGE_SIZE;
   2.355 +		address += PAGE_SIZE; 
   2.356 +		v++;
   2.357  	}
   2.358  
   2.359 -	/*
   2.360 -         * Fill in the machine address: PTE ptr is done later by
   2.361 -         * __direct_remap_area_pages(). 
   2.362 -         */
   2.363 -        v->val = (machine_addr & PAGE_MASK) | pgprot_val(prot);
   2.364 -
   2.365 -        machine_addr += PAGE_SIZE;
   2.366 -        address += PAGE_SIZE; 
   2.367 -        v++;
   2.368 -    }
   2.369 +	if (v != w) {
   2.370 +		/* get the ptep's filled in */
   2.371 +		__direct_remap_area_pages(
   2.372 +			mm,
   2.373 +			start_address, 
   2.374 +			address-start_address, 
   2.375 +			w);
   2.376 +		if (unlikely(HYPERVISOR_mmu_update(u, v - u, NULL) < 0))
   2.377 +			return -EFAULT;	
   2.378 +	}
   2.379  
   2.380 -    if ( v != w )
   2.381 -    {
   2.382 -	/* get the ptep's filled in */
   2.383 -	__direct_remap_area_pages(mm,
   2.384 -                                  start_address, 
   2.385 -                                  address-start_address, 
   2.386 -                                  w);	 
   2.387 -	if ( unlikely(HYPERVISOR_mmu_update(u, v - u, NULL) < 0) )
   2.388 -	    return -EFAULT;	    
   2.389 -    }
   2.390 -    
   2.391 -    return 0;
   2.392 +	flush_tlb_all();
   2.393 +
   2.394 +	return 0;
   2.395  }
     3.1 --- a/linux-2.6.9-xen-sparse/arch/xen/kernel/Makefile	Mon Nov 29 16:47:47 2004 +0000
     3.2 +++ b/linux-2.6.9-xen-sparse/arch/xen/kernel/Makefile	Mon Nov 29 18:57:17 2004 +0000
     3.3 @@ -9,4 +9,4 @@ XENARCH	:= $(subst ",,$(CONFIG_XENARCH))
     3.4  
     3.5  extra-y += vmlinux.lds
     3.6  
     3.7 -obj-y	:= ctrl_if.o evtchn.o fixup.o reboot.o xen_proc.o gnttab.o skbuff.o
     3.8 +obj-y	:= ctrl_if.o evtchn.o fixup.o reboot.o xen_proc.o gnttab.o skbuff.o devmem.o
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/linux-2.6.9-xen-sparse/arch/xen/kernel/devmem.c	Mon Nov 29 18:57:17 2004 +0000
     4.3 @@ -0,0 +1,158 @@
     4.4 +/*
     4.5 + *  Originally from linux/drivers/char/mem.c
     4.6 + *
     4.7 + *  Copyright (C) 1991, 1992  Linus Torvalds
     4.8 + *
     4.9 + *  Added devfs support. 
    4.10 + *    Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
    4.11 + *  Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
    4.12 + */
    4.13 +
    4.14 +#include <linux/config.h>
    4.15 +#include <linux/mm.h>
    4.16 +#include <linux/miscdevice.h>
    4.17 +#include <linux/slab.h>
    4.18 +#include <linux/vmalloc.h>
    4.19 +#include <linux/mman.h>
    4.20 +#include <linux/random.h>
    4.21 +#include <linux/init.h>
    4.22 +#include <linux/raw.h>
    4.23 +#include <linux/tty.h>
    4.24 +#include <linux/capability.h>
    4.25 +#include <linux/smp_lock.h>
    4.26 +#include <linux/devfs_fs_kernel.h>
    4.27 +#include <linux/ptrace.h>
    4.28 +#include <linux/device.h>
    4.29 +#include <asm/pgalloc.h>
    4.30 +#include <asm/uaccess.h>
    4.31 +#include <asm/io.h>
    4.32 +
    4.33 +static inline int uncached_access(struct file *file, unsigned long addr)
    4.34 +{
    4.35 +        if (file->f_flags & O_SYNC)
    4.36 +                return 1;
    4.37 +        /* Xen sets correct MTRR type on non-RAM for us. */
    4.38 +        return 0;
    4.39 +}
    4.40 +
    4.41 +/*
    4.42 + * This funcion reads the *physical* memory. The f_pos points directly to the 
    4.43 + * memory location. 
    4.44 + */
    4.45 +static ssize_t read_mem(struct file * file, char __user * buf,
    4.46 +			size_t count, loff_t *ppos)
    4.47 +{
    4.48 +	unsigned long i, p = *ppos;
    4.49 +	ssize_t read = 0;
    4.50 +	void *v;
    4.51 +
    4.52 +	if ((v = ioremap(p, count)) == NULL) {
    4.53 +		/*
    4.54 +		 * Some programs (e.g., dmidecode) groove off into weird RAM
    4.55 +		 * areas where no table scan possibly exist (because Xen will
    4.56 +		 * have stomped on them!). These programs get rather upset if
    4.57 +                 * we let them know that Xen failed their access, so we fake
    4.58 +                 * out a read of all zeroes. :-)
    4.59 +		 */
    4.60 +		for (i = 0; i < count; i++)
    4.61 +			if (put_user(0, buf+i))
    4.62 +				return -EFAULT;
    4.63 +		return count;
    4.64 +	}
    4.65 +	if (copy_to_user(buf, v, count))
    4.66 +		return -EFAULT;
    4.67 +	iounmap(v);
    4.68 +
    4.69 +	read += count;
    4.70 +	*ppos += read;
    4.71 +
    4.72 +	return read;
    4.73 +}
    4.74 +
    4.75 +static ssize_t write_mem(struct file * file, const char __user * buf, 
    4.76 +			 size_t count, loff_t *ppos)
    4.77 +{
    4.78 +	unsigned long p = *ppos;
    4.79 +	ssize_t written = 0;
    4.80 +	void *v;
    4.81 +
    4.82 +	if ((v = ioremap(p, count)) == NULL)
    4.83 +		return -EFAULT;
    4.84 +	if (copy_to_user(v, buf, count))
    4.85 +		return -EFAULT;
    4.86 +	iounmap(v);
    4.87 +
    4.88 +	written += count;
    4.89 +	*ppos += written;
    4.90 +
    4.91 +	return written;
    4.92 +}
    4.93 +
    4.94 +static int mmap_mem(struct file * file, struct vm_area_struct * vma)
    4.95 +{
    4.96 +	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
    4.97 +	int uncached;
    4.98 +
    4.99 +	uncached = uncached_access(file, offset);
   4.100 +	if (uncached)
   4.101 +		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
   4.102 +
   4.103 +	/* Don't try to swap out physical pages.. */
   4.104 +	vma->vm_flags |= VM_RESERVED;
   4.105 +
   4.106 +	/*
   4.107 +	 * Don't dump addresses that are not real memory to a core file.
   4.108 +	 */
   4.109 +	if (uncached)
   4.110 +		vma->vm_flags |= VM_IO;
   4.111 +
   4.112 +	if (io_remap_page_range(vma, vma->vm_start, offset, 
   4.113 +				vma->vm_end-vma->vm_start, vma->vm_page_prot))
   4.114 +		return -EAGAIN;
   4.115 +
   4.116 +	return 0;
   4.117 +}
   4.118 +
   4.119 +/*
   4.120 + * The memory devices use the full 32/64 bits of the offset, and so we cannot
   4.121 + * check against negative addresses: they are ok. The return value is weird,
   4.122 + * though, in that case (0).
   4.123 + *
   4.124 + * also note that seeking relative to the "end of file" isn't supported:
   4.125 + * it has no meaning, so it returns -EINVAL.
   4.126 + */
   4.127 +static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
   4.128 +{
   4.129 +	loff_t ret;
   4.130 +
   4.131 +	down(&file->f_dentry->d_inode->i_sem);
   4.132 +	switch (orig) {
   4.133 +		case 0:
   4.134 +			file->f_pos = offset;
   4.135 +			ret = file->f_pos;
   4.136 +			force_successful_syscall_return();
   4.137 +			break;
   4.138 +		case 1:
   4.139 +			file->f_pos += offset;
   4.140 +			ret = file->f_pos;
   4.141 +			force_successful_syscall_return();
   4.142 +			break;
   4.143 +		default:
   4.144 +			ret = -EINVAL;
   4.145 +	}
   4.146 +	up(&file->f_dentry->d_inode->i_sem);
   4.147 +	return ret;
   4.148 +}
   4.149 +
   4.150 +static int open_mem(struct inode * inode, struct file * filp)
   4.151 +{
   4.152 +	return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
   4.153 +}
   4.154 +
   4.155 +struct file_operations mem_fops = {
   4.156 +	.llseek		= memory_lseek,
   4.157 +	.read		= read_mem,
   4.158 +	.write		= write_mem,
   4.159 +	.mmap		= mmap_mem,
   4.160 +	.open		= open_mem,
   4.161 +};
     5.1 --- a/linux-2.6.9-xen-sparse/drivers/char/mem.c	Mon Nov 29 16:47:47 2004 +0000
     5.2 +++ b/linux-2.6.9-xen-sparse/drivers/char/mem.c	Mon Nov 29 18:57:17 2004 +0000
     5.3 @@ -26,7 +26,6 @@
     5.4  
     5.5  #include <asm/uaccess.h>
     5.6  #include <asm/io.h>
     5.7 -#include <asm/pgalloc.h>
     5.8  
     5.9  #ifdef CONFIG_IA64
    5.10  # include <linux/efi.h>
    5.11 @@ -43,12 +42,7 @@ extern void tapechar_init(void);
    5.12   */
    5.13  static inline int uncached_access(struct file *file, unsigned long addr)
    5.14  {
    5.15 -#ifdef CONFIG_XEN
    5.16 -        if (file->f_flags & O_SYNC)
    5.17 -                return 1;
    5.18 -        /* Xen sets correct MTRR type on non-RAM for us. */
    5.19 -        return 0;
    5.20 -#elif defined(__i386__)
    5.21 +#if defined(__i386__)
    5.22  	/*
    5.23  	 * On the PPro and successors, the MTRRs are used to set
    5.24  	 * memory types for physical addresses outside main memory,
    5.25 @@ -149,7 +143,7 @@ static ssize_t do_write_mem(void *p, uns
    5.26  	return written;
    5.27  }
    5.28  
    5.29 -
    5.30 +#ifndef ARCH_HAS_DEV_MEM
    5.31  /*
    5.32   * This funcion reads the *physical* memory. The f_pos points directly to the 
    5.33   * memory location. 
    5.34 @@ -195,8 +189,9 @@ static ssize_t write_mem(struct file * f
    5.35  		return -EFAULT;
    5.36  	return do_write_mem(__va(p), p, buf, count, ppos);
    5.37  }
    5.38 +#endif
    5.39  
    5.40 -static int mmap_mem(struct file * file, struct vm_area_struct * vma)
    5.41 +static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
    5.42  {
    5.43  	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
    5.44  	int uncached;
    5.45 @@ -216,15 +211,9 @@ static int mmap_mem(struct file * file, 
    5.46  	if (uncached)
    5.47  		vma->vm_flags |= VM_IO;
    5.48  
    5.49 -#if defined(CONFIG_XEN)
    5.50 -	if (io_remap_page_range(vma, vma->vm_start, offset, 
    5.51 -				vma->vm_end-vma->vm_start, vma->vm_page_prot))
    5.52 -		return -EAGAIN;
    5.53 -#else
    5.54  	if (remap_page_range(vma, vma->vm_start, offset, vma->vm_end-vma->vm_start,
    5.55  			     vma->vm_page_prot))
    5.56  		return -EAGAIN;
    5.57 -#endif
    5.58  	return 0;
    5.59  }
    5.60  
    5.61 @@ -584,7 +573,7 @@ static int open_port(struct inode * inod
    5.62  	return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
    5.63  }
    5.64  
    5.65 -#define mmap_kmem	mmap_mem
    5.66 +#define mmap_mem	mmap_kmem
    5.67  #define zero_lseek	null_lseek
    5.68  #define full_lseek      null_lseek
    5.69  #define write_zero	write_null
    5.70 @@ -592,6 +581,7 @@ static int open_port(struct inode * inod
    5.71  #define open_mem	open_port
    5.72  #define open_kmem	open_mem
    5.73  
    5.74 +#ifndef ARCH_HAS_DEV_MEM
    5.75  static struct file_operations mem_fops = {
    5.76  	.llseek		= memory_lseek,
    5.77  	.read		= read_mem,
    5.78 @@ -599,6 +589,9 @@ static struct file_operations mem_fops =
    5.79  	.mmap		= mmap_mem,
    5.80  	.open		= open_mem,
    5.81  };
    5.82 +#else
    5.83 +extern struct file_operations mem_fops;
    5.84 +#endif
    5.85  
    5.86  static struct file_operations kmem_fops = {
    5.87  	.llseek		= memory_lseek,
     6.1 --- a/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/io.h	Mon Nov 29 16:47:47 2004 +0000
     6.2 +++ b/linux-2.6.9-xen-sparse/include/asm-xen/asm-i386/io.h	Mon Nov 29 18:57:17 2004 +0000
     6.3 @@ -444,4 +444,7 @@ BUILDIO(b,b,char)
     6.4  BUILDIO(w,w,short)
     6.5  BUILDIO(l,,int)
     6.6  
     6.7 +/* We will be supplying our own /dev/mem implementation */
     6.8 +#define ARCH_HAS_DEV_MEM
     6.9 +
    6.10  #endif