[PATCH] arm64: mm: Align PGDs to at least 64 bytes
Anshuman Khandual
anshuman.khandual at arm.com
Wed Nov 23 20:34:00 PST 2022
On 11/22/22 22:26, Ard Biesheuvel wrote:
> My copy of the ARM ARM (DDI 0487G.a) no longer describes the 64 byte
> minimum alignment of root page tables as being conditional on whether
> 52-bit physical addressing is supported and enabled, even though I seem
> to remember that this was the case formerly (and our code suggests the
> same).
ARM ARM (DDI 0487G.a) says,
"The minimum alignment of a translation table containing fewer than eight
entries is 64 bytes." But that does not seem to be conditional on 52-bit
physical address support, unless only the 52 bit physical address space
support could produce table configurations, which will have fewer than 8
entries in the PGD level.
>
> So align pgd_t[] allocations to 64 bytes. Note that this only affects
> 16k/4 levels configurations, which are unlikely to be in wide use.
Instead of "16k/4 levels configurations", could we mention the in terms
of [PG_SIZE/VA_BITS/PA_BITS] format which can be easily related with
available config options.
>
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> ---
> arch/arm64/mm/pgd.c | 13 +++----------
> 1 file changed, 3 insertions(+), 10 deletions(-)
>
> diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
> index 4a64089e5771c1e2..8f01a75c35caaa9a 100644
> --- a/arch/arm64/mm/pgd.c
> +++ b/arch/arm64/mm/pgd.c
> @@ -40,17 +40,10 @@ void __init pgtable_cache_init(void)
> if (PGD_SIZE == PAGE_SIZE)
> return;
>
> -#ifdef CONFIG_ARM64_PA_BITS_52
> /*
> - * With 52-bit physical addresses, the architecture requires the
> - * top-level table to be aligned to at least 64 bytes.
> + * Naturally aligned pgds required by the architecture, with a minimum
> + * alignment of 64 bytes.
> */
> - BUILD_BUG_ON(PGD_SIZE < 64);
> -#endif
> -
> - /*
> - * Naturally aligned pgds required by the architecture.
> - */
> - pgd_cache = kmem_cache_create("pgd_cache", PGD_SIZE, PGD_SIZE,
> + pgd_cache = kmem_cache_create("pgd_cache", PGD_SIZE, max(PGD_SIZE, 64),
> SLAB_PANIC, NULL);
There is a build warning as follows, which can be fixed with typecasting
constant 64 with (size_t). While here, it would also make sense to define
a macro for PGD minimum alignment requirement i.e 64 bytes.
diff --git a/arch/arm64/mm/pgd.c b/arch/arm64/mm/pgd.c
index 8f01a75c35ca..8d4b28d9590f 100644
--- a/arch/arm64/mm/pgd.c
+++ b/arch/arm64/mm/pgd.c
@@ -44,6 +44,6 @@ void __init pgtable_cache_init(void)
* Naturally aligned pgds required by the architecture, with a minimum
* alignment of 64 bytes.
*/
- pgd_cache = kmem_cache_create("pgd_cache", PGD_SIZE, max(PGD_SIZE, 64),
+ pgd_cache = kmem_cache_create("pgd_cache", PGD_SIZE, max(PGD_SIZE, (size_t) 64),
SLAB_PANIC, NULL);
}
In file included from ./include/linux/kernel.h:26,
from ./arch/arm64/include/asm/cpufeature.h:22,
from ./arch/arm64/include/asm/ptrace.h:11,
from ./arch/arm64/include/asm/irqflags.h:10,
from ./include/linux/irqflags.h:16,
from ./include/linux/spinlock.h:59,
from ./include/linux/mmzone.h:8,
from ./include/linux/gfp.h:7,
from ./include/linux/mm.h:7,
from arch/arm64/mm/pgd.c:9:
arch/arm64/mm/pgd.c: In function ‘pgtable_cache_init’:
./include/linux/minmax.h:20:28: warning: comparison of distinct pointer types lacks a cast
20 | (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
| ^~
./include/linux/minmax.h:26:4: note: in expansion of macro ‘__typecheck’
26 | (__typecheck(x, y) && __no_side_effects(x, y))
| ^~~~~~~~~~~
./include/linux/minmax.h:36:24: note: in expansion of macro ‘__safe_cmp’
36 | __builtin_choose_expr(__safe_cmp(x, y), \
| ^~~~~~~~~~
./include/linux/minmax.h:52:19: note: in expansion of macro ‘__careful_cmp’
52 | #define max(x, y) __careful_cmp(x, y, >)
| ^~~~~~~~~~~~~
arch/arm64/mm/pgd.c:47:55: note: in expansion of macro ‘max’
47 | pgd_cache = kmem_cache_create("pgd_cache", PGD_SIZE, max(PGD_SIZE, 64),
> }
Besides, tested on config [16K|48VA|48PA] producing "CONFIG_PGTABLE_LEVELS=4"
and with PGD_SIZE != PAGE_SIZE, which booted successfully.
More information about the linux-arm-kernel
mailing list