1 From: jbeulich@novell.com
2 Subject: fix Dom0 resume from S3 when MSI is in use
3 Patch-mainline: obsolete
6 --- sle11-2009-04-20.orig/drivers/pci/msi-xen.c 2009-01-09 11:10:27.000000000 +0100
7 +++ sle11-2009-04-20/drivers/pci/msi-xen.c 2009-04-24 13:37:37.000000000 +0200
8 @@ -234,8 +234,8 @@ static int msi_unmap_pirq(struct pci_dev
11 unmap.domid = msi_get_dev_owner(dev);
12 - /* See comments in msi_map_pirq_to_vector, input parameter pirq
13 - * mean irq number only if the device belongs to dom0 itself.
14 + /* See comments in msi_map_vector, input parameter pirq means
15 + * irq number only if the device belongs to dom0 itself.
17 unmap.pirq = (unmap.domid != DOMID_SELF)
18 ? pirq : evtchn_get_xen_pirq(pirq);
19 @@ -271,8 +271,7 @@ static u64 find_table_base(struct pci_de
21 * Protected by msi_lock
23 -static int msi_map_pirq_to_vector(struct pci_dev *dev, int pirq,
24 - int entry_nr, u64 table_base)
25 +static int msi_map_vector(struct pci_dev *dev, int entry_nr, u64 table_base)
27 struct physdev_map_pirq map_irq;
29 @@ -283,7 +282,7 @@ static int msi_map_pirq_to_vector(struct
30 map_irq.domid = domid;
31 map_irq.type = MAP_PIRQ_TYPE_MSI;
33 - map_irq.pirq = pirq < 0 ? -1 : evtchn_get_xen_pirq(pirq);
35 map_irq.bus = dev->bus->number;
36 map_irq.devfn = dev->devfn;
37 map_irq.entry_nr = entry_nr;
38 @@ -294,7 +293,7 @@ static int msi_map_pirq_to_vector(struct
42 - /* This happens when MSI support is not enabled in Xen. */
43 + /* This happens when MSI support is not enabled in older Xen. */
44 if (rc == 0 && map_irq.pirq < 0)
47 @@ -306,12 +305,7 @@ static int msi_map_pirq_to_vector(struct
48 * to another domain, and will be 'Linux irq' if it belongs to dom0.
50 return ((domid != DOMID_SELF) ?
51 - map_irq.pirq : evtchn_map_pirq(pirq, map_irq.pirq));
54 -static int msi_map_vector(struct pci_dev *dev, int entry_nr, u64 table_base)
56 - return msi_map_pirq_to_vector(dev, -1, entry_nr, table_base);
57 + map_irq.pirq : evtchn_map_pirq(-1, map_irq.pirq));
60 static void pci_intx_for_msi(struct pci_dev *dev, int enable)
61 @@ -320,62 +314,24 @@ static void pci_intx_for_msi(struct pci_
62 pci_intx(dev, enable);
65 -static void __pci_restore_msi_state(struct pci_dev *dev)
69 - if (!dev->msi_enabled)
72 - pci_intx_for_msi(dev, 0);
73 - msi_set_enable(dev, 0);
75 - pirq = msi_map_pirq_to_vector(dev, dev->irq, 0, 0);
80 -static void __pci_restore_msix_state(struct pci_dev *dev)
81 +void pci_restore_msi_state(struct pci_dev *dev)
84 - unsigned long flags;
86 - struct msi_dev_list *msi_dev_entry;
87 - struct msi_pirq_entry *pirq_entry, *tmp;
89 + struct physdev_restore_msi restore;
91 - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
95 - if (!dev->msix_enabled)
96 + if (!dev->msi_enabled && !dev->msix_enabled)
99 pci_intx_for_msi(dev, 0);
100 - msix_set_enable(dev, 0);
102 - msi_dev_entry = get_msi_dev_pirq_list(dev);
103 - table_base = find_table_base(dev, pos);
107 - spin_lock_irqsave(&msi_dev_entry->pirq_list_lock, flags);
108 - list_for_each_entry_safe(pirq_entry, tmp,
109 - &msi_dev_entry->pirq_list_head, list) {
110 - int rc = msi_map_pirq_to_vector(dev, pirq_entry->pirq,
111 - pirq_entry->entry_nr, table_base);
113 - printk(KERN_WARNING
114 - "%s: re-mapping irq #%d (pirq%d) failed: %d\n",
115 - pci_name(dev), pirq_entry->entry_nr,
116 - pirq_entry->pirq, rc);
118 - spin_unlock_irqrestore(&msi_dev_entry->pirq_list_lock, flags);
121 -void pci_restore_msi_state(struct pci_dev *dev)
123 - __pci_restore_msi_state(dev);
124 - __pci_restore_msix_state(dev);
125 + if (dev->msi_enabled)
126 + msi_set_enable(dev, 0);
127 + if (dev->msix_enabled)
128 + msix_set_enable(dev, 0);
130 + restore.bus = dev->bus->number;
131 + restore.devfn = dev->devfn;
132 + rc = HYPERVISOR_physdev_op(PHYSDEVOP_restore_msi, &restore);
133 + WARN(rc && rc != -ENOSYS, "restore_msi -> %d\n", rc);
135 EXPORT_SYMBOL_GPL(pci_restore_msi_state);
137 --- sle11-2009-04-20.orig/include/xen/interface/physdev.h 2009-04-24 13:28:45.000000000 +0200
138 +++ sle11-2009-04-20/include/xen/interface/physdev.h 2009-01-05 15:11:37.000000000 +0100
139 @@ -183,6 +183,15 @@ struct physdev_manage_pci {
140 typedef struct physdev_manage_pci physdev_manage_pci_t;
141 DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_t);
143 +#define PHYSDEVOP_restore_msi 19
144 +struct physdev_restore_msi {
149 +typedef struct physdev_restore_msi physdev_restore_msi_t;
150 +DEFINE_XEN_GUEST_HANDLE(physdev_restore_msi_t);
153 * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
154 * hypercall since 0x00030202.