Commit 4a4ba15b2b for qemu.org
commit 4a4ba15b2b0de009c662674dd365ff56048e2b22
Author: Brian Cain <brian.cain@oss.qualcomm.com>
Date: Wed Aug 19 06:02:01 2026 -0700
hw/hexagon: decode an empty TLB size field as 4KB
hex_tlb_pgsize_type() decoded a TLB entry's page size by scanning for
the lowest set bit across the entry with ctz.
A guest TLB write with an empty PPD[9:0] size field but any other bit
set caused an assertion.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
diff --git a/hw/hexagon/hexagon_tlb.c b/hw/hexagon/hexagon_tlb.c
index 6539458f25..d89e4161f1 100644
--- a/hw/hexagon/hexagon_tlb.c
+++ b/hw/hexagon/hexagon_tlb.c
@@ -69,8 +69,6 @@ static const char *pgsize_str[NUM_PGSIZE_TYPES] = {
"1G",
};
-#define INVALID_MASK 0xffffffffLL
-
static const uint64_t encmask_2_mask[] = {
0x0fffLL, /* 4k, 0000 */
0x3fffLL, /* 16k, 0001 */
@@ -82,19 +80,25 @@ static const uint64_t encmask_2_mask[] = {
0x3ffffffLL, /* 64m, 0111 */
0xfffffffLL, /* 256m, 1000 */
0x3fffffffLL, /* 1g, 1001 */
- INVALID_MASK, /* RSVD, 1010 */
};
+/*
+ * The page size is encoded as the position of the lowest set bit of
+ * PPD[9:0]. Bits outside that field belong to the cacheability and
+ * permission fields and must not take part in the decode. An all-zero
+ * field denotes the smallest page, matching get_pgsize() in the reference
+ * simulator.
+ */
+#define PGSIZE_FIELD_MASK ((1 << NUM_PGSIZE_TYPES) - 1)
+
static inline tlb_pgsize_t hex_tlb_pgsize_type(uint64_t entry)
{
- if (entry == 0) {
- qemu_log_mask(CPU_LOG_MMU, "%s: Supplied TLB entry was 0!\n",
- __func__);
- return 0;
+ uint32_t field = GET_PTE_PPD(entry) & PGSIZE_FIELD_MASK;
+
+ if (field == 0) {
+ return PGSIZE_4K;
}
- tlb_pgsize_t size = ctz64(entry);
- g_assert(size < NUM_PGSIZE_TYPES);
- return size;
+ return ctz32(field);
}
static inline uint64_t hex_tlb_page_size_bytes(uint64_t entry)