* [PATCH] x86: don't special case first IO-APIC
@ 2012-10-24 7:53 Jan Beulich
2012-10-24 11:56 ` Keir Fraser
0 siblings, 1 reply; 2+ messages in thread
From: Jan Beulich @ 2012-10-24 7:53 UTC (permalink / raw)
To: xen-devel
[-- Attachment #1: Type: text/plain, Size: 3624 bytes --]
It has always been puzzling me why the first IO-APIC gets special cased
in two places, and finally Xen got run on a system where this breaks:
(XEN) ACPI: IOAPIC (id[0x10] address[0xfecff000] gsi_base[0])
(XEN) IOAPIC[0]: apic_id 16, version 17, address 0xfecff000, GSI 0-2
(XEN) ACPI: IOAPIC (id[0x0f] address[0xfec00000] gsi_base[3])
(XEN) IOAPIC[1]: apic_id 15, version 17, address 0xfec00000, GSI 3-38
(XEN) ACPI: IOAPIC (id[0x0e] address[0xfec01000] gsi_base[39])
(XEN) IOAPIC[2]: apic_id 14, version 17, address 0xfec01000, GSI 39-74
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 1 global_irq 4 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 5 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 3 global_irq 6 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 4 global_irq 7 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 6 global_irq 9 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 7 global_irq 10 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 8 global_irq 11 low edge)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 12 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 12 global_irq 15 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 13 global_irq 16 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 14 global_irq 17 low edge)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 15 global_irq 18 dfl dfl)
i.e. all legacy IRQs (apart from the timer one, but the firmware passed
data doesn't look right for that case anyway, as both Xen and native
Linux are falling back to use the virtual wire setup for IRQ0,
apparently rather using pin 2 of the first IO-APIC) are being handled
by the second IO-APIC.
This at once eliminates the possibility of an unmasked RTE getting
written without having got a vector put in place (in
setup_IO_APIC_irqs()).
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -990,18 +990,17 @@ static void __init setup_IO_APIC_irqs(vo
else
add_pin_to_irq(irq, apic, pin);
- if (!apic && !IO_APIC_IRQ(irq))
+ if (!IO_APIC_IRQ(irq))
continue;
- if (IO_APIC_IRQ(irq)) {
- vector = assign_irq_vector(irq, NULL);
- BUG_ON(vector < 0);
- entry.vector = vector;
- ioapic_register_intr(irq, IOAPIC_AUTO);
+ vector = assign_irq_vector(irq, NULL);
+ BUG_ON(vector < 0);
+ entry.vector = vector;
+ ioapic_register_intr(irq, IOAPIC_AUTO);
+
+ if (platform_legacy_irq(irq))
+ disable_8259A_irq(irq_to_desc(irq));
- if (!apic && platform_legacy_irq(irq))
- disable_8259A_irq(irq_to_desc(irq));
- }
desc = irq_to_desc(irq);
SET_DEST(entry.dest.dest32, entry.dest.logical.logical_dest,
cpu_mask_to_apicid(desc->arch.cpu_mask));
@@ -2245,18 +2244,15 @@ unsigned apic_gsi_base(int apic);
static int apic_pin_2_gsi_irq(int apic, int pin)
{
- int idx, irq;
+ int idx;
if (apic < 0)
return -EINVAL;
- irq = apic_gsi_base(apic) + pin;
- if (apic == 0) {
- idx = find_irq_entry(apic, pin, mp_INT);
- if (idx >= 0)
- irq = pin_2_irq(idx, apic, pin);
- }
- return irq;
+ idx = find_irq_entry(apic, pin, mp_INT);
+
+ return idx >= 0 ? pin_2_irq(idx, apic, pin)
+ : apic_gsi_base(apic) + pin;
}
int ioapic_guest_read(unsigned long physbase, unsigned int reg, u32 *pval)
[-- Attachment #2: x86-IOAPIC-legacy-not-first.patch --]
[-- Type: text/plain, Size: 3659 bytes --]
x86: don't special case first IO-APIC
It has always been puzzling me why the first IO-APIC gets special cased
in two places, and finally Xen got run on a system where this breaks:
(XEN) ACPI: IOAPIC (id[0x10] address[0xfecff000] gsi_base[0])
(XEN) IOAPIC[0]: apic_id 16, version 17, address 0xfecff000, GSI 0-2
(XEN) ACPI: IOAPIC (id[0x0f] address[0xfec00000] gsi_base[3])
(XEN) IOAPIC[1]: apic_id 15, version 17, address 0xfec00000, GSI 3-38
(XEN) ACPI: IOAPIC (id[0x0e] address[0xfec01000] gsi_base[39])
(XEN) IOAPIC[2]: apic_id 14, version 17, address 0xfec01000, GSI 39-74
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 1 global_irq 4 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 5 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 3 global_irq 6 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 4 global_irq 7 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 6 global_irq 9 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 7 global_irq 10 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 8 global_irq 11 low edge)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 12 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 12 global_irq 15 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 13 global_irq 16 dfl dfl)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 14 global_irq 17 low edge)
(XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 15 global_irq 18 dfl dfl)
i.e. all legacy IRQs (apart from the timer one, but the firmware passed
data doesn't look right for that case anyway, as both Xen and native
Linux are falling back to use the virtual wire setup for IRQ0,
apparently rather using pin 2 of the first IO-APIC) are being handled
by the second IO-APIC.
This at once eliminates the possibility of an unmasked RTE getting
written without having got a vector put in place (in
setup_IO_APIC_irqs()).
Signed-off-by: Jan Beulich <jbeulich@suse.com>
--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -990,18 +990,17 @@ static void __init setup_IO_APIC_irqs(vo
else
add_pin_to_irq(irq, apic, pin);
- if (!apic && !IO_APIC_IRQ(irq))
+ if (!IO_APIC_IRQ(irq))
continue;
- if (IO_APIC_IRQ(irq)) {
- vector = assign_irq_vector(irq, NULL);
- BUG_ON(vector < 0);
- entry.vector = vector;
- ioapic_register_intr(irq, IOAPIC_AUTO);
+ vector = assign_irq_vector(irq, NULL);
+ BUG_ON(vector < 0);
+ entry.vector = vector;
+ ioapic_register_intr(irq, IOAPIC_AUTO);
+
+ if (platform_legacy_irq(irq))
+ disable_8259A_irq(irq_to_desc(irq));
- if (!apic && platform_legacy_irq(irq))
- disable_8259A_irq(irq_to_desc(irq));
- }
desc = irq_to_desc(irq);
SET_DEST(entry.dest.dest32, entry.dest.logical.logical_dest,
cpu_mask_to_apicid(desc->arch.cpu_mask));
@@ -2245,18 +2244,15 @@ unsigned apic_gsi_base(int apic);
static int apic_pin_2_gsi_irq(int apic, int pin)
{
- int idx, irq;
+ int idx;
if (apic < 0)
return -EINVAL;
- irq = apic_gsi_base(apic) + pin;
- if (apic == 0) {
- idx = find_irq_entry(apic, pin, mp_INT);
- if (idx >= 0)
- irq = pin_2_irq(idx, apic, pin);
- }
- return irq;
+ idx = find_irq_entry(apic, pin, mp_INT);
+
+ return idx >= 0 ? pin_2_irq(idx, apic, pin)
+ : apic_gsi_base(apic) + pin;
}
int ioapic_guest_read(unsigned long physbase, unsigned int reg, u32 *pval)
[-- Attachment #3: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] x86: don't special case first IO-APIC
2012-10-24 7:53 [PATCH] x86: don't special case first IO-APIC Jan Beulich
@ 2012-10-24 11:56 ` Keir Fraser
0 siblings, 0 replies; 2+ messages in thread
From: Keir Fraser @ 2012-10-24 11:56 UTC (permalink / raw)
To: Jan Beulich, xen-devel
On 24/10/2012 00:53, "Jan Beulich" <JBeulich@suse.com> wrote:
> It has always been puzzling me why the first IO-APIC gets special cased
> in two places, and finally Xen got run on a system where this breaks:
>
> (XEN) ACPI: IOAPIC (id[0x10] address[0xfecff000] gsi_base[0])
> (XEN) IOAPIC[0]: apic_id 16, version 17, address 0xfecff000, GSI 0-2
> (XEN) ACPI: IOAPIC (id[0x0f] address[0xfec00000] gsi_base[3])
> (XEN) IOAPIC[1]: apic_id 15, version 17, address 0xfec00000, GSI 3-38
> (XEN) ACPI: IOAPIC (id[0x0e] address[0xfec01000] gsi_base[39])
> (XEN) IOAPIC[2]: apic_id 14, version 17, address 0xfec01000, GSI 39-74
> (XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 1 global_irq 4 dfl dfl)
> (XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 5 dfl dfl)
> (XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 3 global_irq 6 dfl dfl)
> (XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 4 global_irq 7 dfl dfl)
> (XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 6 global_irq 9 dfl dfl)
> (XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 7 global_irq 10 dfl dfl)
> (XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 8 global_irq 11 low edge)
> (XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 12 dfl dfl)
> (XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 12 global_irq 15 dfl dfl)
> (XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 13 global_irq 16 dfl dfl)
> (XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 14 global_irq 17 low edge)
> (XEN) ACPI: INT_SRC_OVR (bus 0 bus_irq 15 global_irq 18 dfl dfl)
>
> i.e. all legacy IRQs (apart from the timer one, but the firmware passed
> data doesn't look right for that case anyway, as both Xen and native
> Linux are falling back to use the virtual wire setup for IRQ0,
> apparently rather using pin 2 of the first IO-APIC) are being handled
> by the second IO-APIC.
>
> This at once eliminates the possibility of an unmasked RTE getting
> written without having got a vector put in place (in
> setup_IO_APIC_irqs()).
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Keir Fraser <keir@xen.org>
> --- a/xen/arch/x86/io_apic.c
> +++ b/xen/arch/x86/io_apic.c
> @@ -990,18 +990,17 @@ static void __init setup_IO_APIC_irqs(vo
> else
> add_pin_to_irq(irq, apic, pin);
>
> - if (!apic && !IO_APIC_IRQ(irq))
> + if (!IO_APIC_IRQ(irq))
> continue;
>
> - if (IO_APIC_IRQ(irq)) {
> - vector = assign_irq_vector(irq, NULL);
> - BUG_ON(vector < 0);
> - entry.vector = vector;
> - ioapic_register_intr(irq, IOAPIC_AUTO);
> + vector = assign_irq_vector(irq, NULL);
> + BUG_ON(vector < 0);
> + entry.vector = vector;
> + ioapic_register_intr(irq, IOAPIC_AUTO);
> +
> + if (platform_legacy_irq(irq))
> + disable_8259A_irq(irq_to_desc(irq));
>
> - if (!apic && platform_legacy_irq(irq))
> - disable_8259A_irq(irq_to_desc(irq));
> - }
> desc = irq_to_desc(irq);
> SET_DEST(entry.dest.dest32, entry.dest.logical.logical_dest,
> cpu_mask_to_apicid(desc->arch.cpu_mask));
> @@ -2245,18 +2244,15 @@ unsigned apic_gsi_base(int apic);
>
> static int apic_pin_2_gsi_irq(int apic, int pin)
> {
> - int idx, irq;
> + int idx;
>
> if (apic < 0)
> return -EINVAL;
>
> - irq = apic_gsi_base(apic) + pin;
> - if (apic == 0) {
> - idx = find_irq_entry(apic, pin, mp_INT);
> - if (idx >= 0)
> - irq = pin_2_irq(idx, apic, pin);
> - }
> - return irq;
> + idx = find_irq_entry(apic, pin, mp_INT);
> +
> + return idx >= 0 ? pin_2_irq(idx, apic, pin)
> + : apic_gsi_base(apic) + pin;
> }
>
> int ioapic_guest_read(unsigned long physbase, unsigned int reg, u32 *pval)
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2012-10-24 11:56 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-24 7:53 [PATCH] x86: don't special case first IO-APIC Jan Beulich
2012-10-24 11:56 ` Keir Fraser
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).