In ARMv8 Linux, TTBR0_EL1 and TTBR1_EL1 are used by MMU to do virtual memory management.
So where is the PGD of a process saved in ARMv8 Linux?
In X86, CR3 is used to hold the root of a process page table, it is switched during process context switch, so is there a similar register in ARMv8 ?
I wrote a kernel module to check TTBR0/1_EL1 for processes, but I found they are the same in kernel module, did I miss something?
How can I get the root page table of a specific process?
TL;DR - Observing a TTBRx switch on a system can be difficult due to ASID/DACR/pid facilities on the ARM CPU. Ie, the page tables are annotated with 'process information' and a single register accessible from priveledge mode updates on a context switch for a majority of the cases. This keeps cache entries and TLB fresh.
As per ARM64 TTBR0/1, there are two table base registers. This is also relevant to ARMv7-A systems. As well, you have an ASID. There are several ASIDs and if your system does not have a lot of active processes, the TTBR1 will not change as the kernel will only flip the active domain (single register write). This is the 'fast path' in check_and_switch_context()
.
It you have a highly active system with >16 processes contending/active, then you will take the slow path which updated TTBR0/1. This ends up calling cpu_do_switch_mm()
, which you can see does the update.
References:
pid was a ARMv5 mechanics, which was not accepted into the mainline kernel. DACR (domains (ARMv6)) and ASID are very similar, where ASID is a slight evolution of DACR. A pid was a single value, whereas 'domains' allow a process to have several address space maps; so processes can overlap with shared library code for instance. TLB and cache are annotated with domain information (as well as worlds for TrustZone).