target/i386: Fix legacy page table walk
Commitb56617bbcb
("target/i386: Walk NPT in guest real mode") added logic to run the page table walker even in real mode if we are in NPT mode. That function then determined whether real mode or paging is active based on whether the pg_mode variable was 0. Unfortunately pg_mode is 0 in two situations: 1) Paging is disabled (real mode) 2) Paging is in 2-level paging mode (32bit without PAE) That means the walker now assumed that 2-level paging mode was real mode, breaking NetBSD as well as Windows XP. To fix that, this patch adds a new PG flag to pg_mode which indicates whether paging is active at all and uses that to determine whether we are in real mode or not. Cc: qemu-stable@nongnu.org Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2654 Fixes:b56617bbcb
("target/i386: Walk NPT in guest real mode") Signed-off-by: Alexander Graf <graf@amazon.com> Reported-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Link: https://lore.kernel.org/r/20241106154329.67218-1-graf@amazon.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
700784bfc6
commit
8fa11a4df3
@ -346,6 +346,7 @@ typedef enum X86Seg {
|
|||||||
#define PG_MODE_PKE (1 << 17)
|
#define PG_MODE_PKE (1 << 17)
|
||||||
#define PG_MODE_PKS (1 << 18)
|
#define PG_MODE_PKS (1 << 18)
|
||||||
#define PG_MODE_SMEP (1 << 19)
|
#define PG_MODE_SMEP (1 << 19)
|
||||||
|
#define PG_MODE_PG (1 << 20)
|
||||||
|
|
||||||
#define MCG_CTL_P (1ULL<<8) /* MCG_CAP register available */
|
#define MCG_CTL_P (1ULL<<8) /* MCG_CAP register available */
|
||||||
#define MCG_SER_P (1ULL<<24) /* MCA recovery/new status bits */
|
#define MCG_SER_P (1ULL<<24) /* MCA recovery/new status bits */
|
||||||
|
@ -94,7 +94,7 @@ static uint32_t popl(StackAccess *sa)
|
|||||||
|
|
||||||
int get_pg_mode(CPUX86State *env)
|
int get_pg_mode(CPUX86State *env)
|
||||||
{
|
{
|
||||||
int pg_mode = 0;
|
int pg_mode = PG_MODE_PG;
|
||||||
if (!(env->cr[0] & CR0_PG_MASK)) {
|
if (!(env->cr[0] & CR0_PG_MASK)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -298,7 +298,7 @@ static bool mmu_translate(CPUX86State *env, const TranslateParams *in,
|
|||||||
/* combine pde and pte nx, user and rw protections */
|
/* combine pde and pte nx, user and rw protections */
|
||||||
ptep &= pte ^ PG_NX_MASK;
|
ptep &= pte ^ PG_NX_MASK;
|
||||||
page_size = 4096;
|
page_size = 4096;
|
||||||
} else if (pg_mode) {
|
} else if (pg_mode & PG_MODE_PG) {
|
||||||
/*
|
/*
|
||||||
* Page table level 2
|
* Page table level 2
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user