]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
arm64/mm: Fix ttbr0 values stored in struct thread_info for software-pan
authorAnshuman Khandual <anshuman.khandual@arm.com>
Tue, 15 Jun 2021 09:32:58 +0000 (15:02 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 14 Jul 2021 14:53:23 +0000 (16:53 +0200)
[ 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
arch/arm64/kernel/setup.c

index 1355205e5da5e37303e734dfc55ecb96f99147f3..fb564de90aa7ed238f5df2d5afc933af1ea5782a 100644 (file)
@@ -184,9 +184,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);
 }
index 203a0c31f2605c957af1b233d3e5781a58723c00..f55f4a15a905e25e813a0ce24d9e1356fcaba07f 100644 (file)
@@ -356,7 +356,7 @@ void __init 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
 
 #ifdef CONFIG_VT