aboutsummaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--mmu.c18
-rw-r--r--nvdebug.h10
-rw-r--r--runlist.c4
3 files changed, 19 insertions, 13 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]);
diff --git a/nvdebug.h b/nvdebug.h
index 755fada..6a2383e 100644
--- a/nvdebug.h
+++ b/nvdebug.h
@@ -1084,7 +1084,7 @@ typedef union {
1084 uint64_t addr:28; 1084 uint64_t addr:28;
1085// 32:63 1085// 32:63
1086 bool is_volatile:1; 1086 bool is_volatile:1;
1087 enum INST_TARGET:2; 1087 enum INST_TARGET target:2;
1088 bool atomics_disabled:1; 1088 bool atomics_disabled:1;
1089 uint32_t kind:8; 1089 uint32_t kind:8;
1090 uint32_t comptag:20; 1090 uint32_t comptag:20;
@@ -1266,17 +1266,19 @@ extern struct nvdebug_state g_nvdebug_state[NVDEBUG_MAX_DEVICES];
1266int get_runlist_iter(struct nvdebug_state *g, int rl_id, struct runlist_iter *rl_iter); 1266int get_runlist_iter(struct nvdebug_state *g, int rl_id, struct runlist_iter *rl_iter);
1267int preempt_tsg(struct nvdebug_state *g, uint32_t tsg_id); 1267int preempt_tsg(struct nvdebug_state *g, uint32_t tsg_id);
1268int preempt_runlist(struct nvdebug_state *g, uint32_t rl_id); 1268int preempt_runlist(struct nvdebug_state *g, uint32_t rl_id);
1269int resubmit_runlist(struct nvdebug_state *g, uint32_t rl_id);
1269 1270
1270// Defined in mmu.c 1271// Defined in mmu.c
1271void __iomem *phy2PRAMIN(struct nvdebug_state* g, uint64_t phy);
1272uint64_t search_page_directory( 1272uint64_t search_page_directory(
1273 struct nvdebug_state *g, 1273 struct nvdebug_state *g,
1274 page_dir_config_t pd_config, 1274 page_dir_config_t pd_config,
1275 uint64_t addr_to_find); 1275 uint64_t addr_to_find,
1276 enum INST_TARGET addr_to_find_aperture);
1276uint64_t search_v1_page_directory( 1277uint64_t search_v1_page_directory(
1277 struct nvdebug_state *g, 1278 struct nvdebug_state *g,
1278 page_dir_config_t pd_config, 1279 page_dir_config_t pd_config,
1279 uint64_t addr_to_find); 1280 uint64_t addr_to_find,
1281 enum INST_TARGET addr_to_find_aperture);
1280// Defined in bus.c 1282// Defined in bus.c
1281int addr_to_pramin_mut(struct nvdebug_state *g, uint64_t addr, enum INST_TARGET target); 1283int addr_to_pramin_mut(struct nvdebug_state *g, uint64_t addr, enum INST_TARGET target);
1282int get_bar2_pdb(struct nvdebug_state *g, page_dir_config_t* pd); 1284int get_bar2_pdb(struct nvdebug_state *g, page_dir_config_t* pd);
diff --git a/runlist.c b/runlist.c
index 2eee01c..22f47ff 100644
--- a/runlist.c
+++ b/runlist.c
@@ -64,9 +64,9 @@ int get_runlist_iter(struct nvdebug_state *g, int rl_id, struct runlist_iter *rl
64 goto attempt_pramin_access; 64 goto attempt_pramin_access;
65 65
66 if (pd_config.is_ver2) 66 if (pd_config.is_ver2)
67 runlist_bar_vaddr = search_page_directory(g, pd_config, runlist_iova); 67 runlist_bar_vaddr = search_page_directory(g, pd_config, runlist_iova, TARGET_VID_MEM);
68 else 68 else
69 runlist_bar_vaddr = search_v1_page_directory(g, pd_config, runlist_iova); 69 runlist_bar_vaddr = search_v1_page_directory(g, pd_config, runlist_iova, TARGET_VID_MEM);
70 if (!runlist_bar_vaddr) { 70 if (!runlist_bar_vaddr) {
71 printk(KERN_WARNING "[nvdebug] Unable to find runlist %d mapping in BAR2/3 page tables for %x.\n", rl_id, g->chip_id); 71 printk(KERN_WARNING "[nvdebug] Unable to find runlist %d mapping in BAR2/3 page tables for %x.\n", rl_id, g->chip_id);
72 err = -EOPNOTSUPP; 72 err = -EOPNOTSUPP;