|
70 | 70 | #undef MODULE_PARAM_PREFIX |
71 | 71 | #define MODULE_PARAM_PREFIX "xen." |
72 | 72 |
|
| 73 | +/* Interrupt types. */ |
| 74 | +enum xen_irq_type { |
| 75 | + IRQT_UNBOUND = 0, |
| 76 | + IRQT_PIRQ, |
| 77 | + IRQT_VIRQ, |
| 78 | + IRQT_IPI, |
| 79 | + IRQT_EVTCHN |
| 80 | +}; |
| 81 | + |
| 82 | +/* |
| 83 | + * Packed IRQ information: |
| 84 | + * type - enum xen_irq_type |
| 85 | + * event channel - irq->event channel mapping |
| 86 | + * cpu - cpu this event channel is bound to |
| 87 | + * index - type-specific information: |
| 88 | + * PIRQ - vector, with MSB being "needs EIO", or physical IRQ of the HVM |
| 89 | + * guest, or GSI (real passthrough IRQ) of the device. |
| 90 | + * VIRQ - virq number |
| 91 | + * IPI - IPI vector |
| 92 | + * EVTCHN - |
| 93 | + */ |
| 94 | +struct irq_info { |
| 95 | + struct list_head list; |
| 96 | + struct list_head eoi_list; |
| 97 | + short refcnt; |
| 98 | + short spurious_cnt; |
| 99 | + enum xen_irq_type type; /* type */ |
| 100 | + unsigned irq; |
| 101 | + evtchn_port_t evtchn; /* event channel */ |
| 102 | + unsigned short cpu; /* cpu bound */ |
| 103 | + unsigned short eoi_cpu; /* EOI must happen on this cpu-1 */ |
| 104 | + unsigned int irq_epoch; /* If eoi_cpu valid: irq_epoch of event */ |
| 105 | + u64 eoi_time; /* Time in jiffies when to EOI. */ |
| 106 | + |
| 107 | + union { |
| 108 | + unsigned short virq; |
| 109 | + enum ipi_vector ipi; |
| 110 | + struct { |
| 111 | + unsigned short pirq; |
| 112 | + unsigned short gsi; |
| 113 | + unsigned char vector; |
| 114 | + unsigned char flags; |
| 115 | + uint16_t domid; |
| 116 | + } pirq; |
| 117 | + } u; |
| 118 | +}; |
| 119 | + |
| 120 | +#define PIRQ_NEEDS_EOI (1 << 0) |
| 121 | +#define PIRQ_SHAREABLE (1 << 1) |
| 122 | +#define PIRQ_MSI_GROUP (1 << 2) |
| 123 | + |
73 | 124 | static uint __read_mostly event_loop_timeout = 2; |
74 | 125 | module_param(event_loop_timeout, uint, 0644); |
75 | 126 |
|
@@ -110,7 +161,7 @@ static DEFINE_PER_CPU(int [NR_VIRQS], virq_to_irq) = {[0 ... NR_VIRQS-1] = -1}; |
110 | 161 | /* IRQ <-> IPI mapping */ |
111 | 162 | static DEFINE_PER_CPU(int [XEN_NR_IPIS], ipi_to_irq) = {[0 ... XEN_NR_IPIS-1] = -1}; |
112 | 163 |
|
113 | | -int **evtchn_to_irq; |
| 164 | +static int **evtchn_to_irq; |
114 | 165 | #ifdef CONFIG_X86 |
115 | 166 | static unsigned long *pirq_eoi_map; |
116 | 167 | #endif |
@@ -190,7 +241,7 @@ int get_evtchn_to_irq(evtchn_port_t evtchn) |
190 | 241 | } |
191 | 242 |
|
192 | 243 | /* Get info for IRQ */ |
193 | | -struct irq_info *info_for_irq(unsigned irq) |
| 244 | +static struct irq_info *info_for_irq(unsigned irq) |
194 | 245 | { |
195 | 246 | if (irq < nr_legacy_irqs()) |
196 | 247 | return legacy_info_ptrs[irq]; |
@@ -228,7 +279,7 @@ static int xen_irq_info_common_setup(struct irq_info *info, |
228 | 279 |
|
229 | 280 | irq_clear_status_flags(irq, IRQ_NOREQUEST|IRQ_NOAUTOEN); |
230 | 281 |
|
231 | | - return xen_evtchn_port_setup(info); |
| 282 | + return xen_evtchn_port_setup(evtchn); |
232 | 283 | } |
233 | 284 |
|
234 | 285 | static int xen_irq_info_evtchn_setup(unsigned irq, |
@@ -351,7 +402,7 @@ static enum xen_irq_type type_from_irq(unsigned irq) |
351 | 402 | return info_for_irq(irq)->type; |
352 | 403 | } |
353 | 404 |
|
354 | | -unsigned cpu_from_irq(unsigned irq) |
| 405 | +static unsigned cpu_from_irq(unsigned irq) |
355 | 406 | { |
356 | 407 | return info_for_irq(irq)->cpu; |
357 | 408 | } |
@@ -391,7 +442,7 @@ static void bind_evtchn_to_cpu(evtchn_port_t evtchn, unsigned int cpu) |
391 | 442 | #ifdef CONFIG_SMP |
392 | 443 | cpumask_copy(irq_get_affinity_mask(irq), cpumask_of(cpu)); |
393 | 444 | #endif |
394 | | - xen_evtchn_port_bind_to_cpu(info, cpu); |
| 445 | + xen_evtchn_port_bind_to_cpu(evtchn, cpu, info->cpu); |
395 | 446 |
|
396 | 447 | info->cpu = cpu; |
397 | 448 | } |
@@ -745,7 +796,7 @@ static unsigned int __startup_pirq(unsigned int irq) |
745 | 796 | info->evtchn = evtchn; |
746 | 797 | bind_evtchn_to_cpu(evtchn, 0); |
747 | 798 |
|
748 | | - rc = xen_evtchn_port_setup(info); |
| 799 | + rc = xen_evtchn_port_setup(evtchn); |
749 | 800 | if (rc) |
750 | 801 | goto err; |
751 | 802 |
|
@@ -1145,14 +1196,6 @@ static int bind_interdomain_evtchn_to_irq_chip(unsigned int remote_domain, |
1145 | 1196 | chip); |
1146 | 1197 | } |
1147 | 1198 |
|
1148 | | -int bind_interdomain_evtchn_to_irq(unsigned int remote_domain, |
1149 | | - evtchn_port_t remote_port) |
1150 | | -{ |
1151 | | - return bind_interdomain_evtchn_to_irq_chip(remote_domain, remote_port, |
1152 | | - &xen_dynamic_chip); |
1153 | | -} |
1154 | | -EXPORT_SYMBOL_GPL(bind_interdomain_evtchn_to_irq); |
1155 | | - |
1156 | 1199 | int bind_interdomain_evtchn_to_irq_lateeoi(unsigned int remote_domain, |
1157 | 1200 | evtchn_port_t remote_port) |
1158 | 1201 | { |
@@ -1320,19 +1363,6 @@ static int bind_interdomain_evtchn_to_irqhandler_chip( |
1320 | 1363 | return irq; |
1321 | 1364 | } |
1322 | 1365 |
|
1323 | | -int bind_interdomain_evtchn_to_irqhandler(unsigned int remote_domain, |
1324 | | - evtchn_port_t remote_port, |
1325 | | - irq_handler_t handler, |
1326 | | - unsigned long irqflags, |
1327 | | - const char *devname, |
1328 | | - void *dev_id) |
1329 | | -{ |
1330 | | - return bind_interdomain_evtchn_to_irqhandler_chip(remote_domain, |
1331 | | - remote_port, handler, irqflags, devname, |
1332 | | - dev_id, &xen_dynamic_chip); |
1333 | | -} |
1334 | | -EXPORT_SYMBOL_GPL(bind_interdomain_evtchn_to_irqhandler); |
1335 | | - |
1336 | 1366 | int bind_interdomain_evtchn_to_irqhandler_lateeoi(unsigned int remote_domain, |
1337 | 1367 | evtchn_port_t remote_port, |
1338 | 1368 | irq_handler_t handler, |
@@ -2020,8 +2050,8 @@ void xen_setup_callback_vector(void) {} |
2020 | 2050 | static inline void xen_alloc_callback_vector(void) {} |
2021 | 2051 | #endif |
2022 | 2052 |
|
2023 | | -static bool fifo_events = true; |
2024 | | -module_param(fifo_events, bool, 0); |
| 2053 | +bool xen_fifo_events = true; |
| 2054 | +module_param_named(fifo_events, xen_fifo_events, bool, 0); |
2025 | 2055 |
|
2026 | 2056 | static int xen_evtchn_cpu_prepare(unsigned int cpu) |
2027 | 2057 | { |
@@ -2050,10 +2080,12 @@ void __init xen_init_IRQ(void) |
2050 | 2080 | int ret = -EINVAL; |
2051 | 2081 | evtchn_port_t evtchn; |
2052 | 2082 |
|
2053 | | - if (fifo_events) |
| 2083 | + if (xen_fifo_events) |
2054 | 2084 | ret = xen_evtchn_fifo_init(); |
2055 | | - if (ret < 0) |
| 2085 | + if (ret < 0) { |
2056 | 2086 | xen_evtchn_2l_init(); |
| 2087 | + xen_fifo_events = false; |
| 2088 | + } |
2057 | 2089 |
|
2058 | 2090 | xen_cpu_init_eoi(smp_processor_id()); |
2059 | 2091 |
|
|
0 commit comments