kernel/arm: don't set Accessed Flag when initially mapping a page

Pages should not be marked as accessed when initially mapping them.

However, there's a short interval during kernel startup when new pages
are mapped but the fault handler is not installed yet.

Therefore, we set Accessed Flag to 1 in early_map.
Once the kernel initialization has progressed enough, we start mapping
new pages with Accessed Flag set to 0.

The chicken and egg problem of initially mapping the vector page is
tackled by preallocating the vector page in the boot loader.

Change-Id: Ie3be4f81812d7a090af57e8c79420598d16182b9
Reviewed-on: https://review.haiku-os.org/c/haiku/+/6450
Reviewed-by: Fredrik Holmqvist <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
David Karoly
2023-06-06 18:49:56 +00:00
parent a2cb4665de
commit f61fb770f0
5 changed files with 38 additions and 34 deletions
@@ -24,6 +24,8 @@
#define CPSR_F 0x40 #define CPSR_F 0x40
#define CPSR_I 0x80 #define CPSR_I 0x80
#define SCTLR_HIGH_VECTORS 0x00002000
#define FSR_WNR 0x800 #define FSR_WNR 0x800
#define FSR_LPAE 0x200 #define FSR_LPAE 0x200
@@ -35,6 +35,8 @@ static constexpr bool kTracePageDirectory = false;
#define PHYSICAL_MEMORY_LOW 0x00000000 #define PHYSICAL_MEMORY_LOW 0x00000000
#define PHYSICAL_MEMORY_HIGH 0x8000000000ull #define PHYSICAL_MEMORY_HIGH 0x8000000000ull
#define USER_VECTOR_ADDR_HIGH 0xffff0000
#define ALIGN_PAGEDIR (1024 * 16) #define ALIGN_PAGEDIR (1024 * 16)
#define MAX_PAGE_TABLES 192 #define MAX_PAGE_TABLES 192
#define PAGE_TABLE_AREA_SIZE (MAX_PAGE_TABLES * ARM_MMU_L2_COARSE_TABLE_SIZE) #define PAGE_TABLE_AREA_SIZE (MAX_PAGE_TABLES * ARM_MMU_L2_COARSE_TABLE_SIZE)
@@ -42,6 +44,7 @@ static constexpr bool kTracePageDirectory = false;
static uint32_t *sPageDirectory = NULL; static uint32_t *sPageDirectory = NULL;
static uint32_t *sNextPageTable = NULL; static uint32_t *sNextPageTable = NULL;
static uint32_t *sLastPageTable = NULL; static uint32_t *sLastPageTable = NULL;
static uint32_t *sVectorTable = (uint32_t*)USER_VECTOR_ADDR_HIGH;
static void static void
@@ -232,12 +235,23 @@ arch_mmu_allocate_page_tables(void)
} }
static void
arch_mmu_allocate_vector_table(void)
{
if (platform_allocate_region((void **)&sVectorTable, B_PAGE_SIZE, 0, false) != B_OK)
panic("Failed to allocate vector table.");
memset(sVectorTable, 0, B_PAGE_SIZE);
}
uint32_t uint32_t
arch_mmu_generate_post_efi_page_tables(size_t memoryMapSize, arch_mmu_generate_post_efi_page_tables(size_t memoryMapSize,
efi_memory_descriptor *memoryMap, size_t descriptorSize, efi_memory_descriptor *memoryMap, size_t descriptorSize,
uint32_t descriptorVersion) uint32_t descriptorVersion)
{ {
arch_mmu_allocate_page_tables(); arch_mmu_allocate_page_tables();
arch_mmu_allocate_vector_table();
build_physical_memory_list(memoryMapSize, memoryMap, build_physical_memory_list(memoryMapSize, memoryMap,
descriptorSize, descriptorVersion, descriptorSize, descriptorVersion,
+18 -32
View File
@@ -60,8 +60,6 @@
extern int _vectors_start; extern int _vectors_start;
extern int _vectors_end; extern int _vectors_end;
static area_id sVectorPageArea;
static void *sVectorPageAddress;
static area_id sUserVectorPageArea; static area_id sUserVectorPageArea;
static void *sUserVectorPageAddress; static void *sUserVectorPageAddress;
//static fdt_module_info *sFdtModule; //static fdt_module_info *sFdtModule;
@@ -120,52 +118,40 @@ print_iframe(const char *event, struct iframe *frame)
} }
extern "C" void arm_vector_init(void);
status_t status_t
arch_int_init(kernel_args *args) arch_int_init(kernel_args *args)
{ {
TRACE("arch_int_init\n");
// copy vector code to vector page
memcpy((void*)USER_VECTOR_ADDR_HIGH, &_vectors_start, VECTORPAGE_SIZE);
// initialize stack for vectors
arm_vector_init();
// enable high vectors
arm_set_sctlr(arm_get_sctlr() | SCTLR_HIGH_VECTORS);
return B_OK; return B_OK;
} }
extern "C" void arm_vector_init(void);
status_t status_t
arch_int_init_post_vm(kernel_args *args) arch_int_init_post_vm(kernel_args *args)
{ {
// create a read/write kernel area TRACE("arch_int_init_post_vm\n");
sVectorPageArea = create_area("vectorpage", (void **)&sVectorPageAddress,
B_ANY_ADDRESS, VECTORPAGE_SIZE, B_FULL_LOCK,
B_KERNEL_WRITE_AREA | B_KERNEL_READ_AREA);
if (sVectorPageArea < 0)
panic("vector page could not be created!");
// clone it at a fixed address with user read/only permissions
sUserVectorPageAddress = (addr_t*)USER_VECTOR_ADDR_HIGH; sUserVectorPageAddress = (addr_t*)USER_VECTOR_ADDR_HIGH;
sUserVectorPageArea = clone_area("user_vectorpage", sUserVectorPageArea = create_area("user_vectorpage",
(void **)&sUserVectorPageAddress, B_EXACT_ADDRESS, (void **)&sUserVectorPageAddress, B_EXACT_ADDRESS,
B_READ_AREA | B_EXECUTE_AREA, sVectorPageArea); B_PAGE_SIZE, B_ALREADY_WIRED, B_READ_AREA | B_EXECUTE_AREA);
if (sUserVectorPageArea < 0) if (sUserVectorPageArea < 0)
panic("user vector page @ %p could not be created (%x)!", panic("user vector page @ %p could not be created (%x)!",
sVectorPageAddress, sUserVectorPageArea); sUserVectorPageAddress, sUserVectorPageArea);
// copy vectors into the newly created area
memcpy(sVectorPageAddress, &_vectors_start, VECTORPAGE_SIZE);
arm_vector_init();
// see if high vectors are enabled
if ((arm_get_sctlr() & (1 << 13)) != 0)
dprintf("High vectors already enabled\n");
else {
arm_set_sctlr(arm_get_sctlr() | (1 << 13));
if ((arm_get_sctlr() & (1 << 13)) == 0)
dprintf("Unable to enable high vectors!\n");
else
dprintf("Enabled high vectors\n");
}
if (strncmp(args->arch_args.interrupt_controller.kind, INTC_KIND_GICV2, if (strncmp(args->arch_args.interrupt_controller.kind, INTC_KIND_GICV2,
sizeof(args->arch_args.interrupt_controller.kind)) == 0) { sizeof(args->arch_args.interrupt_controller.kind)) == 0) {
@@ -408,7 +408,7 @@ ARMPagingMethod32Bit::MapEarly(kernel_args* args, addr_t virtualAddress,
// now, fill in the pentry // now, fill in the pentry
PutPageTableEntryInTable(ptEntry, PutPageTableEntryInTable(ptEntry,
physicalAddress, attributes, 0, IS_KERNEL_ADDRESS(virtualAddress)); physicalAddress, attributes | PAGE_ACCESSED, 0, IS_KERNEL_ADDRESS(virtualAddress));
return B_OK; return B_OK;
} }
@@ -502,7 +502,6 @@ ARMPagingMethod32Bit::PutPageTableEntryInTable(page_table_entry* entry,
| ARM_MMU_L2_TYPE_SMALLNEW | ARM_MMU_L2_TYPE_SMALLNEW
| MemoryTypeToPageTableEntryFlags(memoryType) | MemoryTypeToPageTableEntryFlags(memoryType)
| AttributesToPageTableEntryFlags(attributes) | AttributesToPageTableEntryFlags(attributes)
| ARM_MMU_L2_FLAG_AP0
| (globalPage ? 0 : ARM_MMU_L2_FLAG_NG); | (globalPage ? 0 : ARM_MMU_L2_FLAG_NG);
// put it in the page table // put it in the page table
@@ -169,6 +169,9 @@ ARMPagingMethod32Bit::AttributesToPageTableEntryFlags(uint32 attributes)
apFlags |= ARM_MMU_L2_FLAG_XN; apFlags |= ARM_MMU_L2_FLAG_XN;
} }
if ((attributes & PAGE_ACCESSED) != 0)
apFlags |= ARM_MMU_L2_FLAG_AP0;
return apFlags; return apFlags;
} }