[PATCH v4 35/61] arm64: pgtable: Decouple PGDIR size macros from PGD/PUD/PMD levels
Catalin Marinas
catalin.marinas at arm.com
Thu Oct 19 09:34:33 PDT 2023
On Tue, Sep 12, 2023 at 02:16:25PM +0000, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb at kernel.org>
>
> The mapping from PGD/PUD/PMD to levels and shifts is very confusing,
> given that, due to folding, the shifts may be equal for different
> levels, if the macros are even #define'd to begin with.
>
> In a subsequent patch, we will modify the ID mapping code to decouple
> the number of levels from the kernel's view of how these types are
> folded, so prepare for this by reformulating the macros without the use
> of these types.
>
> Instead, use SWAPPER_BLOCK_SHIFT as the base quantity, and derive it
> from either PAGE_SHIFT or PMD_SHIFT, which -if defined at all- are
> defined unambiguously for a given page size, regardless of the number of
> configured levels.
>
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> ---
> arch/arm64/include/asm/kernel-pgtable.h | 65 ++++++--------------
> 1 file changed, 19 insertions(+), 46 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h
> index 742a4b2778f7..5000f38ae0c6 100644
> --- a/arch/arm64/include/asm/kernel-pgtable.h
> +++ b/arch/arm64/include/asm/kernel-pgtable.h
> @@ -13,27 +13,22 @@
> #include <asm/sparsemem.h>
>
> /*
> - * The linear mapping and the start of memory are both 2M aligned (per
> - * the arm64 booting.txt requirements). Hence we can use section mapping
> - * with 4K (section size = 2M) but not with 16K (section size = 32M) or
> - * 64K (section size = 512M).
> + * The physical and virtual addresses of the start of the kernel image are
> + * equal modulo 2 MiB (per the arm64 booting.txt requirements). Hence we can
> + * use section mapping with 4K (section size = 2M) but not with 16K (section
> + * size = 32M) or 64K (section size = 512M).
> */
> -
> -/*
> - * The idmap and swapper page tables need some space reserved in the kernel
> - * image. Both require pgd, pud (4 levels only) and pmd tables to (section)
> - * map the kernel. With the 64K page configuration, swapper and idmap need to
> - * map to pte level. The swapper also maps the FDT (see __create_page_tables
> - * for more information). Note that the number of ID map translation levels
> - * could be increased on the fly if system RAM is out of reach for the default
> - * VA range, so pages required to map highest possible PA are reserved in all
> - * cases.
> - */
> -#ifdef CONFIG_ARM64_4K_PAGES
> -#define SWAPPER_PGTABLE_LEVELS (CONFIG_PGTABLE_LEVELS - 1)
> +#if defined(PMD_SIZE) && PMD_SIZE <= MIN_KIMG_ALIGN
Nitpick: we always have PMD_SIZE defined, either directly in the arm64
headers if we have more than 2 levels or included from the generic
pgtable-nopmd.h. Otherwise the logic is fine.
> +#define SWAPPER_BLOCK_SHIFT PMD_SHIFT
> +#define SWAPPER_SKIP_LEVEL 1
> #else
> -#define SWAPPER_PGTABLE_LEVELS (CONFIG_PGTABLE_LEVELS)
> +#define SWAPPER_BLOCK_SHIFT PAGE_SHIFT
> +#define SWAPPER_SKIP_LEVEL 0
> #endif
> +#define SWAPPER_BLOCK_SIZE (UL(1) << SWAPPER_BLOCK_SHIFT)
> +#define SWAPPER_TABLE_SHIFT (SWAPPER_BLOCK_SHIFT + PAGE_SHIFT - 3)
> +
> +#define SWAPPER_PGTABLE_LEVELS (CONFIG_PGTABLE_LEVELS - SWAPPER_SKIP_LEVEL)
Do you use SWAPPER_SKIP_LEVEL anywhere else? If not we might as well
define SWAPPER_PGTABLE_LEVELS directly under the #if/#else blocks.
> #define IDMAP_VA_BITS 48
> #define IDMAP_LEVELS ARM64_HW_PGTABLE_LEVELS(IDMAP_VA_BITS)
> @@ -53,24 +48,13 @@
> #define EARLY_ENTRIES(vstart, vend, shift, add) \
> (SPAN_NR_ENTRIES(vstart, vend, shift) + (add))
>
> -#define EARLY_PGDS(vstart, vend, add) (EARLY_ENTRIES(vstart, vend, PGDIR_SHIFT, add))
> -
> -#if SWAPPER_PGTABLE_LEVELS > 3
> -#define EARLY_PUDS(vstart, vend, add) (EARLY_ENTRIES(vstart, vend, PUD_SHIFT, add))
> -#else
> -#define EARLY_PUDS(vstart, vend, add) (0)
> -#endif
> +#define EARLY_LEVEL(l, vstart, vend, add) \
> + (SWAPPER_PGTABLE_LEVELS > l ? EARLY_ENTRIES(vstart, vend, SWAPPER_BLOCK_SHIFT + l * (PAGE_SHIFT - 3), add) : 0)
It took me a while to realise that this is 'l' and not '1' (I need
better glasses). Maybe if you respin, change this to 'lvl'.
--
Catalin
More information about the linux-arm-kernel
mailing list