Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xen: do not map the same GSI twice in PVHVM guests.

PV on HVM guests map GSIs into event channels. At restore time the
event channels are resumed by restore_pirqs.

Device drivers might try to register the same GSI again through ACPI at
restore time, but the GSI has already been mapped and bound by
restore_pirqs. This patch detects these situations and avoids
mapping the same GSI multiple times.

Without this patch we get:
(XEN) irq.c:2235: dom4: pirq 23 or emuirq 28 already mapped
and waste a pirq.

CC: stable@kernel.org
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>

authored by

Stefano Stabellini and committed by
Konrad Rzeszutek Wilk
68c2c39a 201a52be

+10 -2
+4
arch/x86/pci/xen.c
··· 64 64 int shareable = 0; 65 65 char *name; 66 66 67 + irq = xen_irq_from_gsi(gsi); 68 + if (irq > 0) 69 + return irq; 70 + 67 71 if (set_pirq) 68 72 pirq = gsi; 69 73
+3 -2
drivers/xen/events.c
··· 611 611 disable_dynirq(data); 612 612 } 613 613 614 - static int find_irq_by_gsi(unsigned gsi) 614 + int xen_irq_from_gsi(unsigned gsi) 615 615 { 616 616 struct irq_info *info; 617 617 ··· 625 625 626 626 return -1; 627 627 } 628 + EXPORT_SYMBOL_GPL(xen_irq_from_gsi); 628 629 629 630 /* 630 631 * Do not make any assumptions regarding the relationship between the ··· 645 644 646 645 mutex_lock(&irq_mapping_update_lock); 647 646 648 - irq = find_irq_by_gsi(gsi); 647 + irq = xen_irq_from_gsi(gsi); 649 648 if (irq != -1) { 650 649 printk(KERN_INFO "xen_map_pirq_gsi: returning irq %d for gsi %u\n", 651 650 irq, gsi);
+3
include/xen/events.h
··· 103 103 /* Return the pirq allocated to the irq. */ 104 104 int xen_pirq_from_irq(unsigned irq); 105 105 106 + /* Return the irq allocated to the gsi */ 107 + int xen_irq_from_gsi(unsigned gsi); 108 + 106 109 /* Determine whether to ignore this IRQ if it is passed to a guest. */ 107 110 int xen_test_irq_shared(int irq); 108 111