[PATCH umr] Fix AI multiple level VM decoding

Tom St Denis tom.stdenis at amd.com
Mon Apr 17 17:28:43 UTC 2017


Obvious off by 1 also incorrect page table indecies.

Also added a lot more debugging output which is off by default.

Signed-off-by: Tom St Denis <tom.stdenis at amd.com>
---
 src/lib/read_vram.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/src/lib/read_vram.c b/src/lib/read_vram.c
index 5668f882595f..c9811eadebdf 100644
--- a/src/lib/read_vram.c
+++ b/src/lib/read_vram.c
@@ -272,7 +272,7 @@ static int umr_read_vram_ai(struct umr_asic *asic, uint32_t vmid, uint64_t addre
 	DEBUG("VIRT_ADDR = %08llx\n", (unsigned long long)address);
 	DEBUG("PAGE_START_ADDR = %08llx\n", (unsigned long long)page_table_start_addr);
 	DEBUG("BASE_ADDR = 0x%08llx\n", (unsigned long long)page_table_base_addr);
-	DEBUG("BASE_SIZE = %lu\n", page_table_size);
+	DEBUG("TABLE_SIZE = %lu\n", page_table_size);
 	DEBUG("PAGE_TABLE_DEPTH = %d\n", page_table_depth);
 
 	address -= page_table_start_addr;
@@ -285,19 +285,23 @@ static int umr_read_vram_ai(struct umr_asic *asic, uint32_t vmid, uint64_t addre
 			pte_idx = (address >> 12) & ((1ULL << (9 + page_table_size)) - 1);
 
 			// AI+ supports more than 1 level of PDEs so we iterate for all of the depths
-			pde_address = address;
+			pde_address = page_table_base_addr;
 			while (page_table_depth) {
+				DEBUG("Decoding depth %u...(0x%llx)\n", (unsigned)page_table_depth, (unsigned long long)address);
 				// decode addr into pte and pde selectors...
 				//                         ~~~ PDE selector ~~~      ~~~ PTE selector ~~~
-				pde_idx = (pde_address >> (page_table_depth*9 + (12 + 9 + page_table_size)));
+				pde_idx = (address >> ((page_table_depth-1)*9 + (12 + 9 + page_table_size)));
 
 				// don't mask the first PDE idx
 				if (!first)
 					pde_idx &= (1ULL << 9) - 1;
 				first = 0;
 
+				DEBUG("pde_idx == %llx\n", (unsigned long long)pde_idx);
+				DEBUG("selector mask == %llx\n", ((unsigned long long)511 << ((page_table_depth-1)*9 + (12 + 9 + page_table_size))));
+
 				// read PDE entry
-				umr_read_vram(asic, 0xFFFF, page_table_base_addr + pde_idx * 8, 8, &pde_entry);
+				umr_read_vram(asic, 0xFFFF, pde_address + pde_idx * 8, 8, &pde_entry);
 
 				// decode PDE values
 				pde_fields.frag_size     = (pde_entry >> 59) & 0x1F;
@@ -308,6 +312,7 @@ static int umr_read_vram_ai(struct umr_asic *asic, uint32_t vmid, uint64_t addre
 				// for the next round the address we're decoding is the phys address in the currently decoded PDE
 				--page_table_depth;
 				pde_address = pde_fields.pte_base_addr;
+				DEBUG("...done\n\n");
 			}
 
 			// now read PTE entry for this page
@@ -322,6 +327,7 @@ static int umr_read_vram_ai(struct umr_asic *asic, uint32_t vmid, uint64_t addre
 
 			// compute starting address
 			start_addr = pte_fields.page_base_addr + (address & 0xFFF);
+			DEBUG("phys address to read from: %llx\n\n\n", (unsigned long long)start_addr);
 		} else {
 			// in AI+ the BASE_ADDR is treated like a PDE entry...
 			// decode PDE values
@@ -387,6 +393,7 @@ int umr_read_vram(struct umr_asic *asic, uint32_t vmid, uint64_t address, uint32
 	}
 
 	if (vmid == 0xFFFF) {
+		DEBUG("Reading physical addr: 0x%llx\n", (unsigned long long)address);
 		// addressing is physical
 		if (asic->options.use_pci == 0) {
 			lseek(asic->fd.vram, address, SEEK_SET);
-- 
2.12.0



More information about the amd-gfx mailing list