Merge branch 'x86/core' into core/ipi
[safe/jmp/linux-2.6] / arch / x86 / kernel / ioport.c
index be72d80..99c4d30 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/slab.h>
 #include <linux/thread_info.h>
 #include <linux/syscalls.h>
+#include <asm/syscalls.h>
 
 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
 static void set_bitmap(unsigned long *bitmap, unsigned int base,
@@ -34,8 +35,8 @@ static void set_bitmap(unsigned long *bitmap, unsigned int base,
  */
 asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
 {
-       struct thread_struct * t = &current->thread;
-       struct tss_struct * tss;
+       struct thread_struct *t = &current->thread;
+       struct tss_struct *tss;
        unsigned int i, max_long, bytes, bytes_updated;
 
        if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
@@ -84,19 +85,8 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
 
        t->io_bitmap_max = bytes;
 
-#ifdef CONFIG_X86_32
-       /*
-        * Sets the lazy trigger so that the next I/O operation will
-        * reload the correct bitmap.
-        * Reset the owner so that a process switch will not set
-        * tss->io_bitmap_base to IO_BITMAP_OFFSET.
-        */
-       tss->x86_tss.io_bitmap_base = INVALID_IO_BITMAP_OFFSET_LAZY;
-       tss->io_bitmap_owner = NULL;
-#else
        /* Update the TSS: */
        memcpy(tss->io_bitmap, t->io_bitmap_ptr, bytes_updated);
-#endif
 
        put_cpu();
 
@@ -113,13 +103,9 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
  * on system-call entry - see also fork() and the signal handling
  * code.
  */
-#ifdef CONFIG_X86_32
-asmlinkage long sys_iopl(unsigned long regsp)
+static int do_iopl(unsigned int level, struct pt_regs *regs)
 {
-       struct pt_regs *regs = (struct pt_regs *)&regsp;
-       unsigned int level = regs->bx;
        unsigned int old = (regs->flags >> 12) & 3;
-       struct thread_struct *t = &current->thread;
 
        if (level > 3)
                return -EINVAL;
@@ -128,25 +114,30 @@ asmlinkage long sys_iopl(unsigned long regsp)
                if (!capable(CAP_SYS_RAWIO))
                        return -EPERM;
        }
-       t->iopl = level << 12;
        regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
-       set_iopl_mask(t->iopl);
+
        return 0;
 }
-#else
-asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs)
+
+#ifdef CONFIG_X86_32
+long sys_iopl(struct pt_regs *regs)
 {
-       unsigned int old = (regs->flags >> 12) & 3;
+       unsigned int level = regs->bx;
+       struct thread_struct *t = &current->thread;
+       int rc;
 
-       if (level > 3)
-               return -EINVAL;
-       /* Trying to gain more privileges? */
-       if (level > old) {
-               if (!capable(CAP_SYS_RAWIO))
-                       return -EPERM;
-       }
-       regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
+       rc = do_iopl(level, regs);
+       if (rc < 0)
+               goto out;
 
-       return 0;
+       t->iopl = level << 12;
+       set_iopl_mask(t->iopl);
+out:
+       return rc;
+}
+#else
+asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs)
+{
+       return do_iopl(level, regs);
 }
 #endif