xen/pci: Move check for acpi_sci_override_gsi to xen_setup_acpi_sci.
Previously we would check for acpi_sci_override_gsi == gsi every time a PCI device was enabled. That works during early bootup, but later on it could lead to triggering unnecessarily the acpi_gsi_to_irq(..) lookup. The reason is that acpi_sci_override_gsi was declared in __initdata and after early bootup could contain bogus values. This patch moves the check for acpi_sci_override_gsi to the site where the ACPI SCI is preset. CC: stable@kernel.org Reported-by: Raghavendra D Prabhu <rprabhu@wnohang.net> Tested-by: Raghavendra D Prabhu <rprabhu@wnohang.net> [http://lists.xensource.com/archives/html/xen-devel/2011-07/msg00154.html] Suggested-by: Ian Campbell <ijc@hellion.org.uk> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
This commit is contained in:
		
							parent
							
								
									155a16f219
								
							
						
					
					
						commit
						ee339fe63a
					
				| @ -327,13 +327,12 @@ int __init pci_xen_hvm_init(void) | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_XEN_DOM0 | ||||
| static int xen_register_pirq(u32 gsi, int triggering) | ||||
| static int xen_register_pirq(u32 gsi, int gsi_override, int triggering) | ||||
| { | ||||
| 	int rc, pirq, irq = -1; | ||||
| 	struct physdev_map_pirq map_irq; | ||||
| 	int shareable = 0; | ||||
| 	char *name; | ||||
| 	bool gsi_override = false; | ||||
| 
 | ||||
| 	if (!xen_pv_domain()) | ||||
| 		return -1; | ||||
| @ -345,31 +344,12 @@ static int xen_register_pirq(u32 gsi, int triggering) | ||||
| 		shareable = 1; | ||||
| 		name = "ioapic-level"; | ||||
| 	} | ||||
| 
 | ||||
| 	pirq = xen_allocate_pirq_gsi(gsi); | ||||
| 	if (pirq < 0) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	/* Before we bind the GSI to a Linux IRQ, check whether
 | ||||
| 	 * we need to override it with bus_irq (IRQ) value. Usually for | ||||
| 	 * IRQs below IRQ_LEGACY_IRQ this holds IRQ == GSI, as so: | ||||
| 	 *  ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level) | ||||
| 	 * but there are oddballs where the IRQ != GSI: | ||||
| 	 *  ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level) | ||||
| 	 * which ends up being: gsi_to_irq[9] == 20 | ||||
| 	 * (which is what acpi_gsi_to_irq ends up calling when starting the | ||||
| 	 * the ACPI interpreter and keels over since IRQ 9 has not been | ||||
| 	 * setup as we had setup IRQ 20 for it). | ||||
| 	 */ | ||||
| 	if (gsi == acpi_sci_override_gsi) { | ||||
| 		/* Check whether the GSI != IRQ */ | ||||
| 		acpi_gsi_to_irq(gsi, &irq); | ||||
| 		if (irq != gsi) | ||||
| 			/* Bugger, we MUST have that IRQ. */ | ||||
| 			gsi_override = true; | ||||
| 	} | ||||
| 	if (gsi_override) | ||||
| 		irq = xen_bind_pirq_gsi_to_irq(irq, pirq, shareable, name); | ||||
| 	if (gsi_override >= 0) | ||||
| 		irq = xen_bind_pirq_gsi_to_irq(gsi_override, pirq, shareable, name); | ||||
| 	else | ||||
| 		irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name); | ||||
| 	if (irq < 0) | ||||
| @ -392,7 +372,7 @@ out: | ||||
| 	return irq; | ||||
| } | ||||
| 
 | ||||
| static int xen_register_gsi(u32 gsi, int triggering, int polarity) | ||||
| static int xen_register_gsi(u32 gsi, int gsi_override, int triggering, int polarity) | ||||
| { | ||||
| 	int rc, irq; | ||||
| 	struct physdev_setup_gsi setup_gsi; | ||||
| @ -403,7 +383,7 @@ static int xen_register_gsi(u32 gsi, int triggering, int polarity) | ||||
| 	printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n", | ||||
| 			gsi, triggering, polarity); | ||||
| 
 | ||||
| 	irq = xen_register_pirq(gsi, triggering); | ||||
| 	irq = xen_register_pirq(gsi, gsi_override, triggering); | ||||
| 
 | ||||
| 	setup_gsi.gsi = gsi; | ||||
| 	setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1); | ||||
| @ -425,6 +405,8 @@ static __init void xen_setup_acpi_sci(void) | ||||
| 	int rc; | ||||
| 	int trigger, polarity; | ||||
| 	int gsi = acpi_sci_override_gsi; | ||||
| 	int irq = -1; | ||||
| 	int gsi_override = -1; | ||||
| 
 | ||||
| 	if (!gsi) | ||||
| 		return; | ||||
| @ -441,7 +423,25 @@ static __init void xen_setup_acpi_sci(void) | ||||
| 	printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d " | ||||
| 			"polarity=%d\n", gsi, trigger, polarity); | ||||
| 
 | ||||
| 	gsi = xen_register_gsi(gsi, trigger, polarity); | ||||
| 	/* Before we bind the GSI to a Linux IRQ, check whether
 | ||||
| 	 * we need to override it with bus_irq (IRQ) value. Usually for | ||||
| 	 * IRQs below IRQ_LEGACY_IRQ this holds IRQ == GSI, as so: | ||||
| 	 *  ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level) | ||||
| 	 * but there are oddballs where the IRQ != GSI: | ||||
| 	 *  ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level) | ||||
| 	 * which ends up being: gsi_to_irq[9] == 20 | ||||
| 	 * (which is what acpi_gsi_to_irq ends up calling when starting the | ||||
| 	 * the ACPI interpreter and keels over since IRQ 9 has not been | ||||
| 	 * setup as we had setup IRQ 20 for it). | ||||
| 	 */ | ||||
| 	/* Check whether the GSI != IRQ */ | ||||
| 	if (acpi_gsi_to_irq(gsi, &irq) == 0) { | ||||
| 		if (irq >= 0 && irq != gsi) | ||||
| 			/* Bugger, we MUST have that IRQ. */ | ||||
| 			gsi_override = irq; | ||||
| 	} | ||||
| 
 | ||||
| 	gsi = xen_register_gsi(gsi, gsi_override, trigger, polarity); | ||||
| 	printk(KERN_INFO "xen: acpi sci %d\n", gsi); | ||||
| 
 | ||||
| 	return; | ||||
| @ -450,7 +450,7 @@ static __init void xen_setup_acpi_sci(void) | ||||
| static int acpi_register_gsi_xen(struct device *dev, u32 gsi, | ||||
| 				 int trigger, int polarity) | ||||
| { | ||||
| 	return xen_register_gsi(gsi, trigger, polarity); | ||||
| 	return xen_register_gsi(gsi, -1 /* no GSI override */, trigger, polarity); | ||||
| } | ||||
| 
 | ||||
| static int __init pci_xen_initial_domain(void) | ||||
| @ -489,7 +489,7 @@ void __init xen_setup_pirqs(void) | ||||
| 		if (acpi_get_override_irq(irq, &trigger, &polarity) == -1) | ||||
| 			continue; | ||||
| 
 | ||||
| 		xen_register_pirq(irq, | ||||
| 		xen_register_pirq(irq, -1 /* no GSI override */, | ||||
| 			trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE); | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user