aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/x86/msi.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2012-09-07 17:57:10 +0200
committerJan Beulich <jbeulich@suse.com>2012-09-07 17:57:10 +0200
commit42599de39a98fd826b6b6bac0738a8a0d9df18fe (patch)
tree612a3969fbcedff8a01aaaaf59ff70a471824ae4 /xen/arch/x86/msi.c
parent7a9d7646307b7c872b8dbd7546579acd3b54223d (diff)
downloadxen-42599de39a98fd826b6b6bac0738a8a0d9df18fe.tar.gz
xen-42599de39a98fd826b6b6bac0738a8a0d9df18fe.tar.bz2
xen-42599de39a98fd826b6b6bac0738a8a0d9df18fe.zip
x86/MSI: fix 2nd S3 resume with interrupt remapping enabled
The first resume from S3 was corrupting internal data structures (in that pci_restore_msi_state() updated the globally stored MSI message from traditional to interrupt remapped format, which would then be translated a second time during the second resume, breaking interrupt delivery). Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'xen/arch/x86/msi.c')
-rw-r--r--xen/arch/x86/msi.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
index 782b84b0fd..f982c45df8 100644
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -210,7 +210,10 @@ static void write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
entry->msg = *msg;
if ( iommu_enabled )
+ {
+ ASSERT(msg != &entry->msg);
iommu_update_ire_from_msi(entry, msg);
+ }
switch ( entry->msi_attrib.type )
{
@@ -996,6 +999,7 @@ int pci_restore_msi_state(struct pci_dev *pdev)
int ret;
struct msi_desc *entry, *tmp;
struct irq_desc *desc;
+ struct msi_msg msg;
ASSERT(spin_is_locked(&pcidevs_lock));
@@ -1030,7 +1034,8 @@ int pci_restore_msi_state(struct pci_dev *pdev)
else if ( entry->msi_attrib.type == PCI_CAP_ID_MSIX )
msix_set_enable(pdev, 0);
- write_msi_msg(entry, &entry->msg);
+ msg = entry->msg;
+ write_msi_msg(entry, &msg);
msi_set_mask_bit(desc, entry->msi_attrib.masked);