[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v4 11/26] RISC-V: Improve page table walker spec com
From: |
Michael Clark |
Subject: |
[Qemu-devel] [PATCH v4 11/26] RISC-V: Improve page table walker spec compliance |
Date: |
Mon, 19 Mar 2018 14:18:34 -0700 |
- Inline PTE_TABLE check for better readability
- Improve readibility of User page U mode and SUM test
- Disallow non U mode from fetching from User pages
- Add reserved PTE flag check: W or W|X
- Add misaligned PPN check
- Set READ flag for PTE X flag if mstatus.mxr is in effect
- Change access checks from ternary operator to if statements
- Improves page walker comments
- No measurable performance impact on dd test
Cc: Sagar Karandikar <address@hidden>
Cc: Bastian Koppelmann <address@hidden>
Signed-off-by: Michael Clark <address@hidden>
Signed-off-by: Palmer Dabbelt <address@hidden>
---
target/riscv/cpu_bits.h | 2 --
target/riscv/helper.c | 59 ++++++++++++++++++++++++++++++++++---------------
2 files changed, 41 insertions(+), 20 deletions(-)
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 64aa097..12b4757 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -407,5 +407,3 @@
#define PTE_SOFT 0x300 /* Reserved for Software */
#define PTE_PPN_SHIFT 10
-
-#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
diff --git a/target/riscv/helper.c b/target/riscv/helper.c
index d148bed..c68826b 100644
--- a/target/riscv/helper.c
+++ b/target/riscv/helper.c
@@ -185,16 +185,36 @@ restart:
#endif
target_ulong ppn = pte >> PTE_PPN_SHIFT;
- if (PTE_TABLE(pte)) { /* next level of page table */
+ if (!(pte & PTE_V)) {
+ /* Invalid PTE */
+ return TRANSLATE_FAIL;
+ } else if (!(pte & (PTE_R | PTE_W | PTE_X))) {
+ /* Inner PTE, continue walking */
base = ppn << PGSHIFT;
- } else if ((pte & PTE_U) ? (mode == PRV_S) && !sum : !(mode == PRV_S))
{
- break;
- } else if (!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) {
- break;
- } else if (access_type == MMU_INST_FETCH ? !(pte & PTE_X) :
- access_type == MMU_DATA_LOAD ? !(pte & PTE_R) &&
- !(mxr && (pte & PTE_X)) : !((pte & PTE_R) && (pte & PTE_W)))
{
- break;
+ } else if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
+ /* Reserved leaf PTE flags: PTE_W */
+ return TRANSLATE_FAIL;
+ } else if ((pte & (PTE_R | PTE_W | PTE_X)) == (PTE_W | PTE_X)) {
+ /* Reserved leaf PTE flags: PTE_W + PTE_X */
+ return TRANSLATE_FAIL;
+ } else if ((pte & PTE_U) && ((mode != PRV_U) &&
+ (!sum || access_type == MMU_INST_FETCH))) {
+ /* User PTE flags when not U mode and mstatus.SUM is not set,
+ or the access type is an instruction fetch */
+ return TRANSLATE_FAIL;
+ } else if (ppn & ((1ULL << ptshift) - 1)) {
+ /* Misasligned PPN */
+ return TRANSLATE_FAIL;
+ } else if (access_type == MMU_DATA_LOAD && !((pte & PTE_R) ||
+ ((pte & PTE_X) && mxr))) {
+ /* Read access check failed */
+ return TRANSLATE_FAIL;
+ } else if (access_type == MMU_DATA_STORE && !(pte & PTE_W)) {
+ /* Write access check failed */
+ return TRANSLATE_FAIL;
+ } else if (access_type == MMU_INST_FETCH && !(pte & PTE_X)) {
+ /* Fetch access check failed */
+ return TRANSLATE_FAIL;
} else {
/* if necessary, set accessed and dirty bits. */
target_ulong updated_pte = pte | PTE_A |
@@ -202,11 +222,14 @@ restart:
/* Page table updates need to be atomic with MTTCG enabled */
if (updated_pte != pte) {
- /* if accessed or dirty bits need updating, and the PTE is
- * in RAM, then we do so atomically with a compare and swap.
- * if the PTE is in IO space, then it can't be updated.
- * if the PTE changed, then we must re-walk the page table
- as the PTE is no longer valid */
+ /*
+ * - if accessed or dirty bits need updating, and the PTE is
+ * in RAM, then we do so atomically with a compare and swap.
+ * - if the PTE is in IO space or ROM, then it can't be updated
+ * and we return TRANSLATE_FAIL.
+ * - if the PTE changed by the time we went to update it, then
+ * it is no longer valid and we must re-walk the page table.
+ */
MemoryRegion *mr;
hwaddr l = sizeof(target_ulong), addr1;
enum { success, translate_fail, restart_walk} action = success;
@@ -252,15 +275,15 @@ restart:
target_ulong vpn = addr >> PGSHIFT;
*physical = (ppn | (vpn & ((1L << ptshift) - 1))) << PGSHIFT;
- if ((pte & PTE_R)) {
+ /* set permissions on the TLB entry */
+ if ((pte & PTE_R) || (mode != PRV_U && (pte & PTE_X) && mxr)) {
*prot |= PAGE_READ;
}
if ((pte & PTE_X)) {
*prot |= PAGE_EXEC;
}
- /* only add write permission on stores or if the page
- is already dirty, so that we don't miss further
- page table walks to update the dirty bit */
+ /* add write permission on stores or if the page is already dirty,
+ so that we TLB miss on later writes to update the dirty bit */
if ((pte & PTE_W) &&
(access_type == MMU_DATA_STORE || (pte & PTE_D))) {
*prot |= PAGE_WRITE;
--
2.7.0
- [Qemu-devel] [PATCH v4 06/26] RISC-V: Mark ROM read-only after copying in code, (continued)
- [Qemu-devel] [PATCH v4 06/26] RISC-V: Mark ROM read-only after copying in code, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 08/26] RISC-V: Make sure rom has space for fdt, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 02/26] RISC-V: Replace hardcoded constants with enum values, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 03/26] RISC-V: Make virt board description match spike, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 10/26] RISC-V: Hold rcu_read_lock when accessing memory, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 09/26] RISC-V: Include intruction hex in disassembly, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 07/26] RISC-V: Remove unused class definitions, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 12/26] RISC-V: Update E order and I extension order, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 13/26] RISC-V: Make some header guards more specific, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 16/26] RISC-V: Remove EM_RISCV ELF_MACHINE indirection, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 11/26] RISC-V: Improve page table walker spec compliance,
Michael Clark <=
- [Qemu-devel] [PATCH v4 17/26] RISC-V: Hardwire satp to 0 for no-mmu case, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 14/26] RISC-V: Make virt header comment title consistent, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 24/26] RISC-V: Clear mtval/stval on exceptions without info, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 21/26] RISC-V: No traps on writes to misa, minstret, mcycle, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 20/26] RISC-V: vectored traps are optional, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 15/26] RISC-V: Use memory_region_is_ram in pte update, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 22/26] RISC-V: Remove support for adhoc X_COP interrupt, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 23/26] RISC-V: Convert cpu definition towards future model, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 25/26] RISC-V: Remove erroneous comment from translate.c, Michael Clark, 2018/03/19
- [Qemu-devel] [PATCH v4 19/26] RISC-V: riscv-qemu port supports sv39 and sv48, Michael Clark, 2018/03/19