#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,
*/
asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
{
- struct thread_struct * t = ¤t->thread;
- struct tss_struct * tss;
+ struct thread_struct *t = ¤t->thread;
+ struct tss_struct *tss;
unsigned int i, max_long, bytes, bytes_updated;
if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
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();
* 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 *)®sp;
- unsigned int level = regs->bx;
unsigned int old = (regs->flags >> 12) & 3;
- struct thread_struct *t = ¤t->thread;
if (level > 3)
return -EINVAL;
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 = ¤t->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