[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |