aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-04-14 11:17:36 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-04-14 11:17:36 -0400
commitbeafbdc1df02877612dc9039c1de0639921fddec (patch)
tree6103bd53db2858462c38bcf03b36eb7aad701576
parentc55fa78b13b32d3f19e19cd0c8b9378fdc09e521 (diff)
xen/irq: Check if the PCI device is owned by a domain different than DOMID_SELF.
We check if there is a domain owner for the PCI device. In case of failure (meaning no domain has registered for this device) we make DOMID_SELF the owner. Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> [v2: deal with rebasing on v2.6.37-1] [v3: deal with rebasing on stable/irq.cleanup] [v4: deal with rebasing on stable/irq.ween_of_nr_irqs] [v5: deal with rebasing on v2.6.39-rc3] Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> Acked-by: Xiantao Zhang <xiantao.zhang@intel.com>
-rw-r--r--arch/x86/pci/xen.c21
-rw-r--r--drivers/xen/events.c12
-rw-r--r--include/xen/events.h3
3 files changed, 26 insertions, 10 deletions
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 6075f2d65335..393981feb12f 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -108,7 +108,8 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
108 } 108 }
109 irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, 0, 109 irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, 0,
110 (type == PCI_CAP_ID_MSIX) ? 110 (type == PCI_CAP_ID_MSIX) ?
111 "msi-x" : "msi"); 111 "msi-x" : "msi",
112 DOMID_SELF);
112 if (irq < 0) 113 if (irq < 0)
113 goto error; 114 goto error;
114 dev_dbg(&dev->dev, 115 dev_dbg(&dev->dev,
@@ -148,7 +149,8 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
148 irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], 0, 149 irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], 0,
149 (type == PCI_CAP_ID_MSIX) ? 150 (type == PCI_CAP_ID_MSIX) ?
150 "pcifront-msi-x" : 151 "pcifront-msi-x" :
151 "pcifront-msi"); 152 "pcifront-msi",
153 DOMID_SELF);
152 if (irq < 0) 154 if (irq < 0)
153 goto free; 155 goto free;
154 i++; 156 i++;
@@ -190,9 +192,16 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
190 192
191 list_for_each_entry(msidesc, &dev->msi_list, list) { 193 list_for_each_entry(msidesc, &dev->msi_list, list) {
192 struct physdev_map_pirq map_irq; 194 struct physdev_map_pirq map_irq;
195 domid_t domid;
196
197 domid = ret = xen_find_device_domain_owner(dev);
198 /* N.B. Casting int's -ENODEV to uint16_t results in 0xFFED,
199 * hence check ret value for < 0. */
200 if (ret < 0)
201 domid = DOMID_SELF;
193 202
194 memset(&map_irq, 0, sizeof(map_irq)); 203 memset(&map_irq, 0, sizeof(map_irq));
195 map_irq.domid = DOMID_SELF; 204 map_irq.domid = domid;
196 map_irq.type = MAP_PIRQ_TYPE_MSI; 205 map_irq.type = MAP_PIRQ_TYPE_MSI;
197 map_irq.index = -1; 206 map_irq.index = -1;
198 map_irq.pirq = -1; 207 map_irq.pirq = -1;
@@ -215,14 +224,16 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
215 224
216 ret = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); 225 ret = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq);
217 if (ret) { 226 if (ret) {
218 dev_warn(&dev->dev, "xen map irq failed %d\n", ret); 227 dev_warn(&dev->dev, "xen map irq failed %d for %d domain\n",
228 ret, domid);
219 goto out; 229 goto out;
220 } 230 }
221 231
222 ret = xen_bind_pirq_msi_to_irq(dev, msidesc, 232 ret = xen_bind_pirq_msi_to_irq(dev, msidesc,
223 map_irq.pirq, map_irq.index, 233 map_irq.pirq, map_irq.index,
224 (type == PCI_CAP_ID_MSIX) ? 234 (type == PCI_CAP_ID_MSIX) ?
225 "msi-x" : "msi"); 235 "msi-x" : "msi",
236 domid);
226 if (ret < 0) 237 if (ret < 0)
227 goto out; 238 goto out;
228 } 239 }
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 42d6c930cc87..ac0e22826357 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -101,6 +101,7 @@ struct irq_info
101 unsigned short gsi; 101 unsigned short gsi;
102 unsigned char vector; 102 unsigned char vector;
103 unsigned char flags; 103 unsigned char flags;
104 uint16_t domid;
104 } pirq; 105 } pirq;
105 } u; 106 } u;
106}; 107};
@@ -184,6 +185,7 @@ static void xen_irq_info_pirq_init(unsigned irq,
184 unsigned short pirq, 185 unsigned short pirq,
185 unsigned short gsi, 186 unsigned short gsi,
186 unsigned short vector, 187 unsigned short vector,
188 uint16_t domid,
187 unsigned char flags) 189 unsigned char flags)
188{ 190{
189 struct irq_info *info = info_for_irq(irq); 191 struct irq_info *info = info_for_irq(irq);
@@ -193,6 +195,7 @@ static void xen_irq_info_pirq_init(unsigned irq,
193 info->u.pirq.pirq = pirq; 195 info->u.pirq.pirq = pirq;
194 info->u.pirq.gsi = gsi; 196 info->u.pirq.gsi = gsi;
195 info->u.pirq.vector = vector; 197 info->u.pirq.vector = vector;
198 info->u.pirq.domid = domid;
196 info->u.pirq.flags = flags; 199 info->u.pirq.flags = flags;
197} 200}
198 201
@@ -655,7 +658,7 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
655 goto out; 658 goto out;
656 } 659 }
657 660
658 xen_irq_info_pirq_init(irq, 0, pirq, gsi, irq_op.vector, 661 xen_irq_info_pirq_init(irq, 0, pirq, gsi, irq_op.vector, DOMID_SELF,
659 shareable ? PIRQ_SHAREABLE : 0); 662 shareable ? PIRQ_SHAREABLE : 0);
660 663
661out: 664out:
@@ -680,7 +683,8 @@ int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc)
680} 683}
681 684
682int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, 685int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
683 int pirq, int vector, const char *name) 686 int pirq, int vector, const char *name,
687 domid_t domid)
684{ 688{
685 int irq, ret; 689 int irq, ret;
686 690
@@ -693,7 +697,7 @@ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
693 irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_level_irq, 697 irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_level_irq,
694 name); 698 name);
695 699
696 xen_irq_info_pirq_init(irq, 0, pirq, 0, vector, 0); 700 xen_irq_info_pirq_init(irq, 0, pirq, 0, vector, domid, 0);
697 ret = irq_set_msi_desc(irq, msidesc); 701 ret = irq_set_msi_desc(irq, msidesc);
698 if (ret < 0) 702 if (ret < 0)
699 goto error_irq; 703 goto error_irq;
@@ -722,7 +726,7 @@ int xen_destroy_irq(int irq)
722 726
723 if (xen_initial_domain()) { 727 if (xen_initial_domain()) {
724 unmap_irq.pirq = info->u.pirq.pirq; 728 unmap_irq.pirq = info->u.pirq.pirq;
725 unmap_irq.domid = DOMID_SELF; 729 unmap_irq.domid = info->u.pirq.domid;
726 rc = HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap_irq); 730 rc = HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap_irq);
727 if (rc) { 731 if (rc) {
728 printk(KERN_WARNING "unmap irq failed %d\n", rc); 732 printk(KERN_WARNING "unmap irq failed %d\n", rc);
diff --git a/include/xen/events.h b/include/xen/events.h
index f1b87ad48ac7..9aecc0b5a0e6 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -85,7 +85,8 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
85int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc); 85int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc);
86/* Bind an PSI pirq to an irq. */ 86/* Bind an PSI pirq to an irq. */
87int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc, 87int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
88 int pirq, int vector, const char *name); 88 int pirq, int vector, const char *name,
89 domid_t domid);
89#endif 90#endif
90 91
91/* De-allocates the above mentioned physical interrupt. */ 92/* De-allocates the above mentioned physical interrupt. */