1
linux/arch
Joerg Roedel fd89a13792 x86-32: Separate 1:1 pagetables from swapper_pg_dir
This patch fixes machine crashes which occur when heavily exercising the
CPU hotplug codepaths on a 32-bit kernel. These crashes are caused by
AMD Erratum 383 and result in a fatal machine check exception. Here's
the scenario:

1. On 32-bit, the swapper_pg_dir page table is used as the initial page
table for booting a secondary CPU.

2. To make this work, swapper_pg_dir needs a direct mapping of physical
memory in it (the low mappings). By adding those low, large page (2M)
mappings (PAE kernel), we create the necessary conditions for Erratum
383 to occur.

3. Other CPUs which do not participate in the off- and onlining game may
use swapper_pg_dir while the low mappings are present (when leave_mm is
called). For all steps below, the CPU referred to is a CPU that is using
swapper_pg_dir, and not the CPU which is being onlined.

4. The presence of the low mappings in swapper_pg_dir can result
in TLB entries for addresses below __PAGE_OFFSET to be established
speculatively. These TLB entries are marked global and large.

5. When the CPU with such TLB entry switches to another page table, this
TLB entry remains because it is global.

6. The process then generates an access to an address covered by the
above TLB entry but there is a permission mismatch - the TLB entry
covers a large global page not accessible to userspace.

7. Due to this permission mismatch a new 4kb, user TLB entry gets
established. Further, Erratum 383 provides for a small window of time
where both TLB entries are present. This results in an uncorrectable
machine check exception signalling a TLB multimatch which panics the
machine.

There are two ways to fix this issue:

        1. Always do a global TLB flush when a new cr3 is loaded and the
        old page table was swapper_pg_dir. I consider this a hack hard
        to understand and with performance implications

        2. Do not use swapper_pg_dir to boot secondary CPUs like 64-bit
        does.

This patch implements solution 2. It introduces a trampoline_pg_dir
which has the same layout as swapper_pg_dir with low_mappings. This page
table is used as the initial page table of the booting CPU. Later in the
bringup process, it switches to swapper_pg_dir and does a global TLB
flush. This fixes the crashes in our test cases.

-v2: switch to swapper_pg_dir right after entering start_secondary() so
that we are able to access percpu data which might not be mapped in the
trampoline page table.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
LKML-Reference: <20100816123833.GB28147@aftab>
Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2010-08-18 09:17:20 -07:00
..
alpha defconfig reduction 2010-08-14 22:26:53 +02:00
arm Merge git://git.infradead.org/mtd-2.6 2010-08-15 17:32:47 -07:00
avr32 defconfig reduction 2010-08-14 22:26:53 +02:00
blackfin Merge git://git.infradead.org/mtd-2.6 2010-08-15 17:32:47 -07:00
cris defconfig reduction 2010-08-14 22:26:53 +02:00
frv defconfig reduction 2010-08-14 22:26:53 +02:00
h8300 defconfig reduction 2010-08-14 22:26:53 +02:00
ia64 defconfig reduction 2010-08-14 22:26:53 +02:00
m32r defconfig reduction 2010-08-14 22:26:53 +02:00
m68k defconfig reduction 2010-08-14 22:26:53 +02:00
m68knommu defconfig reduction 2010-08-14 22:26:53 +02:00
microblaze defconfig reduction 2010-08-14 22:26:53 +02:00
mips Merge git://git.infradead.org/mtd-2.6 2010-08-15 17:32:47 -07:00
mn10300 defconfig reduction 2010-08-14 22:26:53 +02:00
parisc defconfig reduction 2010-08-14 22:26:53 +02:00
powerpc archs: replace unifdef-y with header-y 2010-08-14 22:26:51 +02:00
s390 defconfig reduction 2010-08-14 22:26:53 +02:00
score defconfig reduction 2010-08-14 22:26:53 +02:00
sh defconfig reduction 2010-08-14 22:26:53 +02:00
sparc defconfig reduction 2010-08-14 22:26:53 +02:00
tile Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile 2010-08-15 17:31:43 -07:00
um Mark arguments to certain syscalls as being const 2010-08-13 16:53:13 -07:00
x86 x86-32: Separate 1:1 pagetables from swapper_pg_dir 2010-08-18 09:17:20 -07:00
xtensa Mark arguments to certain syscalls as being const 2010-08-13 16:53:13 -07:00
.gitignore
Kconfig Merge branch 'perf/nmi' into perf/core 2010-08-05 08:45:05 +02:00