1

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?

artless noise
  • 21,212
  • 6
  • 68
  • 105
wangt13
  • 959
  • 7
  • 17
  • I'd think that one of registers holds translation table for EL0 (user space) and another one holds translation table for EL1 (kernel space). Kernel translation table base address likely to stay same all the time. User translation table is assigned at context switching every time when running process is changed – user3124812 Aug 18 '22 at 10:00
  • Maybe this helps: https://stackoverflow.com/questions/68525312/cant-read-the-pagetable-using-ttbr0-el1-register-arm64/68526261#68526261 – Marco Bonelli Aug 18 '22 at 12:44

1 Answers1

2

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).

artless noise
  • 21,212
  • 6
  • 68
  • 105
  • Also, even if `cpu_do_switch_mm()` is called, it may use the same memory; not sure about that. Ie, you can update the table and just flush the TLB, so the TTBRx will remain the same. The last reference given explains this process (for ARMv7-A, but probably applicable to ARMv8). – artless noise Aug 18 '22 at 16:08
  • Thanks for answer. So if I hack the cpu_do_switch_mm() to print out the TTBR0/1_EL1 it operates, I can get the close view of process's PGD and TTBRs, right? – wangt13 Aug 19 '22 at 08:09
  • Yes, I believe so. At one point, this was part of the 'proc' table. Ie, there was an assembler call through the 'proc' interfaces in the kernel directory. It will depend on your version of Linux. If you are the current mainline, I think the 'cpu_do_switch_mm()' is the correct function. – artless noise Aug 19 '22 at 15:31
  • I am doing testing around cpu_do_switch_mm() and I just vote for your answer. – wangt13 Aug 19 '22 at 21:54