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. --- bus.c | 50 +++++++++++++------------------------------------- 1 file changed, 13 insertions(+), 37 deletions(-) (limited to 'bus.c') diff --git a/bus.c b/bus.c index 802b6df..951ac77 100644 --- a/bus.c +++ b/bus.c @@ -57,35 +57,25 @@ relocate: window.base = (u32)(addr >> 16); // Safe, due to above range check window.target = target; nvdebug_writel(g, NV_PBUS_BAR0_WINDOW, window.raw); + // Wait for the window to move by re-reading (as done in nvgpu driver) + (void) nvdebug_readl(g, NV_PBUS_BAR0_WINDOW); return (int)(addr & 0xffffull); } - -/* Get a persistent pointer to the page directory base - @param pdb Dereferencable pointer to the zeroeth entry of top-level page - directory (PD3) for the BAR2 register region. - Note: The returned pointer will be into the PRAMIN space. If the PRAMIN - window is moved to a region that does not cover the BAR2 page table, - this ***will move the window***. - Note: Even if the page table is located in SYS_MEM, we route reads/writes via - PRAMIN. This ensures that we always see what the GPU sees, and that - includes any passes through I/O MMUs or IOVA spaces. +/* Get a copy of the BAR2 page directory configuration (base and aperture) + @param pd Pointer at which to store the configuration, including a pointer + and aperture for the zeroth entry of the top-level page directory + (PD3 for V2 page tables). This pointer **may not** be directly + dereferencable, and the caller may need to shift the BAR2 window. + @return 0 on success, -errno on error. + Note: This may move the PRAMIN window. */ -int get_bar2_pdb(struct nvdebug_state *g, void **pdb, bool *is_v2_pdb) { - static void* cached_pdb = NULL; - static bool cached_is_v2_pdb = false; - static long pd_hash = 0; +int get_bar2_pdb(struct nvdebug_state *g, page_dir_config_t* pd) { int ret; bar_config_block_t bar2_block; - page_dir_config_t pd_config; - uint64_t pdb_vram; - // Use cached base as long as it's still pointing to the same thing - if (cached_pdb && readl(cached_pdb) == pd_hash) { - *pdb = cached_pdb; - *is_v2_pdb = cached_is_v2_pdb; - return 0; - } + if (!pd) + return -EINVAL; if (!g->bar2) return -ENXIO; @@ -107,24 +97,10 @@ int get_bar2_pdb(struct nvdebug_state *g, void **pdb, bool *is_v2_pdb) { } printk(KERN_INFO "[nvdebug] BAR2 inst block at off %x in PRAMIN\n", ret); // Pull the page directory base configuration from the instance block - if ((pd_config.raw = nvdebug_readq(g, NV_PRAMIN + ret + NV_PRAMIN_PDB_CONFIG_OFF)) == -1) { + if ((pd->raw = nvdebug_readq(g, NV_PRAMIN + ret + NV_PRAMIN_PDB_CONFIG_OFF)) == -1) { printk(KERN_ERR "[nvdebug] Unable to read BAR2/3 PDB configuration! BAR2/3 inaccessible.\n"); return -ENOTSUPP; } - pdb_vram = pd_config.page_dir_hi; - pdb_vram <<= 20; - pdb_vram |= pd_config.page_dir_lo; - pdb_vram <<= 12; - printk(KERN_INFO "[nvdebug] BAR2 PDB @ %llx (config raw: %llx)\n", pdb_vram, pd_config.raw); - // Setup PRAMIN to point at the page directory - if ((ret = addr_to_pramin_mut(g, pdb_vram, pd_config.target)) < 0) { - printk(KERN_ERR "[nvdebug] Invalid BAR2/3 PDB configuration! BAR2/3 inaccessible.\n"); - return ret; - } - - *pdb = cached_pdb = g->regs + NV_PRAMIN + ret; - pd_hash = readl(cached_pdb); - *is_v2_pdb = cached_is_v2_pdb = pd_config.is_ver2; return 0; } -- cgit v1.2.2