From 90b82dc43f04ece19e17a2b355baa02a63a47f4c Mon Sep 17 00:00:00 2001 From: xvanc Date: Wed, 13 Sep 2023 09:38:47 -0500 Subject: [PATCH] riscv/vmm: use Svpbmt extension when available --- common/mm/vmm.c | 13 +++++++++++++ common/sys/cpu_riscv.c | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/common/mm/vmm.c b/common/mm/vmm.c index b46dba2e..2d456173 100644 --- a/common/mm/vmm.c +++ b/common/mm/vmm.c @@ -246,6 +246,7 @@ level4: #define PT_FLAG_USER ((uint64_t)1 << 4) #define PT_FLAG_ACCESSED ((uint64_t)1 << 6) #define PT_FLAG_DIRTY ((uint64_t)1 << 7) +#define PT_FLAG_PBMT_NC ((uint64_t)1 << 62) #define PT_PADDR_MASK ((uint64_t)0x003ffffffffffc00) #define PT_FLAG_RWX (PT_FLAG_READ | PT_FLAG_WRITE | PT_FLAG_EXEC) @@ -265,6 +266,8 @@ static uint64_t pt_to_vmm_flags_internal(pt_entry_t entry) { flags |= VMM_FLAG_WRITE; if (!(entry & PT_FLAG_EXEC)) flags |= VMM_FLAG_NOEXEC; + if (entry & PT_FLAG_PBMT_NC) + flags |= VMM_FLAG_FB; return flags; } @@ -331,11 +334,19 @@ done: return 6 + max_level; } +static pt_entry_t pbmt_nc = 0; + pagemap_t new_pagemap(int paging_mode) { pagemap_t pagemap; pagemap.paging_mode = paging_mode; pagemap.max_page_size = paging_mode - 6; pagemap.top_level = ext_mem_alloc(PT_SIZE); + + if (riscv_check_isa_extension("svpbmt", NULL, NULL)) { + printv("riscv: Svpbmt extension is supported.\n"); + pbmt_nc = PT_FLAG_PBMT_NC; + } + return pagemap; } @@ -351,6 +362,8 @@ void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_ ptflags |= PT_FLAG_WRITE; if (!(flags & VMM_FLAG_NOEXEC)) ptflags |= PT_FLAG_EXEC; + if (flags & VMM_FLAG_FB) + ptflags |= pbmt_nc; // Start at the highest level. // The values of `enum page_size` map to the level index at which that size is mapped. diff --git a/common/sys/cpu_riscv.c b/common/sys/cpu_riscv.c index 37dcff90..41203b50 100644 --- a/common/sys/cpu_riscv.c +++ b/common/sys/cpu_riscv.c @@ -80,7 +80,7 @@ static inline struct rhct_hart_info *rhct_get_hart_info(struct rhct *rhct, uint3 return NULL; } -void riscv_init(void) { +void init_riscv(void) { struct madt *madt = acpi_get_table("APIC", 0); struct rhct *rhct = acpi_get_table("RHCT", 0); if (madt == NULL || rhct == NULL) { @@ -221,7 +221,7 @@ static bool parse_extension(const char **s, struct isa_extension *ext) { } static bool extension_matches(const struct isa_extension *ext, const char *name) { - for (size_t i = ext->name_len; i > 0; i--) { + for (size_t i = 0; i < ext->name_len; i++) { const char c1 = tolower(ext->name[i]); const char c2 = tolower(*name++); if (c2 == '\0' || c1 != c2) {