This is a note to let you know that I've just added the patch titled

    x86/ioapic: Add register level checks to detect bogus io-apic entries

to the 3.3-stable tree which can be found at:
    
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     x86-ioapic-add-register-level-checks-to-detect-bogus-io-apic-entries.patch
and it can be found in the queue-3.3 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <[email protected]> know about it.


>From 73d63d038ee9f769f5e5b46792d227fe20e442c5 Mon Sep 17 00:00:00 2001
From: Suresh Siddha <[email protected]>
Date: Mon, 12 Mar 2012 11:36:33 -0700
Subject: x86/ioapic: Add register level checks to detect bogus io-apic entries
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

From: Suresh Siddha <[email protected]>

commit 73d63d038ee9f769f5e5b46792d227fe20e442c5 upstream.

With the recent changes to clear_IO_APIC_pin() which tries to
clear remoteIRR bit explicitly, some of the users started to see
"Unable to reset IRR for apic .." messages.

Close look shows that these are related to bogus IO-APIC entries
which return's all 1's for their io-apic registers. And the
above mentioned error messages are benign. But kernel should
have ignored such io-apic's in the first place.

Check if register 0, 1, 2 of the listed io-apic are all 1's and
ignore such io-apic.

Reported-by: Álvaro Castillo <[email protected]>
Tested-by: Jon Dufresne <[email protected]>
Signed-off-by: Suresh Siddha <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: Josh Boyer <[email protected]>
Link: 
http://lkml.kernel.org/r/[email protected]
[ Performed minor cleanup of affected code. ]
Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
 arch/x86/kernel/apic/io_apic.c |   40 ++++++++++++++++++++++++++++++++--------
 1 file changed, 32 insertions(+), 8 deletions(-)

--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3967,18 +3967,36 @@ int mp_find_ioapic_pin(int ioapic, u32 g
 static __init int bad_ioapic(unsigned long address)
 {
        if (nr_ioapics >= MAX_IO_APICS) {
-               printk(KERN_WARNING "WARNING: Max # of I/O APICs (%d) exceeded "
-                      "(found %d), skipping\n", MAX_IO_APICS, nr_ioapics);
+               pr_warn("WARNING: Max # of I/O APICs (%d) exceeded (found %d), 
skipping\n",
+                       MAX_IO_APICS, nr_ioapics);
                return 1;
        }
        if (!address) {
-               printk(KERN_WARNING "WARNING: Bogus (zero) I/O APIC address"
-                      " found in table, skipping!\n");
+               pr_warn("WARNING: Bogus (zero) I/O APIC address found in table, 
skipping!\n");
                return 1;
        }
        return 0;
 }
 
+static __init int bad_ioapic_register(int idx)
+{
+       union IO_APIC_reg_00 reg_00;
+       union IO_APIC_reg_01 reg_01;
+       union IO_APIC_reg_02 reg_02;
+
+       reg_00.raw = io_apic_read(idx, 0);
+       reg_01.raw = io_apic_read(idx, 1);
+       reg_02.raw = io_apic_read(idx, 2);
+
+       if (reg_00.raw == -1 && reg_01.raw == -1 && reg_02.raw == -1) {
+               pr_warn("I/O APIC 0x%x registers return all ones, skipping!\n",
+                       mpc_ioapic_addr(idx));
+               return 1;
+       }
+
+       return 0;
+}
+
 void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
 {
        int idx = 0;
@@ -3995,6 +4013,12 @@ void __init mp_register_ioapic(int id, u
        ioapics[idx].mp_config.apicaddr = address;
 
        set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
+
+       if (bad_ioapic_register(idx)) {
+               clear_fixmap(FIX_IO_APIC_BASE_0 + idx);
+               return;
+       }
+
        ioapics[idx].mp_config.apicid = io_apic_unique_id(id);
        ioapics[idx].mp_config.apicver = io_apic_get_version(idx);
 
@@ -4015,10 +4039,10 @@ void __init mp_register_ioapic(int id, u
        if (gsi_cfg->gsi_end >= gsi_top)
                gsi_top = gsi_cfg->gsi_end + 1;
 
-       printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
-              "GSI %d-%d\n", idx, mpc_ioapic_id(idx),
-              mpc_ioapic_ver(idx), mpc_ioapic_addr(idx),
-              gsi_cfg->gsi_base, gsi_cfg->gsi_end);
+       pr_info("IOAPIC[%d]: apic_id %d, version %d, address 0x%x, GSI %d-%d\n",
+               idx, mpc_ioapic_id(idx),
+               mpc_ioapic_ver(idx), mpc_ioapic_addr(idx),
+               gsi_cfg->gsi_base, gsi_cfg->gsi_end);
 
        nr_ioapics++;
 }


Patches currently in stable-queue which might be from [email protected] 
are

queue-3.3/x86-ioapic-add-register-level-checks-to-detect-bogus-io-apic-entries.patch
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to