On Saturday 11 October 2008 16:10:51 Amit Shah wrote:
> From: Sheng Yang <[EMAIL PROTECTED]>
>
> Keep a record of current interrupt state before injecting. Don't
> assert/deassert repeatedly, so that every caller of kvm_set_irq()
> can be identified as a separate interrupt source for the IOAPIC/PIC
> to implement logical OR of level triggered interrupts on one IRQ line.
>
> Notice that userspace devices are treated as one device for each IRQ
> line. The correctness of sharing interrupt for each IRQ line should be
> ensured by the userspace program (QEmu).
>
> [Amit: rebase to kvm.git HEAD]

Hi, Amit

Thanks for your work! 

But maybe I miss something. I suppose my later patch can work indepently? I 
think the second patch should solve the whole problem (sorry to reply it to 
the second rather than [0/2] which made confusion...). Can you have a check?

Thanks!
--
regards
Yang, Sheng
>
> Signed-off-by: Sheng Yang <[EMAIL PROTECTED]>
> Signed-off-by: Amit Shah <[EMAIL PROTECTED]>
> ---
>  arch/x86/kvm/x86.c       |   13 ++++++++++++-
>  include/linux/kvm_host.h |    3 +++
>  virt/kvm/kvm_main.c      |   12 +++++++++---
>  3 files changed, 24 insertions(+), 4 deletions(-)
>
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index dda478e..6f45428 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -1816,7 +1816,18 @@ long kvm_arch_vm_ioctl(struct file *filp,
>                       goto out;
>               if (irqchip_in_kernel(kvm)) {
>                       mutex_lock(&kvm->lock);
> -                     kvm_set_irq(kvm, irq_event.irq, irq_event.level);
> +                     /*
> +                      * Take one IRQ line as from one device, shared IRQ
> +                      * line should also be handled in the userspace before
> +                      * use KVM_IRQ_LINE ioctl to change IRQ line state.
> +                      */
> +                     if (kvm->userspace_intrsource_states[irq_event.irq]
> +                                     != irq_event.level) {
> +                             kvm_set_irq(kvm, irq_event.irq,
> +                                         irq_event.level);
> +                             kvm->userspace_intrsource_states[irq_event.irq]
> +                                             = irq_event.level;
> +                     }
>                       mutex_unlock(&kvm->lock);
>                       r = 0;
>               }
> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 3833c48..d392e31 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h
> @@ -129,6 +129,8 @@ struct kvm {
>       unsigned long mmu_notifier_seq;
>       long mmu_notifier_count;
>  #endif
> +
> +     int userspace_intrsource_states[KVM_IOAPIC_NUM_PINS];
>  };
>
>  /* The guest did something we don't support. */
> @@ -306,6 +308,7 @@ struct kvm_assigned_dev_kernel {
>       int host_irq;
>       int guest_irq;
>       int irq_requested;
> +     int irq_state;
>       struct pci_dev *dev;
>       struct kvm *kvm;
>  };
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index cf0ab8e..faa56fb 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -104,8 +104,11 @@ static void
> kvm_assigned_dev_interrupt_work_handler(struct work_struct *work) *
> finer-grained lock, update this
>        */
>       mutex_lock(&assigned_dev->kvm->lock);
> -     kvm_set_irq(assigned_dev->kvm,
> -                 assigned_dev->guest_irq, 1);
> +     if (assigned_dev->irq_state == 0) {
> +             kvm_set_irq(assigned_dev->kvm,
> +                         assigned_dev->guest_irq, 1);
> +             assigned_dev->irq_state = 1;
> +     }
>       mutex_unlock(&assigned_dev->kvm->lock);
>       kvm_put_kvm(assigned_dev->kvm);
>  }
> @@ -134,7 +137,10 @@ static void kvm_assigned_dev_ack_irq(struct
> kvm_irq_ack_notifier *kian)
>
>       dev = container_of(kian, struct kvm_assigned_dev_kernel,
>                          ack_notifier);
> -     kvm_set_irq(dev->kvm, dev->guest_irq, 0);
> +     if (dev->irq_state == 1) {
> +             kvm_set_irq(dev->kvm, dev->guest_irq, 0);
> +             dev->irq_state = 0;
> +     }
>       enable_irq(dev->host_irq);
>  }


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to