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>
This commit is contained in:
parent
cf7ed971ae
commit
457a86a0eb
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user