TLB miss and page table fault handling?

I’m wondering how TLB misses and page table faults are handled in general on a complete RISC-V platform (for instance, the rocket chip). The specification itself leaves the implementation fairly free to handle these however they like, but looking around in the riscv-linux source tree there seems to be hardly any code that shows how exactly the page table is written to in the case of a page fault, or what happens to the TLB in the case of a TLB miss.

You won’t find something like that in the Linux source code. It’s not its concern.

The page table format in RAM is documented and standardised.

On a TLB miss (of which page fault is a subset) either the hardware will automatically walk the page table and load the entry into the TLB, or else some CPU-specific low level machine mode code will do it. This is part of the SBI or stage 2 bootloader, or something like that. By the time the Linux kernel is loaded and entered all of that should already be set up and working transparently.

Hm, so is there documentation/a specification I could look at to understand how that works?

The several options for the page table format in RAM (Sv32, Sv39, Sv48) are documented in the “RISC-V Privileged ISA Specification” along with the satp CSR and SFENCE.VMA instruction. https://riscv.org/specifications/privileged-isa/

Nothing else is standardised. You should look for more information in your CPU core vendor’s documentation. Current SiFive cores with page table support use a hardware page table walker.

I found this passage in the specification for the hifive unleashed board:

The U54 MMU has a 39 virtual address space mapped to a 38 physical address space. A hardware page-table walker refills the address translation caches. Both first-level instruction and data address translation caches are fully associative and have 32 entries. There is also a unified second-level translation cache with 128 entries. The MMU supports 2 MiB megapages and 1 GiB gigapages to reduce translation overheads for large contiguous regions of virtual and physical address space.
Note that the U54 does not automatically set the Accessed (A) and Dirty (D) bits in a Sv39
Page Table Entry (PTE). Instead, the U54 MMU will raise a page fault exception for a read to a page with PTE.A=0 or a write to a page with PTE.D=0.

So that bit about a “page fault exception” seems to indicate that there’s some kernel code somewhere that’ll handles page faults (while TLB misses are handled by the hardware page table walker), right? If I’m right about that, does anyone have an idea of where I could look in the riscv-linux source to see the code that handles that?

The page fault handler is here:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/riscv/mm/fault.c

Please consider joining the linux-riscv mailing list at

https://lists.infradead.org/mailman/listinfo/linux-riscv

There are more Linux-oriented folks that read that list than peruse these forums, I think.