aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/vm86.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/vm86.c')
-rw-r--r--arch/i386/kernel/vm86.c21
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
728out: 728out:
@@ -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