[RFC PATCH 1/2] ARMv7: Use a reserved TTB rather than ASID 0 during context switch
Catalin Marinas
catalin.marinas at arm.com
Mon Feb 14 12:39:53 EST 2011
Newer processors like Cortex-A15 may cache entries in the higher page
table levels. These cached entries are ASID-tagged and are invalidated
during normal TLB operations.
When using the reserved ASID 0 during a context switch, the processor
may cache an entry from the first level of page tables and tag it with
ASID 0. Later the corresponding first level entry may no longer be valid
(e.g. second level table freed) but the TLB invalidation is done by the
ASID of the corresponding mm structure and not ASID 0. During a
subsequent context switch, the stale level 1 ASID 0 cached entry may be
used to speculatively fetch a TLB entry. If the level 2 page table it
points to contains random data (page freed as the previous process had
been removed) it could create a global TLB entry which is no longer ASID
tagged. This entry is then used in subsequent user space processes.
This patch uses one of the other methods specified in the ARM ARM for
the context switch sequence. It uses the swapper_pg_dir as it only
contains global (kernel) mappings.
Reported-by: Tony Thompson <anthony.thompson at arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
---
arch/arm/kernel/head.S | 3 +++
arch/arm/mm/proc-v7.S | 11 +++++++----
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index c0225da..cc08f1b 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -48,6 +48,9 @@
.globl swapper_pg_dir
.equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000
+ .globl swapper_pg_dir_phys
+ .equ swapper_pg_dir_phys, KERNEL_RAM_PADDR - 0x4000
+
.macro pgtbl, rd
ldr \rd, =(KERNEL_RAM_PADDR - 0x4000)
.endm
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 0c1172b..38d6436 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -101,19 +101,22 @@ ENDPROC(cpu_v7_dcache_clean_area)
*/
ENTRY(cpu_v7_switch_mm)
#ifdef CONFIG_MMU
- mov r2, #0
ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id
+ ldr r3, =swapper_pg_dir_phys @ prepare global-only TTB 0
ALT_SMP(orr r0, r0, #TTB_FLAGS_SMP)
ALT_UP(orr r0, r0, #TTB_FLAGS_UP)
+ ALT_SMP(orr r3, r3, #TTB_FLAGS_SMP)
+ ALT_UP(orr r3, r3, #TTB_FLAGS_UP)
#ifdef CONFIG_ARM_ERRATA_430973
+ mov r2, #0
mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
#endif
- mcr p15, 0, r2, c13, c0, 1 @ set reserved context ID
- isb
-1: mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
+ mcr p15, 0, r3, c2, c0, 0 @ set global-only TTB 0
isb
mcr p15, 0, r1, c13, c0, 1 @ set context ID
isb
+ mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
+ isb
#endif
mov pc, lr
ENDPROC(cpu_v7_switch_mm)
More information about the linux-arm-kernel
mailing list