WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 3/7] xen: implement xen_hvm_register_pirq

From: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>

xen_hvm_register_pirq allows the kernel to map a GSI into a Xen pirq and
receive the interrupt as an event channel from that point on.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
---
 arch/x86/include/asm/xen/pci.h  |    5 +++++
 arch/x86/pci/xen.c              |   36 ++++++++++++++++++++++++++++++++++++
 drivers/xen/events.c            |    4 +++-
 include/xen/interface/physdev.h |   30 ++++++++++++++++++++++++++++++
 4 files changed, 74 insertions(+), 1 deletions(-)

diff --git a/arch/x86/include/asm/xen/pci.h b/arch/x86/include/asm/xen/pci.h
index 449c82f..b4d908b 100644
--- a/arch/x86/include/asm/xen/pci.h
+++ b/arch/x86/include/asm/xen/pci.h
@@ -3,10 +3,15 @@
 
 #if defined(CONFIG_PCI_XEN)
 extern int __init pci_xen_init(void);
+int xen_hvm_register_pirq(u32 gsi, int triggering);
 #define pci_xen 1
 #else
 #define pci_xen 0
 #define pci_xen_init (0)
+static inline int xen_hvm_register_pirq(u32 gsi, int triggering)
+{
+       return -1;
+}
 #endif
 
 #if defined(CONFIG_PCI_MSI)
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index b19c873..d6fd58f 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -17,6 +17,42 @@
 #include <xen/events.h>
 #include <asm/xen/pci.h>
 
+int xen_hvm_register_pirq(u32 gsi, int triggering)
+{
+       int rc, irq;
+       struct physdev_map_pirq map_irq;
+       int shareable = 0;
+       char *name;
+
+       if (!xen_hvm_domain())
+               return -1;
+
+       map_irq.domid = DOMID_SELF;
+       map_irq.type = MAP_PIRQ_TYPE_GSI;
+       map_irq.index = gsi;
+       map_irq.pirq = -1;
+
+       rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq);
+       if (rc) {
+               printk(KERN_WARNING "xen map irq failed %d\n", rc);
+               return -1;
+       }
+
+       if (triggering == ACPI_EDGE_SENSITIVE) {
+               shareable = 0;
+               name = "ioapic-edge";
+       } else {
+               shareable = 1;
+               name = "ioapic-level";
+       }
+
+       irq = xen_map_pirq_gsi(map_irq.pirq, gsi, shareable, name);
+
+       printk(KERN_DEBUG "xen: --> irq=%d, pirq=%d\n", irq, map_irq.pirq);
+
+       return irq;
+}
+
 #if defined(CONFIG_PCI_MSI)
 #include <linux/msi.h>
 
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index aca7230..302dad1 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -36,6 +36,7 @@
 #include <asm/idle.h>
 #include <asm/io_apic.h>
 #include <asm/sync_bitops.h>
+#include <asm/xen/pci.h>
 #include <asm/xen/hypercall.h>
 #include <asm/xen/hypervisor.h>
 
@@ -75,7 +76,8 @@ enum xen_irq_type {
  * event channel - irq->event channel mapping
  * cpu - cpu this event channel is bound to
  * index - type-specific information:
- *    PIRQ - vector, with MSB being "needs EIO"
+ *    PIRQ - vector, with MSB being "needs EIO", or physical IRQ of the HVM
+ *           guest, or GSI (real passthrough IRQ) of the device.
  *    VIRQ - virq number
  *    IPI - IPI vector
  *    EVTCHN -
diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h
index fbb5883..69a72b9 100644
--- a/include/xen/interface/physdev.h
+++ b/include/xen/interface/physdev.h
@@ -106,6 +106,36 @@ struct physdev_irq {
        uint32_t vector;
 };
 
+#define MAP_PIRQ_TYPE_MSI              0x0
+#define MAP_PIRQ_TYPE_GSI              0x1
+#define MAP_PIRQ_TYPE_UNKNOWN          0x2
+
+#define PHYSDEVOP_map_pirq             13
+struct physdev_map_pirq {
+    domid_t domid;
+    /* IN */
+    int type;
+    /* IN */
+    int index;
+    /* IN or OUT */
+    int pirq;
+    /* IN */
+    int bus;
+    /* IN */
+    int devfn;
+    /* IN */
+    int entry_nr;
+    /* IN */
+    uint64_t table_base;
+};
+
+#define PHYSDEVOP_unmap_pirq           14
+struct physdev_unmap_pirq {
+    domid_t domid;
+    /* IN */
+    int pirq;
+};
+
 /*
  * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
  * hypercall since 0x00030202.
-- 
1.5.6.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel