[PATCH v2] arm64: kpti: Fix the interaction between ASID switching and software PAN
Ard Biesheuvel
ard.biesheuvel at linaro.org
Tue Jan 16 08:23:58 PST 2018
On 16 January 2018 at 12:11, James Morse <james.morse at arm.com> wrote:
> Hi Catalin,
>
> On 15/01/18 17:58, Catalin Marinas wrote:
>> With ARM64_SW_TTBR0_PAN enabled, the exception entry code checks the
>> active ASID to decide whether user access was enabled (non-zero ASID)
>> when the exception was taken. On return from exception, if user access
>> was previously disabled, it re-instates TTBR0_EL1 from the per-thread
>> saved value (updated in switch_mm() or efi_set_pgd()).
>>
>> Commit 7655abb95386 ("arm64: mm: Move ASID from TTBR0 to TTBR1") makes a
>> TTBR0_EL1 + ASID switching non-atomic. Subsequently, commit 27a921e75711
>> ("arm64: mm: Fix and re-enable ARM64_SW_TTBR0_PAN") changes the
>> __uaccess_ttbr0_disable() function and asm macro to first write the
>> reserved TTBR0_EL1 followed by the ASID=0 update in TTBR1_EL1. If an
>> exception occurs between these two, the exception return code will
>> re-instate a valid TTBR0_EL1. Similar scenario can happen in
>> cpu_switch_mm() between setting the reserved TTBR0_EL1 and the ASID
>> update in cpu_do_switch_mm().
>>
>> This patch reverts the entry.S check for ASID == 0 to TTBR0_EL1 and
>> disables the interrupts around the TTBR0_EL1 and ASID switching code in
>> __uaccess_ttbr0_disable(). It also ensures that, when returning from the
>> EFI runtime services, efi_set_pgd() doesn't leave a non-zero ASID in
>> TTBR1_EL1 by using uaccess_ttbr0_{enable,disable}.
>>
>> The accesses to current_thread_info()->ttbr0 are updated to use
>> READ_ONCE/WRITE_ONCE.
>>
>> As a safety measure, __uaccess_ttbr0_enable() always masks out any
>> existing non-zero ASID TTBR1_EL1 before writing in the new ASID.
>>
>> Fixes: 27a921e75711 ("arm64: mm: Fix and re-enable ARM64_SW_TTBR0_PAN")
>> Acked-by: Will Deacon <will.deacon at arm.com>
>> Reported-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>> Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
>> Reviewed-by: James Morse <james.morse at arm.com>
>> Cc: James Morse <james.morse at arm.com>
>> Co-developed-by: Marc Zyngier <marc.zyngier at arm.com>
>> Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
>> ---
>>
>> Changes since v1 (no functional change):
>>
>> - Modified efi_set_pgd() to pair uaccess_ttbr0_disable/enable
>> - Accesses to current_thread_info()->ttbr0 are passed through READ/WRITE_ONCE
>>
>> I dropped James' tested-by, just in case I messed something up.
>
> Tested as before:
> Tested-by: James Morse <james.morse at arm.com>
>
Works for me as well (Gnome Shell desktop + Chromium browser)
Tested-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
More information about the linux-arm-kernel
mailing list