Skip to content

Commit

Permalink
i386/monitor.c: make addresses canonical for "info mem" and "info tlb"
Browse files Browse the repository at this point in the history
Correct the output of the "info mem" and "info tlb" monitor commands to
correctly show canonical addresses.

In 48-bit addressing mode, the upper 16 bits of linear addresses are
equal to bit 47. In 57-bit addressing mode (LA57), the upper 7 bits of
linear addresses are equal to bit 56.

Signed-off-by: Doug Gale <[email protected]>
Message-Id: <[email protected]>
Signed-off-by: Paolo Bonzini <[email protected]>
  • Loading branch information
doug65536 authored and bonzini committed Jul 2, 2018
1 parent fe44105 commit 3afc969
Showing 1 changed file with 44 additions and 32 deletions.
76 changes: 44 additions & 32 deletions target/i386/monitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,28 @@
#include "sev_i386.h"
#include "qapi/qapi-commands-misc.h"


static void print_pte(Monitor *mon, CPUArchState *env, hwaddr addr,
hwaddr pte, hwaddr mask)
/* Perform linear address sign extension */
static hwaddr addr_canonical(CPUArchState *env, hwaddr addr)
{
#ifdef TARGET_X86_64
if (env->cr[4] & CR4_LA57_MASK) {
if (addr & (1ULL << 56)) {
addr |= -1LL << 57;
addr |= (hwaddr)-(1LL << 57);
}
} else {
if (addr & (1ULL << 47)) {
addr |= -1LL << 48;
addr |= (hwaddr)-(1LL << 48);
}
}
#endif
return addr;
}

static void print_pte(Monitor *mon, CPUArchState *env, hwaddr addr,
hwaddr pte, hwaddr mask)
{
addr = addr_canonical(env, addr);

monitor_printf(mon, TARGET_FMT_plx ": " TARGET_FMT_plx
" %c%c%c%c%c%c%c%c%c\n",
addr,
Expand Down Expand Up @@ -243,8 +250,8 @@ void hmp_info_tlb(Monitor *mon, const QDict *qdict)
}
}

static void mem_print(Monitor *mon, hwaddr *pstart,
int *plast_prot,
static void mem_print(Monitor *mon, CPUArchState *env,
hwaddr *pstart, int *plast_prot,
hwaddr end, int prot)
{
int prot1;
Expand All @@ -253,7 +260,9 @@ static void mem_print(Monitor *mon, hwaddr *pstart,
if (*pstart != -1) {
monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " "
TARGET_FMT_plx " %c%c%c\n",
*pstart, end, end - *pstart,
addr_canonical(env, *pstart),
addr_canonical(env, end),
addr_canonical(env, end - *pstart),
prot1 & PG_USER_MASK ? 'u' : '-',
'r',
prot1 & PG_RW_MASK ? 'w' : '-');
Expand Down Expand Up @@ -283,7 +292,7 @@ static void mem_info_32(Monitor *mon, CPUArchState *env)
if (pde & PG_PRESENT_MASK) {
if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
prot = pde & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start, &last_prot, end, prot);
} else {
for(l2 = 0; l2 < 1024; l2++) {
cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4);
Expand All @@ -295,16 +304,16 @@ static void mem_info_32(Monitor *mon, CPUArchState *env)
} else {
prot = 0;
}
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start, &last_prot, end, prot);
}
}
} else {
prot = 0;
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start, &last_prot, end, prot);
}
}
/* Flush last range */
mem_print(mon, &start, &last_prot, (hwaddr)1 << 32, 0);
mem_print(mon, env, &start, &last_prot, (hwaddr)1 << 32, 0);
}

static void mem_info_pae32(Monitor *mon, CPUArchState *env)
Expand Down Expand Up @@ -332,7 +341,7 @@ static void mem_info_pae32(Monitor *mon, CPUArchState *env)
if (pde & PG_PSE_MASK) {
prot = pde & (PG_USER_MASK | PG_RW_MASK |
PG_PRESENT_MASK);
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start, &last_prot, end, prot);
} else {
pt_addr = pde & 0x3fffffffff000ULL;
for (l3 = 0; l3 < 512; l3++) {
Expand All @@ -345,21 +354,21 @@ static void mem_info_pae32(Monitor *mon, CPUArchState *env)
} else {
prot = 0;
}
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start, &last_prot, end, prot);
}
}
} else {
prot = 0;
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start, &last_prot, end, prot);
}
}
} else {
prot = 0;
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start, &last_prot, end, prot);
}
}
/* Flush last range */
mem_print(mon, &start, &last_prot, (hwaddr)1 << 32, 0);
mem_print(mon, env, &start, &last_prot, (hwaddr)1 << 32, 0);
}


Expand Down Expand Up @@ -389,7 +398,7 @@ static void mem_info_la48(Monitor *mon, CPUArchState *env)
prot = pdpe & (PG_USER_MASK | PG_RW_MASK |
PG_PRESENT_MASK);
prot &= pml4e;
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start, &last_prot, end, prot);
} else {
pd_addr = pdpe & 0x3fffffffff000ULL;
for (l3 = 0; l3 < 512; l3++) {
Expand All @@ -401,7 +410,8 @@ static void mem_info_la48(Monitor *mon, CPUArchState *env)
prot = pde & (PG_USER_MASK | PG_RW_MASK |
PG_PRESENT_MASK);
prot &= pml4e & pdpe;
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start,
&last_prot, end, prot);
} else {
pt_addr = pde & 0x3fffffffff000ULL;
for (l4 = 0; l4 < 512; l4++) {
Expand All @@ -418,27 +428,29 @@ static void mem_info_la48(Monitor *mon, CPUArchState *env)
} else {
prot = 0;
}
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start,
&last_prot, end, prot);
}
}
} else {
prot = 0;
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start,
&last_prot, end, prot);
}
}
}
} else {
prot = 0;
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start, &last_prot, end, prot);
}
}
} else {
prot = 0;
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start, &last_prot, end, prot);
}
}
/* Flush last range */
mem_print(mon, &start, &last_prot, (hwaddr)1 << 48, 0);
mem_print(mon, env, &start, &last_prot, (hwaddr)1 << 48, 0);
}

static void mem_info_la57(Monitor *mon, CPUArchState *env)
Expand All @@ -457,7 +469,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
end = l0 << 48;
if (!(pml5e & PG_PRESENT_MASK)) {
prot = 0;
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start, &last_prot, end, prot);
continue;
}

Expand All @@ -468,7 +480,7 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
end = (l0 << 48) + (l1 << 39);
if (!(pml4e & PG_PRESENT_MASK)) {
prot = 0;
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start, &last_prot, end, prot);
continue;
}

Expand All @@ -479,15 +491,15 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
end = (l0 << 48) + (l1 << 39) + (l2 << 30);
if (pdpe & PG_PRESENT_MASK) {
prot = 0;
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start, &last_prot, end, prot);
continue;
}

if (pdpe & PG_PSE_MASK) {
prot = pdpe & (PG_USER_MASK | PG_RW_MASK |
PG_PRESENT_MASK);
prot &= pml5e & pml4e;
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start, &last_prot, end, prot);
continue;
}

Expand All @@ -498,15 +510,15 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
end = (l0 << 48) + (l1 << 39) + (l2 << 30) + (l3 << 21);
if (pde & PG_PRESENT_MASK) {
prot = 0;
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start, &last_prot, end, prot);
continue;
}

if (pde & PG_PSE_MASK) {
prot = pde & (PG_USER_MASK | PG_RW_MASK |
PG_PRESENT_MASK);
prot &= pml5e & pml4e & pdpe;
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start, &last_prot, end, prot);
continue;
}

Expand All @@ -523,14 +535,14 @@ static void mem_info_la57(Monitor *mon, CPUArchState *env)
} else {
prot = 0;
}
mem_print(mon, &start, &last_prot, end, prot);
mem_print(mon, env, &start, &last_prot, end, prot);
}
}
}
}
}
/* Flush last range */
mem_print(mon, &start, &last_prot, (hwaddr)1 << 57, 0);
mem_print(mon, env, &start, &last_prot, (hwaddr)1 << 57, 0);
}
#endif /* TARGET_X86_64 */

Expand Down

0 comments on commit 3afc969

Please sign in to comment.