diff options
author | Stefano Stabellini <stefano.stabellini@eu.citrix.com> | 2010-06-24 16:42:04 +0100 |
---|---|---|
committer | Stefano Stabellini <stefano.stabellini@eu.citrix.com> | 2010-10-22 21:25:41 +0100 |
commit | 42a1de56f35a9c87932f45439dc1b09c8da0cc95 (patch) | |
tree | 4be6a92222ef2efabd1705cd6b3adb7832f7f9a9 | |
parent | 01557baff6e9c371d4c96e01089dca32cf347500 (diff) | |
download | op-kernel-dev-42a1de56f35a9c87932f45439dc1b09c8da0cc95.zip op-kernel-dev-42a1de56f35a9c87932f45439dc1b09c8da0cc95.tar.gz |
xen: implement xen_hvm_register_pirq
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@eu.citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-rw-r--r-- | arch/x86/pci/xen.c | 38 | ||||
-rw-r--r-- | drivers/xen/events.c | 4 | ||||
-rw-r--r-- | include/xen/interface/physdev.h | 30 |
3 files changed, 71 insertions, 1 deletions
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 4e37106..08e3cdc 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -17,6 +17,44 @@ #include <xen/events.h> #include <asm/xen/pci.h> +#ifdef CONFIG_ACPI +static 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; +} +#endif + #if defined(CONFIG_PCI_MSI) #include <linux/msi.h> diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 07e56e5..239b011 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. |