arm64/mm: Fix ttbr0 values stored in struct thread_info for software-pan
[ Upstream commit9163f01130] When using CONFIG_ARM64_SW_TTBR0_PAN, a task's thread_info::ttbr0 must be the TTBR0_EL1 value used to run userspace. With 52-bit PAs, the PA must be packed into the TTBR using phys_to_ttbr(), but we forget to do this in some of the SW PAN code. Thus, if the value is installed into TTBR0_EL1 (as may happen in the uaccess routines), this could result in UNPREDICTABLE behaviour. Since hardware with 52-bit PA support almost certainly has HW PAN, which will be used in preference, this shouldn't be a practical issue, but let's fix this for consistency. Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: James Morse <james.morse@arm.com> Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Fixes:529c4b05a3("arm64: handle 52-bit addresses in TTBR") Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Link: https://lore.kernel.org/r/1623749578-11231-1-git-send-email-anshuman.khandual@arm.com Signed-off-by: Will Deacon <will@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
8d6acfe80d
commit
bb5e089df7
@@ -192,9 +192,9 @@ static inline void update_saved_ttbr0(struct task_struct *tsk,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (mm == &init_mm)
|
if (mm == &init_mm)
|
||||||
ttbr = __pa_symbol(reserved_pg_dir);
|
ttbr = phys_to_ttbr(__pa_symbol(reserved_pg_dir));
|
||||||
else
|
else
|
||||||
ttbr = virt_to_phys(mm->pgd) | ASID(mm) << 48;
|
ttbr = phys_to_ttbr(virt_to_phys(mm->pgd)) | ASID(mm) << 48;
|
||||||
|
|
||||||
WRITE_ONCE(task_thread_info(tsk)->ttbr0, ttbr);
|
WRITE_ONCE(task_thread_info(tsk)->ttbr0, ttbr);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -366,7 +366,7 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p)
|
|||||||
* faults in case uaccess_enable() is inadvertently called by the init
|
* faults in case uaccess_enable() is inadvertently called by the init
|
||||||
* thread.
|
* thread.
|
||||||
*/
|
*/
|
||||||
init_task.thread_info.ttbr0 = __pa_symbol(reserved_pg_dir);
|
init_task.thread_info.ttbr0 = phys_to_ttbr(__pa_symbol(reserved_pg_dir));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (boot_args[1] || boot_args[2] || boot_args[3]) {
|
if (boot_args[1] || boot_args[2] || boot_args[3]) {
|
||||||
|
|||||||
Reference in New Issue
Block a user