* [PATCH 0/14] Start coping gsis < 16 that are not isa irqs.
[not found] ` <4BB0EA22.7000004@zytor.com>
@ 2010-03-29 23:19 ` Eric W. Biederman
2010-03-29 23:20 ` [PATCH 01/14] x86 acpi/irq: Introduce apci_isa_irq_to_gsi Eric W. Biederman
` (15 more replies)
0 siblings, 16 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:19 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Yinghai Lu, Ingo Molnar, Andrew Morton,
Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
len.brown, Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad,
Gary Hade, Natalie Protasevich
It appears there are a few systems in the wild that use acpi
interrupt source overrides to report a gsi > 16 is an isa irq.
This breaks all kinds of assumptions I figure any BIOS doing that
probably should be shot as that is very much not a conservative position.
That said acpi appears to allow this insanity and on the basis of being
liberal in what we accept we should try to do something reasonable, and
keep our notions of gsi, isa irq, and linux irq as straight as we can.
To that end this patchset slightly modifies the gsi to linux irq
mapping. Making it a 1 to 1 identity mapping except for the first 16
gsis. If those gsis are isa irqs (the typical and default acpi
configuration) they will be mapped into the first 16 irqs. If those
first 16 gsis are not isa irqs they will be given a linux irq number
just past the last gsi. Allowing us the chance to use them.
This patchset is my attempt to straighten out our understanding of which
kind of irq name is used where and the cleanups used to get there.
Thanks to Yinghai Lu <yinghai@kernel.org> for taking the first stab at
this and finding that there is a real world problem here. This patchset
is inspired by his work, but little of it remains the same.
This patchset lies in the weird world between the acpi and x86 and ia64.
Since most of the changes are x86 related I think it makes most sense
to go via the x86 tree.
Eric W. Biederman (14):
x86 acpi/irq: Introduce apci_isa_irq_to_gsi
x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq
x86 acpi/irq: pci device dev->irq is an isa irq not a gsi
x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi
x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs
x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h
x86 ioapic: Fix the types of gsi values
x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end
x86 ioapic: In mpparse use mp_register_ioapic
x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic.
x86 ioapic: Optimize pin_2_irq
x86 ioapic: Simplify probe_nr_irqs_gsi.
x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
x86 irq: Kill io_apic_renumber_irq
arch/ia64/kernel/acpi.c | 8 ++
arch/x86/include/asm/io_apic.h | 12 ++--
arch/x86/include/asm/mpspec.h | 10 ---
arch/x86/kernel/acpi/boot.c | 133 ++++++++++++++++++++++++--------------
arch/x86/kernel/apic/es7000_32.c | 19 ------
arch/x86/kernel/apic/io_apic.c | 93 +++++++++++---------------
arch/x86/kernel/mpparse.c | 25 +-------
arch/x86/kernel/sfi.c | 4 +-
drivers/acpi/pci_irq.c | 8 ++-
include/linux/acpi.h | 5 +-
10 files changed, 149 insertions(+), 168 deletions(-)
Eric
^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 01/14] x86 acpi/irq: Introduce apci_isa_irq_to_gsi
2010-03-29 23:19 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
@ 2010-03-29 23:20 ` Eric W. Biederman
2010-03-29 23:20 ` [PATCH 02/14] x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq Eric W. Biederman
` (14 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
There are a number of cases where the current code makes the assumption
that isa irqs identity map to the first 16 acpi global system intereupts.
In most instances that assumption is correct as that is the required
behaviour in dual i8259 mode and the default behavior in ioapic mode.
However there are some systems out there that take advantage of acpis
interrupt remapping for the isa irqs to have a completely different
mapping of isa_irq to gsi.
Introduce acpi_isa_irq_to_gsi to perform this mapping explicitly in the
code that needs it. Initially this will be just the current assumed
identity mapping to ensure it's introduction does not cause regressions.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/ia64/kernel/acpi.c | 8 ++++++++
arch/x86/kernel/acpi/boot.c | 8 ++++++++
include/linux/acpi.h | 1 +
3 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index f1c9f70..16921bd 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -784,6 +784,14 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
return 0;
}
+int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
+{
+ if (isa_irq >= 16)
+ return -1;
+ *gsi = isa_irq;
+ return 0;
+}
+
/*
* ACPI based hotplug CPU support
*/
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 0061ea2..f96060d 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -457,6 +457,14 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
return 0;
}
+int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
+{
+ if (isa_irq >= 16)
+ return -1;
+ *gsi = isa_irq;
+ return 0;
+}
+
/*
* success: return IRQ number (>=0)
* failure: return < 0
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index b926afe..7a937da 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -116,6 +116,7 @@ extern unsigned long acpi_realmode_flags;
int acpi_register_gsi (struct device *dev, u32 gsi, int triggering, int polarity);
int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
+int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);
#ifdef CONFIG_X86_IO_APIC
extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity);
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 02/14] x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq
2010-03-29 23:19 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
2010-03-29 23:20 ` [PATCH 01/14] x86 acpi/irq: Introduce apci_isa_irq_to_gsi Eric W. Biederman
@ 2010-03-29 23:20 ` Eric W. Biederman
2010-03-29 23:20 ` [PATCH 03/14] x86 acpi/irq: pci device dev->irq is an isa irq not a gsi Eric W. Biederman
` (13 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
In perverse acpi implementations the isa irqs are not identity mapped
to the first 16 gsi. Furthermore at least the extended interrupt
resource capability may return gsi's and not isa irqs. So since
what we get from acpi is a gsi teach acpi_get_overrride_irq to
operate on a gsi instead of an isa_irq.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/kernel/apic/io_apic.c | 23 ++++++++++++++---------
include/linux/acpi.h | 4 ++--
2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e4e0ddc..54ba1f7 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -4073,22 +4073,27 @@ int __init io_apic_get_version(int ioapic)
return reg_01.bits.version;
}
-int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
+int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity)
{
- int i;
+ int ioapic, pin, idx;
if (skip_ioapic_setup)
return -1;
- for (i = 0; i < mp_irq_entries; i++)
- if (mp_irqs[i].irqtype == mp_INT &&
- mp_irqs[i].srcbusirq == bus_irq)
- break;
- if (i >= mp_irq_entries)
+ ioapic = mp_find_ioapic(gsi);
+ if (ioapic < 0)
+ return -1;
+
+ pin = mp_find_ioapic_pin(ioapic, gsi);
+ if (pin < 0)
+ return -1;
+
+ idx = find_irq_entry(ioapic, pin, mp_INT);
+ if (idx < 0)
return -1;
- *trigger = irq_trigger(i);
- *polarity = irq_polarity(i);
+ *trigger = irq_trigger(idx);
+ *polarity = irq_polarity(idx);
return 0;
}
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 7a937da..3da73f5 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -119,9 +119,9 @@ int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);
#ifdef CONFIG_X86_IO_APIC
-extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity);
+extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity);
#else
-#define acpi_get_override_irq(bus, trigger, polarity) (-1)
+#define acpi_get_override_irq(gsi, trigger, polarity) (-1)
#endif
/*
* This function undoes the effect of one call to acpi_register_gsi().
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 03/14] x86 acpi/irq: pci device dev->irq is an isa irq not a gsi
2010-03-29 23:19 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
2010-03-29 23:20 ` [PATCH 01/14] x86 acpi/irq: Introduce apci_isa_irq_to_gsi Eric W. Biederman
2010-03-29 23:20 ` [PATCH 02/14] x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq Eric W. Biederman
@ 2010-03-29 23:20 ` Eric W. Biederman
2010-03-29 23:20 ` [PATCH 04/14] x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi Eric W. Biederman
` (12 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Strictly speaking on x86 (where acpi is used) dev->irq must be
a dual i8259 irq input aka an isa irq. Therefore we should translate
that isa irq into a gsi before passing it to a function that
takes a gsi.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
drivers/acpi/pci_irq.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 843699e..703541d 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -400,11 +400,13 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
* driver reported one, then use it. Exit in any case.
*/
if (gsi < 0) {
+ u32 dev_gsi;
dev_warn(&dev->dev, "PCI INT %c: no GSI", pin_name(pin));
/* Interrupt Line values above 0xF are forbidden */
- if (dev->irq > 0 && (dev->irq <= 0xF)) {
- printk(" - using IRQ %d\n", dev->irq);
- acpi_register_gsi(&dev->dev, dev->irq,
+ if (dev->irq > 0 && (dev->irq <= 0xF) &&
+ (acpi_isa_irq_to_gsi(dev->irq, &dev_gsi) == 0)) {
+ printk(" - using ISA IRQ %d\n", dev->irq);
+ acpi_register_gsi(&dev->dev, dev_gsi,
ACPI_LEVEL_SENSITIVE,
ACPI_ACTIVE_LOW);
return 0;
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 04/14] x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi
2010-03-29 23:19 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
` (2 preceding siblings ...)
2010-03-29 23:20 ` [PATCH 03/14] x86 acpi/irq: pci device dev->irq is an isa irq not a gsi Eric W. Biederman
@ 2010-03-29 23:20 ` Eric W. Biederman
2010-03-29 23:20 ` [PATCH 05/14] x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs Eric W. Biederman
` (11 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Currently acpi_sci_ioapic_setup calls mp_override_legacy_irq with
bus_irq == gsi, which is wrong if we are comming from an override
Instead pass the bus_irq into acpi_sci_ioapic_setup.
This fix was inspired by a similar fix from:
Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/kernel/acpi/boot.c | 12 +++++++-----
1 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index f96060d..1742888 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -312,7 +312,7 @@ acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
/*
* Parse Interrupt Source Override for the ACPI SCI
*/
-static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
+static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger, u32 gsi)
{
if (trigger == 0) /* compatible SCI trigger is level */
trigger = 3;
@@ -332,7 +332,7 @@ static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
* If GSI is < 16, this will update its flags,
* else it will create a new mp_irqs[] entry.
*/
- mp_override_legacy_irq(gsi, polarity, trigger, gsi);
+ mp_override_legacy_irq(bus_irq, polarity, trigger, gsi);
/*
* stash over-ride to indicate we've been here
@@ -356,9 +356,10 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header,
acpi_table_print_madt_entry(header);
if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) {
- acpi_sci_ioapic_setup(intsrc->global_irq,
+ acpi_sci_ioapic_setup(intsrc->source_irq,
intsrc->inti_flags & ACPI_MADT_POLARITY_MASK,
- (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
+ (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2,
+ intsrc->global_irq);
return 0;
}
@@ -1161,7 +1162,8 @@ static int __init acpi_parse_madt_ioapic_entries(void)
* pretend we got one so we can set the SCI flags.
*/
if (!acpi_sci_override_gsi)
- acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0);
+ acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0,
+ acpi_gbl_FADT.sci_interrupt);
/* Fill in identity legacy mappings where no override */
mp_config_acpi_legacy_irqs();
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 05/14] x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs
2010-03-29 23:19 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
` (3 preceding siblings ...)
2010-03-29 23:20 ` [PATCH 04/14] x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi Eric W. Biederman
@ 2010-03-29 23:20 ` Eric W. Biederman
2010-03-29 23:20 ` [PATCH 06/14] x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h Eric W. Biederman
` (10 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Remove the assumption that there is not an override for isa irq 0.
Instead lookup the gsi and from that lookup the ioapic and pin of each
isa irq indivdually.
In general this should not have any behavioural affect but in
perverse cases this gets all of the details correct, instead of
doing something weird.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/kernel/acpi/boot.c | 30 ++++++++++++++++++------------
1 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 1742888..9c48e99 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -960,8 +960,6 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
void __init mp_config_acpi_legacy_irqs(void)
{
int i;
- int ioapic;
- unsigned int dstapic;
struct mpc_intsrc mp_irq;
#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
@@ -982,19 +980,27 @@ void __init mp_config_acpi_legacy_irqs(void)
#endif
/*
- * Locate the IOAPIC that manages the ISA IRQs (0-15).
- */
- ioapic = mp_find_ioapic(0);
- if (ioapic < 0)
- return;
- dstapic = mp_ioapics[ioapic].apicid;
-
- /*
* Use the default configuration for the IRQs 0-15. Unless
* overridden by (MADT) interrupt source override entries.
*/
for (i = 0; i < 16; i++) {
+ int ioapic, pin;
+ unsigned int dstapic;
int idx;
+ u32 gsi;
+
+ /* Locate the gsi that irq i maps to. */
+ if (acpi_isa_irq_to_gsi(i, &gsi))
+ continue;
+
+ /*
+ * Locate the IOAPIC that manages the ISA IRQ.
+ */
+ ioapic = mp_find_ioapic(gsi);
+ if (ioapic < 0)
+ continue;
+ pin = mp_find_ioapic_pin(ioapic, gsi);
+ dstapic = mp_ioapics[ioapic].apicid;
for (idx = 0; idx < mp_irq_entries; idx++) {
struct mpc_intsrc *irq = mp_irqs + idx;
@@ -1004,7 +1010,7 @@ void __init mp_config_acpi_legacy_irqs(void)
break;
/* Do we already have a mapping for this IOAPIC pin */
- if (irq->dstapic == dstapic && irq->dstirq == i)
+ if (irq->dstapic == dstapic && irq->dstirq == pin)
break;
}
@@ -1019,7 +1025,7 @@ void __init mp_config_acpi_legacy_irqs(void)
mp_irq.dstapic = dstapic;
mp_irq.irqtype = mp_INT;
mp_irq.srcbusirq = i; /* Identity mapped */
- mp_irq.dstirq = i;
+ mp_irq.dstirq = pin;
save_mp_irq(&mp_irq);
}
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 06/14] x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h
2010-03-29 23:19 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
` (4 preceding siblings ...)
2010-03-29 23:20 ` [PATCH 05/14] x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs Eric W. Biederman
@ 2010-03-29 23:20 ` Eric W. Biederman
2010-03-29 23:20 ` [PATCH 07/14] x86 ioapic: Fix the types of gsi values Eric W. Biederman
` (9 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Multiple declarations of the same function in different headers
is a pain to maintain.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/include/asm/mpspec.h | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index d8bf23a..29994f0 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -106,10 +106,6 @@ struct device;
extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
int active_high_low);
extern int acpi_probe_gsi(void);
-#ifdef CONFIG_X86_IO_APIC
-extern int mp_find_ioapic(int gsi);
-extern int mp_find_ioapic_pin(int ioapic, int gsi);
-#endif
#else /* !CONFIG_ACPI: */
static inline int acpi_probe_gsi(void)
{
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 07/14] x86 ioapic: Fix the types of gsi values
2010-03-29 23:19 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
` (5 preceding siblings ...)
2010-03-29 23:20 ` [PATCH 06/14] x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h Eric W. Biederman
@ 2010-03-29 23:20 ` Eric W. Biederman
2010-03-29 23:20 ` [PATCH 08/14] x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end Eric W. Biederman
` (8 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
This patches fixes the types of gsi_base and gsi_end values in
struct mp_ioapic_gsi, and the gsi parameter of mp_find_ioapic
and mp_find_ioapic_pin
A gsi is cannonically a u32, not an int.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/include/asm/io_apic.h | 10 +++++-----
arch/x86/kernel/apic/io_apic.c | 4 ++--
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 35832a0..feeaf0d 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -180,12 +180,12 @@ extern void ioapic_write_entry(int apic, int pin,
extern void setup_ioapic_ids_from_mpc(void);
struct mp_ioapic_gsi{
- int gsi_base;
- int gsi_end;
+ u32 gsi_base;
+ u32 gsi_end;
};
extern struct mp_ioapic_gsi mp_gsi_routing[];
-int mp_find_ioapic(int gsi);
-int mp_find_ioapic_pin(int ioapic, int gsi);
+int mp_find_ioapic(u32 gsi);
+int mp_find_ioapic_pin(int ioapic, u32 gsi);
void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
extern void __init pre_init_apic_IRQ0(void);
@@ -197,7 +197,7 @@ static const int timer_through_8259 = 0;
static inline void ioapic_init_mappings(void) { }
static inline void ioapic_insert_resources(void) { }
static inline void probe_nr_irqs_gsi(void) { }
-static inline int mp_find_ioapic(int gsi) { return 0; }
+static inline int mp_find_ioapic(u32 gsi) { return 0; }
struct io_apic_irq_attr;
static inline int io_apic_set_pci_routing(struct device *dev, int irq,
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 54ba1f7..32cea57 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -4234,7 +4234,7 @@ void __init ioapic_insert_resources(void)
}
}
-int mp_find_ioapic(int gsi)
+int mp_find_ioapic(u32 gsi)
{
int i = 0;
@@ -4249,7 +4249,7 @@ int mp_find_ioapic(int gsi)
return -1;
}
-int mp_find_ioapic_pin(int ioapic, int gsi)
+int mp_find_ioapic_pin(int ioapic, u32 gsi)
{
if (WARN_ON(ioapic == -1))
return -1;
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 08/14] x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end
2010-03-29 23:19 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
` (6 preceding siblings ...)
2010-03-29 23:20 ` [PATCH 07/14] x86 ioapic: Fix the types of gsi values Eric W. Biederman
@ 2010-03-29 23:20 ` Eric W. Biederman
2010-03-29 23:20 ` [PATCH 09/14] x86 ioapic: In mpparse use mp_register_ioapic Eric W. Biederman
` (7 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Add the global variable gsi_end and teach mp_register_ioapic
to keep it uptodate as we add more ioapics into the system.
ioapics can only be added early in boot so the code that
runs later can treat gsi_end as a constant.
Remove the have hacks in sfi.c to second guess mp_register_ioapic
by keeping t's own running total of how many gsi's have been seen,
and instead use the gsi_end.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/include/asm/io_apic.h | 1 +
arch/x86/kernel/apic/io_apic.c | 6 ++++++
arch/x86/kernel/sfi.c | 4 +---
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index feeaf0d..37b0f2b 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -184,6 +184,7 @@ struct mp_ioapic_gsi{
u32 gsi_end;
};
extern struct mp_ioapic_gsi mp_gsi_routing[];
+extern u32 gsi_end;
int mp_find_ioapic(u32 gsi);
int mp_find_ioapic_pin(int ioapic, u32 gsi);
void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 32cea57..a979a00 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -88,6 +88,9 @@ int nr_ioapics;
/* IO APIC gsi routing info */
struct mp_ioapic_gsi mp_gsi_routing[MAX_IO_APICS];
+/* One past the last gsi number used */
+u32 gsi_end;
+
/* MP IRQ source entries */
struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
@@ -4299,6 +4302,9 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
mp_gsi_routing[idx].gsi_end = gsi_base +
io_apic_get_redir_entries(idx);
+ if (mp_gsi_routing[idx].gsi_end > gsi_end)
+ gsi_end = mp_gsi_routing[idx].gsi_end;
+
printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
"GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr,
diff --git a/arch/x86/kernel/sfi.c b/arch/x86/kernel/sfi.c
index 34e0993..7ef6df2 100644
--- a/arch/x86/kernel/sfi.c
+++ b/arch/x86/kernel/sfi.c
@@ -81,7 +81,6 @@ static int __init sfi_parse_cpus(struct sfi_table_header *table)
#endif /* CONFIG_X86_LOCAL_APIC */
#ifdef CONFIG_X86_IO_APIC
-static u32 gsi_base;
static int __init sfi_parse_ioapic(struct sfi_table_header *table)
{
@@ -94,8 +93,7 @@ static int __init sfi_parse_ioapic(struct sfi_table_header *table)
pentry = (struct sfi_apic_table_entry *)sb->pentry;
for (i = 0; i < num; i++) {
- mp_register_ioapic(i, pentry->phys_addr, gsi_base);
- gsi_base += io_apic_get_redir_entries(i);
+ mp_register_ioapic(i, pentry->phys_addr, gsi_end);
pentry++;
}
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 09/14] x86 ioapic: In mpparse use mp_register_ioapic
2010-03-29 23:19 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
` (7 preceding siblings ...)
2010-03-29 23:20 ` [PATCH 08/14] x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end Eric W. Biederman
@ 2010-03-29 23:20 ` Eric W. Biederman
2010-03-29 23:20 ` [PATCH 10/14] x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic Eric W. Biederman
` (6 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Long ago MP_ioapic_info was the primary way of setting up our
ioapic data structures and mp_register_ioapic was a compatibility
shim for acpi code. Now the situation is reversed and
and mp_register_ioapic is the primary way of setting up our
ioapic data structures.
Keep the setting up of ioapic data structures uniform by
having mp_register_ioapic call mp_register_ioapic.
This changes a few fields:
- type: is now hardset to MP_IOAPIC but type had to
bey MP_IOAPIC or MP_ioapic_info would not have been called.
- flags: is now hard coded to MPC_APIC_USABLE.
We require flags to contain at least MPC_APIC_USEBLE in
MP_ioapic_info and we don't ever examine flags so dropping
a few flags that might possibly exist that we have never
used is harmless.
- apicaddr: Unchanged
- apicver: Read from the ioapic instead of using the cached
hardware value in the MP table. The real hardware value
will be more accurate.
- apicid: Now verified to be unique and changed if it is not.
If the BIOS got this right this is a noop. If the BIOS did
not fixing things appears to be the better solution.
This adds gsi_base and gsi_end values to our ioapics defined with
the mpatable, which will make our lives simpler later since
we can always assume gsi_base and gsi_end are valid.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/kernel/mpparse.c | 25 +------------------------
1 files changed, 1 insertions(+), 24 deletions(-)
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index a2c1edd..c0de938 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -115,21 +115,6 @@ static void __init MP_bus_info(struct mpc_bus *m)
printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str);
}
-static int bad_ioapic(unsigned long address)
-{
- if (nr_ioapics >= MAX_IO_APICS) {
- printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
- "(found %d)\n", MAX_IO_APICS, nr_ioapics);
- panic("Recompile kernel with bigger MAX_IO_APICS!\n");
- }
- if (!address) {
- printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
- " found in table, skipping!\n");
- return 1;
- }
- return 0;
-}
-
static void __init MP_ioapic_info(struct mpc_ioapic *m)
{
if (!(m->flags & MPC_APIC_USABLE))
@@ -138,15 +123,7 @@ static void __init MP_ioapic_info(struct mpc_ioapic *m)
printk(KERN_INFO "I/O APIC #%d Version %d at 0x%X.\n",
m->apicid, m->apicver, m->apicaddr);
- if (bad_ioapic(m->apicaddr))
- return;
-
- mp_ioapics[nr_ioapics].apicaddr = m->apicaddr;
- mp_ioapics[nr_ioapics].apicid = m->apicid;
- mp_ioapics[nr_ioapics].type = m->type;
- mp_ioapics[nr_ioapics].apicver = m->apicver;
- mp_ioapics[nr_ioapics].flags = m->flags;
- nr_ioapics++;
+ mp_register_ioapic(m->apicid, m->apicaddr, gsi_end);
}
static void print_MP_intsrc_info(struct mpc_intsrc *m)
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 10/14] x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic.
2010-03-29 23:19 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
` (8 preceding siblings ...)
2010-03-29 23:20 ` [PATCH 09/14] x86 ioapic: In mpparse use mp_register_ioapic Eric W. Biederman
@ 2010-03-29 23:20 ` Eric W. Biederman
2010-03-29 23:20 ` [PATCH 11/14] x86 ioapic: Optimize pin_2_irq Eric W. Biederman
` (5 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Now that all ioapic registration happens in mp_register_ioapic we can
move the calculation of nr_ioapic_registers there from enable_IO_APIC.
The number of ioapic registers is already calucated in mp_register_ioapic
so all that really needs to be done is to save the caluclated value
in nr_ioapic_registers.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/kernel/apic/io_apic.c | 22 ++++++++--------------
1 files changed, 8 insertions(+), 14 deletions(-)
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index a979a00..0515f26 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1944,20 +1944,8 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
void __init enable_IO_APIC(void)
{
- union IO_APIC_reg_01 reg_01;
int i8259_apic, i8259_pin;
int apic;
- unsigned long flags;
-
- /*
- * The number of IO-APIC IRQ registers (== #pins):
- */
- for (apic = 0; apic < nr_ioapics; apic++) {
- raw_spin_lock_irqsave(&ioapic_lock, flags);
- reg_01.raw = io_apic_read(apic, 1);
- raw_spin_unlock_irqrestore(&ioapic_lock, flags);
- nr_ioapic_registers[apic] = reg_01.bits.entries+1;
- }
if (!legacy_pic->nr_legacy_irqs)
return;
@@ -4280,6 +4268,7 @@ static int bad_ioapic(unsigned long address)
void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
{
int idx = 0;
+ int entries;
if (bad_ioapic(address))
return;
@@ -4298,9 +4287,14 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
* Build basic GSI lookup table to facilitate gsi->io_apic lookups
* and to prevent reprogramming of IOAPIC pins (PCI GSIs).
*/
+ entries = io_apic_get_redir_entries(idx);
mp_gsi_routing[idx].gsi_base = gsi_base;
- mp_gsi_routing[idx].gsi_end = gsi_base +
- io_apic_get_redir_entries(idx);
+ mp_gsi_routing[idx].gsi_end = gsi_base + entries;
+
+ /*
+ * The number of IO-APIC IRQ registers (== #pins):
+ */
+ nr_ioapic_registers[idx] = entries;
if (mp_gsi_routing[idx].gsi_end > gsi_end)
gsi_end = mp_gsi_routing[idx].gsi_end;
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 11/14] x86 ioapic: Optimize pin_2_irq
2010-03-29 23:19 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
` (9 preceding siblings ...)
2010-03-29 23:20 ` [PATCH 10/14] x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic Eric W. Biederman
@ 2010-03-29 23:20 ` Eric W. Biederman
2010-03-29 23:20 ` [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi Eric W. Biederman
` (4 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Now that all ioapics have valid gsi_base values use this to
accellerate pin_2_irq. In the case of acpi this also ensures
that pin_2_irq will compute the same irq value for an ioapic
pin as acpi will.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/kernel/apic/io_apic.c | 13 ++++---------
1 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 0515f26..996cf8f 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1018,7 +1018,7 @@ static inline int irq_trigger(int idx)
int (*ioapic_renumber_irq)(int ioapic, int irq);
static int pin_2_irq(int idx, int apic, int pin)
{
- int irq, i;
+ int irq;
int bus = mp_irqs[idx].srcbus;
/*
@@ -1030,18 +1030,13 @@ static int pin_2_irq(int idx, int apic, int pin)
if (test_bit(bus, mp_bus_not_pci)) {
irq = mp_irqs[idx].srcbusirq;
} else {
- /*
- * PCI IRQs are mapped in order
- */
- i = irq = 0;
- while (i < apic)
- irq += nr_ioapic_registers[i++];
- irq += pin;
+ u32 gsi = mp_gsi_routing[apic].gsi_base + pin;
/*
* For MPS mode, so far only needed by ES7000 platform
*/
if (ioapic_renumber_irq)
- irq = ioapic_renumber_irq(apic, irq);
+ gsi = ioapic_renumber_irq(apic, gsi);
+ irq = gsi;
}
#ifdef CONFIG_X86_32
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi.
2010-03-29 23:19 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
` (10 preceding siblings ...)
2010-03-29 23:20 ` [PATCH 11/14] x86 ioapic: Optimize pin_2_irq Eric W. Biederman
@ 2010-03-29 23:20 ` Eric W. Biederman
2010-03-30 2:16 ` Yinghai Lu
2010-03-29 23:20 ` [PATCH 13/14] x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's Eric W. Biederman
` (3 subsequent siblings)
15 siblings, 1 reply; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Use the global gsi_end value now that all ioapics have
valid gsi numbers instead of a combination of acpi_probe_gsi
and walking all of the ioapics and couting their number of
entries by hand if acpi_probe_gsi gave us an answer we did
not like.
This fixes a small bug in probe_nr_irqs_gsi. Previously
acpi_probe_gsi unnecessarily added 1 to the maximum
gsi_end value. gsi_end is already one past the end of
the number of gsi's so the additional increment was
superfluous.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/include/asm/mpspec.h | 6 ------
arch/x86/kernel/acpi/boot.c | 23 -----------------------
arch/x86/kernel/apic/io_apic.c | 17 +++--------------
3 files changed, 3 insertions(+), 43 deletions(-)
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index 29994f0..c82868e 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -105,12 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void);
struct device;
extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
int active_high_low);
-extern int acpi_probe_gsi(void);
-#else /* !CONFIG_ACPI: */
-static inline int acpi_probe_gsi(void)
-{
- return 0;
-}
#endif /* CONFIG_ACPI */
#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 9c48e99..0e514a1 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -875,29 +875,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
extern int es7000_plat;
#endif
-int __init acpi_probe_gsi(void)
-{
- int idx;
- int gsi;
- int max_gsi = 0;
-
- if (acpi_disabled)
- return 0;
-
- if (!acpi_ioapic)
- return 0;
-
- max_gsi = 0;
- for (idx = 0; idx < nr_ioapics; idx++) {
- gsi = mp_gsi_routing[idx].gsi_end;
-
- if (gsi > max_gsi)
- max_gsi = gsi;
- }
-
- return max_gsi + 1;
-}
-
static void assign_to_mp_irq(struct mpc_intsrc *m,
struct mpc_intsrc *mp_irq)
{
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 996cf8f..b57b7a3 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3837,22 +3837,11 @@ int __init io_apic_get_redir_entries (int ioapic)
void __init probe_nr_irqs_gsi(void)
{
- int nr = 0;
+ int nr;
- nr = acpi_probe_gsi();
- if (nr > nr_irqs_gsi) {
+ nr = gsi_end;
+ if (nr > nr_irqs_gsi)
nr_irqs_gsi = nr;
- } else {
- /* for acpi=off or acpi is not compiled in */
- int idx;
-
- nr = 0;
- for (idx = 0; idx < nr_ioapics; idx++)
- nr += io_apic_get_redir_entries(idx) + 1;
-
- if (nr > nr_irqs_gsi)
- nr_irqs_gsi = nr;
- }
printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
}
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 13/14] x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
2010-03-29 23:19 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
` (11 preceding siblings ...)
2010-03-29 23:20 ` [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi Eric W. Biederman
@ 2010-03-29 23:20 ` Eric W. Biederman
2010-03-29 23:20 ` [PATCH 14/14] x86 irq: Kill io_apic_renumber_irq Eric W. Biederman
` (2 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
ACPI irq source overrides are allowed for the 16 isa irqs and are
allowed to map any gsi to any isa irq. A few motherboards have been
seen to take advantage of this and put the isa irqs on the 2nd or
3rd ioapic. This causes some problems, most notably the fact
that we can not use any gsi < 16.
To correct this move the gsis that are not isa irqs and have
a gsi number < 16 into the linux irq space just past gsi_end.
This is what the es7000 platform is doing today. Moving only the
low 16 gsis above the rest of the gsi's only penalizes weird
platforms, leaving sane acpi implementations with a 1-1 mapping
of gsis and irqs.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/kernel/acpi/boot.c | 57 +++++++++++++++++++++++++++++++++++++---
arch/x86/kernel/apic/io_apic.c | 8 ++++-
2 files changed, 59 insertions(+), 6 deletions(-)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 0e514a1..b372aba 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -92,6 +92,53 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
+/*
+ * ISA irqs by default are the first 16 gsis but can be
+ * any gsi as specified by an interrupt source override.
+ */
+static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+static unsigned int gsi_to_irq(unsigned int gsi)
+{
+ unsigned int irq = gsi + NR_IRQS_LEGACY;
+ unsigned int i;
+
+ for (i = 0; i < NR_IRQS_LEGACY; i++) {
+ if (isa_irq_to_gsi[i] == gsi) {
+ return i;
+ }
+ }
+
+ /* Provide an identity mapping of gsi == irq
+ * except on truly weird platforms that have
+ * non isa irqs in the first 16 gsis.
+ */
+ if (gsi >= NR_IRQS_LEGACY)
+ irq = gsi;
+ else
+ irq = gsi_end + gsi;
+
+ return irq;
+}
+
+static u32 irq_to_gsi(int irq)
+{
+ unsigned int gsi;
+
+ if (irq < NR_IRQS_LEGACY)
+ gsi = isa_irq_to_gsi[irq];
+ else if (irq < gsi_end)
+ gsi = irq;
+ else if (irq < (gsi_end + NR_IRQS_LEGACY))
+ gsi = irq - gsi_end;
+ else
+ gsi = 0xffffffff;
+
+ return gsi;
+}
+
/*
* Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
* to map the target physical address. The problem is that set_fixmap()
@@ -448,7 +495,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
{
- *irq = gsi;
+ *irq = gsi_to_irq(gsi);
#ifdef CONFIG_X86_IO_APIC
if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
@@ -462,7 +509,7 @@ int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
{
if (isa_irq >= 16)
return -1;
- *gsi = isa_irq;
+ *gsi = irq_to_gsi(isa_irq);
return 0;
}
@@ -490,7 +537,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
}
#endif
- irq = plat_gsi;
+ irq = gsi_to_irq(plat_gsi);
return irq;
}
@@ -932,6 +979,8 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
mp_irq.dstirq = pin; /* INTIN# */
save_mp_irq(&mp_irq);
+
+ isa_irq_to_gsi[bus_irq] = gsi;
}
void __init mp_config_acpi_legacy_irqs(void)
@@ -1085,7 +1134,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
- io_apic_set_pci_routing(dev, gsi, &irq_attr);
+ io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr);
return gsi;
}
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index b57b7a3..f2c26d2 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1036,7 +1036,11 @@ static int pin_2_irq(int idx, int apic, int pin)
*/
if (ioapic_renumber_irq)
gsi = ioapic_renumber_irq(apic, gsi);
- irq = gsi;
+
+ if (gsi >= NR_IRQS_LEGACY)
+ irq = gsi;
+ else
+ irq = gsi_end + gsi;
}
#ifdef CONFIG_X86_32
@@ -3839,7 +3843,7 @@ void __init probe_nr_irqs_gsi(void)
{
int nr;
- nr = gsi_end;
+ nr = gsi_end + NR_IRQS_LEGACY;
if (nr > nr_irqs_gsi)
nr_irqs_gsi = nr;
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 14/14] x86 irq: Kill io_apic_renumber_irq
2010-03-29 23:19 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
` (12 preceding siblings ...)
2010-03-29 23:20 ` [PATCH 13/14] x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's Eric W. Biederman
@ 2010-03-29 23:20 ` Eric W. Biederman
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
2010-04-01 2:02 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Len Brown
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-29 23:20 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Now that the generic irq layer is performing the exact same remapping as
io_apic_renumber_irq we can kill this weird es7000 specific function.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/include/asm/io_apic.h | 1 -
arch/x86/kernel/acpi/boot.c | 5 -----
arch/x86/kernel/apic/es7000_32.c | 19 -------------------
arch/x86/kernel/apic/io_apic.c | 6 ------
4 files changed, 0 insertions(+), 31 deletions(-)
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 37b0f2b..9da192a 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -159,7 +159,6 @@ struct io_apic_irq_attr;
extern int io_apic_set_pci_routing(struct device *dev, int irq,
struct io_apic_irq_attr *irq_attr);
void setup_IO_APIC_irq_extra(u32 gsi);
-extern int (*ioapic_renumber_irq)(int ioapic, int irq);
extern void ioapic_init_mappings(void);
extern void ioapic_insert_resources(void);
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index b372aba..a48dfa9 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -1116,11 +1116,6 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
ioapic_pin = mp_find_ioapic_pin(ioapic, gsi);
-#ifdef CONFIG_X86_32
- if (ioapic_renumber_irq)
- gsi = ioapic_renumber_irq(ioapic, gsi);
-#endif
-
if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
printk(KERN_ERR "Invalid reference to IOAPIC pin "
"%d-%d\n", mp_ioapics[ioapic].apicid,
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
index dd2b5f2..7a63d47 100644
--- a/arch/x86/kernel/apic/es7000_32.c
+++ b/arch/x86/kernel/apic/es7000_32.c
@@ -130,24 +130,6 @@ int es7000_plat;
static unsigned int base;
-static int
-es7000_rename_gsi(int ioapic, int gsi)
-{
- if (es7000_plat == ES7000_ZORRO)
- return gsi;
-
- if (!base) {
- int i;
- for (i = 0; i < nr_ioapics; i++)
- base += nr_ioapic_registers[i];
- }
-
- if (!ioapic && (gsi < 16))
- gsi += base;
-
- return gsi;
-}
-
static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
{
unsigned long vect = 0, psaival = 0;
@@ -189,7 +171,6 @@ static void setup_unisys(void)
es7000_plat = ES7000_ZORRO;
else
es7000_plat = ES7000_CLASSIC;
- ioapic_renumber_irq = es7000_rename_gsi;
}
/*
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index f2c26d2..df7dcb3 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1015,7 +1015,6 @@ static inline int irq_trigger(int idx)
return MPBIOS_trigger(idx);
}
-int (*ioapic_renumber_irq)(int ioapic, int irq);
static int pin_2_irq(int idx, int apic, int pin)
{
int irq;
@@ -1031,11 +1030,6 @@ static int pin_2_irq(int idx, int apic, int pin)
irq = mp_irqs[idx].srcbusirq;
} else {
u32 gsi = mp_gsi_routing[apic].gsi_base + pin;
- /*
- * For MPS mode, so far only needed by ES7000 platform
- */
- if (ioapic_renumber_irq)
- gsi = ioapic_renumber_irq(apic, gsi);
if (gsi >= NR_IRQS_LEGACY)
irq = gsi;
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi.
2010-03-29 23:20 ` [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi Eric W. Biederman
@ 2010-03-30 2:16 ` Yinghai Lu
2010-03-30 4:43 ` Eric W. Biederman
0 siblings, 1 reply; 38+ messages in thread
From: Yinghai Lu @ 2010-03-30 2:16 UTC (permalink / raw)
To: Eric W. Biederman
Cc: H. Peter Anvin, Thomas Gleixner, Ingo Molnar, Andrew Morton,
Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
len.brown, Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad,
Gary Hade, Natalie Protasevich
On Mon, Mar 29, 2010 at 4:20 PM, Eric W. Biederman
<ebiederm@xmission.com> wrote:
> From: Eric W. Biederman <ebiederm@xmission.com>
>
> Use the global gsi_end value now that all ioapics have
> valid gsi numbers instead of a combination of acpi_probe_gsi
> and walking all of the ioapics and couting their number of
> entries by hand if acpi_probe_gsi gave us an answer we did
> not like.
>
> This fixes a small bug in probe_nr_irqs_gsi. Previously
> acpi_probe_gsi unnecessarily added 1 to the maximum
> gsi_end value. gsi_end is already one past the end of
> the number of gsi's so the additional increment was
> superfluous.
>
> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
> ---
> arch/x86/include/asm/mpspec.h | 6 ------
> arch/x86/kernel/acpi/boot.c | 23 -----------------------
> arch/x86/kernel/apic/io_apic.c | 17 +++--------------
> 3 files changed, 3 insertions(+), 43 deletions(-)
>
> diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
> index 29994f0..c82868e 100644
> --- a/arch/x86/include/asm/mpspec.h
> +++ b/arch/x86/include/asm/mpspec.h
> @@ -105,12 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void);
> struct device;
> extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
> int active_high_low);
> -extern int acpi_probe_gsi(void);
> -#else /* !CONFIG_ACPI: */
> -static inline int acpi_probe_gsi(void)
> -{
> - return 0;
> -}
> #endif /* CONFIG_ACPI */
>
> #define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS)
> diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
> index 9c48e99..0e514a1 100644
> --- a/arch/x86/kernel/acpi/boot.c
> +++ b/arch/x86/kernel/acpi/boot.c
> @@ -875,29 +875,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
> extern int es7000_plat;
> #endif
>
> -int __init acpi_probe_gsi(void)
> -{
> - int idx;
> - int gsi;
> - int max_gsi = 0;
> -
> - if (acpi_disabled)
> - return 0;
> -
> - if (!acpi_ioapic)
> - return 0;
> -
> - max_gsi = 0;
> - for (idx = 0; idx < nr_ioapics; idx++) {
> - gsi = mp_gsi_routing[idx].gsi_end;
> -
> - if (gsi > max_gsi)
> - max_gsi = gsi;
> - }
> -
> - return max_gsi + 1;
> -}
> -
> static void assign_to_mp_irq(struct mpc_intsrc *m,
> struct mpc_intsrc *mp_irq)
> {
> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
> index 996cf8f..b57b7a3 100644
> --- a/arch/x86/kernel/apic/io_apic.c
> +++ b/arch/x86/kernel/apic/io_apic.c
> @@ -3837,22 +3837,11 @@ int __init io_apic_get_redir_entries (int ioapic)
>
> void __init probe_nr_irqs_gsi(void)
> {
> - int nr = 0;
> + int nr;
>
> - nr = acpi_probe_gsi();
> - if (nr > nr_irqs_gsi) {
> + nr = gsi_end;
you may need +1 here
YH
> + if (nr > nr_irqs_gsi)
> nr_irqs_gsi = nr;
> - } else {
> - /* for acpi=off or acpi is not compiled in */
> - int idx;
> -
> - nr = 0;
> - for (idx = 0; idx < nr_ioapics; idx++)
> - nr += io_apic_get_redir_entries(idx) + 1;
> -
> - if (nr > nr_irqs_gsi)
> - nr_irqs_gsi = nr;
> - }
>
> printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
> }
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi.
2010-03-30 2:16 ` Yinghai Lu
@ 2010-03-30 4:43 ` Eric W. Biederman
2010-03-30 4:55 ` Yinghai Lu
0 siblings, 1 reply; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 4:43 UTC (permalink / raw)
To: Yinghai Lu
Cc: H. Peter Anvin, Thomas Gleixner, Ingo Molnar, Andrew Morton,
Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
len.brown, Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad,
Gary Hade, Natalie Protasevich
Yinghai Lu <yinghai@kernel.org> writes:
> On Mon, Mar 29, 2010 at 4:20 PM, Eric W. Biederman
> <ebiederm@xmission.com> wrote:
>> From: Eric W. Biederman <ebiederm@xmission.com>
>>
>> Use the global gsi_end value now that all ioapics have
>> valid gsi numbers instead of a combination of acpi_probe_gsi
>> and walking all of the ioapics and couting their number of
>> entries by hand if acpi_probe_gsi gave us an answer we did
>> not like.
>>
>> This fixes a small bug in probe_nr_irqs_gsi. Previously
>> acpi_probe_gsi unnecessarily added 1 to the maximum
>> gsi_end value. gsi_end is already one past the end of
>> the number of gsi's so the additional increment was
>> superfluous.
>>
>> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
>> ---
>> arch/x86/include/asm/mpspec.h | 6 ------
>> arch/x86/kernel/acpi/boot.c | 23 -----------------------
>> arch/x86/kernel/apic/io_apic.c | 17 +++--------------
>> 3 files changed, 3 insertions(+), 43 deletions(-)
>>
>> diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
>> index 29994f0..c82868e 100644
>> --- a/arch/x86/include/asm/mpspec.h
>> +++ b/arch/x86/include/asm/mpspec.h
>> @@ -105,12 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void);
>> struct device;
>> extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
>> int active_high_low);
>> -extern int acpi_probe_gsi(void);
>> -#else /* !CONFIG_ACPI: */
>> -static inline int acpi_probe_gsi(void)
>> -{
>> - return 0;
>> -}
>> #endif /* CONFIG_ACPI */
>>
>> #define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS)
>> diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
>> index 9c48e99..0e514a1 100644
>> --- a/arch/x86/kernel/acpi/boot.c
>> +++ b/arch/x86/kernel/acpi/boot.c
>> @@ -875,29 +875,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
>> extern int es7000_plat;
>> #endif
>>
>> -int __init acpi_probe_gsi(void)
>> -{
>> - int idx;
>> - int gsi;
>> - int max_gsi = 0;
>> -
>> - if (acpi_disabled)
>> - return 0;
>> -
>> - if (!acpi_ioapic)
>> - return 0;
>> -
>> - max_gsi = 0;
>> - for (idx = 0; idx < nr_ioapics; idx++) {
>> - gsi = mp_gsi_routing[idx].gsi_end;
>> -
>> - if (gsi > max_gsi)
>> - max_gsi = gsi;
>> - }
>> -
>> - return max_gsi + 1;
>> -}
>> -
>> static void assign_to_mp_irq(struct mpc_intsrc *m,
>> struct mpc_intsrc *mp_irq)
>> {
>> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
>> index 996cf8f..b57b7a3 100644
>> --- a/arch/x86/kernel/apic/io_apic.c
>> +++ b/arch/x86/kernel/apic/io_apic.c
>> @@ -3837,22 +3837,11 @@ int __init io_apic_get_redir_entries (int ioapic)
>>
>> void __init probe_nr_irqs_gsi(void)
>> {
>> - int nr = 0;
>> + int nr;
>>
>> - nr = acpi_probe_gsi();
>> - if (nr > nr_irqs_gsi) {
>> + nr = gsi_end;
>
> you may need +1 here
As documented in my comment that extra +1 has every appearance of a
bug. Nothing is at gsi_end. gsi_end is already at 1 past the last in
use gsi. Therefore an extra +1 puts us two past the end for no
apparent reason.
Eric
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi.
2010-03-30 4:43 ` Eric W. Biederman
@ 2010-03-30 4:55 ` Yinghai Lu
2010-03-30 5:41 ` Eric W. Biederman
0 siblings, 1 reply; 38+ messages in thread
From: Yinghai Lu @ 2010-03-30 4:55 UTC (permalink / raw)
To: Eric W. Biederman
Cc: H. Peter Anvin, Thomas Gleixner, Ingo Molnar, Andrew Morton,
Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
len.brown, Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad,
Gary Hade, Natalie Protasevich
On 03/29/2010 09:43 PM, Eric W. Biederman wrote:
> Yinghai Lu <yinghai@kernel.org> writes:
>
>> On Mon, Mar 29, 2010 at 4:20 PM, Eric W. Biederman
>> <ebiederm@xmission.com> wrote:
>>> From: Eric W. Biederman <ebiederm@xmission.com>
>>>
>>> Use the global gsi_end value now that all ioapics have
>>> valid gsi numbers instead of a combination of acpi_probe_gsi
>>> and walking all of the ioapics and couting their number of
>>> entries by hand if acpi_probe_gsi gave us an answer we did
>>> not like.
>>>
>>> This fixes a small bug in probe_nr_irqs_gsi. Previously
>>> acpi_probe_gsi unnecessarily added 1 to the maximum
>>> gsi_end value. gsi_end is already one past the end of
>>> the number of gsi's so the additional increment was
>>> superfluous.
>>>
>>> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
>>> ---
>>> arch/x86/include/asm/mpspec.h | 6 ------
>>> arch/x86/kernel/acpi/boot.c | 23 -----------------------
>>> arch/x86/kernel/apic/io_apic.c | 17 +++--------------
>>> 3 files changed, 3 insertions(+), 43 deletions(-)
>>>
>>> diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
>>> index 29994f0..c82868e 100644
>>> --- a/arch/x86/include/asm/mpspec.h
>>> +++ b/arch/x86/include/asm/mpspec.h
>>> @@ -105,12 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void);
>>> struct device;
>>> extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
>>> int active_high_low);
>>> -extern int acpi_probe_gsi(void);
>>> -#else /* !CONFIG_ACPI: */
>>> -static inline int acpi_probe_gsi(void)
>>> -{
>>> - return 0;
>>> -}
>>> #endif /* CONFIG_ACPI */
>>>
>>> #define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS)
>>> diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
>>> index 9c48e99..0e514a1 100644
>>> --- a/arch/x86/kernel/acpi/boot.c
>>> +++ b/arch/x86/kernel/acpi/boot.c
>>> @@ -875,29 +875,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
>>> extern int es7000_plat;
>>> #endif
>>>
>>> -int __init acpi_probe_gsi(void)
>>> -{
>>> - int idx;
>>> - int gsi;
>>> - int max_gsi = 0;
>>> -
>>> - if (acpi_disabled)
>>> - return 0;
>>> -
>>> - if (!acpi_ioapic)
>>> - return 0;
>>> -
>>> - max_gsi = 0;
>>> - for (idx = 0; idx < nr_ioapics; idx++) {
>>> - gsi = mp_gsi_routing[idx].gsi_end;
>>> -
>>> - if (gsi > max_gsi)
>>> - max_gsi = gsi;
>>> - }
>>> -
>>> - return max_gsi + 1;
>>> -}
>>> -
>>> static void assign_to_mp_irq(struct mpc_intsrc *m,
>>> struct mpc_intsrc *mp_irq)
>>> {
>>> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
>>> index 996cf8f..b57b7a3 100644
>>> --- a/arch/x86/kernel/apic/io_apic.c
>>> +++ b/arch/x86/kernel/apic/io_apic.c
>>> @@ -3837,22 +3837,11 @@ int __init io_apic_get_redir_entries (int ioapic)
>>>
>>> void __init probe_nr_irqs_gsi(void)
>>> {
>>> - int nr = 0;
>>> + int nr;
>>>
>>> - nr = acpi_probe_gsi();
>>> - if (nr > nr_irqs_gsi) {
>>> + nr = gsi_end;
>>
>> you may need +1 here
>
> As documented in my comment that extra +1 has every appearance of a
> bug. Nothing is at gsi_end. gsi_end is already at 1 past the last in
> use gsi. Therefore an extra +1 puts us two past the end for no
> apparent reason.
io_apic_get_redir_entries(), and io apic register readingout will return 23 if the total entries is 24.
[ 0.000000] ACPI: IOAPIC (id[0x08] address[0xfec00000] gsi_base[0])
[ 0.000000] IOAPIC[0]: apic_id 8, version 32, address 0xfec00000, GSI 0-23
[ 0.000000] ACPI: IOAPIC (id[0x09] address[0xfec02000] gsi_base[24])
[ 0.000000] IOAPIC[1]: apic_id 9, version 32, address 0xfec02000, GSI 24-47
[ 0.000000] ACPI: IOAPIC (id[0x0a] address[0xfec04000] gsi_base[48])
[ 0.000000] IOAPIC[2]: apic_id 10, version 32, address 0xfec04000, GSI 48-71
[ 0.000000] ACPI: IOAPIC (id[0x0b] address[0xfec08000] gsi_base[72])
[ 0.000000] IOAPIC[3]: apic_id 11, version 32, address 0xfec08000, GSI 72-95
[ 0.000000] ACPI: IOAPIC (id[0x0c] address[0xfec0c000] gsi_base[96])
[ 0.000000] IOAPIC[4]: apic_id 12, version 32, address 0xfec0c000, GSI 96-119
mp_gsi_routing[idx].gsi_end = gsi_base +
io_apic_get_redir_entries(idx);
printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
"GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr,
mp_gsi_routing[idx].gsi_base, mp_gsi_routing[idx].gsi_end);
YH
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi.
2010-03-30 4:55 ` Yinghai Lu
@ 2010-03-30 5:41 ` Eric W. Biederman
0 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 5:41 UTC (permalink / raw)
To: Yinghai Lu
Cc: H. Peter Anvin, Thomas Gleixner, Ingo Molnar, Andrew Morton,
Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
len.brown, Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad,
Gary Hade, Natalie Protasevich
Yinghai Lu <yinghai@kernel.org> writes:
> On 03/29/2010 09:43 PM, Eric W. Biederman wrote:
>> Yinghai Lu <yinghai@kernel.org> writes:
>>
>>> On Mon, Mar 29, 2010 at 4:20 PM, Eric W. Biederman
>>> <ebiederm@xmission.com> wrote:
>>>> From: Eric W. Biederman <ebiederm@xmission.com>
>>>>
>>>> Use the global gsi_end value now that all ioapics have
>>>> valid gsi numbers instead of a combination of acpi_probe_gsi
>>>> and walking all of the ioapics and couting their number of
>>>> entries by hand if acpi_probe_gsi gave us an answer we did
>>>> not like.
>>>>
>>>> This fixes a small bug in probe_nr_irqs_gsi. Previously
>>>> acpi_probe_gsi unnecessarily added 1 to the maximum
>>>> gsi_end value. gsi_end is already one past the end of
>>>> the number of gsi's so the additional increment was
>>>> superfluous.
>>>>
>>>> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
>>>> ---
>>>> arch/x86/include/asm/mpspec.h | 6 ------
>>>> arch/x86/kernel/acpi/boot.c | 23 -----------------------
>>>> arch/x86/kernel/apic/io_apic.c | 17 +++--------------
>>>> 3 files changed, 3 insertions(+), 43 deletions(-)
>>>>
>>>> diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
>>>> index 29994f0..c82868e 100644
>>>> --- a/arch/x86/include/asm/mpspec.h
>>>> +++ b/arch/x86/include/asm/mpspec.h
>>>> @@ -105,12 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void);
>>>> struct device;
>>>> extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
>>>> int active_high_low);
>>>> -extern int acpi_probe_gsi(void);
>>>> -#else /* !CONFIG_ACPI: */
>>>> -static inline int acpi_probe_gsi(void)
>>>> -{
>>>> - return 0;
>>>> -}
>>>> #endif /* CONFIG_ACPI */
>>>>
>>>> #define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS)
>>>> diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
>>>> index 9c48e99..0e514a1 100644
>>>> --- a/arch/x86/kernel/acpi/boot.c
>>>> +++ b/arch/x86/kernel/acpi/boot.c
>>>> @@ -875,29 +875,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
>>>> extern int es7000_plat;
>>>> #endif
>>>>
>>>> -int __init acpi_probe_gsi(void)
>>>> -{
>>>> - int idx;
>>>> - int gsi;
>>>> - int max_gsi = 0;
>>>> -
>>>> - if (acpi_disabled)
>>>> - return 0;
>>>> -
>>>> - if (!acpi_ioapic)
>>>> - return 0;
>>>> -
>>>> - max_gsi = 0;
>>>> - for (idx = 0; idx < nr_ioapics; idx++) {
>>>> - gsi = mp_gsi_routing[idx].gsi_end;
>>>> -
>>>> - if (gsi > max_gsi)
>>>> - max_gsi = gsi;
>>>> - }
>>>> -
>>>> - return max_gsi + 1;
>>>> -}
>>>> -
>>>> static void assign_to_mp_irq(struct mpc_intsrc *m,
>>>> struct mpc_intsrc *mp_irq)
>>>> {
>>>> diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
>>>> index 996cf8f..b57b7a3 100644
>>>> --- a/arch/x86/kernel/apic/io_apic.c
>>>> +++ b/arch/x86/kernel/apic/io_apic.c
>>>> @@ -3837,22 +3837,11 @@ int __init io_apic_get_redir_entries (int ioapic)
>>>>
>>>> void __init probe_nr_irqs_gsi(void)
>>>> {
>>>> - int nr = 0;
>>>> + int nr;
>>>>
>>>> - nr = acpi_probe_gsi();
>>>> - if (nr > nr_irqs_gsi) {
>>>> + nr = gsi_end;
>>>
>>> you may need +1 here
>>
>> As documented in my comment that extra +1 has every appearance of a
>> bug. Nothing is at gsi_end. gsi_end is already at 1 past the last in
>> use gsi. Therefore an extra +1 puts us two past the end for no
>> apparent reason.
>
> io_apic_get_redir_entries(), and io apic register readingout will return 23 if the total entries is 24.
Good catch. I don't know if I have ever seen a function with a name to function
correspondence. Apparently sfi.c also got this wrong when it was written.
and I missed the +1 in other places.
I guess this calls for another patch way at the beginning of my series that fixes
this brain damage.
Eric
^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2
2010-03-29 23:19 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
` (13 preceding siblings ...)
2010-03-29 23:20 ` [PATCH 14/14] x86 irq: Kill io_apic_renumber_irq Eric W. Biederman
@ 2010-03-30 8:06 ` Eric W. Biederman
2010-03-30 8:07 ` [PATCH 01/15] x86 acpi/irq: Introduce apci_isa_irq_to_gsi Eric W. Biederman
` (15 more replies)
2010-04-01 2:02 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Len Brown
15 siblings, 16 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 8:06 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Yinghai Lu, Ingo Molnar, Andrew Morton,
Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
len.brown, Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad,
Gary Hade, Natalie Protasevich
It appears there are a few systems in the wild that use acpi
interrupt source overrides to report a gsi > 16 is an isa irq.
This breaks all kinds of assumptions I figure any BIOS doing that
probably should be shot as that is very much not a conservative position.
That said acpi appears to allow this insanity and on the basis of being
liberal in what we accept we should try to do something reasonable, and
keep our notions of gsi, isa irq, and linux irq as straight as we can.
To that end this patchset slightly modifies the gsi to linux irq
mapping. Making it a 1 to 1 identity mapping except for the first 16
gsis. If those gsis are isa irqs (the typical and default acpi
configuration) they will be mapped into the first 16 irqs. If those
first 16 gsis are not isa irqs they will be given a linux irq number
just past the last gsi. Allowing us the chance to use them.
This patchset is my attempt to straighten out our understanding of which
kind of irq name is used where and the cleanups used to get there.
Thanks to Yinghai Lu <yinghai@kernel.org> for taking the first stab at
this and finding that there is a real world problem here. This patchset
is inspired by his work, but little of it remains the same.
This patchset lies in the weird world between the acpi and x86 and ia64.
Since most of the changes are x86 related I think it makes most sense
to go via the x86 tree.
v2: Recognize that gsi_end is last gsi for an ioapic not one past the end.
Since I use gsi_end widely in my patchset a respin of many of the patches
made sense.
Eric W. Biederman (15):
x86 acpi/irq: Introduce apci_isa_irq_to_gsi
x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq
x86 acpi/irq: pci device dev->irq is an isa irq not a gsi
x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi
x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs
x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h
x86 ioapic: Fix io_apic_redir_entries to return the number of entries.
x86 ioapic: Fix the types of gsi values
x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end
x86 ioapic: In mpparse use mp_register_ioapic
x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic.
x86 ioapic: Optimize pin_2_irq
x86 ioapic: Simplify probe_nr_irqs_gsi.
x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
x86 irq: Kill io_apic_renumber_irq
arch/ia64/kernel/acpi.c | 8 ++
arch/x86/include/asm/io_apic.h | 12 ++--
arch/x86/include/asm/mpspec.h | 10 ---
arch/x86/kernel/acpi/boot.c | 133 ++++++++++++++++++++++++--------------
arch/x86/kernel/apic/es7000_32.c | 19 ------
arch/x86/kernel/apic/io_apic.c | 99 +++++++++++++---------------
arch/x86/kernel/mpparse.c | 25 +-------
arch/x86/kernel/sfi.c | 4 +-
drivers/acpi/pci_irq.c | 8 ++-
include/linux/acpi.h | 5 +-
10 files changed, 154 insertions(+), 169 deletions(-)
Eric
^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 01/15] x86 acpi/irq: Introduce apci_isa_irq_to_gsi
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
@ 2010-03-30 8:07 ` Eric W. Biederman
2010-03-30 8:07 ` [PATCH 02/15] x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq Eric W. Biederman
` (14 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 8:07 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
There are a number of cases where the current code makes the assumption
that isa irqs identity map to the first 16 acpi global system intereupts.
In most instances that assumption is correct as that is the required
behaviour in dual i8259 mode and the default behavior in ioapic mode.
However there are some systems out there that take advantage of acpis
interrupt remapping for the isa irqs to have a completely different
mapping of isa_irq to gsi.
Introduce acpi_isa_irq_to_gsi to perform this mapping explicitly in the
code that needs it. Initially this will be just the current assumed
identity mapping to ensure it's introduction does not cause regressions.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/ia64/kernel/acpi.c | 8 ++++++++
arch/x86/kernel/acpi/boot.c | 8 ++++++++
include/linux/acpi.h | 1 +
3 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index f1c9f70..16921bd 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -784,6 +784,14 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
return 0;
}
+int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
+{
+ if (isa_irq >= 16)
+ return -1;
+ *gsi = isa_irq;
+ return 0;
+}
+
/*
* ACPI based hotplug CPU support
*/
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 0061ea2..f96060d 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -457,6 +457,14 @@ int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
return 0;
}
+int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
+{
+ if (isa_irq >= 16)
+ return -1;
+ *gsi = isa_irq;
+ return 0;
+}
+
/*
* success: return IRQ number (>=0)
* failure: return < 0
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index b926afe..7a937da 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -116,6 +116,7 @@ extern unsigned long acpi_realmode_flags;
int acpi_register_gsi (struct device *dev, u32 gsi, int triggering, int polarity);
int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
+int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);
#ifdef CONFIG_X86_IO_APIC
extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity);
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 02/15] x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
2010-03-30 8:07 ` [PATCH 01/15] x86 acpi/irq: Introduce apci_isa_irq_to_gsi Eric W. Biederman
@ 2010-03-30 8:07 ` Eric W. Biederman
2010-03-30 8:07 ` [PATCH 03/15] x86 acpi/irq: pci device dev->irq is an isa irq not a gsi Eric W. Biederman
` (13 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 8:07 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
In perverse acpi implementations the isa irqs are not identity mapped
to the first 16 gsi. Furthermore at least the extended interrupt
resource capability may return gsi's and not isa irqs. So since
what we get from acpi is a gsi teach acpi_get_overrride_irq to
operate on a gsi instead of an isa_irq.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/kernel/apic/io_apic.c | 23 ++++++++++++++---------
include/linux/acpi.h | 4 ++--
2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e4e0ddc..54ba1f7 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -4073,22 +4073,27 @@ int __init io_apic_get_version(int ioapic)
return reg_01.bits.version;
}
-int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
+int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity)
{
- int i;
+ int ioapic, pin, idx;
if (skip_ioapic_setup)
return -1;
- for (i = 0; i < mp_irq_entries; i++)
- if (mp_irqs[i].irqtype == mp_INT &&
- mp_irqs[i].srcbusirq == bus_irq)
- break;
- if (i >= mp_irq_entries)
+ ioapic = mp_find_ioapic(gsi);
+ if (ioapic < 0)
+ return -1;
+
+ pin = mp_find_ioapic_pin(ioapic, gsi);
+ if (pin < 0)
+ return -1;
+
+ idx = find_irq_entry(ioapic, pin, mp_INT);
+ if (idx < 0)
return -1;
- *trigger = irq_trigger(i);
- *polarity = irq_polarity(i);
+ *trigger = irq_trigger(idx);
+ *polarity = irq_polarity(idx);
return 0;
}
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 7a937da..3da73f5 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -119,9 +119,9 @@ int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
int acpi_isa_irq_to_gsi (unsigned isa_irq, u32 *gsi);
#ifdef CONFIG_X86_IO_APIC
-extern int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity);
+extern int acpi_get_override_irq(u32 gsi, int *trigger, int *polarity);
#else
-#define acpi_get_override_irq(bus, trigger, polarity) (-1)
+#define acpi_get_override_irq(gsi, trigger, polarity) (-1)
#endif
/*
* This function undoes the effect of one call to acpi_register_gsi().
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 03/15] x86 acpi/irq: pci device dev->irq is an isa irq not a gsi
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
2010-03-30 8:07 ` [PATCH 01/15] x86 acpi/irq: Introduce apci_isa_irq_to_gsi Eric W. Biederman
2010-03-30 8:07 ` [PATCH 02/15] x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq Eric W. Biederman
@ 2010-03-30 8:07 ` Eric W. Biederman
2010-03-30 8:07 ` [PATCH 04/15] x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi Eric W. Biederman
` (12 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 8:07 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Strictly speaking on x86 (where acpi is used) dev->irq must be
a dual i8259 irq input aka an isa irq. Therefore we should translate
that isa irq into a gsi before passing it to a function that
takes a gsi.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
drivers/acpi/pci_irq.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 843699e..703541d 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -400,11 +400,13 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
* driver reported one, then use it. Exit in any case.
*/
if (gsi < 0) {
+ u32 dev_gsi;
dev_warn(&dev->dev, "PCI INT %c: no GSI", pin_name(pin));
/* Interrupt Line values above 0xF are forbidden */
- if (dev->irq > 0 && (dev->irq <= 0xF)) {
- printk(" - using IRQ %d\n", dev->irq);
- acpi_register_gsi(&dev->dev, dev->irq,
+ if (dev->irq > 0 && (dev->irq <= 0xF) &&
+ (acpi_isa_irq_to_gsi(dev->irq, &dev_gsi) == 0)) {
+ printk(" - using ISA IRQ %d\n", dev->irq);
+ acpi_register_gsi(&dev->dev, dev_gsi,
ACPI_LEVEL_SENSITIVE,
ACPI_ACTIVE_LOW);
return 0;
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 04/15] x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
` (2 preceding siblings ...)
2010-03-30 8:07 ` [PATCH 03/15] x86 acpi/irq: pci device dev->irq is an isa irq not a gsi Eric W. Biederman
@ 2010-03-30 8:07 ` Eric W. Biederman
2010-03-30 8:07 ` [PATCH 05/15] x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs Eric W. Biederman
` (11 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 8:07 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Currently acpi_sci_ioapic_setup calls mp_override_legacy_irq with
bus_irq == gsi, which is wrong if we are comming from an override
Instead pass the bus_irq into acpi_sci_ioapic_setup.
This fix was inspired by a similar fix from:
Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/kernel/acpi/boot.c | 12 +++++++-----
1 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index f96060d..1742888 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -312,7 +312,7 @@ acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
/*
* Parse Interrupt Source Override for the ACPI SCI
*/
-static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
+static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger, u32 gsi)
{
if (trigger == 0) /* compatible SCI trigger is level */
trigger = 3;
@@ -332,7 +332,7 @@ static void __init acpi_sci_ioapic_setup(u32 gsi, u16 polarity, u16 trigger)
* If GSI is < 16, this will update its flags,
* else it will create a new mp_irqs[] entry.
*/
- mp_override_legacy_irq(gsi, polarity, trigger, gsi);
+ mp_override_legacy_irq(bus_irq, polarity, trigger, gsi);
/*
* stash over-ride to indicate we've been here
@@ -356,9 +356,10 @@ acpi_parse_int_src_ovr(struct acpi_subtable_header * header,
acpi_table_print_madt_entry(header);
if (intsrc->source_irq == acpi_gbl_FADT.sci_interrupt) {
- acpi_sci_ioapic_setup(intsrc->global_irq,
+ acpi_sci_ioapic_setup(intsrc->source_irq,
intsrc->inti_flags & ACPI_MADT_POLARITY_MASK,
- (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2);
+ (intsrc->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2,
+ intsrc->global_irq);
return 0;
}
@@ -1161,7 +1162,8 @@ static int __init acpi_parse_madt_ioapic_entries(void)
* pretend we got one so we can set the SCI flags.
*/
if (!acpi_sci_override_gsi)
- acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0);
+ acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0,
+ acpi_gbl_FADT.sci_interrupt);
/* Fill in identity legacy mappings where no override */
mp_config_acpi_legacy_irqs();
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 05/15] x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
` (3 preceding siblings ...)
2010-03-30 8:07 ` [PATCH 04/15] x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi Eric W. Biederman
@ 2010-03-30 8:07 ` Eric W. Biederman
2010-03-30 8:07 ` [PATCH 06/15] x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h Eric W. Biederman
` (10 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 8:07 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Remove the assumption that there is not an override for isa irq 0.
Instead lookup the gsi and from that lookup the ioapic and pin of each
isa irq indivdually.
In general this should not have any behavioural affect but in
perverse cases this gets all of the details correct, instead of
doing something weird.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/kernel/acpi/boot.c | 30 ++++++++++++++++++------------
1 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 1742888..9c48e99 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -960,8 +960,6 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
void __init mp_config_acpi_legacy_irqs(void)
{
int i;
- int ioapic;
- unsigned int dstapic;
struct mpc_intsrc mp_irq;
#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
@@ -982,19 +980,27 @@ void __init mp_config_acpi_legacy_irqs(void)
#endif
/*
- * Locate the IOAPIC that manages the ISA IRQs (0-15).
- */
- ioapic = mp_find_ioapic(0);
- if (ioapic < 0)
- return;
- dstapic = mp_ioapics[ioapic].apicid;
-
- /*
* Use the default configuration for the IRQs 0-15. Unless
* overridden by (MADT) interrupt source override entries.
*/
for (i = 0; i < 16; i++) {
+ int ioapic, pin;
+ unsigned int dstapic;
int idx;
+ u32 gsi;
+
+ /* Locate the gsi that irq i maps to. */
+ if (acpi_isa_irq_to_gsi(i, &gsi))
+ continue;
+
+ /*
+ * Locate the IOAPIC that manages the ISA IRQ.
+ */
+ ioapic = mp_find_ioapic(gsi);
+ if (ioapic < 0)
+ continue;
+ pin = mp_find_ioapic_pin(ioapic, gsi);
+ dstapic = mp_ioapics[ioapic].apicid;
for (idx = 0; idx < mp_irq_entries; idx++) {
struct mpc_intsrc *irq = mp_irqs + idx;
@@ -1004,7 +1010,7 @@ void __init mp_config_acpi_legacy_irqs(void)
break;
/* Do we already have a mapping for this IOAPIC pin */
- if (irq->dstapic == dstapic && irq->dstirq == i)
+ if (irq->dstapic == dstapic && irq->dstirq == pin)
break;
}
@@ -1019,7 +1025,7 @@ void __init mp_config_acpi_legacy_irqs(void)
mp_irq.dstapic = dstapic;
mp_irq.irqtype = mp_INT;
mp_irq.srcbusirq = i; /* Identity mapped */
- mp_irq.dstirq = i;
+ mp_irq.dstirq = pin;
save_mp_irq(&mp_irq);
}
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 06/15] x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
` (4 preceding siblings ...)
2010-03-30 8:07 ` [PATCH 05/15] x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs Eric W. Biederman
@ 2010-03-30 8:07 ` Eric W. Biederman
2010-03-30 8:07 ` [PATCH 07/15] x86 ioapic: Fix io_apic_redir_entries to return the number of entries Eric W. Biederman
` (9 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 8:07 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Multiple declarations of the same function in different headers
is a pain to maintain.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/include/asm/mpspec.h | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index d8bf23a..29994f0 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -106,10 +106,6 @@ struct device;
extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
int active_high_low);
extern int acpi_probe_gsi(void);
-#ifdef CONFIG_X86_IO_APIC
-extern int mp_find_ioapic(int gsi);
-extern int mp_find_ioapic_pin(int ioapic, int gsi);
-#endif
#else /* !CONFIG_ACPI: */
static inline int acpi_probe_gsi(void)
{
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 07/15] x86 ioapic: Fix io_apic_redir_entries to return the number of entries.
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
` (5 preceding siblings ...)
2010-03-30 8:07 ` [PATCH 06/15] x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h Eric W. Biederman
@ 2010-03-30 8:07 ` Eric W. Biederman
2010-03-30 8:07 ` [PATCH 08/15] x86 ioapic: Fix the types of gsi values Eric W. Biederman
` (8 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 8:07 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
io_apic_redir_entries has a huge conceptual bug. It returns the maximum
redirection entry not the number of redirection entries. Which simply
does not match what the name of the function. This just caught me
and it caught Feng Tang, and Len Brown when they wrote sfi_parse_ioapic.
Modify io_apic_redir_entries to actually return the number of redirection
entries, and fix the callers so that they properly handle receiving the
number of the number of redirection table entries, instead of the
number of redirection table entries less one.
While the usage in sfi.c does not show up in this patch it is fixed
by virtue of the fact that io_apic_redir_entries now has the semantics
sfi_parse_ioapic most reasonably expects.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/kernel/apic/io_apic.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 54ba1f7..7e139bb 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3846,7 +3846,11 @@ int __init io_apic_get_redir_entries (int ioapic)
reg_01.raw = io_apic_read(ioapic, 1);
raw_spin_unlock_irqrestore(&ioapic_lock, flags);
- return reg_01.bits.entries;
+ /* The register returns the maximum index redir index
+ * supported, which is one less than the total number of redir
+ * entries.
+ */
+ return reg_01.bits.entries + 1;
}
void __init probe_nr_irqs_gsi(void)
@@ -3862,7 +3866,7 @@ void __init probe_nr_irqs_gsi(void)
nr = 0;
for (idx = 0; idx < nr_ioapics; idx++)
- nr += io_apic_get_redir_entries(idx) + 1;
+ nr += io_apic_get_redir_entries(idx);
if (nr > nr_irqs_gsi)
nr_irqs_gsi = nr;
@@ -4297,7 +4301,7 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
*/
mp_gsi_routing[idx].gsi_base = gsi_base;
mp_gsi_routing[idx].gsi_end = gsi_base +
- io_apic_get_redir_entries(idx);
+ io_apic_get_redir_entries(idx) - 1;
printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
"GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 08/15] x86 ioapic: Fix the types of gsi values
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
` (6 preceding siblings ...)
2010-03-30 8:07 ` [PATCH 07/15] x86 ioapic: Fix io_apic_redir_entries to return the number of entries Eric W. Biederman
@ 2010-03-30 8:07 ` Eric W. Biederman
2010-03-30 8:07 ` [PATCH 09/15] x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end Eric W. Biederman
` (7 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 8:07 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
This patches fixes the types of gsi_base and gsi_end values in
struct mp_ioapic_gsi, and the gsi parameter of mp_find_ioapic
and mp_find_ioapic_pin
A gsi is cannonically a u32, not an int.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/include/asm/io_apic.h | 10 +++++-----
arch/x86/kernel/apic/io_apic.c | 4 ++--
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 35832a0..feeaf0d 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -180,12 +180,12 @@ extern void ioapic_write_entry(int apic, int pin,
extern void setup_ioapic_ids_from_mpc(void);
struct mp_ioapic_gsi{
- int gsi_base;
- int gsi_end;
+ u32 gsi_base;
+ u32 gsi_end;
};
extern struct mp_ioapic_gsi mp_gsi_routing[];
-int mp_find_ioapic(int gsi);
-int mp_find_ioapic_pin(int ioapic, int gsi);
+int mp_find_ioapic(u32 gsi);
+int mp_find_ioapic_pin(int ioapic, u32 gsi);
void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
extern void __init pre_init_apic_IRQ0(void);
@@ -197,7 +197,7 @@ static const int timer_through_8259 = 0;
static inline void ioapic_init_mappings(void) { }
static inline void ioapic_insert_resources(void) { }
static inline void probe_nr_irqs_gsi(void) { }
-static inline int mp_find_ioapic(int gsi) { return 0; }
+static inline int mp_find_ioapic(u32 gsi) { return 0; }
struct io_apic_irq_attr;
static inline int io_apic_set_pci_routing(struct device *dev, int irq,
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 7e139bb..4611c43 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -4238,7 +4238,7 @@ void __init ioapic_insert_resources(void)
}
}
-int mp_find_ioapic(int gsi)
+int mp_find_ioapic(u32 gsi)
{
int i = 0;
@@ -4253,7 +4253,7 @@ int mp_find_ioapic(int gsi)
return -1;
}
-int mp_find_ioapic_pin(int ioapic, int gsi)
+int mp_find_ioapic_pin(int ioapic, u32 gsi)
{
if (WARN_ON(ioapic == -1))
return -1;
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 09/15] x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
` (7 preceding siblings ...)
2010-03-30 8:07 ` [PATCH 08/15] x86 ioapic: Fix the types of gsi values Eric W. Biederman
@ 2010-03-30 8:07 ` Eric W. Biederman
2010-03-30 8:07 ` [PATCH 10/15] x86 ioapic: In mpparse use mp_register_ioapic Eric W. Biederman
` (6 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 8:07 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Add the global variable gsi_end and teach mp_register_ioapic
to keep it uptodate as we add more ioapics into the system.
ioapics can only be added early in boot so the code that
runs later can treat gsi_end as a constant.
Remove the have hacks in sfi.c to second guess mp_register_ioapic
by keeping t's own running total of how many gsi's have been seen,
and instead use the gsi_end.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/include/asm/io_apic.h | 1 +
arch/x86/kernel/apic/io_apic.c | 6 ++++++
arch/x86/kernel/sfi.c | 4 +---
3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index feeaf0d..37b0f2b 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -184,6 +184,7 @@ struct mp_ioapic_gsi{
u32 gsi_end;
};
extern struct mp_ioapic_gsi mp_gsi_routing[];
+extern u32 gsi_end;
int mp_find_ioapic(u32 gsi);
int mp_find_ioapic_pin(int ioapic, u32 gsi);
void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 4611c43..71988c5 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -88,6 +88,9 @@ int nr_ioapics;
/* IO APIC gsi routing info */
struct mp_ioapic_gsi mp_gsi_routing[MAX_IO_APICS];
+/* The last gsi number used */
+u32 gsi_end;
+
/* MP IRQ source entries */
struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
@@ -4303,6 +4306,9 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
mp_gsi_routing[idx].gsi_end = gsi_base +
io_apic_get_redir_entries(idx) - 1;
+ if (mp_gsi_routing[idx].gsi_end > gsi_end)
+ gsi_end = mp_gsi_routing[idx].gsi_end;
+
printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
"GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr,
diff --git a/arch/x86/kernel/sfi.c b/arch/x86/kernel/sfi.c
index 34e0993..7ded578 100644
--- a/arch/x86/kernel/sfi.c
+++ b/arch/x86/kernel/sfi.c
@@ -81,7 +81,6 @@ static int __init sfi_parse_cpus(struct sfi_table_header *table)
#endif /* CONFIG_X86_LOCAL_APIC */
#ifdef CONFIG_X86_IO_APIC
-static u32 gsi_base;
static int __init sfi_parse_ioapic(struct sfi_table_header *table)
{
@@ -94,8 +93,7 @@ static int __init sfi_parse_ioapic(struct sfi_table_header *table)
pentry = (struct sfi_apic_table_entry *)sb->pentry;
for (i = 0; i < num; i++) {
- mp_register_ioapic(i, pentry->phys_addr, gsi_base);
- gsi_base += io_apic_get_redir_entries(i);
+ mp_register_ioapic(i, pentry->phys_addr, gsi_end + 1);
pentry++;
}
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 10/15] x86 ioapic: In mpparse use mp_register_ioapic
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
` (8 preceding siblings ...)
2010-03-30 8:07 ` [PATCH 09/15] x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end Eric W. Biederman
@ 2010-03-30 8:07 ` Eric W. Biederman
2010-03-30 8:07 ` [PATCH 11/15] x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic Eric W. Biederman
` (5 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 8:07 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Long ago MP_ioapic_info was the primary way of setting up our
ioapic data structures and mp_register_ioapic was a compatibility
shim for acpi code. Now the situation is reversed and
and mp_register_ioapic is the primary way of setting up our
ioapic data structures.
Keep the setting up of ioapic data structures uniform by
having mp_register_ioapic call mp_register_ioapic.
This changes a few fields:
- type: is now hardset to MP_IOAPIC but type had to
bey MP_IOAPIC or MP_ioapic_info would not have been called.
- flags: is now hard coded to MPC_APIC_USABLE.
We require flags to contain at least MPC_APIC_USEBLE in
MP_ioapic_info and we don't ever examine flags so dropping
a few flags that might possibly exist that we have never
used is harmless.
- apicaddr: Unchanged
- apicver: Read from the ioapic instead of using the cached
hardware value in the MP table. The real hardware value
will be more accurate.
- apicid: Now verified to be unique and changed if it is not.
If the BIOS got this right this is a noop. If the BIOS did
not fixing things appears to be the better solution.
This adds gsi_base and gsi_end values to our ioapics defined with
the mpatable, which will make our lives simpler later since
we can always assume gsi_base and gsi_end are valid.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/kernel/mpparse.c | 25 +------------------------
1 files changed, 1 insertions(+), 24 deletions(-)
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index a2c1edd..22ba4f3 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -115,21 +115,6 @@ static void __init MP_bus_info(struct mpc_bus *m)
printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str);
}
-static int bad_ioapic(unsigned long address)
-{
- if (nr_ioapics >= MAX_IO_APICS) {
- printk(KERN_ERR "ERROR: Max # of I/O APICs (%d) exceeded "
- "(found %d)\n", MAX_IO_APICS, nr_ioapics);
- panic("Recompile kernel with bigger MAX_IO_APICS!\n");
- }
- if (!address) {
- printk(KERN_ERR "WARNING: Bogus (zero) I/O APIC address"
- " found in table, skipping!\n");
- return 1;
- }
- return 0;
-}
-
static void __init MP_ioapic_info(struct mpc_ioapic *m)
{
if (!(m->flags & MPC_APIC_USABLE))
@@ -138,15 +123,7 @@ static void __init MP_ioapic_info(struct mpc_ioapic *m)
printk(KERN_INFO "I/O APIC #%d Version %d at 0x%X.\n",
m->apicid, m->apicver, m->apicaddr);
- if (bad_ioapic(m->apicaddr))
- return;
-
- mp_ioapics[nr_ioapics].apicaddr = m->apicaddr;
- mp_ioapics[nr_ioapics].apicid = m->apicid;
- mp_ioapics[nr_ioapics].type = m->type;
- mp_ioapics[nr_ioapics].apicver = m->apicver;
- mp_ioapics[nr_ioapics].flags = m->flags;
- nr_ioapics++;
+ mp_register_ioapic(m->apicid, m->apicaddr, gsi_end + 1);
}
static void print_MP_intsrc_info(struct mpc_intsrc *m)
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 11/15] x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic.
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
` (9 preceding siblings ...)
2010-03-30 8:07 ` [PATCH 10/15] x86 ioapic: In mpparse use mp_register_ioapic Eric W. Biederman
@ 2010-03-30 8:07 ` Eric W. Biederman
2010-03-30 8:07 ` [PATCH 12/15] x86 ioapic: Optimize pin_2_irq Eric W. Biederman
` (4 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 8:07 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Now that all ioapic registration happens in mp_register_ioapic we can
move the calculation of nr_ioapic_registers there from enable_IO_APIC.
The number of ioapic registers is already calucated in mp_register_ioapic
so all that really needs to be done is to save the caluclated value
in nr_ioapic_registers.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/kernel/apic/io_apic.c | 22 ++++++++--------------
1 files changed, 8 insertions(+), 14 deletions(-)
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 71988c5..c505fe0 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1944,20 +1944,8 @@ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
void __init enable_IO_APIC(void)
{
- union IO_APIC_reg_01 reg_01;
int i8259_apic, i8259_pin;
int apic;
- unsigned long flags;
-
- /*
- * The number of IO-APIC IRQ registers (== #pins):
- */
- for (apic = 0; apic < nr_ioapics; apic++) {
- raw_spin_lock_irqsave(&ioapic_lock, flags);
- reg_01.raw = io_apic_read(apic, 1);
- raw_spin_unlock_irqrestore(&ioapic_lock, flags);
- nr_ioapic_registers[apic] = reg_01.bits.entries+1;
- }
if (!legacy_pic->nr_legacy_irqs)
return;
@@ -4284,6 +4272,7 @@ static int bad_ioapic(unsigned long address)
void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
{
int idx = 0;
+ int entries;
if (bad_ioapic(address))
return;
@@ -4302,9 +4291,14 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
* Build basic GSI lookup table to facilitate gsi->io_apic lookups
* and to prevent reprogramming of IOAPIC pins (PCI GSIs).
*/
+ entries = io_apic_get_redir_entries(idx);
mp_gsi_routing[idx].gsi_base = gsi_base;
- mp_gsi_routing[idx].gsi_end = gsi_base +
- io_apic_get_redir_entries(idx) - 1;
+ mp_gsi_routing[idx].gsi_end = gsi_base + entries - 1;
+
+ /*
+ * The number of IO-APIC IRQ registers (== #pins):
+ */
+ nr_ioapic_registers[idx] = entries;
if (mp_gsi_routing[idx].gsi_end > gsi_end)
gsi_end = mp_gsi_routing[idx].gsi_end;
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 12/15] x86 ioapic: Optimize pin_2_irq
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
` (10 preceding siblings ...)
2010-03-30 8:07 ` [PATCH 11/15] x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic Eric W. Biederman
@ 2010-03-30 8:07 ` Eric W. Biederman
2010-03-30 8:07 ` [PATCH 13/15] x86 ioapic: Simplify probe_nr_irqs_gsi Eric W. Biederman
` (3 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 8:07 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Now that all ioapics have valid gsi_base values use this to
accellerate pin_2_irq. In the case of acpi this also ensures
that pin_2_irq will compute the same irq value for an ioapic
pin as acpi will.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/kernel/apic/io_apic.c | 13 ++++---------
1 files changed, 4 insertions(+), 9 deletions(-)
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index c505fe0..764c74c 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1018,7 +1018,7 @@ static inline int irq_trigger(int idx)
int (*ioapic_renumber_irq)(int ioapic, int irq);
static int pin_2_irq(int idx, int apic, int pin)
{
- int irq, i;
+ int irq;
int bus = mp_irqs[idx].srcbus;
/*
@@ -1030,18 +1030,13 @@ static int pin_2_irq(int idx, int apic, int pin)
if (test_bit(bus, mp_bus_not_pci)) {
irq = mp_irqs[idx].srcbusirq;
} else {
- /*
- * PCI IRQs are mapped in order
- */
- i = irq = 0;
- while (i < apic)
- irq += nr_ioapic_registers[i++];
- irq += pin;
+ u32 gsi = mp_gsi_routing[apic].gsi_base + pin;
/*
* For MPS mode, so far only needed by ES7000 platform
*/
if (ioapic_renumber_irq)
- irq = ioapic_renumber_irq(apic, irq);
+ gsi = ioapic_renumber_irq(apic, gsi);
+ irq = gsi;
}
#ifdef CONFIG_X86_32
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 13/15] x86 ioapic: Simplify probe_nr_irqs_gsi.
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
` (11 preceding siblings ...)
2010-03-30 8:07 ` [PATCH 12/15] x86 ioapic: Optimize pin_2_irq Eric W. Biederman
@ 2010-03-30 8:07 ` Eric W. Biederman
2010-03-30 8:07 ` [PATCH 14/15] x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's Eric W. Biederman
` (2 subsequent siblings)
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 8:07 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Use the global gsi_end value now that all ioapics have
valid gsi numbers instead of a combination of acpi_probe_gsi
and walking all of the ioapics and couting their number of
entries by hand if acpi_probe_gsi gave us an answer we did
not like.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/include/asm/mpspec.h | 6 ------
arch/x86/kernel/acpi/boot.c | 23 -----------------------
arch/x86/kernel/apic/io_apic.c | 17 +++--------------
3 files changed, 3 insertions(+), 43 deletions(-)
diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
index 29994f0..c82868e 100644
--- a/arch/x86/include/asm/mpspec.h
+++ b/arch/x86/include/asm/mpspec.h
@@ -105,12 +105,6 @@ extern void mp_config_acpi_legacy_irqs(void);
struct device;
extern int mp_register_gsi(struct device *dev, u32 gsi, int edge_level,
int active_high_low);
-extern int acpi_probe_gsi(void);
-#else /* !CONFIG_ACPI: */
-static inline int acpi_probe_gsi(void)
-{
- return 0;
-}
#endif /* CONFIG_ACPI */
#define PHYSID_ARRAY_SIZE BITS_TO_LONGS(MAX_APICS)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 9c48e99..0e514a1 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -875,29 +875,6 @@ static int __init acpi_parse_madt_lapic_entries(void)
extern int es7000_plat;
#endif
-int __init acpi_probe_gsi(void)
-{
- int idx;
- int gsi;
- int max_gsi = 0;
-
- if (acpi_disabled)
- return 0;
-
- if (!acpi_ioapic)
- return 0;
-
- max_gsi = 0;
- for (idx = 0; idx < nr_ioapics; idx++) {
- gsi = mp_gsi_routing[idx].gsi_end;
-
- if (gsi > max_gsi)
- max_gsi = gsi;
- }
-
- return max_gsi + 1;
-}
-
static void assign_to_mp_irq(struct mpc_intsrc *m,
struct mpc_intsrc *mp_irq)
{
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 764c74c..6d6def8 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3841,22 +3841,11 @@ int __init io_apic_get_redir_entries (int ioapic)
void __init probe_nr_irqs_gsi(void)
{
- int nr = 0;
+ int nr;
- nr = acpi_probe_gsi();
- if (nr > nr_irqs_gsi) {
+ nr = gsi_end + 1;
+ if (nr > nr_irqs_gsi)
nr_irqs_gsi = nr;
- } else {
- /* for acpi=off or acpi is not compiled in */
- int idx;
-
- nr = 0;
- for (idx = 0; idx < nr_ioapics; idx++)
- nr += io_apic_get_redir_entries(idx);
-
- if (nr > nr_irqs_gsi)
- nr_irqs_gsi = nr;
- }
printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
}
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 14/15] x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
` (12 preceding siblings ...)
2010-03-30 8:07 ` [PATCH 13/15] x86 ioapic: Simplify probe_nr_irqs_gsi Eric W. Biederman
@ 2010-03-30 8:07 ` Eric W. Biederman
2010-03-30 8:07 ` [PATCH 15/15] x86 irq: Kill io_apic_renumber_irq Eric W. Biederman
2010-05-03 23:21 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 8:07 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
ACPI irq source overrides are allowed for the 16 isa irqs and are
allowed to map any gsi to any isa irq. A few motherboards have been
seen to take advantage of this and put the isa irqs on the 2nd or
3rd ioapic. This causes some problems, most notably the fact
that we can not use any gsi < 16.
To correct this move the gsis that are not isa irqs and have
a gsi number < 16 into the linux irq space just past gsi_end.
This is what the es7000 platform is doing today. Moving only the
low 16 gsis above the rest of the gsi's only penalizes weird
platforms, leaving sane acpi implementations with a 1-1 mapping
of gsis and irqs.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/kernel/acpi/boot.c | 57 +++++++++++++++++++++++++++++++++++++---
arch/x86/kernel/apic/io_apic.c | 8 ++++-
2 files changed, 59 insertions(+), 6 deletions(-)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 0e514a1..c4b4bd9 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -92,6 +92,53 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
+/*
+ * ISA irqs by default are the first 16 gsis but can be
+ * any gsi as specified by an interrupt source override.
+ */
+static u32 isa_irq_to_gsi[NR_IRQS_LEGACY] __read_mostly = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+static unsigned int gsi_to_irq(unsigned int gsi)
+{
+ unsigned int irq = gsi + NR_IRQS_LEGACY;
+ unsigned int i;
+
+ for (i = 0; i < NR_IRQS_LEGACY; i++) {
+ if (isa_irq_to_gsi[i] == gsi) {
+ return i;
+ }
+ }
+
+ /* Provide an identity mapping of gsi == irq
+ * except on truly weird platforms that have
+ * non isa irqs in the first 16 gsis.
+ */
+ if (gsi >= NR_IRQS_LEGACY)
+ irq = gsi;
+ else
+ irq = gsi_end + 1 + gsi;
+
+ return irq;
+}
+
+static u32 irq_to_gsi(int irq)
+{
+ unsigned int gsi;
+
+ if (irq < NR_IRQS_LEGACY)
+ gsi = isa_irq_to_gsi[irq];
+ else if (irq <= gsi_end)
+ gsi = irq;
+ else if (irq <= (gsi_end + NR_IRQS_LEGACY))
+ gsi = irq - gsi_end;
+ else
+ gsi = 0xffffffff;
+
+ return gsi;
+}
+
/*
* Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
* to map the target physical address. The problem is that set_fixmap()
@@ -448,7 +495,7 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
int acpi_gsi_to_irq(u32 gsi, unsigned int *irq)
{
- *irq = gsi;
+ *irq = gsi_to_irq(gsi);
#ifdef CONFIG_X86_IO_APIC
if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC)
@@ -462,7 +509,7 @@ int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
{
if (isa_irq >= 16)
return -1;
- *gsi = isa_irq;
+ *gsi = irq_to_gsi(isa_irq);
return 0;
}
@@ -490,7 +537,7 @@ int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
}
#endif
- irq = plat_gsi;
+ irq = gsi_to_irq(plat_gsi);
return irq;
}
@@ -932,6 +979,8 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
mp_irq.dstirq = pin; /* INTIN# */
save_mp_irq(&mp_irq);
+
+ isa_irq_to_gsi[bus_irq] = gsi;
}
void __init mp_config_acpi_legacy_irqs(void)
@@ -1085,7 +1134,7 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
set_io_apic_irq_attr(&irq_attr, ioapic, ioapic_pin,
trigger == ACPI_EDGE_SENSITIVE ? 0 : 1,
polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
- io_apic_set_pci_routing(dev, gsi, &irq_attr);
+ io_apic_set_pci_routing(dev, gsi_to_irq(gsi), &irq_attr);
return gsi;
}
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 6d6def8..0ac368a 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1036,7 +1036,11 @@ static int pin_2_irq(int idx, int apic, int pin)
*/
if (ioapic_renumber_irq)
gsi = ioapic_renumber_irq(apic, gsi);
- irq = gsi;
+
+ if (gsi >= NR_IRQS_LEGACY)
+ irq = gsi;
+ else
+ irq = gsi_end + 1 + gsi;
}
#ifdef CONFIG_X86_32
@@ -3843,7 +3847,7 @@ void __init probe_nr_irqs_gsi(void)
{
int nr;
- nr = gsi_end + 1;
+ nr = gsi_end + 1 + NR_IRQS_LEGACY;
if (nr > nr_irqs_gsi)
nr_irqs_gsi = nr;
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* [PATCH 15/15] x86 irq: Kill io_apic_renumber_irq
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
` (13 preceding siblings ...)
2010-03-30 8:07 ` [PATCH 14/15] x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's Eric W. Biederman
@ 2010-03-30 8:07 ` Eric W. Biederman
2010-05-03 23:21 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-03-30 8:07 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Ingo Molnar, Andrew Morton, Jesse Barnes,
linux-kernel, Thomas Renninger, Suresh Siddha, len.brown,
Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad, Gary Hade,
Natalie Protasevich, Eric W. Biederman
From: Eric W. Biederman <ebiederm@xmission.com>
Now that the generic irq layer is performing the exact same remapping as
io_apic_renumber_irq we can kill this weird es7000 specific function.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
arch/x86/include/asm/io_apic.h | 1 -
arch/x86/kernel/acpi/boot.c | 5 -----
arch/x86/kernel/apic/es7000_32.c | 19 -------------------
arch/x86/kernel/apic/io_apic.c | 6 ------
4 files changed, 0 insertions(+), 31 deletions(-)
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 37b0f2b..9da192a 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -159,7 +159,6 @@ struct io_apic_irq_attr;
extern int io_apic_set_pci_routing(struct device *dev, int irq,
struct io_apic_irq_attr *irq_attr);
void setup_IO_APIC_irq_extra(u32 gsi);
-extern int (*ioapic_renumber_irq)(int ioapic, int irq);
extern void ioapic_init_mappings(void);
extern void ioapic_insert_resources(void);
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index c4b4bd9..614f3a7 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -1116,11 +1116,6 @@ int mp_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
ioapic_pin = mp_find_ioapic_pin(ioapic, gsi);
-#ifdef CONFIG_X86_32
- if (ioapic_renumber_irq)
- gsi = ioapic_renumber_irq(ioapic, gsi);
-#endif
-
if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
printk(KERN_ERR "Invalid reference to IOAPIC pin "
"%d-%d\n", mp_ioapics[ioapic].apicid,
diff --git a/arch/x86/kernel/apic/es7000_32.c b/arch/x86/kernel/apic/es7000_32.c
index dd2b5f2..7a63d47 100644
--- a/arch/x86/kernel/apic/es7000_32.c
+++ b/arch/x86/kernel/apic/es7000_32.c
@@ -130,24 +130,6 @@ int es7000_plat;
static unsigned int base;
-static int
-es7000_rename_gsi(int ioapic, int gsi)
-{
- if (es7000_plat == ES7000_ZORRO)
- return gsi;
-
- if (!base) {
- int i;
- for (i = 0; i < nr_ioapics; i++)
- base += nr_ioapic_registers[i];
- }
-
- if (!ioapic && (gsi < 16))
- gsi += base;
-
- return gsi;
-}
-
static int __cpuinit wakeup_secondary_cpu_via_mip(int cpu, unsigned long eip)
{
unsigned long vect = 0, psaival = 0;
@@ -189,7 +171,6 @@ static void setup_unisys(void)
es7000_plat = ES7000_ZORRO;
else
es7000_plat = ES7000_CLASSIC;
- ioapic_renumber_irq = es7000_rename_gsi;
}
/*
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 0ac368a..d23002d 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -1015,7 +1015,6 @@ static inline int irq_trigger(int idx)
return MPBIOS_trigger(idx);
}
-int (*ioapic_renumber_irq)(int ioapic, int irq);
static int pin_2_irq(int idx, int apic, int pin)
{
int irq;
@@ -1031,11 +1030,6 @@ static int pin_2_irq(int idx, int apic, int pin)
irq = mp_irqs[idx].srcbusirq;
} else {
u32 gsi = mp_gsi_routing[apic].gsi_base + pin;
- /*
- * For MPS mode, so far only needed by ES7000 platform
- */
- if (ioapic_renumber_irq)
- gsi = ioapic_renumber_irq(apic, gsi);
if (gsi >= NR_IRQS_LEGACY)
irq = gsi;
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 38+ messages in thread
* Re: [PATCH 0/14] Start coping gsis < 16 that are not isa irqs.
2010-03-29 23:19 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
` (14 preceding siblings ...)
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
@ 2010-04-01 2:02 ` Len Brown
2010-04-01 3:31 ` Eric W. Biederman
15 siblings, 1 reply; 38+ messages in thread
From: Len Brown @ 2010-04-01 2:02 UTC (permalink / raw)
To: Eric W. Biederman
Cc: H. Peter Anvin, Thomas Gleixner, Yinghai Lu, Ingo Molnar,
Andrew Morton, Jesse Barnes, linux-kernel, Thomas Renninger,
Suresh Siddha, len.brown, Tony Luck, Fenghua Yu, linux-acpi,
Iranna D Ankad, Gary Hade, Natalie Protasevich
> It appears there are a few systems in the wild that use acpi
> interrupt source overrides to report a gsi > 16 is an isa irq.
>
> This breaks all kinds of assumptions I figure any BIOS doing that
> probably should be shot as that is very much not a conservative position.
You might run into trouble here on the ES7000 -- though I don't know
if anybody is booting a modern kernel on one of those these days.
IIR, ES7000 treated the bottom 16 as a special case.
When there was an irq shortage, I think they used overrides
to map higher PCI irqs into the empty spots below 16,
but I think to make room for them they may have mapped
some of the ISA irqs to high numbers. Fuzzy memory
on this at the moment...
cheers,
Len Brown, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 0/14] Start coping gsis < 16 that are not isa irqs.
2010-04-01 2:02 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Len Brown
@ 2010-04-01 3:31 ` Eric W. Biederman
0 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-04-01 3:31 UTC (permalink / raw)
To: Len Brown
Cc: H. Peter Anvin, Thomas Gleixner, Yinghai Lu, Ingo Molnar,
Andrew Morton, Jesse Barnes, linux-kernel, Thomas Renninger,
Suresh Siddha, len.brown, Tony Luck, Fenghua Yu, linux-acpi,
Iranna D Ankad, Gary Hade, Natalie Protasevich
Len Brown <lenb@kernel.org> writes:
>> It appears there are a few systems in the wild that use acpi
>> interrupt source overrides to report a gsi > 16 is an isa irq.
>>
>> This breaks all kinds of assumptions I figure any BIOS doing that
>> probably should be shot as that is very much not a conservative position.
>
> You might run into trouble here on the ES7000 -- though I don't know
> if anybody is booting a modern kernel on one of those these days.
>
> IIR, ES7000 treated the bottom 16 as a special case.
> When there was an irq shortage, I think they used overrides
> to map higher PCI irqs into the empty spots below 16,
> but I think to make room for them they may have mapped
> some of the ISA irqs to high numbers. Fuzzy memory
> on this at the moment...
A couple of things.
The ES7000 change is trivially safe because despite differences in how
the numbers are computed I have made that transform that the es7000
does always apply.
I also talked to Natalie about this. I can't be certain about this
but from your description, from Natalies memories and from looking
at the code. I believe the problem on the ES7000 is exactly what
I am fixing in the code. Natalie has threatened to test this on
an ES7000.
The case of interest is this:
Weird but valid platforms where
GSI 0-15 are not ISA irqs.
Some high numbered GSIs are ISA irqs and use interrupt source
overrides to describe them.
That is the case on the IBM platform that regressed a bit ago
and Iranna D Ankad bisected a failure on. On that IBM platform
GSI 0-15 (because the are not ISA irqs) are unusable today.
Everything points to this problem I an fixing being the problem with
early ES7000 machines, including the memory of their boot firmware
developers complaint that they were in spec.
Eric
^ permalink raw reply [flat|nested] 38+ messages in thread
* Re: [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
` (14 preceding siblings ...)
2010-03-30 8:07 ` [PATCH 15/15] x86 irq: Kill io_apic_renumber_irq Eric W. Biederman
@ 2010-05-03 23:21 ` Eric W. Biederman
15 siblings, 0 replies; 38+ messages in thread
From: Eric W. Biederman @ 2010-05-03 23:21 UTC (permalink / raw)
To: H. Peter Anvin
Cc: Thomas Gleixner, Yinghai Lu, Ingo Molnar, Andrew Morton,
Jesse Barnes, linux-kernel, Thomas Renninger, Suresh Siddha,
len.brown, Tony Luck, Fenghua Yu, linux-acpi, Iranna D Ankad,
Gary Hade, Natalie Protasevich
ebiederm@xmission.com (Eric W. Biederman) writes:
> It appears there are a few systems in the wild that use acpi
> interrupt source overrides to report a gsi > 16 is an isa irq.
>
> This breaks all kinds of assumptions I figure any BIOS doing that
> probably should be shot as that is very much not a conservative position.
>
> That said acpi appears to allow this insanity and on the basis of being
> liberal in what we accept we should try to do something reasonable, and
> keep our notions of gsi, isa irq, and linux irq as straight as we can.
>
> To that end this patchset slightly modifies the gsi to linux irq
> mapping. Making it a 1 to 1 identity mapping except for the first 16
> gsis. If those gsis are isa irqs (the typical and default acpi
> configuration) they will be mapped into the first 16 irqs. If those
> first 16 gsis are not isa irqs they will be given a linux irq number
> just past the last gsi. Allowing us the chance to use them.
>
> This patchset is my attempt to straighten out our understanding of which
> kind of irq name is used where and the cleanups used to get there.
>
> Thanks to Yinghai Lu <yinghai@kernel.org> for taking the first stab at
> this and finding that there is a real world problem here. This patchset
> is inspired by his work, but little of it remains the same.
>
> This patchset lies in the weird world between the acpi and x86 and ia64.
> Since most of the changes are x86 related I think it makes most sense
> to go via the x86 tree.
>
> v2: Recognize that gsi_end is last gsi for an ioapic not one past the end.
> Since I use gsi_end widely in my patchset a respin of many of the patches
> made sense.
>
> Eric W. Biederman (15):
> x86 acpi/irq: Introduce apci_isa_irq_to_gsi
> x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq
> x86 acpi/irq: pci device dev->irq is an isa irq not a gsi
> x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi
> x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs
> x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h
> x86 ioapic: Fix io_apic_redir_entries to return the number of entries.
> x86 ioapic: Fix the types of gsi values
> x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end
> x86 ioapic: In mpparse use mp_register_ioapic
> x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic.
> x86 ioapic: Optimize pin_2_irq
> x86 ioapic: Simplify probe_nr_irqs_gsi.
> x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's.
> x86 irq: Kill io_apic_renumber_irq
>
> arch/ia64/kernel/acpi.c | 8 ++
> arch/x86/include/asm/io_apic.h | 12 ++--
> arch/x86/include/asm/mpspec.h | 10 ---
> arch/x86/kernel/acpi/boot.c | 133 ++++++++++++++++++++++++--------------
> arch/x86/kernel/apic/es7000_32.c | 19 ------
> arch/x86/kernel/apic/io_apic.c | 99 +++++++++++++---------------
> arch/x86/kernel/mpparse.c | 25 +-------
> arch/x86/kernel/sfi.c | 4 +-
> drivers/acpi/pci_irq.c | 8 ++-
> include/linux/acpi.h | 5 +-
> 10 files changed, 154 insertions(+), 169 deletions(-)
ping
Where are we at with this patchset?
Eric
^ permalink raw reply [flat|nested] 38+ messages in thread
end of thread, other threads:[~2010-05-03 23:21 UTC | newest]
Thread overview: 38+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <1269221770-9667-1-git-send-email-yinghai@kernel.org>
[not found] ` <1269221770-9667-3-git-send-email-yinghai@kernel.org>
[not found] ` <alpine.LFD.2.00.1003221131470.3147@localhost.localdomain>
[not found] ` <m1iq8f1c1f.fsf@fess.ebiederm.org>
[not found] ` <4BB0EA22.7000004@zytor.com>
2010-03-29 23:19 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Eric W. Biederman
2010-03-29 23:20 ` [PATCH 01/14] x86 acpi/irq: Introduce apci_isa_irq_to_gsi Eric W. Biederman
2010-03-29 23:20 ` [PATCH 02/14] x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq Eric W. Biederman
2010-03-29 23:20 ` [PATCH 03/14] x86 acpi/irq: pci device dev->irq is an isa irq not a gsi Eric W. Biederman
2010-03-29 23:20 ` [PATCH 04/14] x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi Eric W. Biederman
2010-03-29 23:20 ` [PATCH 05/14] x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs Eric W. Biederman
2010-03-29 23:20 ` [PATCH 06/14] x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h Eric W. Biederman
2010-03-29 23:20 ` [PATCH 07/14] x86 ioapic: Fix the types of gsi values Eric W. Biederman
2010-03-29 23:20 ` [PATCH 08/14] x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end Eric W. Biederman
2010-03-29 23:20 ` [PATCH 09/14] x86 ioapic: In mpparse use mp_register_ioapic Eric W. Biederman
2010-03-29 23:20 ` [PATCH 10/14] x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic Eric W. Biederman
2010-03-29 23:20 ` [PATCH 11/14] x86 ioapic: Optimize pin_2_irq Eric W. Biederman
2010-03-29 23:20 ` [PATCH 12/14] x86 ioapic: Simplify probe_nr_irqs_gsi Eric W. Biederman
2010-03-30 2:16 ` Yinghai Lu
2010-03-30 4:43 ` Eric W. Biederman
2010-03-30 4:55 ` Yinghai Lu
2010-03-30 5:41 ` Eric W. Biederman
2010-03-29 23:20 ` [PATCH 13/14] x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's Eric W. Biederman
2010-03-29 23:20 ` [PATCH 14/14] x86 irq: Kill io_apic_renumber_irq Eric W. Biederman
2010-03-30 8:06 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
2010-03-30 8:07 ` [PATCH 01/15] x86 acpi/irq: Introduce apci_isa_irq_to_gsi Eric W. Biederman
2010-03-30 8:07 ` [PATCH 02/15] x86 acpi/irq: Teach acpi_get_override_irq to take a gsi not an isa_irq Eric W. Biederman
2010-03-30 8:07 ` [PATCH 03/15] x86 acpi/irq: pci device dev->irq is an isa irq not a gsi Eric W. Biederman
2010-03-30 8:07 ` [PATCH 04/15] x86 acpi/irq: Fix acpi_sci_ioapic_setup so it has both bus_irq and gsi Eric W. Biederman
2010-03-30 8:07 ` [PATCH 05/15] x86 acpi/irq: Generalize mp_config_acpi_legacy_irqs Eric W. Biederman
2010-03-30 8:07 ` [PATCH 06/15] x86 ioapic: Only export mp_find_ioapic and mp_find_ioapic_pin in io_apic.h Eric W. Biederman
2010-03-30 8:07 ` [PATCH 07/15] x86 ioapic: Fix io_apic_redir_entries to return the number of entries Eric W. Biederman
2010-03-30 8:07 ` [PATCH 08/15] x86 ioapic: Fix the types of gsi values Eric W. Biederman
2010-03-30 8:07 ` [PATCH 09/15] x86 ioapic: Teach mp_register_ioapic to compute a global gsi_end Eric W. Biederman
2010-03-30 8:07 ` [PATCH 10/15] x86 ioapic: In mpparse use mp_register_ioapic Eric W. Biederman
2010-03-30 8:07 ` [PATCH 11/15] x86 ioapic: Move nr_ioapic_registers calculation to mp_register_ioapic Eric W. Biederman
2010-03-30 8:07 ` [PATCH 12/15] x86 ioapic: Optimize pin_2_irq Eric W. Biederman
2010-03-30 8:07 ` [PATCH 13/15] x86 ioapic: Simplify probe_nr_irqs_gsi Eric W. Biederman
2010-03-30 8:07 ` [PATCH 14/15] x86 acpi/irq: Handle isa irqs that are not identity mapped to gsi's Eric W. Biederman
2010-03-30 8:07 ` [PATCH 15/15] x86 irq: Kill io_apic_renumber_irq Eric W. Biederman
2010-05-03 23:21 ` [PATCH 0/15] Start coping gsis < 16 that are not isa irqs. v2 Eric W. Biederman
2010-04-01 2:02 ` [PATCH 0/14] Start coping gsis < 16 that are not isa irqs Len Brown
2010-04-01 3:31 ` Eric W. Biederman
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).