@samitouri / QOSamiQemu / commits / 3e33da68f1

target/riscv/cpu_helper.c: fault with reserved PTE.PBMT val

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 <daniel.barboza@oss.qualcomm.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20260521130727.2311629-1-daniel.barboza@oss.qualcomm.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

Daniel Henrique Barboza committed May 21, 2026 at 10:07 UTC 3e33da68f1db7ab586063b708aa571086e7400ce
1 file changed +36
target/riscv/cpu_helper.c
+36
@@ -1446,6 +1446,25 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
1446 return TRANSLATE_FAIL;
1447 }
1448
1449 + /*
1450 + * priv spec, "Svpbmt" chapter:
1451 + * "For non-leaf PTEs, bits 62-61 are reserved for future
1452 + * standard use. Until their use is defined by a standard
1453 + * extension, they must be cleared by software for forward
1454 + * compatibility, or else a page-fault exception is raised."
1455 + *
1456 + * For leaf PTEs the same bits are also reserved but in that
1457 + * case the page-fault is mandatory. Make both cases consistent
1458 + * by also page faulting here.
1459 + */
1460 + if ((pte & PTE_PBMT) == PTE_PBMT) {
1461 + qemu_log_mask(LOG_GUEST_ERROR, "%s: PBMT bits 62 and 61 are "
1462 + "reserved but are set in PTE: "
1463 + "addr: 0x%" HWADDR_PRIx " pte: 0x" TARGET_FMT_lx "\n",
1464 + __func__, pte_addr, pte);
1465 + return TRANSLATE_FAIL;
1466 + }
1467 +
1468 if (!riscv_cpu_cfg(env)->ext_svnapot && (pte & PTE_N)) {
1469 /* Reserved without Svnapot extension */
1470 qemu_log_mask(LOG_GUEST_ERROR, "%s: N bit set in PTE, "
@@ -1498,6 +1517,23 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
1517 return TRANSLATE_FAIL;
1518 }
1519
1520 + /*
1521 + * priv spec, "Svpbmt" chapter:
1522 + * "For leaf PTEs, setting bits 62-61 to the value 3 is reserved
1523 + * for future standard use. Until this value is defined by a
1524 + * standard extension, using this reserved value in a leaf PTE
1525 + * raises a page-fault exception. "
1526 + *
1527 + * Raise a fault if 62-61 (i.e. PTE_PBMT) are set.
1528 + */
1529 + if ((pte & PTE_PBMT) == PTE_PBMT) {
1530 + qemu_log_mask(LOG_GUEST_ERROR, "%s: PBMT bits 62 and 61 are "
1531 + "reserved but are set in leaf PTE: "
1532 + "addr: 0x%" HWADDR_PRIx " pte: 0x" TARGET_FMT_lx "\n",
1533 + __func__, pte_addr, pte);
1534 + return TRANSLATE_FAIL;
1535 + }
1536 +
1537 target_ulong rwx = pte & (PTE_R | PTE_W | PTE_X);
1538 /* Check for reserved combinations of RWX flags. */
1539 switch (rwx) {