From 664251e57c998ac97b66e8fc1dca1cb1b38a0c1e Mon Sep 17 00:00:00 2001 From: Joshua Bakita Date: Tue, 9 Apr 2024 14:15:27 -0400 Subject: Improve debugging messages for reverse page translation --- mmu.c | 10 ++++++---- nvdebug.h | 11 +++++++++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/mmu.c b/mmu.c index 23adaf2..30e9362 100644 --- a/mmu.c +++ b/mmu.c @@ -64,21 +64,22 @@ uint64_t search_page_directory_subtree(struct nvdebug_state *g, // Hack to workaround PDE0 being double-size and strangely formatted if (NV_MMU_PT_V2_ENTRY_SZ[level] == 16) pde_offset += 8; - entry.raw = readl(pde_offset); + entry.raw_w = readq(pde_offset); // If we reached an invalid (unpopulated) PDE, walk back up the tree if (entry.target == PD_AND_TARGET_INVALID) return 0; // Succeed when we reach a PTE with the address we want if (entry.is_pte) { - printk(KERN_INFO "[nvdebug] PTE for phy addr %llx (raw: %x)\n", ((u64)entry.addr) << 12, entry.raw); + // TODO: Handle huge pages here + printk(KERN_INFO "[nvdebug] PTE for phy addr %#018llx, ap '%s', vol '%d', priv '%d', ro '%d', no_atomics '%d' (raw: %#018llx)\n", ((u64)entry.addr_w) << 12, pd_target_to_text(entry.target), entry.is_volatile, entry.is_privileged, entry.is_readonly, entry.atomics_disabled, entry.raw_w); return (uint64_t)entry.addr << 12 == addr_to_find; } - printk(KERN_INFO "[nvdebug] Found PDE pointing to %llx in ap '%d' at lvl %d (raw: %x)\n", ((u64)entry.addr) << 12, entry.target, level, entry.raw); + printk(KERN_INFO "[nvdebug] Found PDE pointing to %#018llx in ap '%s' vol '%d' at lvl %d (raw: %#018llx)\n", ((u64)entry.addr_w) << 12, pd_target_to_text(entry.target), entry.is_volatile, level, entry.raw_w); // Depth-first search of the page table for (i = 0; i < NV_MMU_PT_V2_SZ[level + 1]; i++) { next = off2addr(g, ((uint64_t)entry.addr << 12) + NV_MMU_PT_V2_ENTRY_SZ[level + 1] * i); // off2addr can fail - if (!next) { + if (!next || !entry.addr_w) { printk(KERN_ERR "[nvdebug] %s: Unable to resolve GPU PA to CPU PA\n", __func__); return 0; } @@ -111,6 +112,7 @@ uint64_t search_page_directory(struct nvdebug_state *g, printk(KERN_WARNING "[nvdebug] Attempting to search for unaligned address %llx in search_page_directory()!\n", addr_to_find); return 0; } + printk(KERN_INFO "[nvdebug] Searching for addr %#018llx in page table with base %#018llx\n", (u64)addr_to_find, (u64)pde_offset); // Search the top-level page directory (PDE3) for (i = 0; i < NV_MMU_PT_V2_SZ[0]; i++) if ((res = search_page_directory_subtree(g, pde_offset + NV_MMU_PT_V2_ENTRY_SZ[0] * i, off2addr, addr_to_find, 0))) diff --git a/nvdebug.h b/nvdebug.h index fcc6cff..67f2111 100644 --- a/nvdebug.h +++ b/nvdebug.h @@ -935,7 +935,6 @@ static inline const char *pd_target_to_text(enum PD_TARGET t) { // // V3 introduced with Hopper, but Hopper and Blackwell also support V2 // -// FIXME: This structure is 32 bits, but PDE/PTEs are actually 64 bits! typedef union { // Page Directory Entry (PDE) struct { @@ -943,6 +942,7 @@ typedef union { bool is_volatile:1; uint32_t padding1:4; uint32_t addr:24; + uint32_t __unused1; } __attribute__((packed)); // Page Table Entry (PTE) struct { @@ -954,8 +954,15 @@ typedef union { bool is_readonly:1; bool atomics_disabled:1; uint32_t __addr:24; + uint32_t __unused2; } __attribute__((packed)); - uint32_t raw; + // For wide addresses in PTEs or PDEs; only used if target is SYS_MEM + struct { + uint32_t __overlap:8; + uint64_t addr_w:46; + uint32_t __unused3:10; + } __attribute__((packed)); + uint64_t raw_w; } page_dir_entry_t; // Page Directory Entry/Page Table Entry V1 type -- cgit v1.2.2