arm64: Create an empty page table for use as a placeholder page table.
Change-Id: Iff78f06a7abd6b2403e521b252c011d37f657c60 Reviewed-on: https://review.haiku-os.org/c/haiku/+/8103 Haiku-Format: Haiku-format Bot <[email protected]> Tested-by: Commit checker robot <[email protected]> Reviewed-by: Fredrik Holmqvist <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
fa359dc091
commit
c37d2d8eaa
@@ -5,5 +5,6 @@
|
|||||||
#ifndef _KERNEL_ARCH_ARM64_ARCH_VM_TRANSLATION_MAP_H_
|
#ifndef _KERNEL_ARCH_ARM64_ARCH_VM_TRANSLATION_MAP_H_
|
||||||
#define _KERNEL_ARCH_ARM64_ARCH_VM_TRANSLATION_MAP_H_
|
#define _KERNEL_ARCH_ARM64_ARCH_VM_TRANSLATION_MAP_H_
|
||||||
|
|
||||||
|
void arch_vm_install_empty_table_ttbr0(void);
|
||||||
|
|
||||||
#endif /* _KERNEL_ARCH_ARM64_ARCH_VM_TRANSLATION_MAP_H_ */
|
#endif /* _KERNEL_ARCH_ARM64_ARCH_VM_TRANSLATION_MAP_H_ */
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <boot/kernel_args.h>
|
#include <boot/kernel_args.h>
|
||||||
#include <vm/VMAddressSpace.h>
|
#include <vm/VMAddressSpace.h>
|
||||||
#include <vm/vm.h>
|
#include <vm/vm.h>
|
||||||
|
#include <vm/vm_page.h>
|
||||||
|
|
||||||
#include "PMAPPhysicalPageMapper.h"
|
#include "PMAPPhysicalPageMapper.h"
|
||||||
#include "VMSAv8TranslationMap.h"
|
#include "VMSAv8TranslationMap.h"
|
||||||
@@ -18,12 +19,37 @@ static char sPhysicalPageMapperData[sizeof(PMAPPhysicalPageMapper)];
|
|||||||
// low bit is implicitly zero.
|
// low bit is implicitly zero.
|
||||||
static constexpr uint64_t kTtbrBasePhysAddrMask = (((1UL << 47) - 1) << 1);
|
static constexpr uint64_t kTtbrBasePhysAddrMask = (((1UL << 47) - 1) << 1);
|
||||||
|
|
||||||
|
// Physical pointer to an empty page table, which is used for break-before-make
|
||||||
|
// when updating TTBR0_EL1.
|
||||||
|
static phys_addr_t sEmptyTable;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
arch_vm_alloc_empty_table(void)
|
||||||
|
{
|
||||||
|
vm_page_reservation reservation;
|
||||||
|
vm_page_reserve_pages(&reservation, 1, VM_PRIORITY_SYSTEM);
|
||||||
|
vm_page* page = vm_page_allocate_page(&reservation, PAGE_STATE_WIRED | VM_PAGE_ALLOC_CLEAR);
|
||||||
|
DEBUG_PAGE_ACCESS_END(page);
|
||||||
|
sEmptyTable = page->physical_page_number << PAGE_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
arch_vm_install_empty_table_ttbr0(void)
|
||||||
|
{
|
||||||
|
WRITE_SPECIALREG(TTBR0_EL1, sEmptyTable);
|
||||||
|
asm("isb");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
arch_vm_translation_map_create_map(bool kernel, VMTranslationMap** _map)
|
arch_vm_translation_map_create_map(bool kernel, VMTranslationMap** _map)
|
||||||
{
|
{
|
||||||
phys_addr_t pt = 0;
|
phys_addr_t pt = 0;
|
||||||
if (kernel) {
|
if (kernel) {
|
||||||
pt = READ_SPECIALREG(TTBR1_EL1) & kTtbrBasePhysAddrMask;
|
pt = READ_SPECIALREG(TTBR1_EL1) & kTtbrBasePhysAddrMask;
|
||||||
|
arch_vm_install_empty_table_ttbr0();
|
||||||
}
|
}
|
||||||
|
|
||||||
*_map = new (std::nothrow) VMSAv8TranslationMap(kernel, pt, 12, 48, 1);
|
*_map = new (std::nothrow) VMSAv8TranslationMap(kernel, pt, 12, 48, 1);
|
||||||
@@ -40,6 +66,9 @@ arch_vm_translation_map_init(kernel_args* args, VMPhysicalPageMapper** _physical
|
|||||||
{
|
{
|
||||||
dprintf("arch_vm_translation_map_init\n");
|
dprintf("arch_vm_translation_map_init\n");
|
||||||
|
|
||||||
|
// Create an empty page table for use when we don't want a userspace page table.
|
||||||
|
arch_vm_alloc_empty_table();
|
||||||
|
|
||||||
// nuke TTBR0 mapping, we use identity mapping in kernel space at KERNEL_PMAP_BASE
|
// nuke TTBR0 mapping, we use identity mapping in kernel space at KERNEL_PMAP_BASE
|
||||||
memset((void*) READ_SPECIALREG(TTBR0_EL1), 0, B_PAGE_SIZE);
|
memset((void*) READ_SPECIALREG(TTBR0_EL1), 0, B_PAGE_SIZE);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user