MMU usage on ARMv8 ------------------ = Permissions = Pages are mapped with the minimum permissions required. This means all data is mapped as Write/XN (read/write but not execute) and code is mapped as read-only. To prevent the page tables from being modified by an attacker, the page tables are not mapped into virtual memory at all. Therefore, the page tables cannot be modified after the MMU is turned on. To protect against buffer overflows, some pages are left unmapped to act as guard pages. For applications like iBoot that need to clear memory, these pages need to be cleared prior to enabling the MMU. The ROM trampoline is a special case, as it needs to be copied out of the ROM into SRAM so that it can be executed from outside of ROM after ROM access is disabled. To deal with this, the trampoline is copied by startup code prior to the MMU being enabled, and then mapped as read-only. This allows the ROM to jump into the trampoline without having a security risk from writeable code. To enforce all of the above, the WXN (write execute never) bit is set in SCTLR whenever the MMU is enabled. = Secure/Non-secure Walks The top level page table (regardless of how many total levels you have) is always walked in secure mode in EL3 regardless of SCR_EL3.NS. For subsequent levels, the page table attributes (which we mark as non-secure) are used. Almost immediately after starting up on cpus with EL3 support, iBoot switches to EL3 non-secure mode. If we tried to dynamically update the top-level page table to add a mapping those writes would be non-secure and woudl be tagged as such in the L2 cache. This means they wouldn't be seen by the top-level page table walk (which remember is always secure) resulting in an abort when the code tries to access the new mapping. This is not an issue when the page tables are not modified after enabling the MMU, so this note is mainly for historical purposes. See . = Address space sizes = All of our ARMv8 CPUs are in SoCs with 36-bit physical addresses. Because we always map so that a virtual address corresponds to its physical address, we set the virtual address size to 36 bits in TCR to match the physical address. As a result, one less level of walk is required than if we used the full 48-bit virtual addresses supported by the architecture Address translation source bits at L0..L3 depend on selection of 4KB/16KB/64KB granule. = Translation table sizes = Because translation tables cannot be modified after enabling the MMU, they need to live in their own pages. Therefore, regardless of how many entries in a tables are used, each table must be aligned to and have the size of a mapping granule. L0 Translation table. Not used L1 Translation table. Granule bits entries size in bytes entry type 4KB [35:30] 128 4096 1GB L2 or block 16KB N/A 0 0 64GB L2 64KB N/A 0 0 4TB L2 L2 Translation table. Granule bits entries size in bytes entry type 4KB [29:21] 512 4096 2MB L3 or block 16KB [35:25] 2048 16384 32MB L3 or block 64KB [35:29] 2048 65536 512MB L3 or block L3 Translation table Granule bits entries size in bytes entry type 4KB [20:12] 512 4096 4KB block 16KB [24:14] 2048 16384 16KB block 64KB [28:16] 8192 65536 64KB block