diff options
Diffstat (limited to 'arch/i386/kernel/vm86.c')
| -rw-r--r-- | arch/i386/kernel/vm86.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c index 2f3d52dacff7..ec0f68ce6886 100644 --- a/arch/i386/kernel/vm86.c +++ b/arch/i386/kernel/vm86.c | |||
| @@ -222,7 +222,7 @@ asmlinkage int sys_vm86(struct pt_regs regs) | |||
| 222 | goto out; | 222 | goto out; |
| 223 | case VM86_PLUS_INSTALL_CHECK: | 223 | case VM86_PLUS_INSTALL_CHECK: |
| 224 | /* NOTE: on old vm86 stuff this will return the error | 224 | /* NOTE: on old vm86 stuff this will return the error |
| 225 | from verify_area(), because the subfunction is | 225 | from access_ok(), because the subfunction is |
| 226 | interpreted as (invalid) address to vm86_struct. | 226 | interpreted as (invalid) address to vm86_struct. |
| 227 | So the installation check works. | 227 | So the installation check works. |
| 228 | */ | 228 | */ |
| @@ -294,8 +294,8 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk | |||
| 294 | */ | 294 | */ |
| 295 | info->regs32->eax = 0; | 295 | info->regs32->eax = 0; |
| 296 | tsk->thread.saved_esp0 = tsk->thread.esp0; | 296 | tsk->thread.saved_esp0 = tsk->thread.esp0; |
| 297 | asm volatile("movl %%fs,%0":"=m" (tsk->thread.saved_fs)); | 297 | asm volatile("mov %%fs,%0":"=m" (tsk->thread.saved_fs)); |
| 298 | asm volatile("movl %%gs,%0":"=m" (tsk->thread.saved_gs)); | 298 | asm volatile("mov %%gs,%0":"=m" (tsk->thread.saved_gs)); |
| 299 | 299 | ||
| 300 | tss = &per_cpu(init_tss, get_cpu()); | 300 | tss = &per_cpu(init_tss, get_cpu()); |
| 301 | tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; | 301 | tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; |
| @@ -717,12 +717,12 @@ static irqreturn_t irq_handler(int intno, void *dev_id, struct pt_regs * regs) | |||
| 717 | irqbits |= irq_bit; | 717 | irqbits |= irq_bit; |
| 718 | if (vm86_irqs[intno].sig) | 718 | if (vm86_irqs[intno].sig) |
| 719 | send_sig(vm86_irqs[intno].sig, vm86_irqs[intno].tsk, 1); | 719 | send_sig(vm86_irqs[intno].sig, vm86_irqs[intno].tsk, 1); |
| 720 | spin_unlock_irqrestore(&irqbits_lock, flags); | ||
| 721 | /* | 720 | /* |
| 722 | * IRQ will be re-enabled when user asks for the irq (whether | 721 | * IRQ will be re-enabled when user asks for the irq (whether |
| 723 | * polling or as a result of the signal) | 722 | * polling or as a result of the signal) |
| 724 | */ | 723 | */ |
| 725 | disable_irq(intno); | 724 | disable_irq_nosync(intno); |
| 725 | spin_unlock_irqrestore(&irqbits_lock, flags); | ||
| 726 | return IRQ_HANDLED; | 726 | return IRQ_HANDLED; |
| 727 | 727 | ||
| 728 | out: | 728 | out: |
| @@ -754,17 +754,20 @@ static inline int get_and_reset_irq(int irqnumber) | |||
| 754 | { | 754 | { |
| 755 | int bit; | 755 | int bit; |
| 756 | unsigned long flags; | 756 | unsigned long flags; |
| 757 | int ret = 0; | ||
| 757 | 758 | ||
| 758 | if (invalid_vm86_irq(irqnumber)) return 0; | 759 | if (invalid_vm86_irq(irqnumber)) return 0; |
| 759 | if (vm86_irqs[irqnumber].tsk != current) return 0; | 760 | if (vm86_irqs[irqnumber].tsk != current) return 0; |
| 760 | spin_lock_irqsave(&irqbits_lock, flags); | 761 | spin_lock_irqsave(&irqbits_lock, flags); |
| 761 | bit = irqbits & (1 << irqnumber); | 762 | bit = irqbits & (1 << irqnumber); |
| 762 | irqbits &= ~bit; | 763 | irqbits &= ~bit; |
| 764 | if (bit) { | ||
| 765 | enable_irq(irqnumber); | ||
| 766 | ret = 1; | ||
| 767 | } | ||
| 768 | |||
| 763 | spin_unlock_irqrestore(&irqbits_lock, flags); | 769 | spin_unlock_irqrestore(&irqbits_lock, flags); |
| 764 | if (!bit) | 770 | return ret; |
| 765 | return 0; | ||
| 766 | enable_irq(irqnumber); | ||
| 767 | return 1; | ||
| 768 | } | 771 | } |
| 769 | 772 | ||
| 770 | 773 | ||
