x86: add set/clear_cpu_cap operations
[deliverable/linux.git] / arch / x86 / kernel / ioport_32.c
index 4ed48dc8df1e76fa925f15e11febe5ebc79481fa..c281ffa182596a905ffa42b54d66fdc732702dd5 100644 (file)
 #include <linux/syscalls.h>
 
 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
-static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
+static void set_bitmap(unsigned long *bitmap, unsigned int base,
+                      unsigned int extent, int new_value)
 {
-       unsigned long mask;
-       unsigned long *bitmap_base = bitmap + (base / BITS_PER_LONG);
-       unsigned int low_index = base & (BITS_PER_LONG-1);
-       int length = low_index + extent;
-
-       if (low_index != 0) {
-               mask = (~0UL << low_index);
-               if (length < BITS_PER_LONG)
-                       mask &= ~(~0UL << length);
-               if (new_value)
-                       *bitmap_base++ |= mask;
-               else
-                       *bitmap_base++ &= ~mask;
-               length -= BITS_PER_LONG;
-       }
-
-       mask = (new_value ? ~0UL : 0UL);
-       while (length >= BITS_PER_LONG) {
-               *bitmap_base++ = mask;
-               length -= BITS_PER_LONG;
-       }
+       unsigned int i;
 
-       if (length > 0) {
-               mask = ~(~0UL << length);
+       for (i = base; i < base + extent; i++) {
                if (new_value)
-                       *bitmap_base++ |= mask;
+                       __set_bit(i, bitmap);
                else
-                       *bitmap_base++ &= ~mask;
+                       __clear_bit(i, bitmap);
        }
 }
 
-
 /*
  * this changes the io permissions bitmap in the current task.
  */
 asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
 {
-       unsigned long i, max_long, bytes, bytes_updated;
        struct thread_struct * t = &current->thread;
        struct tss_struct * tss;
-       unsigned long *bitmap;
+       unsigned long i, max_long;
 
        if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
                return -EINVAL;
@@ -71,7 +49,8 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
         * this is why we delay this operation until now:
         */
        if (!t->io_bitmap_ptr) {
-               bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
+               unsigned long *bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
+
                if (!bitmap)
                        return -ENOMEM;
 
@@ -100,10 +79,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
                if (t->io_bitmap_ptr[i] != ~0UL)
                        max_long = i;
 
-       bytes = (max_long + 1) * sizeof(long);
-       bytes_updated = max(bytes, t->io_bitmap_max);
-
-       t->io_bitmap_max = bytes;
+       t->io_bitmap_max = (max_long + 1) * sizeof(unsigned long);
 
        /*
         * Sets the lazy trigger so that the next I/O operation will
@@ -130,9 +106,9 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
  * code.
  */
 
-asmlinkage long sys_iopl(unsigned long unused)
+asmlinkage long sys_iopl(unsigned long regsp)
 {
-       volatile struct pt_regs * regs = (struct pt_regs *) &unused;
+       volatile struct pt_regs *regs = (struct pt_regs *)&regsp;
        unsigned int level = regs->ebx;
        unsigned int old = (regs->eflags >> 12) & 3;
        struct thread_struct *t = &current->thread;
@@ -144,8 +120,10 @@ asmlinkage long sys_iopl(unsigned long unused)
                if (!capable(CAP_SYS_RAWIO))
                        return -EPERM;
        }
+
        t->iopl = level << 12;
        regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
        set_iopl_mask(t->iopl);
+
        return 0;
 }
This page took 0.030562 seconds and 5 git commands to generate.