User avatar
rahealy
Posts: 24
Joined: Thu Dec 19, 2019 5:30 pm

Updating/Changing MMU Page Tables

Sat Mar 21, 2020 5:49 pm

Greetings,

I'm currently writing a simple OS for fun and educational purposes. The problem I'm currently trying to solve is updating the MMU page tables when a new task is loaded into the address space. Currently everything runs at EL1, identity mapped.

According to:

Arm® Architecture Reference Manual Armv8, for Armv8-A architecture profile
The AArch64 Virtual Memory System Architecture

D5.10 TLB maintenance requirements and the TLB maintenance instructions:
A break-before-make sequence on changing from an old translation table entry to a new translation table entry
requires the following steps:
1. Replace the old translation table entry with an invalid entry, and execute a DSB instruction.
2. Invalidate the translation table entry with a broadcast TLB invalidation instruction, and execute a DSB
instruction to ensure the completion of that invalidation.
3. Write the new translation table entry, and execute a DSB instruction to ensure that the new entry is visible.
In D5.10.2 TLB maintenance instructions:
An instruction that applies to the translation regime of an Exception level higher than
the Exception level at which the instruction is executed is UNDEFINED.
I must be in EL2 to perform TLB operations that affect EL1, correct? If so, is there another way to update page tables from EL1?

The other options are:
- Run tasks in EL0.
- Load all tasks into memory first then set page tables.
- ???

Thank you in advance for any assistance,

-Richard

bzt
Posts: 509
Joined: Sat Oct 14, 2017 9:57 pm

Re: Updating/Changing MMU Page Tables

Wed Mar 25, 2020 6:58 pm

Hi,

If you create an entirely new address space, then set it's paging table physical address in TTBR0/1_EL1, then

Code: Select all

TLBI VMALLE1
DSB ISH
ISB
This will reload the entire address space for the new task. Obviously you'll need to map this code at the same address in the old as well as in the new tables, otherwise you'll probably get prefetch abort. Here it is very handy that ARM has two address spaces: run this code somewhere in high memory pointed by TTBR1, and only replace TTBR0 on task switch (or creation). Thus TTBR1 will always be the same (kernel space), and TTBR0 will be unique to each task (user space).

This can work with code pointed by TTBR0 running at EL1, however I'd recommend using EL0, much safer.

Cheers,
bzt

User avatar
rahealy
Posts: 24
Joined: Thu Dec 19, 2019 5:30 pm

Re: Updating/Changing MMU Page Tables

Sat Mar 28, 2020 6:00 pm

Hi @bzt,

Thank you for your voice of experience.

I'm not sure what I want to do yet. I'm leaning toward moving tasks into EL0.

-Richard

Return to “Bare metal, Assembly language”