aboutsummaryrefslogtreecommitdiffstats
path: root/mmu.c
diff options
context:
space:
mode:
authorJoshua Bakita <bakitajoshua@gmail.com>2024-04-21 17:18:10 -0400
committerJoshua Bakita <bakitajoshua@gmail.com>2024-04-21 17:18:10 -0400
commitfa1c67d86e8071fee8873aaa03ab4ece3a189b64 (patch)
tree423bfee00a5a21ac549d46315aacc6ac3ec4fb6a /mmu.c
parent613b1589a3da73cdc5e9313d65bc7c723f574531 (diff)
Match aperture when doing page table searches
Previously, addresses of any aperture would match. This can result in very confusing results when attempting to verify that a mapping correctly exists.
Diffstat (limited to 'mmu.c')
-rw-r--r--mmu.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/mmu.c b/mmu.c
index ea21f4e..eaf7d5f 100644
--- a/mmu.c
+++ b/mmu.c
@@ -70,6 +70,7 @@ uint64_t search_page_directory_subtree(struct nvdebug_state *g,
70 uintptr_t pde_addr, 70 uintptr_t pde_addr,
71 enum PD_TARGET pde_target, 71 enum PD_TARGET pde_target,
72 uint64_t addr_to_find, 72 uint64_t addr_to_find,
73 enum INST_TARGET addr_to_find_aperture,
73 uint32_t level) { 74 uint32_t level) {
74 uint64_t res, i; 75 uint64_t res, i;
75 void __iomem *pde_kern; 76 void __iomem *pde_kern;
@@ -94,13 +95,13 @@ uint64_t search_page_directory_subtree(struct nvdebug_state *g,
94 if (entry.is_pte) { 95 if (entry.is_pte) {
95 // TODO: Handle huge pages here 96 // TODO: Handle huge pages here
96 printk_debug(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); 97 printk_debug(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);
97 return (uint64_t)entry.addr << 12 == addr_to_find; 98 return (uint64_t)entry.addr << 12 == addr_to_find && entry.aperture == addr_to_find_aperture;
98 } 99 }
99 printk_debug(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); 100 printk_debug(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);
100 // Depth-first search of the page table 101 // Depth-first search of the page table
101 for (i = 0; i < NV_MMU_PT_V2_SZ[level + 1]; i++) { 102 for (i = 0; i < NV_MMU_PT_V2_SZ[level + 1]; i++) {
102 uint64_t next = ((uint64_t)entry.addr << 12) + NV_MMU_PT_V2_ENTRY_SZ[level + 1] * i; 103 uint64_t next = ((uint64_t)entry.addr << 12) + NV_MMU_PT_V2_ENTRY_SZ[level + 1] * i;
103 res = search_page_directory_subtree(g, next, entry.target, addr_to_find, level + 1); 104 res = search_page_directory_subtree(g, next, entry.target, addr_to_find, addr_to_find_aperture, level + 1);
104 if (res) 105 if (res)
105 return res | (i << NV_MMU_PT_V2_LSB[level + 1]); 106 return res | (i << NV_MMU_PT_V2_LSB[level + 1]);
106 } 107 }
@@ -119,12 +120,14 @@ uint64_t search_page_directory_subtree(struct nvdebug_state *g,
119 @param pd_config Page Directory configuration, containing pointer and 120 @param pd_config Page Directory configuration, containing pointer and
120 aperture for the start of the PDE3 entries 121 aperture for the start of the PDE3 entries
121 @param addr_to_find Physical address to reconstruct the virtual address of 122 @param addr_to_find Physical address to reconstruct the virtual address of
123 @param addr_to_find_aperture Aperture (SYS_MEM or VID_MEM) of addr_to_find
122 @return 0 on error, otherwise the virtual address at which addr_to_find is 124 @return 0 on error, otherwise the virtual address at which addr_to_find is
123 mapped into by this page table. (Zero is not a valid virtual address) 125 mapped into by this page table. (Zero is not a valid virtual address)
124*/ 126*/
125uint64_t search_page_directory(struct nvdebug_state *g, 127uint64_t search_page_directory(struct nvdebug_state *g,
126 page_dir_config_t pd_config, 128 page_dir_config_t pd_config,
127 uint64_t addr_to_find) { 129 uint64_t addr_to_find,
130 enum INST_TARGET addr_to_find_aperture) {
128 uint64_t res, i; 131 uint64_t res, i;
129 // Make sure that the query is page-aligned 132 // Make sure that the query is page-aligned
130 if (addr_to_find & 0xfff) { 133 if (addr_to_find & 0xfff) {
@@ -134,7 +137,7 @@ uint64_t search_page_directory(struct nvdebug_state *g,
134 printk(KERN_INFO "[nvdebug] Searching for addr %#018llx in page table with base %#018lx\n", addr_to_find, (uintptr_t)pd_config.page_dir << 12); 137 printk(KERN_INFO "[nvdebug] Searching for addr %#018llx in page table with base %#018lx\n", addr_to_find, (uintptr_t)pd_config.page_dir << 12);
135 // Search the top-level page directory (PDE3) 138 // Search the top-level page directory (PDE3)
136 for (i = 0; i < NV_MMU_PT_V2_SZ[0]; i++) 139 for (i = 0; i < NV_MMU_PT_V2_SZ[0]; i++)
137 if ((res = search_page_directory_subtree(g, ((uintptr_t)pd_config.page_dir << 12) + NV_MMU_PT_V2_ENTRY_SZ[0] * i, INST2PD_TARGET(pd_config.target), addr_to_find, 0))) 140 if ((res = search_page_directory_subtree(g, ((uintptr_t)pd_config.page_dir << 12) + NV_MMU_PT_V2_ENTRY_SZ[0] * i, INST2PD_TARGET(pd_config.target), addr_to_find, addr_to_find_aperture, 0)))
138 return (res & ~0xfff) | (i << NV_MMU_PT_V2_LSB[0]); 141 return (res & ~0xfff) | (i << NV_MMU_PT_V2_LSB[0]);
139 return 0; 142 return 0;
140} 143}
@@ -143,8 +146,9 @@ uint64_t search_page_directory(struct nvdebug_state *g,
143 (See `search_page_directory()` for documentation.) 146 (See `search_page_directory()` for documentation.)
144 */ 147 */
145uint64_t search_v1_page_directory(struct nvdebug_state *g, 148uint64_t search_v1_page_directory(struct nvdebug_state *g,
146 page_dir_config_t pd_config, 149 page_dir_config_t pd_config,
147 uint64_t addr_to_find) { 150 uint64_t addr_to_find,
151 enum INST_TARGET addr_to_find_aperture) {
148 uint64_t j, i = 0; 152 uint64_t j, i = 0;
149 page_dir_entry_v1_t pde; 153 page_dir_entry_v1_t pde;
150 page_tbl_entry_v1_t pte; 154 page_tbl_entry_v1_t pte;
@@ -188,7 +192,7 @@ uint64_t search_v1_page_directory(struct nvdebug_state *g,
188 continue; 192 continue;
189 printk_debug(KERN_INFO "[nvdebug] PTE for phy addr %llx %s (raw: %llx)\n", ((u64)pte.addr) << 12, pte.is_present ? "present" : "non-present", pte.raw); 193 printk_debug(KERN_INFO "[nvdebug] PTE for phy addr %llx %s (raw: %llx)\n", ((u64)pte.addr) << 12, pte.is_present ? "present" : "non-present", pte.raw);
190 // If we find a matching PTE, return its virtual address 194 // If we find a matching PTE, return its virtual address
191 if ((uint64_t)pte.addr << 12 == addr_to_find) 195 if ((uint64_t)pte.addr << 12 == addr_to_find && pte.target == addr_to_find_aperture)
192 return i << NV_MMU_PT_V1_LSB[0] | j << NV_MMU_PT_V1_LSB[1]; 196 return i << NV_MMU_PT_V1_LSB[0] | j << NV_MMU_PT_V1_LSB[1];
193 } 197 }
194 } while (++i < NV_MMU_PT_V1_SZ[0]); 198 } while (++i < NV_MMU_PT_V1_SZ[0]);