[PATCH v3 4/4] ARM: Implement PAN for LPAE by TTBR0 page table walks disablement

Geert Uytterhoeven geert at linux-m68k.org
Tue May 7 06:10:00 PDT 2024


Hi Linus,

On Tue, Mar 12, 2024 at 1:52 PM Linus Walleij <linus.walleij at linaro.org> wrote:
> From: Catalin Marinas <catalin.marinas at arm.com>
>
> With LPAE enabled, privileged no-access cannot be enforced using CPU
> domains as such feature is not available. This patch implements PAN
> by disabling TTBR0 page table walks while in kernel mode.
>
> The ARM architecture allows page table walks to be split between TTBR0
> and TTBR1. With LPAE enabled, the split is defined by a combination of
> TTBCR T0SZ and T1SZ bits. Currently, an LPAE-enabled kernel uses TTBR0
> for user addresses and TTBR1 for kernel addresses with the VMSPLIT_2G
> and VMSPLIT_3G configurations. The main advantage for the 3:1 split is
> that TTBR1 is reduced to 2 levels, so potentially faster TLB refill
> (though usually the first level entries are already cached in the TLB).
>
> The PAN support on LPAE-enabled kernels uses TTBR0 when running in user
> space or in kernel space during user access routines (TTBCR T0SZ and
> T1SZ are both 0). When running user accesses are disabled in kernel
> mode, TTBR0 page table walks are disabled by setting TTBCR.EPD0. TTBR1
> is used for kernel accesses (including loadable modules; anything
> covered by swapper_pg_dir) by reducing the TTBCR.T0SZ to the minimum
> (2^(32-7) = 32MB). To avoid user accesses potentially hitting stale TLB
> entries, the ASID is switched to 0 (reserved) by setting TTBCR.A1 and
> using the ASID value in TTBR1. The difference from a non-PAN kernel is
> that with the 3:1 memory split, TTBR1 always uses 3 levels of page
> tables.
>
> As part of the change we are using preprocessor elif definied() clauses
> so balance these clauses by converting relevant precedingt ifdef
> clauses to if defined() clauses.
>
> Signed-off-by: Catalin Marinas <catalin.marinas at arm.com>
> Reviewed-by: Kees Cook <keescook at chromium.org>
> Signed-off-by: Linus Walleij <linus.walleij at linaro.org>

Thanks for your patch, which is now commit 7af5b901e84743c6 ("ARM:
9358/2: Implement PAN for LPAE by TTBR0 page table walks disablement")
in arm/for-next (next-20240502 and later).

On Koelsch (R-Car M2-W with dual Cortex A15) with LPAE enabled:

    Run /sbin/init as init process
      with arguments:
        /sbin/init
      with environment:
        HOME=/
        TERM=linux
    Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004
    CPU: 1 PID: 1 Comm: init Tainted: G        W        N
6.9.0-rc1-koelsch-00004-g7af5b901e847 #1930
    Hardware name: Generic R-Car Gen2 (Flattened Device Tree)
    Call trace:
     unwind_backtrace from show_stack+0x10/0x14
     show_stack from dump_stack_lvl+0x78/0xa8
     dump_stack_lvl from panic+0x118/0x398
     panic from do_exit+0x1ec/0x938
     do_exit from sys_exit_group+0x0/0x10
    ---[ end Kernel panic - not syncing: Attempted to kill init!
exitcode=0x00000004 ]---

Disabling LPAE fixes the issue.

Note that shmobile_defconfig has CONFIG_LPAE=n, and thus works fine.

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds



More information about the linux-arm-kernel mailing list