ia64/xen-unstable

changeset 10326:28128dafbe03

[LINUX][X86/64] Support IO-port permissions bitmaps (ioperm() syscall).
Signed-off-by: Jan Beulich <jbeulich@novell.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Jun 07 13:38:08 2006 +0100 (2006-06-07)
parents ec903b8e6612
children cca6641d4087
files linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c	Wed Jun 07 11:24:44 2006 +0100
     1.2 +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/ioport-xen.c	Wed Jun 07 13:38:08 2006 +0100
     1.3 @@ -19,6 +19,56 @@
     1.4  #include <linux/thread_info.h>
     1.5  #include <xen/interface/physdev.h>
     1.6  
     1.7 +/* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
     1.8 +static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
     1.9 +{
    1.10 +	int i;
    1.11 +
    1.12 +	if (new_value)
    1.13 +		for (i = base; i < base + extent; i++)
    1.14 +			__set_bit(i, bitmap);
    1.15 +	else
    1.16 +		for (i = base; i < base + extent; i++)
    1.17 +			clear_bit(i, bitmap);
    1.18 +}
    1.19 +
    1.20 +/*
    1.21 + * this changes the io permissions bitmap in the current task.
    1.22 + */
    1.23 +asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
    1.24 +{
    1.25 +	struct thread_struct * t = &current->thread;
    1.26 +	unsigned long *bitmap;
    1.27 +	struct physdev_set_iobitmap set_iobitmap;
    1.28 +
    1.29 +	if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
    1.30 +		return -EINVAL;
    1.31 +	if (turn_on && !capable(CAP_SYS_RAWIO))
    1.32 +		return -EPERM;
    1.33 +
    1.34 +	/*
    1.35 +	 * If it's the first ioperm() call in this thread's lifetime, set the
    1.36 +	 * IO bitmap up. ioperm() is much less timing critical than clone(),
    1.37 +	 * this is why we delay this operation until now:
    1.38 +	 */
    1.39 +	if (!t->io_bitmap_ptr) {
    1.40 +		bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
    1.41 +		if (!bitmap)
    1.42 +			return -ENOMEM;
    1.43 +
    1.44 +		memset(bitmap, 0xff, IO_BITMAP_BYTES);
    1.45 +		t->io_bitmap_ptr = bitmap;
    1.46 +
    1.47 +		set_iobitmap.bitmap   = (char *)bitmap;
    1.48 +		set_iobitmap.nr_ports = IO_BITMAP_BITS;
    1.49 +		HYPERVISOR_physdev_op(PHYSDEVOP_set_iobitmap, &set_iobitmap);
    1.50 +	}
    1.51 +
    1.52 +	set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
    1.53 +
    1.54 +	return 0;
    1.55 +}
    1.56 +
    1.57  /*
    1.58   * sys_iopl has to be used when you want to access the IO ports
    1.59   * beyond the 0x3ff range: to get the full 65536 ports bitmapped
    1.60 @@ -47,11 +97,3 @@ asmlinkage long sys_iopl(unsigned int ne
    1.61  
    1.62  	return 0;
    1.63  }
    1.64 -
    1.65 -/*
    1.66 - * this changes the io permissions bitmap in the current task.
    1.67 - */
    1.68 -asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
    1.69 -{
    1.70 -  return turn_on ? sys_iopl(3, NULL) : 0;
    1.71 -}