Skip to content

Commit 51ecb29

Browse files
Anshuman Khandualctmarinas
authored andcommitted
arm64/mm: Define PTDESC_ORDER
Address bytes shifted with a single 64 bit page table entry (any page table level) has been always hard coded as 3 (aka 2^3 = 8). Although intuitive it is not very readable or easy to reason about. Besides it is going to change with D128, where each 128 bit page table entry will shift address bytes by 4 (aka 2^4 = 16) instead. Let's just formalise this address bytes shift value into a new macro called PTDESC_ORDER establishing a logical abstraction, thus improving readability as well. While here re-organize EARLY_LEVEL macro along with its dependents for better clarity. This does not cause any functional change. Also replace all (PAGE_SHIFT - PTDESC_ORDER) instances with PTDESC_TABLE_SHIFT. Cc: Will Deacon <will@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com> Cc: Alexander Potapenko <glider@google.com> Cc: Andrey Konovalov <andreyknvl@gmail.com> Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Ard Biesheuvel <ardb@kernel.org> Cc: Ryan Roberts <ryan.roberts@arm.com> Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Cc: kasan-dev@googlegroups.com Acked-by: Ard Biesheuvel <ardb@kernel.org> Reviewed-by: Ryan Roberts <ryan.roberts@arm.com> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com> Link: https://lore.kernel.org/r/20250311045710.550625-1-anshuman.khandual@arm.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
1 parent bf25266 commit 51ecb29

File tree

5 files changed

+27
-21
lines changed

5 files changed

+27
-21
lines changed

arch/arm64/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ config ARCH_MMAP_RND_BITS_MIN
323323
default 18
324324

325325
# max bits determined by the following formula:
326-
# VA_BITS - PAGE_SHIFT - 3
326+
# VA_BITS - PTDESC_TABLE_SHIFT
327327
config ARCH_MMAP_RND_BITS_MAX
328328
default 19 if ARM64_VA_BITS=36
329329
default 24 if ARM64_VA_BITS=39

arch/arm64/include/asm/kernel-pgtable.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@
4545
#define SPAN_NR_ENTRIES(vstart, vend, shift) \
4646
((((vend) - 1) >> (shift)) - ((vstart) >> (shift)) + 1)
4747

48-
#define EARLY_ENTRIES(vstart, vend, shift, add) \
49-
(SPAN_NR_ENTRIES(vstart, vend, shift) + (add))
48+
#define EARLY_ENTRIES(lvl, vstart, vend) \
49+
SPAN_NR_ENTRIES(vstart, vend, SWAPPER_BLOCK_SHIFT + lvl * PTDESC_TABLE_SHIFT)
5050

51-
#define EARLY_LEVEL(lvl, lvls, vstart, vend, add) \
52-
(lvls > lvl ? EARLY_ENTRIES(vstart, vend, SWAPPER_BLOCK_SHIFT + lvl * (PAGE_SHIFT - 3), add) : 0)
51+
#define EARLY_LEVEL(lvl, lvls, vstart, vend, add) \
52+
((lvls) > (lvl) ? EARLY_ENTRIES(lvl, vstart, vend) + (add) : 0)
5353

5454
#define EARLY_PAGES(lvls, vstart, vend, add) (1 /* PGDIR page */ \
5555
+ EARLY_LEVEL(3, (lvls), (vstart), (vend), add) /* each entry needs a next level page table */ \

arch/arm64/include/asm/pgtable-hwdef.h

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,46 @@
77

88
#include <asm/memory.h>
99

10+
#define PTDESC_ORDER 3
11+
12+
/* Number of VA bits resolved by a single translation table level */
13+
#define PTDESC_TABLE_SHIFT (PAGE_SHIFT - PTDESC_ORDER)
14+
1015
/*
1116
* Number of page-table levels required to address 'va_bits' wide
1217
* address, without section mapping. We resolve the top (va_bits - PAGE_SHIFT)
13-
* bits with (PAGE_SHIFT - 3) bits at each page table level. Hence:
18+
* bits with PTDESC_TABLE_SHIFT bits at each page table level. Hence:
1419
*
15-
* levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), (PAGE_SHIFT - 3))
20+
* levels = DIV_ROUND_UP((va_bits - PAGE_SHIFT), PTDESC_TABLE_SHIFT)
1621
*
1722
* where DIV_ROUND_UP(n, d) => (((n) + (d) - 1) / (d))
1823
*
1924
* We cannot include linux/kernel.h which defines DIV_ROUND_UP here
2025
* due to build issues. So we open code DIV_ROUND_UP here:
2126
*
22-
* ((((va_bits) - PAGE_SHIFT) + (PAGE_SHIFT - 3) - 1) / (PAGE_SHIFT - 3))
27+
* ((((va_bits) - PAGE_SHIFT) + PTDESC_TABLE_SHIFT - 1) / PTDESC_TABLE_SHIFT)
2328
*
2429
* which gets simplified as :
2530
*/
26-
#define ARM64_HW_PGTABLE_LEVELS(va_bits) (((va_bits) - 4) / (PAGE_SHIFT - 3))
31+
#define ARM64_HW_PGTABLE_LEVELS(va_bits) \
32+
(((va_bits) - PTDESC_ORDER - 1) / PTDESC_TABLE_SHIFT)
2733

2834
/*
2935
* Size mapped by an entry at level n ( -1 <= n <= 3)
30-
* We map (PAGE_SHIFT - 3) at all translation levels and PAGE_SHIFT bits
36+
* We map PTDESC_TABLE_SHIFT at all translation levels and PAGE_SHIFT bits
3137
* in the final page. The maximum number of translation levels supported by
3238
* the architecture is 5. Hence, starting at level n, we have further
3339
* ((4 - n) - 1) levels of translation excluding the offset within the page.
3440
* So, the total number of bits mapped by an entry at level n is :
3541
*
36-
* ((4 - n) - 1) * (PAGE_SHIFT - 3) + PAGE_SHIFT
42+
* ((4 - n) - 1) * PTDESC_TABLE_SHIFT + PAGE_SHIFT
3743
*
3844
* Rearranging it a bit we get :
39-
* (4 - n) * (PAGE_SHIFT - 3) + 3
45+
* (4 - n) * PTDESC_TABLE_SHIFT + PTDESC_ORDER
4046
*/
41-
#define ARM64_HW_PGTABLE_LEVEL_SHIFT(n) ((PAGE_SHIFT - 3) * (4 - (n)) + 3)
47+
#define ARM64_HW_PGTABLE_LEVEL_SHIFT(n) (PTDESC_TABLE_SHIFT * (4 - (n)) + PTDESC_ORDER)
4248

43-
#define PTRS_PER_PTE (1 << (PAGE_SHIFT - 3))
49+
#define PTRS_PER_PTE (1 << PTDESC_TABLE_SHIFT)
4450

4551
/*
4652
* PMD_SHIFT determines the size a level 2 page table entry can map.
@@ -49,7 +55,7 @@
4955
#define PMD_SHIFT ARM64_HW_PGTABLE_LEVEL_SHIFT(2)
5056
#define PMD_SIZE (_AC(1, UL) << PMD_SHIFT)
5157
#define PMD_MASK (~(PMD_SIZE-1))
52-
#define PTRS_PER_PMD (1 << (PAGE_SHIFT - 3))
58+
#define PTRS_PER_PMD (1 << PTDESC_TABLE_SHIFT)
5359
#endif
5460

5561
/*
@@ -59,14 +65,14 @@
5965
#define PUD_SHIFT ARM64_HW_PGTABLE_LEVEL_SHIFT(1)
6066
#define PUD_SIZE (_AC(1, UL) << PUD_SHIFT)
6167
#define PUD_MASK (~(PUD_SIZE-1))
62-
#define PTRS_PER_PUD (1 << (PAGE_SHIFT - 3))
68+
#define PTRS_PER_PUD (1 << PTDESC_TABLE_SHIFT)
6369
#endif
6470

6571
#if CONFIG_PGTABLE_LEVELS > 4
6672
#define P4D_SHIFT ARM64_HW_PGTABLE_LEVEL_SHIFT(0)
6773
#define P4D_SIZE (_AC(1, UL) << P4D_SHIFT)
6874
#define P4D_MASK (~(P4D_SIZE-1))
69-
#define PTRS_PER_P4D (1 << (PAGE_SHIFT - 3))
75+
#define PTRS_PER_P4D (1 << PTDESC_TABLE_SHIFT)
7076
#endif
7177

7278
/*

arch/arm64/kernel/pi/map_range.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ void __init map_range(u64 *pte, u64 start, u64 end, u64 pa, pgprot_t prot,
3131
{
3232
u64 cmask = (level == 3) ? CONT_PTE_SIZE - 1 : U64_MAX;
3333
pteval_t protval = pgprot_val(prot) & ~PTE_TYPE_MASK;
34-
int lshift = (3 - level) * (PAGE_SHIFT - 3);
34+
int lshift = (3 - level) * PTDESC_TABLE_SHIFT;
3535
u64 lmask = (PAGE_SIZE << lshift) - 1;
3636

3737
start &= PAGE_MASK;

arch/arm64/mm/kasan_init.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ static void __init kasan_pgd_populate(unsigned long addr, unsigned long end,
190190
*/
191191
static bool __init root_level_aligned(u64 addr)
192192
{
193-
int shift = (ARM64_HW_PGTABLE_LEVELS(vabits_actual) - 1) * (PAGE_SHIFT - 3);
193+
int shift = (ARM64_HW_PGTABLE_LEVELS(vabits_actual) - 1) * PTDESC_TABLE_SHIFT;
194194

195195
return (addr % (PAGE_SIZE << shift)) == 0;
196196
}
@@ -245,7 +245,7 @@ static int __init root_level_idx(u64 addr)
245245
*/
246246
u64 vabits = IS_ENABLED(CONFIG_ARM64_64K_PAGES) ? VA_BITS
247247
: vabits_actual;
248-
int shift = (ARM64_HW_PGTABLE_LEVELS(vabits) - 1) * (PAGE_SHIFT - 3);
248+
int shift = (ARM64_HW_PGTABLE_LEVELS(vabits) - 1) * PTDESC_TABLE_SHIFT;
249249

250250
return (addr & ~_PAGE_OFFSET(vabits)) >> (shift + PAGE_SHIFT);
251251
}
@@ -269,7 +269,7 @@ static void __init clone_next_level(u64 addr, pgd_t *tmp_pg_dir, pud_t *pud)
269269
*/
270270
static int __init next_level_idx(u64 addr)
271271
{
272-
int shift = (ARM64_HW_PGTABLE_LEVELS(vabits_actual) - 2) * (PAGE_SHIFT - 3);
272+
int shift = (ARM64_HW_PGTABLE_LEVELS(vabits_actual) - 2) * PTDESC_TABLE_SHIFT;
273273

274274
return (addr >> (shift + PAGE_SHIFT)) % PTRS_PER_PTE;
275275
}

0 commit comments

Comments
 (0)