Amit,

Attached is a patch for the pci-passthrough tree.
To this point, the same work structure is used to
schedule work when an interrupt is received on the
host and when the guest is acknowledging an interrupt.
There might be a race that will break the schedule.
This patch separates the the two cases, to make it safer.
I tested it with an e1000 NIC and it seems to work ok.

Please let me know if you have any comments.

Regards,
Ben

From e7a02a0f16563963c8060b37a87f1a6a873c4148 Mon Sep 17 00:00:00 2001
From: Ben-Ami Yassour <[EMAIL PROTECTED]>
Date: Thu, 29 May 2008 19:45:23 +0300
Subject: [PATCH] KVM: PCIPT: separate interrupt work structure and ack work 
structure

Signed-off-by: Ben-Ami Yassour <[EMAIL PROTECTED]>
---
 arch/x86/kvm/x86.c         |   16 ++++++++++++----
 include/asm-x86/kvm_host.h |    1 +
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index cf3a47c..4159609 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -236,12 +236,12 @@ void kvm_pci_pt_ack_irq(struct kvm *kvm, int vector)
                return;
        }

-       pci_pt_dev->pt_dev.int_work.irq = irq;
-       pci_pt_dev->pt_dev.int_work.kvm = kvm;
-       pci_pt_dev->pt_dev.int_work.source = 1;
+       pci_pt_dev->pt_dev.ack_work.irq = irq;
+       pci_pt_dev->pt_dev.ack_work.kvm = kvm;
+       pci_pt_dev->pt_dev.ack_work.source = 1;

        kvm_get_kvm(kvm);
-       schedule_work(&pci_pt_dev->pt_dev.int_work.work);
+       schedule_work(&pci_pt_dev->pt_dev.ack_work.work);
        read_unlock_irqrestore(&kvm_pci_pt_lock, flags);
 }

@@ -308,6 +308,7 @@ static int kvm_vm_ioctl_pci_pt_dev(struct kvm *kvm,
        write_lock_irqsave(&kvm_pci_pt_lock, flags);

        INIT_WORK(&match->pt_dev.int_work.work, kvm_pci_pt_work_fn);
+       INIT_WORK(&match->pt_dev.ack_work.work, kvm_pci_pt_work_fn);

        list_add(&match->list, &kvm->arch.pci_pt_dev_head);

@@ -335,6 +336,13 @@ static void kvm_free_pci_passthrough(struct kvm *kvm)
                         * care of kvm_put_kvm.
                         */
                        kvm_put_kvm(kvm);
+
+               if (cancel_work_sync(&pci_pt_dev->pt_dev.ack_work.work))
+                       /* We had pending work. That means we will have to take
+                        * care of kvm_put_kvm.
+                        */
+                       kvm_put_kvm(kvm);
+
        }

        write_lock_irqsave(&kvm_pci_pt_lock, flags);
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h
index 6b374dc..6f62dc3 100644
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@ -317,6 +317,7 @@ struct kvm_pci_passthrough_dev_kernel {
        struct kvm_pci_pt_info guest;
        struct kvm_pci_pt_info host;
        struct kvm_pci_pt_work int_work;
+       struct kvm_pci_pt_work ack_work;
 };

 /* This list is to store the guest bus:device:function-irq and host
--
1.5.5.1









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