Commit 42a1de56 authored by Stefano Stabellini's avatar Stefano Stabellini

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: default avatarStefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
parent 01557baf
...@@ -17,6 +17,44 @@ ...@@ -17,6 +17,44 @@
#include <xen/events.h> #include <xen/events.h>
#include <asm/xen/pci.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) #if defined(CONFIG_PCI_MSI)
#include <linux/msi.h> #include <linux/msi.h>
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <asm/idle.h> #include <asm/idle.h>
#include <asm/io_apic.h> #include <asm/io_apic.h>
#include <asm/sync_bitops.h> #include <asm/sync_bitops.h>
#include <asm/xen/pci.h>
#include <asm/xen/hypercall.h> #include <asm/xen/hypercall.h>
#include <asm/xen/hypervisor.h> #include <asm/xen/hypervisor.h>
...@@ -75,7 +76,8 @@ enum xen_irq_type { ...@@ -75,7 +76,8 @@ enum xen_irq_type {
* event channel - irq->event channel mapping * event channel - irq->event channel mapping
* cpu - cpu this event channel is bound to * cpu - cpu this event channel is bound to
* index - type-specific information: * 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 * VIRQ - virq number
* IPI - IPI vector * IPI - IPI vector
* EVTCHN - * EVTCHN -
......
...@@ -106,6 +106,36 @@ struct physdev_irq { ...@@ -106,6 +106,36 @@ struct physdev_irq {
uint32_t vector; 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() * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
* hypercall since 0x00030202. * hypercall since 0x00030202.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment