aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorRalf Ramsauer <ralf.ramsauer@oth-regensburg.de>2022-04-23 23:59:07 +0200
committerAlistair Francis <alistair.francis@wdc.com>2022-04-29 10:47:46 +1000
commit457a86a0ebe6a5544aa4f2ee7a2af5c125b9fb1b (patch)
tree26014f0fdecb8ff07ca9cc9b3b01dffea025ff99 /target
parentcf7ed971ae6f4e3683340b890a2db664a88cd896 (diff)
downloadqemu-457a86a0ebe6a5544aa4f2ee7a2af5c125b9fb1b.zip
qemu-457a86a0ebe6a5544aa4f2ee7a2af5c125b9fb1b.tar.gz
qemu-457a86a0ebe6a5544aa4f2ee7a2af5c125b9fb1b.tar.bz2
target/riscv: Fix incorrect PTE merge in walk_pte
Two non-subsequent PTEs can be mapped to subsequent paddrs. In this case, walk_pte will erroneously merge them. Enforce the split up, by tracking the virtual base address. Let's say we have the mapping: 0x81200000 -> 0x89623000 (4K) 0x8120f000 -> 0x89624000 (4K) Before, walk_pte would have shown: vaddr paddr size attr ---------------- ---------------- ---------------- ------- 0000000081200000 0000000089623000 0000000000002000 rwxu-ad as it only checks for subsequent paddrs. With this patch, it becomes: vaddr paddr size attr ---------------- ---------------- ---------------- ------- 0000000081200000 0000000089623000 0000000000001000 rwxu-ad 000000008120f000 0000000089624000 0000000000001000 rwxu-ad Signed-off-by: Ralf Ramsauer <ralf.ramsauer@oth-regensburg.de> Reviewed-by: Bin Meng <bmeng.cn@gmail.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-Id: <20220423215907.673663-1-ralf.ramsauer@oth-regensburg.de> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target')
-rw-r--r--target/riscv/monitor.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
index 7efb4b6..17e63fa 100644
--- a/target/riscv/monitor.c
+++ b/target/riscv/monitor.c
@@ -84,6 +84,7 @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
{
hwaddr pte_addr;
hwaddr paddr;
+ target_ulong last_start = -1;
target_ulong pgsize;
target_ulong pte;
int ptshift;
@@ -111,12 +112,13 @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
* A leaf PTE has been found
*
* If current PTE's permission bits differ from the last one,
- * or current PTE's ppn does not make a contiguous physical
- * address block together with the last one, print out the last
- * contiguous mapped block details.
+ * or the current PTE breaks up a contiguous virtual or
+ * physical mapping, address block together with the last one,
+ * print out the last contiguous mapped block details.
*/
if ((*last_attr != attr) ||
- (*last_paddr + *last_size != paddr)) {
+ (*last_paddr + *last_size != paddr) ||
+ (last_start + *last_size != start)) {
print_pte(mon, va_bits, *vbase, *pbase,
*last_paddr + *last_size - *pbase, *last_attr);
@@ -125,6 +127,7 @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
*last_attr = attr;
}
+ last_start = start;
*last_paddr = paddr;
*last_size = pgsize;
} else {