diff options
-rw-r--r-- | drivers/xen/events.c | 30 | ||||
-rw-r--r-- | include/xen/interface/physdev.h | 6 |
2 files changed, 32 insertions, 4 deletions
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 018a96275ee4..07e56e5a5d2d 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -102,6 +102,7 @@ struct irq_info | |||
102 | 102 | ||
103 | static struct irq_info *irq_info; | 103 | static struct irq_info *irq_info; |
104 | static int *pirq_to_irq; | 104 | static int *pirq_to_irq; |
105 | static int nr_pirqs; | ||
105 | 106 | ||
106 | static int *evtchn_to_irq; | 107 | static int *evtchn_to_irq; |
107 | struct cpu_evtchn_s { | 108 | struct cpu_evtchn_s { |
@@ -378,10 +379,12 @@ static int get_nr_hw_irqs(void) | |||
378 | return ret; | 379 | return ret; |
379 | } | 380 | } |
380 | 381 | ||
382 | /* callers of this function should make sure that PHYSDEVOP_get_nr_pirqs | ||
383 | * succeeded otherwise nr_pirqs won't hold the right value */ | ||
381 | static int find_unbound_pirq(void) | 384 | static int find_unbound_pirq(void) |
382 | { | 385 | { |
383 | int i; | 386 | int i; |
384 | for (i = 0; i < nr_irqs; i++) { | 387 | for (i = nr_pirqs-1; i >= 0; i--) { |
385 | if (pirq_to_irq[i] < 0) | 388 | if (pirq_to_irq[i] < 0) |
386 | return i; | 389 | return i; |
387 | } | 390 | } |
@@ -602,6 +605,13 @@ int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name) | |||
602 | 605 | ||
603 | spin_lock(&irq_mapping_update_lock); | 606 | spin_lock(&irq_mapping_update_lock); |
604 | 607 | ||
608 | if ((pirq > nr_pirqs) || (gsi > nr_irqs)) { | ||
609 | printk(KERN_WARNING "xen_map_pirq_gsi: %s %s is incorrect!\n", | ||
610 | pirq > nr_pirqs ? "nr_pirqs" :"", | ||
611 | gsi > nr_irqs ? "nr_irqs" : ""); | ||
612 | goto out; | ||
613 | } | ||
614 | |||
605 | irq = find_irq_by_gsi(gsi); | 615 | irq = find_irq_by_gsi(gsi); |
606 | if (irq != -1) { | 616 | if (irq != -1) { |
607 | printk(KERN_INFO "xen_map_pirq_gsi: returning irq %d for gsi %u\n", | 617 | printk(KERN_INFO "xen_map_pirq_gsi: returning irq %d for gsi %u\n", |
@@ -1349,14 +1359,26 @@ void xen_callback_vector(void) {} | |||
1349 | 1359 | ||
1350 | void __init xen_init_IRQ(void) | 1360 | void __init xen_init_IRQ(void) |
1351 | { | 1361 | { |
1352 | int i; | 1362 | int i, rc; |
1363 | struct physdev_nr_pirqs op_nr_pirqs; | ||
1353 | 1364 | ||
1354 | cpu_evtchn_mask_p = kcalloc(nr_cpu_ids, sizeof(struct cpu_evtchn_s), | 1365 | cpu_evtchn_mask_p = kcalloc(nr_cpu_ids, sizeof(struct cpu_evtchn_s), |
1355 | GFP_KERNEL); | 1366 | GFP_KERNEL); |
1356 | irq_info = kcalloc(nr_irqs, sizeof(*irq_info), GFP_KERNEL); | 1367 | irq_info = kcalloc(nr_irqs, sizeof(*irq_info), GFP_KERNEL); |
1357 | 1368 | ||
1358 | pirq_to_irq = kcalloc(nr_irqs, sizeof(*pirq_to_irq), GFP_KERNEL); | 1369 | rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_nr_pirqs, &op_nr_pirqs); |
1359 | for (i = 0; i < nr_irqs; i++) | 1370 | if (rc < 0) { |
1371 | nr_pirqs = nr_irqs; | ||
1372 | if (rc != -ENOSYS) | ||
1373 | printk(KERN_WARNING "PHYSDEVOP_get_nr_pirqs returned rc=%d\n", rc); | ||
1374 | } else { | ||
1375 | if (xen_pv_domain() && !xen_initial_domain()) | ||
1376 | nr_pirqs = max((int)op_nr_pirqs.nr_pirqs, nr_irqs); | ||
1377 | else | ||
1378 | nr_pirqs = op_nr_pirqs.nr_pirqs; | ||
1379 | } | ||
1380 | pirq_to_irq = kcalloc(nr_pirqs, sizeof(*pirq_to_irq), GFP_KERNEL); | ||
1381 | for (i = 0; i < nr_pirqs; i++) | ||
1360 | pirq_to_irq[i] = -1; | 1382 | pirq_to_irq[i] = -1; |
1361 | 1383 | ||
1362 | evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq), | 1384 | evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq), |
diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h index cd6939147cb6..fbb58833f13e 100644 --- a/include/xen/interface/physdev.h +++ b/include/xen/interface/physdev.h | |||
@@ -121,6 +121,12 @@ struct physdev_op { | |||
121 | } u; | 121 | } u; |
122 | }; | 122 | }; |
123 | 123 | ||
124 | #define PHYSDEVOP_get_nr_pirqs 22 | ||
125 | struct physdev_nr_pirqs { | ||
126 | /* OUT */ | ||
127 | uint32_t nr_pirqs; | ||
128 | }; | ||
129 | |||
124 | /* | 130 | /* |
125 | * Notify that some PIRQ-bound event channels have been unmasked. | 131 | * Notify that some PIRQ-bound event channels have been unmasked. |
126 | * ** This command is obsolete since interface version 0x00030202 and is ** | 132 | * ** This command is obsolete since interface version 0x00030202 and is ** |