[PATCH 1/1] UBUNTU: x86: work around X86-32 kernel failures on Intel Atom CPU

Colin King colin.king at canonical.com
Wed Feb 17 13:44:08 UTC 2010

From: Colin Ian King <colin.king at canonical.com>

BugLink: https://bugs.launchpad.net/bugs/523112

This is a workaround to errata AAE44 as listed in
page 33, namely: "Code Fetch May Occur to Incorrect Address
After a Large Page is Split into 4-KB Byte Pages". This is the same
as Errata AAH41 (Atom 3xx series) but named AAE44 for the Atom
Z5xx series.

This fix is not totally bullet proof. There is still a possibility
of a race between __set_pmd_pte and __flush_tlb_all() during which
the other hyperthread could do a code fetch and get garbage. Hence
this patch narrows the window for the race but does not completely
prevent it.

This patch is a backport of the upstream commit
211b3d03c7400f48a781977a50104c9d12f4e229, the original commit message
was as follows:

Impact: work around boot crash

Work around Intel Atom erratum AAH41 (probabilistically) - it's triggering
in the field.

Reported-by: Linus Torvalds <torvalds at linux-foundation.org>
Tested-by: Kyle McMartin <kyle at redhat.com>
Signed-off-by: Ingo Molnar <mingo at elte.hu>
Signed-off-by: Colin Ian King <colin.king at canonical.com>
 arch/x86/mm/pageattr_32.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/arch/x86/mm/pageattr_32.c b/arch/x86/mm/pageattr_32.c
index 260073c..92c91ea 100644
--- a/arch/x86/mm/pageattr_32.c
+++ b/arch/x86/mm/pageattr_32.c
@@ -65,6 +65,17 @@ static struct page *split_large_page(unsigned long address, pgprot_t prot,
                set_pte(&pbase[i], pfn_pte(addr >> PAGE_SHIFT,
                                           addr == address ? prot : ref_prot));
+	/*
+	 * Intel Atom errata AAH41 and AAE44 workaround.
+	 *
+	 * The real fix should be in hw or in a microcode update, but
+	 * we also probabilistically try to reduce the window of having
+	 * a large TLB mixed with 4K TLBs while instruction fetches are
+	 * going on.
+	 */
+	 __flush_tlb_all();
 	return base;

More information about the kernel-team mailing list