drm/radeon/kms: clear confusion in GART init/deinit path
[safe/jmp/linux-2.6] / arch / x86 / kernel / vm86_32.c
index 6a91fcf..9c4e625 100644 (file)
@@ -46,6 +46,7 @@
 #include <asm/io.h>
 #include <asm/tlbflush.h>
 #include <asm/irq.h>
+#include <asm/syscalls.h>
 
 /*
  * Known problems:
@@ -139,7 +140,7 @@ struct pt_regs *save_v86_state(struct kernel_vm86_regs *regs)
                printk("no vm86_info: BAD\n");
                do_exit(SIGSEGV);
        }
-       set_flags(regs->pt.flags, VEFLAGS, VIF_MASK | current->thread.v86mask);
+       set_flags(regs->pt.flags, VEFLAGS, X86_EFLAGS_VIF | current->thread.v86mask);
        tmp = copy_vm86_regs_to_user(&current->thread.vm86_info->regs, regs);
        tmp += put_user(current->thread.screen_bitmap, &current->thread.vm86_info->screen_bitmap);
        if (tmp) {
@@ -157,7 +158,7 @@ struct pt_regs *save_v86_state(struct kernel_vm86_regs *regs)
        ret = KVM86->regs32;
 
        ret->fs = current->thread.saved_fs;
-       loadsegment(gs, current->thread.saved_gs);
+       set_user_gs(ret, current->thread.saved_gs);
 
        return ret;
 }
@@ -196,9 +197,9 @@ out:
 static int do_vm86_irq_handling(int subfunction, int irqnumber);
 static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk);
 
-asmlinkage int sys_vm86old(struct pt_regs regs)
+int sys_vm86old(struct pt_regs *regs)
 {
-       struct vm86_struct __user *v86 = (struct vm86_struct __user *)regs.bx;
+       struct vm86_struct __user *v86 = (struct vm86_struct __user *)regs->bx;
        struct kernel_vm86_struct info; /* declare this _on top_,
                                         * this avoids wasting of stack space.
                                         * This remains on the stack until we
@@ -217,7 +218,7 @@ asmlinkage int sys_vm86old(struct pt_regs regs)
        if (tmp)
                goto out;
        memset(&info.vm86plus, 0, (int)&info.regs32 - (int)&info.vm86plus);
-       info.regs32 = &regs;
+       info.regs32 = regs;
        tsk->thread.vm86_info = v86;
        do_sys_vm86(&info, tsk);
        ret = 0;        /* we never return here */
@@ -226,7 +227,7 @@ out:
 }
 
 
-asmlinkage int sys_vm86(struct pt_regs regs)
+int sys_vm86(struct pt_regs *regs)
 {
        struct kernel_vm86_struct info; /* declare this _on top_,
                                         * this avoids wasting of stack space.
@@ -238,12 +239,12 @@ asmlinkage int sys_vm86(struct pt_regs regs)
        struct vm86plus_struct __user *v86;
 
        tsk = current;
-       switch (regs.bx) {
+       switch (regs->bx) {
        case VM86_REQUEST_IRQ:
        case VM86_FREE_IRQ:
        case VM86_GET_IRQ_BITS:
        case VM86_GET_AND_RESET_IRQ:
-               ret = do_vm86_irq_handling(regs.bx, (int)regs.cx);
+               ret = do_vm86_irq_handling(regs->bx, (int)regs->cx);
                goto out;
        case VM86_PLUS_INSTALL_CHECK:
                /*
@@ -260,14 +261,14 @@ asmlinkage int sys_vm86(struct pt_regs regs)
        ret = -EPERM;
        if (tsk->thread.saved_sp0)
                goto out;
-       v86 = (struct vm86plus_struct __user *)regs.cx;
+       v86 = (struct vm86plus_struct __user *)regs->cx;
        tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs,
                                       offsetof(struct kernel_vm86_struct, regs32) -
                                       sizeof(info.regs));
        ret = -EFAULT;
        if (tmp)
                goto out;
-       info.regs32 = &regs;
+       info.regs32 = regs;
        info.vm86plus.is_vm86pus = 1;
        tsk->thread.vm86_info = (struct vm86_struct __user *)v86;
        do_sys_vm86(&info, tsk);
@@ -286,10 +287,9 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
        info->regs.pt.ds = 0;
        info->regs.pt.es = 0;
        info->regs.pt.fs = 0;
-
-/* we are clearing gs later just before "jmp resume_userspace",
- * because it is not saved/restored.
- */
+#ifndef CONFIG_X86_32_LAZY_GS
+       info->regs.pt.gs = 0;
+#endif
 
 /*
  * The flags register is also special: we cannot trust that the user
@@ -299,30 +299,30 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
        VEFLAGS = info->regs.pt.flags;
        info->regs.pt.flags &= SAFE_MASK;
        info->regs.pt.flags |= info->regs32->flags & ~SAFE_MASK;
-       info->regs.pt.flags |= VM_MASK;
+       info->regs.pt.flags |= X86_VM_MASK;
 
        switch (info->cpu_type) {
        case CPU_286:
                tsk->thread.v86mask = 0;
                break;
        case CPU_386:
-               tsk->thread.v86mask = NT_MASK | IOPL_MASK;
+               tsk->thread.v86mask = X86_EFLAGS_NT | X86_EFLAGS_IOPL;
                break;
        case CPU_486:
-               tsk->thread.v86mask = AC_MASK | NT_MASK | IOPL_MASK;
+               tsk->thread.v86mask = X86_EFLAGS_AC | X86_EFLAGS_NT | X86_EFLAGS_IOPL;
                break;
        default:
-               tsk->thread.v86mask = ID_MASK | AC_MASK | NT_MASK | IOPL_MASK;
+               tsk->thread.v86mask = X86_EFLAGS_ID | X86_EFLAGS_AC | X86_EFLAGS_NT | X86_EFLAGS_IOPL;
                break;
        }
 
 /*
- * Save old state, set default return value (%ax) to 0
+ * Save old state, set default return value (%ax) to 0 (VM86_SIGNAL)
  */
-       info->regs32->ax = 0;
+       info->regs32->ax = VM86_SIGNAL;
        tsk->thread.saved_sp0 = tsk->thread.sp0;
        tsk->thread.saved_fs = info->regs32->fs;
-       savesegment(gs, tsk->thread.saved_gs);
+       tsk->thread.saved_gs = get_user_gs(info->regs32);
 
        tss = &per_cpu(init_tss, get_cpu());
        tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
@@ -342,7 +342,9 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
        __asm__ __volatile__(
                "movl %0,%%esp\n\t"
                "movl %1,%%ebp\n\t"
+#ifdef CONFIG_X86_32_LAZY_GS
                "mov  %2, %%gs\n\t"
+#endif
                "jmp resume_userspace"
                : /* no outputs */
                :"r" (&info->regs), "r" (task_thread_info(tsk)), "r" (0));
@@ -363,24 +365,24 @@ static inline void return_to_32bit(struct kernel_vm86_regs *regs16, int retval)
 
 static inline void set_IF(struct kernel_vm86_regs *regs)
 {
-       VEFLAGS |= VIF_MASK;
-       if (VEFLAGS & VIP_MASK)
+       VEFLAGS |= X86_EFLAGS_VIF;
+       if (VEFLAGS & X86_EFLAGS_VIP)
                return_to_32bit(regs, VM86_STI);
 }
 
 static inline void clear_IF(struct kernel_vm86_regs *regs)
 {
-       VEFLAGS &= ~VIF_MASK;
+       VEFLAGS &= ~X86_EFLAGS_VIF;
 }
 
 static inline void clear_TF(struct kernel_vm86_regs *regs)
 {
-       regs->pt.flags &= ~TF_MASK;
+       regs->pt.flags &= ~X86_EFLAGS_TF;
 }
 
 static inline void clear_AC(struct kernel_vm86_regs *regs)
 {
-       regs->pt.flags &= ~AC_MASK;
+       regs->pt.flags &= ~X86_EFLAGS_AC;
 }
 
 /*
@@ -399,7 +401,7 @@ static inline void set_vflags_long(unsigned long flags, struct kernel_vm86_regs
 {
        set_flags(VEFLAGS, flags, current->thread.v86mask);
        set_flags(regs->pt.flags, flags, SAFE_MASK);
-       if (flags & IF_MASK)
+       if (flags & X86_EFLAGS_IF)
                set_IF(regs);
        else
                clear_IF(regs);
@@ -409,7 +411,7 @@ static inline void set_vflags_short(unsigned short flags, struct kernel_vm86_reg
 {
        set_flags(VFLAGS, flags, current->thread.v86mask);
        set_flags(regs->pt.flags, flags, SAFE_MASK);
-       if (flags & IF_MASK)
+       if (flags & X86_EFLAGS_IF)
                set_IF(regs);
        else
                clear_IF(regs);
@@ -419,9 +421,9 @@ static inline unsigned long get_vflags(struct kernel_vm86_regs *regs)
 {
        unsigned long flags = regs->pt.flags & RETURN_MASK;
 
-       if (VEFLAGS & VIF_MASK)
-               flags |= IF_MASK;
-       flags |= IOPL_MASK;
+       if (VEFLAGS & X86_EFLAGS_VIF)
+               flags |= X86_EFLAGS_IF;
+       flags |= X86_EFLAGS_IOPL;
        return flags | (VEFLAGS & current->thread.v86mask);
 }
 
@@ -557,16 +559,9 @@ int handle_vm86_trap(struct kernel_vm86_regs *regs, long error_code, int trapno)
        }
        if (trapno != 1)
                return 1; /* we let this handle by the calling routine */
-       if (current->ptrace & PT_PTRACED) {
-               unsigned long flags;
-               spin_lock_irqsave(&current->sighand->siglock, flags);
-               sigdelset(&current->blocked, SIGTRAP);
-               recalc_sigpending();
-               spin_unlock_irqrestore(&current->sighand->siglock, flags);
-       }
-       send_sig(SIGTRAP, current, 1);
        current->thread.trap_no = trapno;
        current->thread.error_code = error_code;
+       force_sig(SIGTRAP, current);
        return 0;
 }
 
@@ -580,11 +575,11 @@ void handle_vm86_fault(struct kernel_vm86_regs *regs, long error_code)
 
 #define CHECK_IF_IN_TRAP \
        if (VMPI.vm86dbg_active && VMPI.vm86dbg_TFpendig) \
-               newflags |= TF_MASK
+               newflags |= X86_EFLAGS_TF
 #define VM86_FAULT_RETURN do { \
-       if (VMPI.force_return_for_pic  && (VEFLAGS & (IF_MASK | VIF_MASK))) \
+       if (VMPI.force_return_for_pic  && (VEFLAGS & (X86_EFLAGS_IF | X86_EFLAGS_VIF))) \
                return_to_32bit(regs, VM86_PICRETURN); \
-       if (orig_flags & TF_MASK) \
+       if (orig_flags & X86_EFLAGS_TF) \
                handle_vm86_trap(regs, 0, 1); \
        return; } while (0)