diff options
author | Joshua Bakita <bakitajoshua@gmail.com> | 2024-04-11 12:23:18 -0400 |
---|---|---|
committer | Joshua Bakita <jbakita@cs.unc.edu> | 2024-04-11 13:03:20 -0400 |
commit | a8fd5a8dee066d0008e7667b0c9e6a60cd5f3a2e (patch) | |
tree | f05095d4b6458a709034a182649e6d16b6a8558a /runlist.c | |
parent | 5ea953292441e31e37ae074e48d8b3b5ce1d9440 (diff) |
Support page directories outside PRAMIN or in SYS_MEM
- Re-read PRAMIN configuration after update to verify change applies
- Return a page_dir_config_t rather than just an address and page.
table version from `get_bar2_pdb()`.
- Less verbose logging for MMU-related functions by default.
- Perform all conversion from SYS_MEM/VID_MEM addresses to kernel
addresses inside the translation functions, via the new function
'pd_deref()`.
- Support use of an I/O MMU, page tables/directories outside the
current PRAMIN window, and page tables/directories arbitrarially
located in SYS_MEM or VID_MEM on different levels of the same tree.
- Heavily improve documentation and add references for Version 1 and
Version 0 page tables.
- Improve logging in `runlist.c` to include runlist and chip IDs.
- Update all users of search_page_directory* to use the new API.
- Remove now-unused supporting functions from `mmu.c`.
Tested on GTX 970, GTX 1060 3GB, Jetson TX2, Titan V, Jetson Xavier,
and RTX 2080 Ti.
Diffstat (limited to 'runlist.c')
-rw-r--r-- | runlist.c | 33 |
1 files changed, 19 insertions, 14 deletions
@@ -9,7 +9,8 @@ | |||
9 | 9 | ||
10 | // Uncomment to, upon BAR2 access failure, return a PRAMIN-based runlist pointer | 10 | // Uncomment to, upon BAR2 access failure, return a PRAMIN-based runlist pointer |
11 | // **If enabled, PRAMIN may not be otherwise used while walking the runlist!** | 11 | // **If enabled, PRAMIN may not be otherwise used while walking the runlist!** |
12 | #define FALLBACK_TO_PRAMIN | 12 | // Runlists can only be printed on the Jetson TX2 if this is enabled. |
13 | //#define FALLBACK_TO_PRAMIN | ||
13 | 14 | ||
14 | /* Get runlist head and info (incl. length) | 15 | /* Get runlist head and info (incl. length) |
15 | @param rl_id Which runlist to obtain? | 16 | @param rl_id Which runlist to obtain? |
@@ -20,6 +21,7 @@ int get_runlist_iter(struct nvdebug_state *g, int rl_id, struct runlist_iter *rl | |||
20 | uint64_t runlist_iova; | 21 | uint64_t runlist_iova; |
21 | enum INST_TARGET runlist_target; | 22 | enum INST_TARGET runlist_target; |
22 | uint16_t runlist_len; | 23 | uint16_t runlist_len; |
24 | int err; | ||
23 | #ifdef FALLBACK_TO_PRAMIN | 25 | #ifdef FALLBACK_TO_PRAMIN |
24 | int off; | 26 | int off; |
25 | #endif // FALLBACK_TO_PRAMIN | 27 | #endif // FALLBACK_TO_PRAMIN |
@@ -33,9 +35,9 @@ int get_runlist_iter(struct nvdebug_state *g, int rl_id, struct runlist_iter *rl | |||
33 | return -EIO; | 35 | return -EIO; |
34 | runlist_iova = ((uint64_t)rl.ptr) << 12; | 36 | runlist_iova = ((uint64_t)rl.ptr) << 12; |
35 | runlist_target = rl.target; | 37 | runlist_target = rl.target; |
36 | printk(KERN_INFO "[nvdebug] Runlist %d: %d entries @ %llx in %s (config raw: %#018llx)\n", | ||
37 | rl_id, rl.len, runlist_iova, target_to_text(rl.target), rl.raw); | ||
38 | runlist_len = rl.len; | 38 | runlist_len = rl.len; |
39 | printk(KERN_INFO "[nvdebug] Runlist %d for %x: %d entries @ %llx in %s (config raw: %#018llx)\n", | ||
40 | rl_id, g->chip_id, rl.len, runlist_iova, target_to_text(rl.target), rl.raw); | ||
39 | } else if (g->chip_id < NV_CHIP_ID_AMPERE) { | 41 | } else if (g->chip_id < NV_CHIP_ID_AMPERE) { |
40 | runlist_base_tu102_t base; | 42 | runlist_base_tu102_t base; |
41 | runlist_submit_tu102_t submit; | 43 | runlist_submit_tu102_t submit; |
@@ -46,6 +48,8 @@ int get_runlist_iter(struct nvdebug_state *g, int rl_id, struct runlist_iter *rl | |||
46 | runlist_iova = ((uint64_t)base.ptr) << 12; | 48 | runlist_iova = ((uint64_t)base.ptr) << 12; |
47 | runlist_target = base.target; | 49 | runlist_target = base.target; |
48 | runlist_len = submit.len; | 50 | runlist_len = submit.len; |
51 | printk(KERN_INFO "[nvdebug] Runlist %d for %x: %d entries @ %llx in %s (config raw: %#018llx %#018llx)\n", | ||
52 | rl_id, g->chip_id, submit.len, runlist_iova, target_to_text(runlist_target), base.raw, submit.raw); | ||
49 | } | 53 | } |
50 | // Return early on an empty runlist | 54 | // Return early on an empty runlist |
51 | if (!runlist_len) | 55 | if (!runlist_len) |
@@ -53,24 +57,25 @@ int get_runlist_iter(struct nvdebug_state *g, int rl_id, struct runlist_iter *rl | |||
53 | 57 | ||
54 | // If the runlist is in VID_MEM, search the BAR2/3 page tables for a mapping | 58 | // If the runlist is in VID_MEM, search the BAR2/3 page tables for a mapping |
55 | if (runlist_target == TARGET_VID_MEM) { | 59 | if (runlist_target == TARGET_VID_MEM) { |
56 | void __iomem *bar2_page_dir; | ||
57 | bool pdb_is_ver2; | ||
58 | uint64_t runlist_bar_vaddr; | 60 | uint64_t runlist_bar_vaddr; |
61 | page_dir_config_t pd_config; | ||
59 | 62 | ||
60 | if (get_bar2_pdb(g, &bar2_page_dir, &pdb_is_ver2) < 0) | 63 | if ((err = get_bar2_pdb(g, &pd_config)) < 0) |
61 | return -EIO; | 64 | goto attempt_pramin_access; |
62 | 65 | ||
63 | if (pdb_is_ver2) | 66 | if (pd_config.is_ver2) |
64 | runlist_bar_vaddr = search_page_directory(g, bar2_page_dir, phy2PRAMIN, runlist_iova); | 67 | runlist_bar_vaddr = search_page_directory(g, pd_config, runlist_iova); |
65 | else | 68 | else |
66 | runlist_bar_vaddr = search_v1_page_directory(g, bar2_page_dir, phy2PRAMIN, runlist_iova); | 69 | runlist_bar_vaddr = search_v1_page_directory(g, pd_config, runlist_iova); |
67 | if (!runlist_bar_vaddr) { | 70 | if (!runlist_bar_vaddr) { |
68 | printk(KERN_WARNING "[nvdebug] Unable to find runlist mapping in BAR2/3 page tables.\n"); | 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; | ||
69 | goto attempt_pramin_access; | 73 | goto attempt_pramin_access; |
70 | } | 74 | } |
71 | printk(KERN_INFO "[nvdebug] Runlist @ %llx in BAR2 virtual address space.\n", runlist_bar_vaddr); | 75 | |
76 | printk(KERN_INFO "[nvdebug] Runlist %d for %x @ %llx in BAR2 virtual address space.\n", rl_id, g->chip_id, runlist_bar_vaddr); | ||
72 | if (!g->bar2) { | 77 | if (!g->bar2) { |
73 | printk(KERN_WARNING "[nvdebug] BAR2/3 not mapped.\n"); | 78 | printk(KERN_WARNING "[nvdebug] BAR2/3 not mapped for %x.\n", g->chip_id); |
74 | return -ENODEV; | 79 | return -ENODEV; |
75 | } | 80 | } |
76 | rl_iter->curr_entry = g->bar2 + runlist_bar_vaddr; | 81 | rl_iter->curr_entry = g->bar2 + runlist_bar_vaddr; |
@@ -91,7 +96,7 @@ attempt_pramin_access: | |||
91 | rl_iter->len = runlist_len; | 96 | rl_iter->len = runlist_len; |
92 | return 0; | 97 | return 0; |
93 | #else | 98 | #else |
94 | return -EOPNOTSUPP; | 99 | return err; |
95 | #endif // FALLBACK_TO_PRAMIN | 100 | #endif // FALLBACK_TO_PRAMIN |
96 | } | 101 | } |
97 | 102 | ||