Skip to content

Commit b9293d4

Browse files
jamieilesctmarinas
authored andcommitted
arm64/mm: remove now-superfluous ISBs from TTBR writes
At the time of authoring 7655abb ("arm64: mm: Move ASID from TTBR0 to TTBR1"), the Arm ARM did not specify any ordering guarantees for direct writes to TTBR0_ELx and TTBR1_ELx and so an ISB was required after each write to ensure TLBs would only be populated from the expected (or reserved tables). In a recent update to the Arm ARM, the requirements have been relaxed to reflect the implementation of current CPUs and required implementation of future CPUs to read (RDYDPX in D8.2.3 Translation table base address register): Direct writes to TTBR0_ELx and TTBR1_ELx occur in program order relative to one another, without the need for explicit synchronization. For any one translation, all indirect reads of TTBR0_ELx and TTBR1_ELx that are made as part of the translation observe only one point in that order of direct writes. Remove the superfluous ISBs to optimize uaccess helpers and context switch. Cc: Will Deacon <[email protected]> Cc: Mark Rutland <[email protected]> Signed-off-by: Jamie Iles <[email protected]> Reviewed-by: Mark Rutland <[email protected]> Link: https://lore.kernel.org/r/[email protected] [[email protected]: rename __cpu_set_reserved_ttbr0 to ..._nosync] [[email protected]: move the cpu_set_reserved_ttbr0_nosync() call to cpu_do_switch_mm()] Signed-off-by: Catalin Marinas <[email protected]>
1 parent 601eaec commit b9293d4

File tree

4 files changed

+7
-7
lines changed

4 files changed

+7
-7
lines changed

arch/arm64/include/asm/asm-uaccess.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
bic \tmp1, \tmp1, #TTBR_ASID_MASK
1919
sub \tmp1, \tmp1, #RESERVED_SWAPPER_OFFSET // reserved_pg_dir
2020
msr ttbr0_el1, \tmp1 // set reserved TTBR0_EL1
21-
isb
2221
add \tmp1, \tmp1, #RESERVED_SWAPPER_OFFSET
2322
msr ttbr1_el1, \tmp1 // set reserved ASID
2423
isb
@@ -31,7 +30,6 @@
3130
extr \tmp2, \tmp2, \tmp1, #48
3231
ror \tmp2, \tmp2, #16
3332
msr ttbr1_el1, \tmp2 // set the active ASID
34-
isb
3533
msr ttbr0_el1, \tmp1 // set the non-PAN TTBR0_EL1
3634
isb
3735
.endm

arch/arm64/include/asm/mmu_context.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,16 @@ static inline void contextidr_thread_switch(struct task_struct *next)
3939
/*
4040
* Set TTBR0 to reserved_pg_dir. No translations will be possible via TTBR0.
4141
*/
42-
static inline void cpu_set_reserved_ttbr0(void)
42+
static inline void cpu_set_reserved_ttbr0_nosync(void)
4343
{
4444
unsigned long ttbr = phys_to_ttbr(__pa_symbol(reserved_pg_dir));
4545

4646
write_sysreg(ttbr, ttbr0_el1);
47+
}
48+
49+
static inline void cpu_set_reserved_ttbr0(void)
50+
{
51+
cpu_set_reserved_ttbr0_nosync();
4752
isb();
4853
}
4954

@@ -52,7 +57,6 @@ void cpu_do_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
5257
static inline void cpu_switch_mm(pgd_t *pgd, struct mm_struct *mm)
5358
{
5459
BUG_ON(pgd == swapper_pg_dir);
55-
cpu_set_reserved_ttbr0();
5660
cpu_do_switch_mm(virt_to_phys(pgd),mm);
5761
}
5862

arch/arm64/include/asm/uaccess.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ static inline void __uaccess_ttbr0_disable(void)
6565
ttbr &= ~TTBR_ASID_MASK;
6666
/* reserved_pg_dir placed before swapper_pg_dir */
6767
write_sysreg(ttbr - RESERVED_SWAPPER_OFFSET, ttbr0_el1);
68-
isb();
6968
/* Set reserved ASID */
7069
write_sysreg(ttbr, ttbr1_el1);
7170
isb();
@@ -89,7 +88,6 @@ static inline void __uaccess_ttbr0_enable(void)
8988
ttbr1 &= ~TTBR_ASID_MASK; /* safety measure */
9089
ttbr1 |= ttbr0 & TTBR_ASID_MASK;
9190
write_sysreg(ttbr1, ttbr1_el1);
92-
isb();
9391

9492
/* Restore user page table */
9593
write_sysreg(ttbr0, ttbr0_el1);

arch/arm64/mm/context.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@ void cpu_do_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm)
364364
ttbr1 &= ~TTBR_ASID_MASK;
365365
ttbr1 |= FIELD_PREP(TTBR_ASID_MASK, asid);
366366

367+
cpu_set_reserved_ttbr0_nosync();
367368
write_sysreg(ttbr1, ttbr1_el1);
368-
isb();
369369
write_sysreg(ttbr0, ttbr0_el1);
370370
isb();
371371
post_ttbr_update_workaround();

0 commit comments

Comments
 (0)