From: Daniel Henrique Barboza <[email protected]> We need to fault during any access done while PTE bits 62-61 are both set, according to the RISC-V priv spec.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3494 Signed-off-by: Daniel Henrique Barboza <[email protected]> Reviewed-by: Alistair Francis <[email protected]> Message-ID: <[email protected]> Signed-off-by: Alistair Francis <[email protected]> (cherry picked from commit 3e33da68f1db7ab586063b708aa571086e7400ce) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index dc21c4ee44..8703d136a2 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -1490,6 +1490,25 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical, return TRANSLATE_FAIL; } + /* + * priv spec, "Svpbmt" chapter: + * "For non-leaf PTEs, bits 62-61 are reserved for future + * standard use. Until their use is defined by a standard + * extension, they must be cleared by software for forward + * compatibility, or else a page-fault exception is raised." + * + * For leaf PTEs the same bits are also reserved but in that + * case the page-fault is mandatory. Make both cases consistent + * by also page faulting here. + */ + if ((pte & PTE_PBMT) == PTE_PBMT) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: PBMT bits 62 and 61 are " + "reserved but are set in PTE: " + "addr: 0x%" HWADDR_PRIx " pte: 0x" TARGET_FMT_lx "\n", + __func__, pte_addr, pte); + return TRANSLATE_FAIL; + } + if (!riscv_cpu_cfg(env)->ext_svnapot && (pte & PTE_N)) { /* Reserved without Svnapot extension */ qemu_log_mask(LOG_GUEST_ERROR, "%s: N bit set in PTE, " @@ -1542,6 +1561,23 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical, return TRANSLATE_FAIL; } + /* + * priv spec, "Svpbmt" chapter: + * "For leaf PTEs, setting bits 62-61 to the value 3 is reserved + * for future standard use. Until this value is defined by a + * standard extension, using this reserved value in a leaf PTE + * raises a page-fault exception. " + * + * Raise a fault if 62-61 (i.e. PTE_PBMT) are set. + */ + if ((pte & PTE_PBMT) == PTE_PBMT) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: PBMT bits 62 and 61 are " + "reserved but are set in leaf PTE: " + "addr: 0x%" HWADDR_PRIx " pte: 0x" TARGET_FMT_lx "\n", + __func__, pte_addr, pte); + return TRANSLATE_FAIL; + } + target_ulong rwx = pte & (PTE_R | PTE_W | PTE_X); /* Check for reserved combinations of RWX flags. */ switch (rwx) { -- 2.47.3
