The allocation of IRQ numbers in Linux privileged domains is based
on finding the first unbound IRQ number. After the allocation is done
a HYPERCALL to Xen is done, which allocates a PIRQ globally.
That PIRQ->IRQ binding is saved in data structures that are used
during ISR executions.
Before this patch, for non-privileged domains we would return the local
IRQ number instead of the PIRQ. The non-privileged domains require the
PIRQ so that they can attach the their own interrupt handler to it.
Fortunatly there is a function, 'xen_gsi_from_irq' that returns
that global IRQ number.
This has been succesfully tested with MSI devices. I hadn't tested it
with MSI-X yet.
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
---
 drivers/xen/pciback/conf_space_capability_msi.c |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/xen/pciback/conf_space_capability_msi.c 
b/drivers/xen/pciback/conf_space_capability_msi.c
index 762e396..7fb5371 100644
--- a/drivers/xen/pciback/conf_space_capability_msi.c
+++ b/drivers/xen/pciback/conf_space_capability_msi.c
@@ -6,6 +6,7 @@
 #include "conf_space.h"
 #include "conf_space_capability.h"
 #include <xen/interface/io/pciif.h>
+#include <xen/events.h>
 #include "pciback.h"
 
 int pciback_enable_msi(struct pciback_device *pdev,
@@ -22,7 +23,9 @@ int pciback_enable_msi(struct pciback_device *pdev,
                return XEN_PCI_ERR_op_failed;
        }
 
-       op->value = dev->irq;
+       /* The value the guest needs is actually the IDT vector, not the
+        * the local domain's IRQ number. */
+       op->value = xen_gsi_from_irq(dev->irq);
        return 0;
 }
 
@@ -31,7 +34,7 @@ int pciback_disable_msi(struct pciback_device *pdev,
 {
        pci_disable_msi(dev);
 
-       op->value = dev->irq;
+       op->value = xen_gsi_from_irq(dev->irq);
        return 0;
 }
 
@@ -57,7 +60,8 @@ int pciback_enable_msix(struct pciback_device *pdev,
 
        for (i = 0; i < op->value; i++) {
                op->msix_entries[i].entry = entries[i].entry;
-               op->msix_entries[i].vector = entries[i].vector;
+               op->msix_entries[i].vector =
+                                       xen_gsi_from_irq(entries[i].vector);
        }
 
        kfree(entries);
@@ -73,7 +77,7 @@ int pciback_disable_msix(struct pciback_device *pdev,
 
        pci_disable_msix(dev);
 
-       op->value = dev->irq;
+       op->value = xen_gsi_from_irq(dev->irq);
        return 0;
 }
 
-- 
1.6.2.5
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
 |