Skip to content

Commit e13d918

Browse files
Lorenzo Pieralisiwildea01
Lorenzo Pieralisi
authored andcommitted
arm64: kernel: fix tcr_el1.t0sz restore on systems with extended idmap
Commit dd006da ("arm64: mm: increase VA range of identity map") introduced a mechanism to extend the virtual memory map range to support arm64 systems with system RAM located at very high offset, where the identity mapping used to enable/disable the MMU requires additional translation levels to map the physical memory at an equal virtual offset. The kernel detects at boot time the tcr_el1.t0sz value required by the identity mapping and sets-up the tcr_el1.t0sz register field accordingly, any time the identity map is required in the kernel (ie when enabling the MMU). After enabling the MMU, in the cold boot path the kernel resets the tcr_el1.t0sz to its default value (ie the actual configuration value for the system virtual address space) so that after enabling the MMU the memory space translated by ttbr0_el1 is restored as expected. Commit dd006da ("arm64: mm: increase VA range of identity map") also added code to set-up the tcr_el1.t0sz value when the kernel resumes from low-power states with the MMU off through cpu_resume() in order to effectively use the identity mapping to enable the MMU but failed to add the code required to restore the tcr_el1.t0sz to its default value, when the core returns to the kernel with the MMU enabled, so that the kernel might end up running with tcr_el1.t0sz value set-up for the identity mapping which can be lower than the value required by the actual virtual address space, resulting in an erroneous set-up. This patchs adds code in the resume path that restores the tcr_el1.t0sz default value upon core resume, mirroring this way the cold boot path behaviour therefore fixing the issue. Cc: <stable@vger.kernel.org> Cc: Catalin Marinas <catalin.marinas@arm.com> Fixes: dd006da ("arm64: mm: increase VA range of identity map") Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
1 parent 589cb22 commit e13d918

File tree

1 file changed

+13
-9
lines changed

1 file changed

+13
-9
lines changed

arch/arm64/kernel/suspend.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,21 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
8080
if (ret == 0) {
8181
/*
8282
* We are resuming from reset with TTBR0_EL1 set to the
83-
* idmap to enable the MMU; restore the active_mm mappings in
84-
* TTBR0_EL1 unless the active_mm == &init_mm, in which case
85-
* the thread entered cpu_suspend with TTBR0_EL1 set to
86-
* reserved TTBR0 page tables and should be restored as such.
83+
* idmap to enable the MMU; set the TTBR0 to the reserved
84+
* page tables to prevent speculative TLB allocations, flush
85+
* the local tlb and set the default tcr_el1.t0sz so that
86+
* the TTBR0 address space set-up is properly restored.
87+
* If the current active_mm != &init_mm we entered cpu_suspend
88+
* with mappings in TTBR0 that must be restored, so we switch
89+
* them back to complete the address space configuration
90+
* restoration before returning.
8791
*/
88-
if (mm == &init_mm)
89-
cpu_set_reserved_ttbr0();
90-
else
91-
cpu_switch_mm(mm->pgd, mm);
92-
92+
cpu_set_reserved_ttbr0();
9393
flush_tlb_all();
94+
cpu_set_default_tcr_t0sz();
95+
96+
if (mm != &init_mm)
97+
cpu_switch_mm(mm->pgd, mm);
9498

9599
/*
96100
* Restore per-cpu offset before any kernel

0 commit comments

Comments
 (0)