| From 0486c235790b5eb91d186a1eb15c0cf8e942672a Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 15 Jun 2021 15:02:58 +0530 |
| Subject: arm64/mm: Fix ttbr0 values stored in struct thread_info for |
| software-pan |
| |
| From: Anshuman Khandual <anshuman.khandual@arm.com> |
| |
| [ Upstream commit 9163f01130304fab1f74683d7d44632da7bda637 ] |
| |
| 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: 529c4b05a3cb ("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> |
| --- |
| arch/arm64/include/asm/mmu_context.h | 4 ++-- |
| arch/arm64/kernel/setup.c | 2 +- |
| 2 files changed, 3 insertions(+), 3 deletions(-) |
| |
| diff --git a/arch/arm64/include/asm/mmu_context.h b/arch/arm64/include/asm/mmu_context.h |
| index 68028de06d18..5a54a5ab5f92 100644 |
| --- a/arch/arm64/include/asm/mmu_context.h |
| +++ b/arch/arm64/include/asm/mmu_context.h |
| @@ -192,9 +192,9 @@ static inline void update_saved_ttbr0(struct task_struct *tsk, |
| return; |
| |
| if (mm == &init_mm) |
| - ttbr = __pa_symbol(reserved_pg_dir); |
| + ttbr = phys_to_ttbr(__pa_symbol(reserved_pg_dir)); |
| 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); |
| } |
| diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c |
| index c28a9ec76b11..eb4b24652c10 100644 |
| --- a/arch/arm64/kernel/setup.c |
| +++ b/arch/arm64/kernel/setup.c |
| @@ -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 |
| * 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 |
| |
| if (boot_args[1] || boot_args[2] || boot_args[3]) { |
| -- |
| 2.30.2 |
| |