[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