aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/hvm/irq.c
diff options
context:
space:
mode:
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-08-06 11:08:57 +0100
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>2007-08-06 11:08:57 +0100
commitb12c493fd8591cd69825d97079e8590b3196d163 (patch)
tree9d5126ea1ad1413b9399a7f3c85cc1b91a6861aa /xen/arch/x86/hvm/irq.c
parentf26a3dbc3640aeb728cff637f486927d5bf13777 (diff)
downloadxen-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>
Diffstat (limited to 'xen/arch/x86/hvm/irq.c')
-rw-r--r--xen/arch/x86/hvm/irq.c26
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)