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:
@@ -24,6 +24,8 @@
|
||||
#define CPSR_F 0x40
|
||||
#define CPSR_I 0x80
|
||||
|
||||
#define SCTLR_HIGH_VECTORS 0x00002000
|
||||
|
||||
#define FSR_WNR 0x800
|
||||
#define FSR_LPAE 0x200
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ static constexpr bool kTracePageDirectory = false;
|
||||
#define PHYSICAL_MEMORY_LOW 0x00000000
|
||||
#define PHYSICAL_MEMORY_HIGH 0x8000000000ull
|
||||
|
||||
#define USER_VECTOR_ADDR_HIGH 0xffff0000
|
||||
|
||||
#define ALIGN_PAGEDIR (1024 * 16)
|
||||
#define MAX_PAGE_TABLES 192
|
||||
#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 *sNextPageTable = NULL;
|
||||
static uint32_t *sLastPageTable = NULL;
|
||||
static uint32_t *sVectorTable = (uint32_t*)USER_VECTOR_ADDR_HIGH;
|
||||
|
||||
|
||||
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
|
||||
arch_mmu_generate_post_efi_page_tables(size_t memoryMapSize,
|
||||
efi_memory_descriptor *memoryMap, size_t descriptorSize,
|
||||
uint32_t descriptorVersion)
|
||||
{
|
||||
arch_mmu_allocate_page_tables();
|
||||
arch_mmu_allocate_vector_table();
|
||||
|
||||
build_physical_memory_list(memoryMapSize, memoryMap,
|
||||
descriptorSize, descriptorVersion,
|
||||
|
||||
@@ -60,8 +60,6 @@
|
||||
extern int _vectors_start;
|
||||
extern int _vectors_end;
|
||||
|
||||
static area_id sVectorPageArea;
|
||||
static void *sVectorPageAddress;
|
||||
static area_id sUserVectorPageArea;
|
||||
static void *sUserVectorPageAddress;
|
||||
//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
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
extern "C" void arm_vector_init(void);
|
||||
|
||||
|
||||
status_t
|
||||
arch_int_init_post_vm(kernel_args *args)
|
||||
{
|
||||
// create a read/write kernel area
|
||||
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!");
|
||||
TRACE("arch_int_init_post_vm\n");
|
||||
|
||||
// clone it at a fixed address with user read/only permissions
|
||||
sUserVectorPageAddress = (addr_t*)USER_VECTOR_ADDR_HIGH;
|
||||
sUserVectorPageArea = clone_area("user_vectorpage",
|
||||
sUserVectorPageArea = create_area("user_vectorpage",
|
||||
(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)
|
||||
panic("user vector page @ %p could not be created (%x)!",
|
||||
sVectorPageAddress, 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");
|
||||
}
|
||||
sUserVectorPageAddress, sUserVectorPageArea);
|
||||
|
||||
if (strncmp(args->arch_args.interrupt_controller.kind, INTC_KIND_GICV2,
|
||||
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
|
||||
PutPageTableEntryInTable(ptEntry,
|
||||
physicalAddress, attributes, 0, IS_KERNEL_ADDRESS(virtualAddress));
|
||||
physicalAddress, attributes | PAGE_ACCESSED, 0, IS_KERNEL_ADDRESS(virtualAddress));
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@@ -502,7 +502,6 @@ ARMPagingMethod32Bit::PutPageTableEntryInTable(page_table_entry* entry,
|
||||
| ARM_MMU_L2_TYPE_SMALLNEW
|
||||
| MemoryTypeToPageTableEntryFlags(memoryType)
|
||||
| AttributesToPageTableEntryFlags(attributes)
|
||||
| ARM_MMU_L2_FLAG_AP0
|
||||
| (globalPage ? 0 : ARM_MMU_L2_FLAG_NG);
|
||||
|
||||
// put it in the page table
|
||||
|
||||
@@ -169,6 +169,9 @@ ARMPagingMethod32Bit::AttributesToPageTableEntryFlags(uint32 attributes)
|
||||
apFlags |= ARM_MMU_L2_FLAG_XN;
|
||||
}
|
||||
|
||||
if ((attributes & PAGE_ACCESSED) != 0)
|
||||
apFlags |= ARM_MMU_L2_FLAG_AP0;
|
||||
|
||||
return apFlags;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user