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 pte_addr;
|
||||||
hwaddr paddr;
|
hwaddr paddr;
|
||||||
|
target_ulong last_start = -1;
|
||||||
target_ulong pgsize;
|
target_ulong pgsize;
|
||||||
target_ulong pte;
|
target_ulong pte;
|
||||||
int ptshift;
|
int ptshift;
|
||||||
@ -111,12 +112,13 @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start,
|
|||||||
* A leaf PTE has been found
|
* A leaf PTE has been found
|
||||||
*
|
*
|
||||||
* If current PTE's permission bits differ from the last one,
|
* If current PTE's permission bits differ from the last one,
|
||||||
* or current PTE's ppn does not make a contiguous physical
|
* or the current PTE breaks up a contiguous virtual or
|
||||||
* address block together with the last one, print out the last
|
* physical mapping, address block together with the last one,
|
||||||
* contiguous mapped block details.
|
* print out the last contiguous mapped block details.
|
||||||
*/
|
*/
|
||||||
if ((*last_attr != attr) ||
|
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,
|
print_pte(mon, va_bits, *vbase, *pbase,
|
||||||
*last_paddr + *last_size - *pbase, *last_attr);
|
*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_attr = attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
last_start = start;
|
||||||
*last_paddr = paddr;
|
*last_paddr = paddr;
|
||||||
*last_size = pgsize;
|
*last_size = pgsize;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user