File 21089-x86-startup-irq-from-setup-gsi.patch of Package xen.import4929

# HG changeset patch
# User Keir Fraser <keir.fraser@citrix.com>
# Date 1270026749 -3600
# Node ID 4f796e29987c0db1579787fe0b7d3d5af00963ea
# Parent  589d075ba2953123c1b39ecdbc190689ac6f443c
x86: start PCI IRQs Xen uses from Dom0-invoked io_apic_set_pci_routing()

When using a serial port from an add-in PCI card, and that IRQ is (as
usual) outside of the legacy range (0...15), Xen would never really
enable the IRQ, as at the time setup_irq() runs the handler for the
IRQ still is &no_irq_type. Consequently, once the trigger mode and
polarity of the interrupt become known to Xen, it should start such
IRQ(s) it uses for itself.

The question is whether the same should also be done in
ioapic_guest_write(): Legacy kernels don't use PHYSDEVOP_setup_gsi
(and hence don't trigger the code path modified).

Note however that even when a kernel is using PHYSDEVOP_setup_gsi in
the way the pv-ops kernel currently does, there's still no guarantee
that the call would ever be issued for IRQs Xen may be using, since
this happens only when devices get enabled. For Xen's purposes, this
function should be called for *all* device IRQs, regardless of
whether those would actually be (attempted to be) used by the kernel,
i.e. in a subsys_initcall() from drivers/acpi/pci_irq.c iterating
over all PCI devices and doing mostly what acpi_pci_irq_enable() does
except for calling this function in place of acpi_register_gsi(). The
downside of this approach is that without extra filtering in Xen
(based on a hint from Dom0), vectors will then get up even for IRQs
that are unused by both hypervisor and kernel.

Signed-off-by: Jan Beulich <jbeulich@novell.com>

# HG changeset patch
# User Keir Fraser <keir.fraser@citrix.com>
# Date 1271090214 -3600
# Node ID 7eeb131880b20a33e7675cc1726ae312a489be2d
# Parent  b65a41dc6c6a2e2341ae778d8386a08d502bbfa4
Fix bug in 21089:4f796e29987c

Signed-off-by: Jan Beulich <jbeulich@novell.com>

# HG changeset patch
# User Keir Fraser <keir.fraser@citrix.com>
# Date 1271169507 -3600
# Node ID 0bebb5fa4f051df9b4fed4d11a723fae91bc7523
# Parent  859a372efa66e6bcba8e1fd968e521cb16da12ea
Make c/s 21089 work again with c/s 21092

Unfortunately the latter c/s' change to mpparse.c yielded the former
patch non-functional - Xen's serial port IRQ is not in IRQ_DISABLED
state, yet must be allowed to get its trigger mode and polarity set
up in order for it to be usable.

Signed-off-by: Jan Beulich <jbeulich@novell.com>

--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -2223,6 +2223,7 @@ int __init io_apic_get_redir_entries (in
 
 int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low)
 {
+    struct irq_desc *desc = irq_to_desc(irq);
     struct IO_APIC_route_entry entry;
     unsigned long flags;
     int vector;
@@ -2273,7 +2274,12 @@ int io_apic_set_pci_routing (int ioapic,
     spin_lock_irqsave(&ioapic_lock, flags);
     __ioapic_write_entry(ioapic, pin, 0, entry);
     set_native_irq_info(irq, TARGET_CPUS);
-    spin_unlock_irqrestore(&ioapic_lock, flags);
+    spin_unlock(&ioapic_lock);
+
+    spin_lock(&desc->lock);
+    if (!(desc->status & (IRQ_DISABLED | IRQ_GUEST)))
+        desc->handler->startup(irq);
+    spin_unlock_irqrestore(&desc->lock, flags);
 
     return 0;
 }
--- a/xen/arch/x86/mpparse.c
+++ b/xen/arch/x86/mpparse.c
@@ -1102,6 +1102,8 @@ int mp_register_gsi (u32 gsi, int trigge
 	int			ioapic = -1;
 	int			ioapic_pin = 0;
 	int			idx, bit = 0;
+	struct irq_desc *	desc;
+	unsigned long		flags;
 
 	/*
 	 * Mapping between Global System Interrups, which
@@ -1123,8 +1125,13 @@ int mp_register_gsi (u32 gsi, int trigge
 
 	ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
 
-	if (!(irq_to_desc(gsi)->status & IRQ_DISABLED))
+	desc = irq_to_desc(gsi);
+	spin_lock_irqsave(&desc->lock, flags);
+	if (!(desc->status & IRQ_DISABLED) && desc->handler != &no_irq_type) {
+		spin_unlock_irqrestore(&desc->lock, flags);
 		return -EEXIST;
+	}
+	spin_unlock_irqrestore(&desc->lock, flags);
 
 	/* 
 	 * Avoid pin reprogramming.  PRTs typically include entries  
openSUSE Build Service is sponsored by