From: Mikael Pettersson <mikpe@csd.uu.se>
To: marcelo@conectiva.com.br, torvalds@transmeta.com
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] 2.4.17/2.5.1 apic.c LVTERR fixes
Date: Sun, 23 Dec 2001 16:14:16 +0100 (MET) [thread overview]
Message-ID: <200112231514.QAA25107@harpo.it.uu.se> (raw)
Linus & Marcelo,
Here is a patch which fixes a long-standing bug in the x86 local APIC
code. The patch applies to both 2.4.17 and 2.5.1. Please apply.
The Intel P6 local APIC internally signals an Illegal Vector error
whenever a zero vector is written to an LVT entry, even if the entry
is simultaneously masked. The bug is that apic.c triggers these errors
when the contents of LVTERR is defined by the BIOS and not the kernel,
which can cause unexpected interrupts on unknown vectors. This typically
happens at boot-time initialisation, PM suspend, and PM resume.
The patch eliminates the problem by changing the initialisation order
in apic.c's clear_local_APIC() and apic_pm_resume() to ensure that LVTERR
is masked when we write (potentially) null vectors to LVT entries.
(Non-broken UP BIOSen often boot the kernel with LVTERR null and masked,
and leave LVTERR alone at PM suspend/resume, so _usually_ the errors just
show up as annoying kernel messages. It is, however, an extremely bad
idea to rely on the BIOS to mask errors caused the kernel itself.)
/Mikael
--- linux-2.4.17-apicfixes/arch/i386/kernel/apic.c.~1~ Fri Nov 23 22:40:14 2001
+++ linux-2.4.17-apicfixes/arch/i386/kernel/apic.c Sun Dec 23 15:09:06 2001
@@ -56,6 +56,14 @@
maxlvt = get_maxlvt();
/*
+ * Masking an LVT entry on a P6 can trigger a local APIC error
+ * if the vector is zero. Mask LVTERR first to prevent this.
+ */
+ if (maxlvt >= 3) {
+ v = ERROR_APIC_VECTOR; /* any non-zero vector will do */
+ apic_write_around(APIC_LVTERR, v | APIC_LVT_MASKED);
+ }
+ /*
* Careful: we have to set masks only first to deassert
* any level-triggered sources.
*/
@@ -65,10 +73,6 @@
apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED);
v = apic_read(APIC_LVT1);
apic_write_around(APIC_LVT1, v | APIC_LVT_MASKED);
- if (maxlvt >= 3) {
- v = apic_read(APIC_LVTERR);
- apic_write_around(APIC_LVTERR, v | APIC_LVT_MASKED);
- }
if (maxlvt >= 4) {
v = apic_read(APIC_LVTPC);
apic_write_around(APIC_LVTPC, v | APIC_LVT_MASKED);
@@ -84,6 +88,8 @@
apic_write_around(APIC_LVTERR, APIC_LVT_MASKED);
if (maxlvt >= 4)
apic_write_around(APIC_LVTPC, APIC_LVT_MASKED);
+ apic_write(APIC_ESR, 0);
+ v = apic_read(APIC_ESR);
}
void __init connect_bsp_APIC(void)
@@ -480,6 +486,7 @@
l &= ~MSR_IA32_APICBASE_BASE;
l |= MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
wrmsr(MSR_IA32_APICBASE, l, h);
+ apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED);
apic_write(APIC_ID, apic_pm_state.apic_id);
apic_write(APIC_DFR, apic_pm_state.apic_dfr);
apic_write(APIC_LDR, apic_pm_state.apic_ldr);
@@ -487,15 +494,15 @@
apic_write(APIC_SPIV, apic_pm_state.apic_spiv);
apic_write(APIC_LVT0, apic_pm_state.apic_lvt0);
apic_write(APIC_LVT1, apic_pm_state.apic_lvt1);
+ apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc);
+ apic_write(APIC_LVTT, apic_pm_state.apic_lvtt);
+ apic_write(APIC_TDCR, apic_pm_state.apic_tdcr);
+ apic_write(APIC_TMICT, apic_pm_state.apic_tmict);
apic_write(APIC_ESR, 0);
apic_read(APIC_ESR);
apic_write(APIC_LVTERR, apic_pm_state.apic_lvterr);
apic_write(APIC_ESR, 0);
apic_read(APIC_ESR);
- apic_write(APIC_LVTPC, apic_pm_state.apic_lvtpc);
- apic_write(APIC_LVTT, apic_pm_state.apic_lvtt);
- apic_write(APIC_TDCR, apic_pm_state.apic_tdcr);
- apic_write(APIC_TMICT, apic_pm_state.apic_tmict);
__restore_flags(flags);
if (apic_pm_state.perfctr_pmdev)
pm_send(apic_pm_state.perfctr_pmdev, PM_RESUME, data);
next reply other threads:[~2001-12-23 15:14 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-12-23 15:14 Mikael Pettersson [this message]
2002-01-03 14:57 ` Maciej W. Rozycki
2002-01-03 20:13 Mikael Pettersson
2002-01-04 12:12 ` Maciej W. Rozycki
2002-01-04 15:08 Mikael Pettersson
2002-01-04 16:32 ` Maciej W. Rozycki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200112231514.QAA25107@harpo.it.uu.se \
--to=mikpe@csd.uu.se \
--cc=linux-kernel@vger.kernel.org \
--cc=marcelo@conectiva.com.br \
--cc=torvalds@transmeta.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®