diff options
Diffstat (limited to 'mmu.c')
| -rw-r--r-- | mmu.c | 10 |
1 files changed, 6 insertions, 4 deletions
| @@ -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))) |
