aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoshua Bakita <jbakita@cs.unc.edu>2024-04-09 14:15:27 -0400
committerJoshua Bakita <jbakita@cs.unc.edu>2024-04-09 14:15:27 -0400
commit664251e57c998ac97b66e8fc1dca1cb1b38a0c1e (patch)
treed254e5c752ba50cb7ca9ff031106006558fe4cd9
parent8f9ed4c3b1f0e438107035147b5aa43fdcd66165 (diff)
Improve debugging messages for reverse page translation
-rw-r--r--mmu.c10
-rw-r--r--nvdebug.h11
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,
64 // Hack to workaround PDE0 being double-size and strangely formatted 64 // Hack to workaround PDE0 being double-size and strangely formatted
65 if (NV_MMU_PT_V2_ENTRY_SZ[level] == 16) 65 if (NV_MMU_PT_V2_ENTRY_SZ[level] == 16)
66 pde_offset += 8; 66 pde_offset += 8;
67 entry.raw = readl(pde_offset); 67 entry.raw_w = readq(pde_offset);
68 // If we reached an invalid (unpopulated) PDE, walk back up the tree 68 // If we reached an invalid (unpopulated) PDE, walk back up the tree
69 if (entry.target == PD_AND_TARGET_INVALID) 69 if (entry.target == PD_AND_TARGET_INVALID)
70 return 0; 70 return 0;
71 // Succeed when we reach a PTE with the address we want 71 // Succeed when we reach a PTE with the address we want
72 if (entry.is_pte) { 72 if (entry.is_pte) {
73 printk(KERN_INFO "[nvdebug] PTE for phy addr %llx (raw: %x)\n", ((u64)entry.addr) << 12, entry.raw); 73 // TODO: Handle huge pages here
74 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);
74 return (uint64_t)entry.addr << 12 == addr_to_find; 75 return (uint64_t)entry.addr << 12 == addr_to_find;
75 } 76 }
76 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); 77 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);
77 // Depth-first search of the page table 78 // Depth-first search of the page table
78 for (i = 0; i < NV_MMU_PT_V2_SZ[level + 1]; i++) { 79 for (i = 0; i < NV_MMU_PT_V2_SZ[level + 1]; i++) {
79 next = off2addr(g, ((uint64_t)entry.addr << 12) + NV_MMU_PT_V2_ENTRY_SZ[level + 1] * i); 80 next = off2addr(g, ((uint64_t)entry.addr << 12) + NV_MMU_PT_V2_ENTRY_SZ[level + 1] * i);
80 // off2addr can fail 81 // off2addr can fail
81 if (!next) { 82 if (!next || !entry.addr_w) {
82 printk(KERN_ERR "[nvdebug] %s: Unable to resolve GPU PA to CPU PA\n", __func__); 83 printk(KERN_ERR "[nvdebug] %s: Unable to resolve GPU PA to CPU PA\n", __func__);
83 return 0; 84 return 0;
84 } 85 }
@@ -111,6 +112,7 @@ uint64_t search_page_directory(struct nvdebug_state *g,
111 printk(KERN_WARNING "[nvdebug] Attempting to search for unaligned address %llx in search_page_directory()!\n", addr_to_find); 112 printk(KERN_WARNING "[nvdebug] Attempting to search for unaligned address %llx in search_page_directory()!\n", addr_to_find);
112 return 0; 113 return 0;
113 } 114 }
115 printk(KERN_INFO "[nvdebug] Searching for addr %#018llx in page table with base %#018llx\n", (u64)addr_to_find, (u64)pde_offset);
114 // Search the top-level page directory (PDE3) 116 // Search the top-level page directory (PDE3)
115 for (i = 0; i < NV_MMU_PT_V2_SZ[0]; i++) 117 for (i = 0; i < NV_MMU_PT_V2_SZ[0]; i++)
116 if ((res = search_page_directory_subtree(g, pde_offset + NV_MMU_PT_V2_ENTRY_SZ[0] * i, off2addr, addr_to_find, 0))) 118 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) {
935// 935//
936// V3 introduced with Hopper, but Hopper and Blackwell also support V2 936// V3 introduced with Hopper, but Hopper and Blackwell also support V2
937// 937//
938// FIXME: This structure is 32 bits, but PDE/PTEs are actually 64 bits!
939typedef union { 938typedef union {
940 // Page Directory Entry (PDE) 939 // Page Directory Entry (PDE)
941 struct { 940 struct {
@@ -943,6 +942,7 @@ typedef union {
943 bool is_volatile:1; 942 bool is_volatile:1;
944 uint32_t padding1:4; 943 uint32_t padding1:4;
945 uint32_t addr:24; 944 uint32_t addr:24;
945 uint32_t __unused1;
946 } __attribute__((packed)); 946 } __attribute__((packed));
947 // Page Table Entry (PTE) 947 // Page Table Entry (PTE)
948 struct { 948 struct {
@@ -954,8 +954,15 @@ typedef union {
954 bool is_readonly:1; 954 bool is_readonly:1;
955 bool atomics_disabled:1; 955 bool atomics_disabled:1;
956 uint32_t __addr:24; 956 uint32_t __addr:24;
957 uint32_t __unused2;
957 } __attribute__((packed)); 958 } __attribute__((packed));
958 uint32_t raw; 959 // For wide addresses in PTEs or PDEs; only used if target is SYS_MEM
960 struct {
961 uint32_t __overlap:8;
962 uint64_t addr_w:46;
963 uint32_t __unused3:10;
964 } __attribute__((packed));
965 uint64_t raw_w;
959} page_dir_entry_t; 966} page_dir_entry_t;
960 967
961// Page Directory Entry/Page Table Entry V1 type 968// Page Directory Entry/Page Table Entry V1 type