[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] [HVM] Fixed 2 bugs for smp HVM PV driver save/restore



[PATCH] [HVM] Fixed 2 bugs for smp HVM PV driver save/restore
1. After restore, if AP's HYPERVISOR_yield() happen when BSP reinitialize 
hyper-call
  page in resume_hypercall_stubs(), there is a crash. Add a rwlock to fix it.
2. For pseudo PCI dev if an intr is asserted but not deasserted and save happen,
  after restore gsi_assert_count got increased so that vioapic_update_EOI will
  continuously deliver intr W/O any chance to deasserted as 
callback_via_asserted
  is lost during save/restore. Force a deassert in such case to avoid deadlock.

Signed-off-by: Edwin Zhai <edwin.zhai@xxxxxxxxx>


diff -r 88bb0d305308 unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c
--- a/unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c        Wed Aug 
01 15:47:54 2007 +0100
+++ b/unmodified_drivers/linux-2.6/platform-pci/machine_reboot.c        Mon Aug 
06 13:55:10 2007 +0800
@@ -10,6 +10,12 @@ struct ap_suspend_info {
        int      do_spin;
        atomic_t nr_spinning;
 };
+
+/*
+ * use a rwlock to protect the hypercall page in case that AP execute 
+ * the hypercall code when BSP re-initialize it after restore
+ */
+DEFINE_RWLOCK(suspend_lock);
 
 /*
  * Spinning prevents, for example, APs touching grant table entries while
@@ -27,7 +33,9 @@ static void ap_suspend(void *_info)
 
        while (info->do_spin) {
                cpu_relax();
+               read_lock(&suspend_lock);
                HYPERVISOR_yield();
+               read_unlock(&suspend_lock);
        }
 
        mb();
@@ -43,7 +51,9 @@ static int bp_suspend(void)
        suspend_cancelled = HYPERVISOR_shutdown(SHUTDOWN_suspend);
 
        if (!suspend_cancelled) {
+               write_lock(&suspend_lock);
                platform_pci_resume();
+               write_unlock(&suspend_lock);
                gnttab_resume();
                irq_resume();
        }
diff -r 88bb0d305308 xen/arch/x86/hvm/irq.c
--- a/xen/arch/x86/hvm/irq.c    Wed Aug 01 15:47:54 2007 +0100
+++ b/xen/arch/x86/hvm/irq.c    Mon Aug 06 14:37:50 2007 +0800
@@ -395,6 +395,35 @@ static int irq_save_pci(struct domain *d
 static int irq_save_pci(struct domain *d, hvm_domain_context_t *h)
 {
     struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    unsigned int gsi, pdev, pintx;
+
+    /*
+     * deassert if necessary to avoid PV drv deadlock in following case:
+     * gsi_assert_count got increased when assert then save happen,
+     * after restore gsi_assert_count got increased again so that 
+     * vioapic_update_EOI will continue dilver intr W/O any chance 
+     * to deassert as callback_via_asserted is 0. 
+     */
+    if ( hvm_irq->callback_via_asserted ) {
+
+        switch ( hvm_irq->callback_via_type )
+        {
+            case HVMIRQ_callback_gsi:
+                gsi = hvm_irq->callback_via.gsi;
+                if ( (--hvm_irq->gsi_assert_count[gsi] == 0) && (gsi <= 15) )
+                    vpic_irq_negative_edge(d, gsi);
+                gdprintk(XENLOG_INFO, "deassert gsi %d, cnt %d.\n", gsi, 
hvm_irq->gsi_assert_count[gsi]);
+                break;
+            case HVMIRQ_callback_pci_intx:
+                pdev  = hvm_irq->callback_via.pci.dev;
+                pintx = hvm_irq->callback_via.pci.intx;
+                __hvm_pci_intx_deassert(d, pdev, pintx);
+                gdprintk(XENLOG_INFO, "deassert pci pdev %d, pintx %d.\n", 
pdev, pintx);
+                break;
+            default:
+                break;
+        }
+    }
 
     /* Save PCI IRQ lines */
     return ( hvm_save_entry(PCI_IRQ, 0, h, &hvm_irq->pci_intx) );

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.