From a8fd5a8dee066d0008e7667b0c9e6a60cd5f3a2e Mon Sep 17 00:00:00 2001 From: Joshua Bakita Date: Thu, 11 Apr 2024 12:23:18 -0400 Subject: 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. --- runlist.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'runlist.c') diff --git a/runlist.c b/runlist.c index c725e77..2eee01c 100644 --- a/runlist.c +++ b/runlist.c @@ -9,7 +9,8 @@ // Uncomment to, upon BAR2 access failure, return a PRAMIN-based runlist pointer // **If enabled, PRAMIN may not be otherwise used while walking the runlist!** -#define FALLBACK_TO_PRAMIN +// Runlists can only be printed on the Jetson TX2 if this is enabled. +//#define FALLBACK_TO_PRAMIN /* Get runlist head and info (incl. length) @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 uint64_t runlist_iova; enum INST_TARGET runlist_target; uint16_t runlist_len; + int err; #ifdef FALLBACK_TO_PRAMIN int off; #endif // FALLBACK_TO_PRAMIN @@ -33,9 +35,9 @@ int get_runlist_iter(struct nvdebug_state *g, int rl_id, struct runlist_iter *rl return -EIO; runlist_iova = ((uint64_t)rl.ptr) << 12; runlist_target = rl.target; - printk(KERN_INFO "[nvdebug] Runlist %d: %d entries @ %llx in %s (config raw: %#018llx)\n", - rl_id, rl.len, runlist_iova, target_to_text(rl.target), rl.raw); runlist_len = rl.len; + printk(KERN_INFO "[nvdebug] Runlist %d for %x: %d entries @ %llx in %s (config raw: %#018llx)\n", + rl_id, g->chip_id, rl.len, runlist_iova, target_to_text(rl.target), rl.raw); } else if (g->chip_id < NV_CHIP_ID_AMPERE) { runlist_base_tu102_t base; runlist_submit_tu102_t submit; @@ -46,6 +48,8 @@ int get_runlist_iter(struct nvdebug_state *g, int rl_id, struct runlist_iter *rl runlist_iova = ((uint64_t)base.ptr) << 12; runlist_target = base.target; runlist_len = submit.len; + printk(KERN_INFO "[nvdebug] Runlist %d for %x: %d entries @ %llx in %s (config raw: %#018llx %#018llx)\n", + rl_id, g->chip_id, submit.len, runlist_iova, target_to_text(runlist_target), base.raw, submit.raw); } // Return early on an empty runlist if (!runlist_len) @@ -53,24 +57,25 @@ int get_runlist_iter(struct nvdebug_state *g, int rl_id, struct runlist_iter *rl // If the runlist is in VID_MEM, search the BAR2/3 page tables for a mapping if (runlist_target == TARGET_VID_MEM) { - void __iomem *bar2_page_dir; - bool pdb_is_ver2; uint64_t runlist_bar_vaddr; + page_dir_config_t pd_config; - if (get_bar2_pdb(g, &bar2_page_dir, &pdb_is_ver2) < 0) - return -EIO; + if ((err = get_bar2_pdb(g, &pd_config)) < 0) + goto attempt_pramin_access; - if (pdb_is_ver2) - runlist_bar_vaddr = search_page_directory(g, bar2_page_dir, phy2PRAMIN, runlist_iova); + if (pd_config.is_ver2) + runlist_bar_vaddr = search_page_directory(g, pd_config, runlist_iova); else - runlist_bar_vaddr = search_v1_page_directory(g, bar2_page_dir, phy2PRAMIN, runlist_iova); + runlist_bar_vaddr = search_v1_page_directory(g, pd_config, runlist_iova); if (!runlist_bar_vaddr) { - printk(KERN_WARNING "[nvdebug] Unable to find runlist mapping in BAR2/3 page tables.\n"); + printk(KERN_WARNING "[nvdebug] Unable to find runlist %d mapping in BAR2/3 page tables for %x.\n", rl_id, g->chip_id); + err = -EOPNOTSUPP; goto attempt_pramin_access; } - printk(KERN_INFO "[nvdebug] Runlist @ %llx in BAR2 virtual address space.\n", runlist_bar_vaddr); + + printk(KERN_INFO "[nvdebug] Runlist %d for %x @ %llx in BAR2 virtual address space.\n", rl_id, g->chip_id, runlist_bar_vaddr); if (!g->bar2) { - printk(KERN_WARNING "[nvdebug] BAR2/3 not mapped.\n"); + printk(KERN_WARNING "[nvdebug] BAR2/3 not mapped for %x.\n", g->chip_id); return -ENODEV; } rl_iter->curr_entry = g->bar2 + runlist_bar_vaddr; @@ -91,7 +96,7 @@ attempt_pramin_access: rl_iter->len = runlist_len; return 0; #else - return -EOPNOTSUPP; + return err; #endif // FALLBACK_TO_PRAMIN } -- cgit v1.2.2