diff options
author | Ralf Ramsauer <ralf.ramsauer@oth-regensburg.de> | 2022-04-23 23:59:07 +0200 |
---|---|---|
committer | Alistair Francis <alistair.francis@wdc.com> | 2022-04-29 10:47:46 +1000 |
commit | 457a86a0ebe6a5544aa4f2ee7a2af5c125b9fb1b (patch) | |
tree | 26014f0fdecb8ff07ca9cc9b3b01dffea025ff99 /target | |
parent | cf7ed971ae6f4e3683340b890a2db664a88cd896 (diff) | |
download | qemu-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.c | 11 |
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 { |