ia64/xen-unstable

changeset 8092:367b9ca30e88

arch/xen/kernel/fixup.c -> arch/xen/i386/kernel/fixup.c
arch/xen/kernel/devmem.c -> drivers/xen/char/mem.c
arch/xen/kernel/smp.c deleted

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Mon Nov 28 14:08:53 2005 +0100 (2005-11-28)
parents 2eb868d02f0f
children b3f8d3158a1c
files linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile linux-2.6-xen-sparse/arch/xen/i386/kernel/fixup.c linux-2.6-xen-sparse/arch/xen/kernel/Makefile linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c linux-2.6-xen-sparse/drivers/xen/Makefile linux-2.6-xen-sparse/drivers/xen/char/Makefile linux-2.6-xen-sparse/drivers/xen/char/mem.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile	Mon Nov 28 13:39:22 2005 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile	Mon Nov 28 14:08:53 2005 +0100
     1.3 @@ -11,7 +11,7 @@ extra-y := head.o init_task.o
     1.4  
     1.5  obj-y	:= process.o signal.o entry.o traps.o \
     1.6  		time.o ioport.o ldt.o setup.o \
     1.7 -		pci-dma.o i386_ksyms.o irq.o quirks.o
     1.8 +		pci-dma.o i386_ksyms.o irq.o quirks.o fixup.o
     1.9  
    1.10  c-obj-y	:= semaphore.o vm86.o \
    1.11  		ptrace.o sys_i386.o \
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/fixup.c	Mon Nov 28 14:08:53 2005 +0100
     2.3 @@ -0,0 +1,93 @@
     2.4 +/******************************************************************************
     2.5 + * fixup.c
     2.6 + * 
     2.7 + * Binary-rewriting of certain IA32 instructions, on notification by Xen.
     2.8 + * Used to avoid repeated slow emulation of common instructions used by the
     2.9 + * user-space TLS (Thread-Local Storage) libraries.
    2.10 + * 
    2.11 + * **** NOTE ****
    2.12 + *  Issues with the binary rewriting have caused it to be removed. Instead
    2.13 + *  we rely on Xen's emulator to boot the kernel, and then print a banner
    2.14 + *  message recommending that the user disables /lib/tls.
    2.15 + * 
    2.16 + * Copyright (c) 2004, K A Fraser
    2.17 + * 
    2.18 + * This program is free software; you can redistribute it and/or modify
    2.19 + * it under the terms of the GNU General Public License as published by
    2.20 + * the Free Software Foundation; either version 2 of the License, or
    2.21 + * (at your option) any later version.
    2.22 + * 
    2.23 + * This program is distributed in the hope that it will be useful,
    2.24 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.25 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.26 + * GNU General Public License for more details.
    2.27 + * 
    2.28 + * You should have received a copy of the GNU General Public License
    2.29 + * along with this program; if not, write to the Free Software
    2.30 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    2.31 + */
    2.32 +
    2.33 +#include <linux/config.h>
    2.34 +#include <linux/init.h>
    2.35 +#include <linux/sched.h>
    2.36 +#include <linux/slab.h>
    2.37 +#include <linux/kernel.h>
    2.38 +#include <linux/delay.h>
    2.39 +#include <linux/version.h>
    2.40 +
    2.41 +#define DP(_f, _args...) printk(KERN_ALERT "  " _f "\n" , ## _args )
    2.42 +
    2.43 +fastcall void do_fixup_4gb_segment(struct pt_regs *regs, long error_code)
    2.44 +{
    2.45 +	static unsigned long printed = 0;
    2.46 +	char info[100];
    2.47 +	int i;
    2.48 +
    2.49 +	if (test_and_set_bit(0, &printed))
    2.50 +		return;
    2.51 +
    2.52 +	HYPERVISOR_vm_assist(
    2.53 +		VMASST_CMD_disable, VMASST_TYPE_4gb_segments_notify);
    2.54 +
    2.55 +	sprintf(info, "%s (pid=%d)", current->comm, current->tgid);
    2.56 +
    2.57 +
    2.58 +	DP("");
    2.59 +	DP("***************************************************************");
    2.60 +	DP("***************************************************************");
    2.61 +	DP("** WARNING: Currently emulating unsupported memory accesses  **");
    2.62 +	DP("**          in /lib/tls libraries. The emulation is very     **");
    2.63 +	DP("**          slow. To ensure full performance you should      **");
    2.64 +	DP("**          execute the following as root:                   **");
    2.65 +	DP("**          mv /lib/tls /lib/tls.disabled                    **");
    2.66 +	DP("** Offending process: %-38.38s **", info);
    2.67 +	DP("***************************************************************");
    2.68 +	DP("***************************************************************");
    2.69 +	DP("");
    2.70 +
    2.71 +	for (i = 5; i > 0; i--) {
    2.72 +		printk("Pausing... %d", i);
    2.73 +		mdelay(1000);
    2.74 +		printk("\b\b\b\b\b\b\b\b\b\b\b\b");
    2.75 +	}
    2.76 +
    2.77 +	printk("Continuing...\n\n");
    2.78 +}
    2.79 +
    2.80 +static int __init fixup_init(void)
    2.81 +{
    2.82 +	HYPERVISOR_vm_assist(
    2.83 +		VMASST_CMD_enable, VMASST_TYPE_4gb_segments_notify);
    2.84 +	return 0;
    2.85 +}
    2.86 +__initcall(fixup_init);
    2.87 +
    2.88 +/*
    2.89 + * Local variables:
    2.90 + *  c-file-style: "linux"
    2.91 + *  indent-tabs-mode: t
    2.92 + *  c-indent-level: 8
    2.93 + *  c-basic-offset: 8
    2.94 + *  tab-width: 8
    2.95 + * End:
    2.96 + */
     3.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/Makefile	Mon Nov 28 13:39:22 2005 +0100
     3.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/Makefile	Mon Nov 28 14:08:53 2005 +0100
     3.3 @@ -11,8 +11,8 @@ CPPFLAGS_vmlinux.lds += -U$(XENARCH)
     3.4  
     3.5  extra-y += vmlinux.lds
     3.6  
     3.7 -obj-y   := evtchn.o fixup.o reboot.o gnttab.o devmem.o
     3.8 +obj-y   := evtchn.o reboot.o gnttab.o
     3.9  
    3.10  obj-$(CONFIG_PROC_FS) += xen_proc.o
    3.11  obj-$(CONFIG_NET)     += skbuff.o
    3.12 -obj-$(CONFIG_SMP)     += smp.o smpboot.o
    3.13 +obj-$(CONFIG_SMP)     += smpboot.o
     4.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/devmem.c	Mon Nov 28 13:39:22 2005 +0100
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,157 +0,0 @@
     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 -#include <asm/hypervisor.h>
    4.33 -
    4.34 -static inline int uncached_access(struct file *file)
    4.35 -{
    4.36 -        if (file->f_flags & O_SYNC)
    4.37 -                return 1;
    4.38 -        /* Xen sets correct MTRR type on non-RAM for us. */
    4.39 -        return 0;
    4.40 -}
    4.41 -
    4.42 -/*
    4.43 - * This funcion reads the *physical* memory. The f_pos points directly to the 
    4.44 - * memory location. 
    4.45 - */
    4.46 -static ssize_t read_mem(struct file * file, char __user * buf,
    4.47 -			size_t count, loff_t *ppos)
    4.48 -{
    4.49 -	unsigned long i, p = *ppos;
    4.50 -	ssize_t read = -EFAULT;
    4.51 -	void __iomem *v;
    4.52 -
    4.53 -	if ((v = ioremap(p, count)) == NULL) {
    4.54 -		/*
    4.55 -		 * Some programs (e.g., dmidecode) groove off into weird RAM
    4.56 -		 * areas where no table scan possibly exist (because Xen will
    4.57 -		 * have stomped on them!). These programs get rather upset if
    4.58 -                 * we let them know that Xen failed their access, so we fake
    4.59 -                 * out a read of all zeroes. :-)
    4.60 -		 */
    4.61 -		for (i = 0; i < count; i++)
    4.62 -			if (put_user(0, buf+i))
    4.63 -				return -EFAULT;
    4.64 -		return count;
    4.65 -	}
    4.66 -	if (copy_to_user(buf, v, count))
    4.67 -		goto out;
    4.68 -
    4.69 -	read = count;
    4.70 -	*ppos += read;
    4.71 -out:
    4.72 -	iounmap(v);
    4.73 -	return read;
    4.74 -}
    4.75 -
    4.76 -static ssize_t write_mem(struct file * file, const char __user * buf, 
    4.77 -			 size_t count, loff_t *ppos)
    4.78 -{
    4.79 -	unsigned long p = *ppos;
    4.80 -	ssize_t written = -EFAULT;
    4.81 -	void __iomem *v;
    4.82 -
    4.83 -	if ((v = ioremap(p, count)) == NULL)
    4.84 -		return -EFAULT;
    4.85 -	if (copy_from_user(v, buf, count))
    4.86 -		goto out;
    4.87 -
    4.88 -	written = count;
    4.89 -	*ppos += written;
    4.90 -out:
    4.91 -	iounmap(v);
    4.92 -	return written;
    4.93 -}
    4.94 -
    4.95 -static int mmap_mem(struct file * file, struct vm_area_struct * vma)
    4.96 -{
    4.97 -	if (uncached_access(file))
    4.98 -		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
    4.99 -
   4.100 -	if (direct_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
   4.101 -				   vma->vm_end - vma->vm_start,
   4.102 -				   vma->vm_page_prot, DOMID_IO))
   4.103 -		return -EAGAIN;
   4.104 -
   4.105 -	return 0;
   4.106 -}
   4.107 -
   4.108 -/*
   4.109 - * The memory devices use the full 32/64 bits of the offset, and so we cannot
   4.110 - * check against negative addresses: they are ok. The return value is weird,
   4.111 - * though, in that case (0).
   4.112 - *
   4.113 - * also note that seeking relative to the "end of file" isn't supported:
   4.114 - * it has no meaning, so it returns -EINVAL.
   4.115 - */
   4.116 -static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
   4.117 -{
   4.118 -	loff_t ret;
   4.119 -
   4.120 -	down(&file->f_dentry->d_inode->i_sem);
   4.121 -	switch (orig) {
   4.122 -		case 0:
   4.123 -			file->f_pos = offset;
   4.124 -			ret = file->f_pos;
   4.125 -			force_successful_syscall_return();
   4.126 -			break;
   4.127 -		case 1:
   4.128 -			file->f_pos += offset;
   4.129 -			ret = file->f_pos;
   4.130 -			force_successful_syscall_return();
   4.131 -			break;
   4.132 -		default:
   4.133 -			ret = -EINVAL;
   4.134 -	}
   4.135 -	up(&file->f_dentry->d_inode->i_sem);
   4.136 -	return ret;
   4.137 -}
   4.138 -
   4.139 -static int open_mem(struct inode * inode, struct file * filp)
   4.140 -{
   4.141 -	return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
   4.142 -}
   4.143 -
   4.144 -struct file_operations mem_fops = {
   4.145 -	.llseek		= memory_lseek,
   4.146 -	.read		= read_mem,
   4.147 -	.write		= write_mem,
   4.148 -	.mmap		= mmap_mem,
   4.149 -	.open		= open_mem,
   4.150 -};
   4.151 -
   4.152 -/*
   4.153 - * Local variables:
   4.154 - *  c-file-style: "linux"
   4.155 - *  indent-tabs-mode: t
   4.156 - *  c-indent-level: 8
   4.157 - *  c-basic-offset: 8
   4.158 - *  tab-width: 8
   4.159 - * End:
   4.160 - */
     5.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/fixup.c	Mon Nov 28 13:39:22 2005 +0100
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,93 +0,0 @@
     5.4 -/******************************************************************************
     5.5 - * fixup.c
     5.6 - * 
     5.7 - * Binary-rewriting of certain IA32 instructions, on notification by Xen.
     5.8 - * Used to avoid repeated slow emulation of common instructions used by the
     5.9 - * user-space TLS (Thread-Local Storage) libraries.
    5.10 - * 
    5.11 - * **** NOTE ****
    5.12 - *  Issues with the binary rewriting have caused it to be removed. Instead
    5.13 - *  we rely on Xen's emulator to boot the kernel, and then print a banner
    5.14 - *  message recommending that the user disables /lib/tls.
    5.15 - * 
    5.16 - * Copyright (c) 2004, K A Fraser
    5.17 - * 
    5.18 - * This program is free software; you can redistribute it and/or modify
    5.19 - * it under the terms of the GNU General Public License as published by
    5.20 - * the Free Software Foundation; either version 2 of the License, or
    5.21 - * (at your option) any later version.
    5.22 - * 
    5.23 - * This program is distributed in the hope that it will be useful,
    5.24 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.25 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.26 - * GNU General Public License for more details.
    5.27 - * 
    5.28 - * You should have received a copy of the GNU General Public License
    5.29 - * along with this program; if not, write to the Free Software
    5.30 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    5.31 - */
    5.32 -
    5.33 -#include <linux/config.h>
    5.34 -#include <linux/init.h>
    5.35 -#include <linux/sched.h>
    5.36 -#include <linux/slab.h>
    5.37 -#include <linux/kernel.h>
    5.38 -#include <linux/delay.h>
    5.39 -#include <linux/version.h>
    5.40 -
    5.41 -#define DP(_f, _args...) printk(KERN_ALERT "  " _f "\n" , ## _args )
    5.42 -
    5.43 -fastcall void do_fixup_4gb_segment(struct pt_regs *regs, long error_code)
    5.44 -{
    5.45 -	static unsigned long printed = 0;
    5.46 -	char info[100];
    5.47 -	int i;
    5.48 -
    5.49 -	if (test_and_set_bit(0, &printed))
    5.50 -		return;
    5.51 -
    5.52 -	HYPERVISOR_vm_assist(
    5.53 -		VMASST_CMD_disable, VMASST_TYPE_4gb_segments_notify);
    5.54 -
    5.55 -	sprintf(info, "%s (pid=%d)", current->comm, current->tgid);
    5.56 -
    5.57 -
    5.58 -	DP("");
    5.59 -	DP("***************************************************************");
    5.60 -	DP("***************************************************************");
    5.61 -	DP("** WARNING: Currently emulating unsupported memory accesses  **");
    5.62 -	DP("**          in /lib/tls libraries. The emulation is very     **");
    5.63 -	DP("**          slow. To ensure full performance you should      **");
    5.64 -	DP("**          execute the following as root:                   **");
    5.65 -	DP("**          mv /lib/tls /lib/tls.disabled                    **");
    5.66 -	DP("** Offending process: %-38.38s **", info);
    5.67 -	DP("***************************************************************");
    5.68 -	DP("***************************************************************");
    5.69 -	DP("");
    5.70 -
    5.71 -	for (i = 5; i > 0; i--) {
    5.72 -		printk("Pausing... %d", i);
    5.73 -		mdelay(1000);
    5.74 -		printk("\b\b\b\b\b\b\b\b\b\b\b\b");
    5.75 -	}
    5.76 -
    5.77 -	printk("Continuing...\n\n");
    5.78 -}
    5.79 -
    5.80 -static int __init fixup_init(void)
    5.81 -{
    5.82 -	HYPERVISOR_vm_assist(
    5.83 -		VMASST_CMD_enable, VMASST_TYPE_4gb_segments_notify);
    5.84 -	return 0;
    5.85 -}
    5.86 -__initcall(fixup_init);
    5.87 -
    5.88 -/*
    5.89 - * Local variables:
    5.90 - *  c-file-style: "linux"
    5.91 - *  indent-tabs-mode: t
    5.92 - *  c-indent-level: 8
    5.93 - *  c-basic-offset: 8
    5.94 - *  tab-width: 8
    5.95 - * End:
    5.96 - */
     6.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/smp.c	Mon Nov 28 13:39:22 2005 +0100
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,25 +0,0 @@
     6.4 -/* Copyright (C) 2004, Christian Limpach */
     6.5 -
     6.6 -#include <linux/init.h>
     6.7 -#include <linux/kernel.h>
     6.8 -#include <linux/threads.h>
     6.9 -
    6.10 -/*
    6.11 - * the frequency of the profiling timer can be changed
    6.12 - * by writing a multiplier value into /proc/profile.
    6.13 - */
    6.14 -int setup_profiling_timer(unsigned int multiplier)
    6.15 -{
    6.16 -	printk("setup_profiling_timer\n");
    6.17 -	return 0;
    6.18 -}
    6.19 -
    6.20 -/*
    6.21 - * Local variables:
    6.22 - *  c-file-style: "linux"
    6.23 - *  indent-tabs-mode: t
    6.24 - *  c-indent-level: 8
    6.25 - *  c-basic-offset: 8
    6.26 - *  tab-width: 8
    6.27 - * End:
    6.28 - */
     7.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c	Mon Nov 28 13:39:22 2005 +0100
     7.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c	Mon Nov 28 14:08:53 2005 +0100
     7.3 @@ -420,6 +420,12 @@ void __init smp_cpus_done(unsigned int m
     7.4  {
     7.5  }
     7.6  
     7.7 +int setup_profiling_timer(unsigned int multiplier)
     7.8 +{
     7.9 +	/* Dummy function. */
    7.10 +	return 0;
    7.11 +}
    7.12 +
    7.13  /*
    7.14   * Local variables:
    7.15   *  c-file-style: "linux"
     8.1 --- a/linux-2.6-xen-sparse/drivers/xen/Makefile	Mon Nov 28 13:39:22 2005 +0100
     8.2 +++ b/linux-2.6-xen-sparse/drivers/xen/Makefile	Mon Nov 28 14:08:53 2005 +0100
     8.3 @@ -2,6 +2,7 @@
     8.4  obj-y	+= net_driver_util.o
     8.5  obj-y	+= util.o
     8.6  
     8.7 +obj-y	+= char/
     8.8  obj-y	+= console/
     8.9  obj-y	+= evtchn/
    8.10  obj-y	+= balloon/
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/linux-2.6-xen-sparse/drivers/xen/char/Makefile	Mon Nov 28 14:08:53 2005 +0100
     9.3 @@ -0,0 +1,2 @@
     9.4 +
     9.5 +obj-y	:= mem.o
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/linux-2.6-xen-sparse/drivers/xen/char/mem.c	Mon Nov 28 14:08:53 2005 +0100
    10.3 @@ -0,0 +1,157 @@
    10.4 +/*
    10.5 + *  Originally from linux/drivers/char/mem.c
    10.6 + *
    10.7 + *  Copyright (C) 1991, 1992  Linus Torvalds
    10.8 + *
    10.9 + *  Added devfs support. 
   10.10 + *    Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
   10.11 + *  Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
   10.12 + */
   10.13 +
   10.14 +#include <linux/config.h>
   10.15 +#include <linux/mm.h>
   10.16 +#include <linux/miscdevice.h>
   10.17 +#include <linux/slab.h>
   10.18 +#include <linux/vmalloc.h>
   10.19 +#include <linux/mman.h>
   10.20 +#include <linux/random.h>
   10.21 +#include <linux/init.h>
   10.22 +#include <linux/raw.h>
   10.23 +#include <linux/tty.h>
   10.24 +#include <linux/capability.h>
   10.25 +#include <linux/smp_lock.h>
   10.26 +#include <linux/devfs_fs_kernel.h>
   10.27 +#include <linux/ptrace.h>
   10.28 +#include <linux/device.h>
   10.29 +#include <asm/pgalloc.h>
   10.30 +#include <asm/uaccess.h>
   10.31 +#include <asm/io.h>
   10.32 +#include <asm/hypervisor.h>
   10.33 +
   10.34 +static inline int uncached_access(struct file *file)
   10.35 +{
   10.36 +        if (file->f_flags & O_SYNC)
   10.37 +                return 1;
   10.38 +        /* Xen sets correct MTRR type on non-RAM for us. */
   10.39 +        return 0;
   10.40 +}
   10.41 +
   10.42 +/*
   10.43 + * This funcion reads the *physical* memory. The f_pos points directly to the 
   10.44 + * memory location. 
   10.45 + */
   10.46 +static ssize_t read_mem(struct file * file, char __user * buf,
   10.47 +			size_t count, loff_t *ppos)
   10.48 +{
   10.49 +	unsigned long i, p = *ppos;
   10.50 +	ssize_t read = -EFAULT;
   10.51 +	void __iomem *v;
   10.52 +
   10.53 +	if ((v = ioremap(p, count)) == NULL) {
   10.54 +		/*
   10.55 +		 * Some programs (e.g., dmidecode) groove off into weird RAM
   10.56 +		 * areas where no table scan possibly exist (because Xen will
   10.57 +		 * have stomped on them!). These programs get rather upset if
   10.58 +                 * we let them know that Xen failed their access, so we fake
   10.59 +                 * out a read of all zeroes. :-)
   10.60 +		 */
   10.61 +		for (i = 0; i < count; i++)
   10.62 +			if (put_user(0, buf+i))
   10.63 +				return -EFAULT;
   10.64 +		return count;
   10.65 +	}
   10.66 +	if (copy_to_user(buf, v, count))
   10.67 +		goto out;
   10.68 +
   10.69 +	read = count;
   10.70 +	*ppos += read;
   10.71 +out:
   10.72 +	iounmap(v);
   10.73 +	return read;
   10.74 +}
   10.75 +
   10.76 +static ssize_t write_mem(struct file * file, const char __user * buf, 
   10.77 +			 size_t count, loff_t *ppos)
   10.78 +{
   10.79 +	unsigned long p = *ppos;
   10.80 +	ssize_t written = -EFAULT;
   10.81 +	void __iomem *v;
   10.82 +
   10.83 +	if ((v = ioremap(p, count)) == NULL)
   10.84 +		return -EFAULT;
   10.85 +	if (copy_from_user(v, buf, count))
   10.86 +		goto out;
   10.87 +
   10.88 +	written = count;
   10.89 +	*ppos += written;
   10.90 +out:
   10.91 +	iounmap(v);
   10.92 +	return written;
   10.93 +}
   10.94 +
   10.95 +static int mmap_mem(struct file * file, struct vm_area_struct * vma)
   10.96 +{
   10.97 +	if (uncached_access(file))
   10.98 +		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
   10.99 +
  10.100 +	if (direct_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
  10.101 +				   vma->vm_end - vma->vm_start,
  10.102 +				   vma->vm_page_prot, DOMID_IO))
  10.103 +		return -EAGAIN;
  10.104 +
  10.105 +	return 0;
  10.106 +}
  10.107 +
  10.108 +/*
  10.109 + * The memory devices use the full 32/64 bits of the offset, and so we cannot
  10.110 + * check against negative addresses: they are ok. The return value is weird,
  10.111 + * though, in that case (0).
  10.112 + *
  10.113 + * also note that seeking relative to the "end of file" isn't supported:
  10.114 + * it has no meaning, so it returns -EINVAL.
  10.115 + */
  10.116 +static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
  10.117 +{
  10.118 +	loff_t ret;
  10.119 +
  10.120 +	down(&file->f_dentry->d_inode->i_sem);
  10.121 +	switch (orig) {
  10.122 +		case 0:
  10.123 +			file->f_pos = offset;
  10.124 +			ret = file->f_pos;
  10.125 +			force_successful_syscall_return();
  10.126 +			break;
  10.127 +		case 1:
  10.128 +			file->f_pos += offset;
  10.129 +			ret = file->f_pos;
  10.130 +			force_successful_syscall_return();
  10.131 +			break;
  10.132 +		default:
  10.133 +			ret = -EINVAL;
  10.134 +	}
  10.135 +	up(&file->f_dentry->d_inode->i_sem);
  10.136 +	return ret;
  10.137 +}
  10.138 +
  10.139 +static int open_mem(struct inode * inode, struct file * filp)
  10.140 +{
  10.141 +	return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
  10.142 +}
  10.143 +
  10.144 +struct file_operations mem_fops = {
  10.145 +	.llseek		= memory_lseek,
  10.146 +	.read		= read_mem,
  10.147 +	.write		= write_mem,
  10.148 +	.mmap		= mmap_mem,
  10.149 +	.open		= open_mem,
  10.150 +};
  10.151 +
  10.152 +/*
  10.153 + * Local variables:
  10.154 + *  c-file-style: "linux"
  10.155 + *  indent-tabs-mode: t
  10.156 + *  c-indent-level: 8
  10.157 + *  c-basic-offset: 8
  10.158 + *  tab-width: 8
  10.159 + * End:
  10.160 + */