From fa1c67d86e8071fee8873aaa03ab4ece3a189b64 Mon Sep 17 00:00:00 2001 From: Joshua Bakita Date: Sun, 21 Apr 2024 17:18:10 -0400 Subject: 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. --- mmu.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'mmu.c') 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, uintptr_t pde_addr, enum PD_TARGET pde_target, uint64_t addr_to_find, + enum INST_TARGET addr_to_find_aperture, uint32_t level) { uint64_t res, i; void __iomem *pde_kern; @@ -94,13 +95,13 @@ uint64_t search_page_directory_subtree(struct nvdebug_state *g, if (entry.is_pte) { // TODO: Handle huge pages here 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); - return (uint64_t)entry.addr << 12 == addr_to_find; + return (uint64_t)entry.addr << 12 == addr_to_find && entry.aperture == addr_to_find_aperture; } 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); // Depth-first search of the page table for (i = 0; i < NV_MMU_PT_V2_SZ[level + 1]; i++) { uint64_t next = ((uint64_t)entry.addr << 12) + NV_MMU_PT_V2_ENTRY_SZ[level + 1] * i; - res = search_page_directory_subtree(g, next, entry.target, addr_to_find, level + 1); + res = search_page_directory_subtree(g, next, entry.target, addr_to_find, addr_to_find_aperture, level + 1); if (res) return res | (i << NV_MMU_PT_V2_LSB[level + 1]); } @@ -119,12 +120,14 @@ uint64_t search_page_directory_subtree(struct nvdebug_state *g, @param pd_config Page Directory configuration, containing pointer and aperture for the start of the PDE3 entries @param addr_to_find Physical address to reconstruct the virtual address of + @param addr_to_find_aperture Aperture (SYS_MEM or VID_MEM) of addr_to_find @return 0 on error, otherwise the virtual address at which addr_to_find is mapped into by this page table. (Zero is not a valid virtual address) */ uint64_t search_page_directory(struct nvdebug_state *g, page_dir_config_t pd_config, - uint64_t addr_to_find) { + uint64_t addr_to_find, + enum INST_TARGET addr_to_find_aperture) { uint64_t res, i; // Make sure that the query is page-aligned if (addr_to_find & 0xfff) { @@ -134,7 +137,7 @@ uint64_t search_page_directory(struct nvdebug_state *g, 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); // Search the top-level page directory (PDE3) for (i = 0; i < NV_MMU_PT_V2_SZ[0]; i++) - 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))) + 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))) return (res & ~0xfff) | (i << NV_MMU_PT_V2_LSB[0]); return 0; } @@ -143,8 +146,9 @@ uint64_t search_page_directory(struct nvdebug_state *g, (See `search_page_directory()` for documentation.) */ uint64_t search_v1_page_directory(struct nvdebug_state *g, - page_dir_config_t pd_config, - uint64_t addr_to_find) { + page_dir_config_t pd_config, + uint64_t addr_to_find, + enum INST_TARGET addr_to_find_aperture) { uint64_t j, i = 0; page_dir_entry_v1_t pde; page_tbl_entry_v1_t pte; @@ -188,7 +192,7 @@ uint64_t search_v1_page_directory(struct nvdebug_state *g, continue; 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); // If we find a matching PTE, return its virtual address - if ((uint64_t)pte.addr << 12 == addr_to_find) + if ((uint64_t)pte.addr << 12 == addr_to_find && pte.target == addr_to_find_aperture) return i << NV_MMU_PT_V1_LSB[0] | j << NV_MMU_PT_V1_LSB[1]; } } while (++i < NV_MMU_PT_V1_SZ[0]); -- cgit v1.2.2