aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Stabellini <stefano.stabellini@eu.citrix.com>2010-06-24 11:42:04 -0400
committerStefano Stabellini <stefano.stabellini@eu.citrix.com>2010-10-22 16:25:41 -0400
commit42a1de56f35a9c87932f45439dc1b09c8da0cc95 (patch)
tree4be6a92222ef2efabd1705cd6b3adb7832f7f9a9
parent01557baff6e9c371d4c96e01089dca32cf347500 (diff)
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.c38
-rw-r--r--drivers/xen/events.c4
-rw-r--r--include/xen/interface/physdev.h30
3 files changed, 71 insertions, 1 deletions
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 4e371065ce41..08e3cdccdfa8 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -17,6 +17,44 @@
17#include <xen/events.h> 17#include <xen/events.h>
18#include <asm/xen/pci.h> 18#include <asm/xen/pci.h>
19 19
20#ifdef CONFIG_ACPI
21static int xen_hvm_register_pirq(u32 gsi, int triggering)
22{
23 int rc, irq;
24 struct physdev_map_pirq map_irq;
25 int shareable = 0;
26 char *name;
27
28 if (!xen_hvm_domain())
29 return -1;
30
31 map_irq.domid = DOMID_SELF;
32 map_irq.type = MAP_PIRQ_TYPE_GSI;
33 map_irq.index = gsi;
34 map_irq.pirq = -1;
35
36 rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq);
37 if (rc) {
38 printk(KERN_WARNING "xen map irq failed %d\n", rc);
39 return -1;
40 }
41
42 if (triggering == ACPI_EDGE_SENSITIVE) {
43 shareable = 0;
44 name = "ioapic-edge";
45 } else {
46 shareable = 1;
47 name = "ioapic-level";
48 }
49
50 irq = xen_map_pirq_gsi(map_irq.pirq, gsi, shareable, name);
51
52 printk(KERN_DEBUG "xen: --> irq=%d, pirq=%d\n", irq, map_irq.pirq);
53
54 return irq;
55}
56#endif
57
20#if defined(CONFIG_PCI_MSI) 58#if defined(CONFIG_PCI_MSI)
21#include <linux/msi.h> 59#include <linux/msi.h>
22 60
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 07e56e5a5d2d..239b011ef56f 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -36,6 +36,7 @@
36#include <asm/idle.h> 36#include <asm/idle.h>
37#include <asm/io_apic.h> 37#include <asm/io_apic.h>
38#include <asm/sync_bitops.h> 38#include <asm/sync_bitops.h>
39#include <asm/xen/pci.h>
39#include <asm/xen/hypercall.h> 40#include <asm/xen/hypercall.h>
40#include <asm/xen/hypervisor.h> 41#include <asm/xen/hypervisor.h>
41 42
@@ -75,7 +76,8 @@ enum xen_irq_type {
75 * event channel - irq->event channel mapping 76 * event channel - irq->event channel mapping
76 * cpu - cpu this event channel is bound to 77 * cpu - cpu this event channel is bound to
77 * index - type-specific information: 78 * index - type-specific information:
78 * PIRQ - vector, with MSB being "needs EIO" 79 * PIRQ - vector, with MSB being "needs EIO", or physical IRQ of the HVM
80 * guest, or GSI (real passthrough IRQ) of the device.
79 * VIRQ - virq number 81 * VIRQ - virq number
80 * IPI - IPI vector 82 * IPI - IPI vector
81 * EVTCHN - 83 * EVTCHN -
diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h
index fbb58833f13e..69a72b96a6cb 100644
--- a/include/xen/interface/physdev.h
+++ b/include/xen/interface/physdev.h
@@ -106,6 +106,36 @@ struct physdev_irq {
106 uint32_t vector; 106 uint32_t vector;
107}; 107};
108 108
109#define MAP_PIRQ_TYPE_MSI 0x0
110#define MAP_PIRQ_TYPE_GSI 0x1
111#define MAP_PIRQ_TYPE_UNKNOWN 0x2
112
113#define PHYSDEVOP_map_pirq 13
114struct physdev_map_pirq {
115 domid_t domid;
116 /* IN */
117 int type;
118 /* IN */
119 int index;
120 /* IN or OUT */
121 int pirq;
122 /* IN */
123 int bus;
124 /* IN */
125 int devfn;
126 /* IN */
127 int entry_nr;
128 /* IN */
129 uint64_t table_base;
130};
131
132#define PHYSDEVOP_unmap_pirq 14
133struct physdev_unmap_pirq {
134 domid_t domid;
135 /* IN */
136 int pirq;
137};
138
109/* 139/*
110 * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op() 140 * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
111 * hypercall since 0x00030202. 141 * hypercall since 0x00030202.