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 | ||