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) {