Hi Sam,
On Sun, 24 Aug 2025 04:05:05 +0100, Sam Edwards cfsworks@gmail.com wrote:
On Sat, Aug 23, 2025 at 5:29 PM Ard Biesheuvel ardb@kernel.org wrote:
[...]
Under which conditions would PGD_SIZE assume a value greater than PAGE_SIZE?
I might be doing my math wrong, but wouldn't 52-bit VA with 4K granules and 5 levels result in this?
No. 52bit VA at 4kB granule results in levels 0-3 each resolving 9 bits, and level -1 resolving 4 bits. That's a total of 40 bits, plus the 12 bits coming directly from the VA making for the expected 52.
Each PTE represents 4K of virtual memory, so covers VA bits [11:0] (this is level 3)
That's where you got it wrong. The architecture is pretty clear that each level resolves PAGE_SHIFT-3 bits, hence the computation above. The bottom PAGE_SHIFT bits are directly extracted from the VA, without any translation.
Each PMD has 512 PTEs, the index of which covers VA bits [20:12] (this is level 2) Each PUD references 512 PMDs, the index covering VA [29:21] (this is level 1) Each P4D references 512 PUDs, indexed by VA [38:30] (this is level 0) The PGD, at level -1, therefore has to cover VA bits [51:39], which means it has a 13-bit index: 8192 entries of 8 bytes each would make it 16 pages in size.
Note that at stage 1, arm64 does not support page table concatenation, and so the root page table is never larger than a page.
Doesn't PGD_SIZE refer to the size used for userspace PGDs after the boot progresses beyond stage 1? (What do you mean by "never" here? "Under no circumstances is it larger than a page at stage 1"? Or "during the entire lifecycle of the system, there is no time at which it's larger than a page"?)
Never, ever, is a S1 table bigger than a page. This concept doesn't exist in the architecture. Only S2 tables can use concatenation at the top-most level, for up to 16 pages (in order to skip a level when possible).
The top-level can be smaller than a page, with some alignment constraints, but that's about the only degree of freedom you have for S1 page tables.
Thanks,
M.