aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/riscv64/kernel/vmem.c36
-rw-r--r--common/tcb.c16
-rw-r--r--include/arch/vmem.h18
3 files changed, 56 insertions, 14 deletions
diff --git a/arch/riscv64/kernel/vmem.c b/arch/riscv64/kernel/vmem.c
index d12015c..68ccbd3 100644
--- a/arch/riscv64/kernel/vmem.c
+++ b/arch/riscv64/kernel/vmem.c
@@ -122,6 +122,38 @@ static pm_t *__find_vmem(struct vmem *b, vm_t v, enum mm_order *o)
return 0;
}
+stat_t set_vpage_flags(struct vmem *branch, vm_t vaddr, vmflags_t flags)
+{
+ enum mm_order order;
+ pm_t *pte = __find_vmem(branch, vaddr, &order);
+ if (pte) {
+ set_bits(*pte, vp_flags(flags));
+
+ if (order == __mm_max_order)
+ return INFO_SEFF;
+ else
+ return OK;
+ }
+
+ return ERR_NF;
+}
+
+stat_t clear_vpage_flags(struct vmem *branch, vm_t vaddr, vmflags_t flags)
+{
+ enum mm_order order;
+ pm_t *pte = __find_vmem(branch, vaddr, &order);
+ if (pte) {
+ clear_bits(*pte, vp_flags(flags));
+
+ if (order == __mm_max_order)
+ return INFO_SEFF;
+ else
+ return OK;
+ }
+
+ return ERR_NF;
+}
+
stat_t mod_vpage(struct vmem *branch, vm_t vaddr, pm_t paddr, vmflags_t flags)
{
enum mm_order order;
@@ -227,7 +259,7 @@ stat_t unmap_vpage(struct vmem *branch, vm_t vaddr)
void flush_tlb()
{
- __asm__ volatile ("sfence.vma %0\n" : : "r" (cpu_id()) : "memory");
+ __asm__ volatile ("sfence.vma %0\n" : : "r" (0) : "memory");
}
void flush_tlb_all()
@@ -256,7 +288,7 @@ static void __use_vmem(struct vmem *branch, enum mm_mode m)
mode = SATP_MODE_Sv48;
csr_write(CSR_SATP, mode | pn);
- flush_tlb_all();
+ flush_tlb();
/* Sv57 && Sv64 in the future? */
/** @todo ASID table for maybe faster context switches? */
}
diff --git a/common/tcb.c b/common/tcb.c
index aa66d3f..daaae4d 100644
--- a/common/tcb.c
+++ b/common/tcb.c
@@ -387,12 +387,8 @@ static void mark_rpc_inaccessible(struct tcb *t, vm_t start, vm_t end)
size_t page_size = BASE_PAGE_SIZE;
size_t size = end - start;
size_t pages = size / page_size;
- while (pages--) {
- /** @todo something like mod_vpage_flags could be faster */
- vmflags_t flags; pm_t paddr;
- stat_vpage(t->rpc.vmem, start, &paddr, NULL, &flags);
- mod_vpage(t->rpc.vmem, start, paddr, clear_bits(flags, VM_U));
- }
+ while (pages--)
+ clear_vpage_flags(t->rpc.vmem, start + pages * page_size, VM_U);
}
/**
@@ -407,12 +403,8 @@ static void mark_rpc_accessible(struct tcb *t, vm_t start, vm_t end)
size_t page_size = BASE_PAGE_SIZE;
size_t size = end - start;
size_t pages = size / page_size;
- while (pages--) {
- /** @todo something like mod_vpage_flags could be faster */
- vmflags_t flags; pm_t paddr;
- stat_vpage(t->rpc.vmem, start, &paddr, NULL, &flags);
- mod_vpage(t->rpc.vmem, start, paddr, set_bits(flags, VM_U));
- }
+ while (pages--)
+ set_vpage_flags(t->rpc.vmem, start + pages * page_size, VM_U);
}
void save_context(struct tcb *t)
diff --git a/include/arch/vmem.h b/include/arch/vmem.h
index bbaf9c4..1a2ab7e 100644
--- a/include/arch/vmem.h
+++ b/include/arch/vmem.h
@@ -48,6 +48,24 @@ stat_t map_vpage(struct vmem *branch, pm_t paddr, vm_t vaddr, vmflags_t flags,
stat_t unmap_vpage(struct vmem *branch, vm_t vaddr);
/**
+ * Set flags in page at virtual address \p vaddr.
+ *
+ * @param branch Branch in which to work.
+ * @param vaddr Virtual address of page.
+ * @param flags Flags to set.
+ */
+stat_t set_vpage_flags(struct vmem *branch, vm_t vaddr, vmflags_t flags);
+
+/**
+ * Clear flags in page at virtual address \p vaddr.
+ *
+ * @param branch Branch in which to work.
+ * @param vaddr Virtual address of page.
+ * @param flags Flags to clear.
+ */
+stat_t clear_vpage_flags(struct vmem *branch, vm_t vaddr, vmflags_t flags);
+
+/**
* Modify page mapping physical address and flags.
*
* Note that changing the order of a page is not supported, to do that unmap and