lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <Pine.LNX.4.64.0611011003270.25218@g5.osdl.org>
Date:	Wed, 1 Nov 2006 10:25:30 -0800 (PST)
From:	Linus Torvalds <torvalds@...l.org>
To:	Andi Kleen <ak@...e.de>
cc:	"Michael S. Tsirkin" <mst@...lanox.co.il>,
	Ernst Herzberg <earny@...4u.de>, Len Brown <lenb@...nel.org>,
	Adrian Bunk <bunk@...sta.de>, Hugh Dickins <hugh@...itas.com>,
	Pavel Machek <pavel@...e.cz>, Andrew Morton <akpm@...l.org>,
	Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
	linux-acpi@...r.kernel.org, linux-pm@...l.org,
	Martin Lorenz <martin@...enz.eu.org>
Subject: Re: 2.6.19-rc <-> ThinkPads



On Wed, 1 Nov 2006, Andi Kleen wrote:
>
> Ok please revert the i386 patch for now then if it fixes the ThinkPads. 
> The x86-64 version should be probably fixed too, but doesn't cleanly. I will 
> send you later a patch to fix this there properly.

Actually, I should have just fixed the ordering. I did some cleanups too, 
but those are unrelated (except in the sense that I wanted to look at the 
assembly code, and the cleanups made the code generation at least half-way 
sane!)

I've pushed out the changes, but here is the part that may or may not 
matter for anybody who wants to test it if they don't use git or if it 
hasn't mirrored out yet. Michael? Martin?

Andi: I think the patches should work pretty much as-is for x86-64 too, 
since all the issues would seem to be similar. 

I'm not entirely happy with "ioapic_write_entry()" now either (if we 
change an entry that was already unmasked, we should probably mask it 
first by writing the low word with the mask bit set, then write the high 
word, and then write the low word again), but 

 - this makes us match the ordering we _used_ to have, so if the cleanup 
   broke things for people, this should unbreak it, and at least not be 
   any worse than it used to be.

 - when we write new unmasked entries, they all _should_ have been masked 
   before, so hopefully the "change a unmasked entry while it's unmasked" 
   case doesn't actually ever happen. But I didn't actually _check_.

Somebody should look into that case. Does anybody feel like they want to 
learn more about the IO-APIC? Halloween is over and gone, but if you want 
to scare small children _next_ year, telling them about the IO-APIC is 
likely a good strategy.

		Linus

---
commit f9dadfa71bc594df09044da61d1c72701121d802
Author: Linus Torvalds <torvalds@...mini.osdl.org>
Date:   Wed Nov 1 10:05:35 2006 -0800

    i386: write IO APIC irq routing entries in correct order
    
    Since the "mask" bit is in the low word, when we write a new entry, we
    need to write the high word first, before we potentially unmask it.
    
    The exception is when we actually want to mask the interrupt, in which
    case we want to write the low word first to make sure that the high word
    doesn't change while the interrupt routing is still active.
    
    Signed-off-by: Linus Torvalds <torvalds@...l.org>

diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index eb10bd5..507983c 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -147,12 +147,34 @@ static struct IO_APIC_route_entry ioapic
 	return eu.entry;
 }
 
+/*
+ * When we write a new IO APIC routing entry, we need to write the high
+ * word first! If the mask bit in the low word is clear, we will enable
+ * the interrupt, and we need to make sure the entry is fully populated
+ * before that happens.
+ */
 static void ioapic_write_entry(int apic, int pin, struct IO_APIC_route_entry e)
 {
 	unsigned long flags;
 	union entry_union eu;
 	eu.entry = e;
 	spin_lock_irqsave(&ioapic_lock, flags);
+	io_apic_write(apic, 0x11 + 2*pin, eu.w2);
+	io_apic_write(apic, 0x10 + 2*pin, eu.w1);
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+}
+
+/*
+ * When we mask an IO APIC routing entry, we need to write the low
+ * word first, in order to set the mask bit before we change the
+ * high bits!
+ */
+static void ioapic_mask_entry(int apic, int pin)
+{
+	unsigned long flags;
+	union entry_union eu = { .entry.mask = 1 };
+
+	spin_lock_irqsave(&ioapic_lock, flags);
 	io_apic_write(apic, 0x10 + 2*pin, eu.w1);
 	io_apic_write(apic, 0x11 + 2*pin, eu.w2);
 	spin_unlock_irqrestore(&ioapic_lock, flags);
@@ -274,9 +296,7 @@ static void clear_IO_APIC_pin(unsigned i
 	/*
 	 * Disable it in the IO-APIC irq-routing table:
 	 */
-	memset(&entry, 0, sizeof(entry));
-	entry.mask = 1;
-	ioapic_write_entry(apic, pin, entry);
+	ioapic_mask_entry(apic, pin);
 }
 
 static void clear_IO_APIC (void)
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ