aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;