diff options
author | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2007-08-06 11:08:57 +0100 |
---|---|---|
committer | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2007-08-06 11:08:57 +0100 |
commit | b12c493fd8591cd69825d97079e8590b3196d163 (patch) | |
tree | 9d5126ea1ad1413b9399a7f3c85cc1b91a6861aa | |
parent | f26a3dbc3640aeb728cff637f486927d5bf13777 (diff) | |
download | xen-b12c493fd8591cd69825d97079e8590b3196d163.tar.gz xen-b12c493fd8591cd69825d97079e8590b3196d163.tar.bz2 xen-b12c493fd8591cd69825d97079e8590b3196d163.zip |
hvm: Fix save/restore when callback_via line is routed through a PCI
INTx wire.
Signed-off-by: Edwin Zhai <edwin.zhai@intel.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r-- | xen/arch/x86/hvm/irq.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c index 6494ea8567..9212e93fe1 100644 --- a/xen/arch/x86/hvm/irq.c +++ b/xen/arch/x86/hvm/irq.c @@ -395,9 +395,33 @@ static void irq_dump(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 asserted, pdev, pintx; + int rc; + + spin_lock(&d->arch.hvm_domain.irq_lock); + + pdev = hvm_irq->callback_via.pci.dev; + pintx = hvm_irq->callback_via.pci.intx; + asserted = (hvm_irq->callback_via_asserted && + (hvm_irq->callback_via_type == HVMIRQ_callback_pci_intx)); + + /* + * Deassert virtual interrupt via PCI INTx line. The virtual interrupt + * status is not save/restored, so the INTx line must be deasserted in + * the restore context. + */ + if ( asserted ) + __hvm_pci_intx_deassert(d, pdev, pintx); /* Save PCI IRQ lines */ - return ( hvm_save_entry(PCI_IRQ, 0, h, &hvm_irq->pci_intx) ); + rc = hvm_save_entry(PCI_IRQ, 0, h, &hvm_irq->pci_intx); + + if ( asserted ) + __hvm_pci_intx_assert(d, pdev, pintx); + + spin_unlock(&d->arch.hvm_domain.irq_lock); + + return rc; } static int irq_save_isa(struct domain *d, hvm_domain_context_t *h) |