Gregory Haskins wrote: > From: None <None> > > The current code is geared towards using a user-mode (A)PIC. This patch adds > an "irqdevice" abstraction, and implements a "userint" model to handle the > duties of the original code. Later, we can develop other irqdevice models > to handle objects like LAPIC, IOAPIC, i8259, etc, as appropriate > >
Viewed in light of 3/3, various races are exposed. > @@ -2044,13 +2043,11 @@ static int kvm_vcpu_ioctl_set_sregs(struct kvm_vcpu > *vcpu, > if (mmu_reset_needed) > kvm_mmu_reset_context(vcpu); > > - memcpy(vcpu->irq_pending, sregs->interrupt_bitmap, > - sizeof vcpu->irq_pending); > - vcpu->irq_summary = 0; > - for (i = 0; i < NR_IRQ_WORDS; ++i) > - if (vcpu->irq_pending[i]) > - __set_bit(i, &vcpu->irq_summary); > - > + /* walk the interrupt-bitmap and inject an IRQ for each bit found */ > + for (i = 0; i < 256; ++i) > + if (test_bit(i, &sregs->interrupt_bitmap[0])) > + kvm_irqdevice_set_pin(&vcpu->irq_dev, i, 1); > + > You need to lower a pin here if it was previously set. > diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c > index 61a6116..a0fdf02 100644 > --- a/drivers/kvm/vmx.c > +++ b/drivers/kvm/vmx.c > @@ -1219,13 +1219,8 @@ static void inject_rmode_irq(struct kvm_vcpu *vcpu, > int irq) > > static void kvm_do_inject_irq(struct kvm_vcpu *vcpu) > { > - int word_index = __ffs(vcpu->irq_summary); > - int bit_index = __ffs(vcpu->irq_pending[word_index]); > - int irq = word_index * BITS_PER_LONG + bit_index; > - > - clear_bit(bit_index, &vcpu->irq_pending[word_index]); > - if (!vcpu->irq_pending[word_index]) > - clear_bit(word_index, &vcpu->irq_summary); > + int irq = kvm_irqdevice_read_vector(&vcpu->irq_dev, 0); > + BUG_ON(irq < 0); > This BUG can trigger. A level-triggered irq was asserted, then deasserted. > > if (vcpu->rmode.active) { > inject_rmode_irq(vcpu, irq); > @@ -1246,7 +1241,7 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu, > (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0); > > if (vcpu->interrupt_window_open && > - vcpu->irq_summary && > + kvm_irqdevice_pending(&vcpu->irq_dev, 0) && > !(vmcs_read32(VM_ENTRY_INTR_INFO_FIELD) & INTR_INFO_VALID_MASK)) > What if an irq is made pending here? > /* > * If interrupts enabled, and not blocked by sti or mov ss. > Good. > @@ -1255,7 +1250,8 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu, > > cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); > if (!vcpu->interrupt_window_open && > - (vcpu->irq_summary || kvm_run->request_interrupt_window)) > + (kvm_irqdevice_pending(&vcpu->irq_dev, 0) || > + kvm_run->request_interrupt_window)) > /* > * Interrupts blocked. Wait for unblock. > */ > or here? > @@ -1619,8 +1615,9 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu, > kvm_run->if_flag = (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF) != 0; > kvm_run->cr8 = vcpu->cr8; > kvm_run->apic_base = vcpu->apic_base; > - kvm_run->ready_for_interrupt_injection = (vcpu->interrupt_window_open && > - vcpu->irq_summary == 0); > + kvm_run->ready_for_interrupt_injection = > + (vcpu->interrupt_window_open && > + !kvm_irqdevice_pending(&vcpu->irq_dev, 0)); > } > or here? possibly a good answer is "don't rely on r_f_i_i if not using userint". > > static int handle_interrupt_window(struct kvm_vcpu *vcpu, > @@ -1631,7 +1628,7 @@ static int handle_interrupt_window(struct kvm_vcpu > *vcpu, > * possible > */ > if (kvm_run->request_interrupt_window && > - !vcpu->irq_summary) { > + !kvm_irqdevice_pending(&vcpu->irq_dev, 0)) { > kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN; > ++kvm_stat.irq_window_exits; > return 0; > ditto. > @@ -1713,7 +1710,7 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, > struct kvm_vcpu *vcpu) > static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu, > struct kvm_run *kvm_run) > { > - return (!vcpu->irq_summary && > + return (!kvm_irqdevice_pending(&vcpu->irq_dev, 0) && > kvm_run->request_interrupt_window && > vcpu->interrupt_window_open && > (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_IF)); > > > ditto. -- error compiling committee.c: too many arguments to function ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel