mirror of
https://github.com/xemu-project/xemu.git
synced 2025-02-25 07:02:38 +00:00
target/i386: only include bits in pg_mode if they are not ignored
LA57/PKE/PKS is only relevant in 64-bit mode, and NXE is only relevant if PAE is in use. Since there is code that checks PG_MODE_LA57 to determine the canonicality of addresses, make sure that the bit is not set by mistake in 32-bit mode. While it would not be a problem because 32-bit addresses by definition fit in both 48-bit and 57-bit address spaces, it is nicer if get_pg_mode() actually returns whether a feature is enabled, and it allows a few simplifications in the page table walker. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
def4c5570c
commit
991ec97625
@ -25,32 +25,35 @@
|
|||||||
int get_pg_mode(CPUX86State *env)
|
int get_pg_mode(CPUX86State *env)
|
||||||
{
|
{
|
||||||
int pg_mode = 0;
|
int pg_mode = 0;
|
||||||
|
if (!(env->cr[0] & CR0_PG_MASK)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (env->cr[0] & CR0_WP_MASK) {
|
if (env->cr[0] & CR0_WP_MASK) {
|
||||||
pg_mode |= PG_MODE_WP;
|
pg_mode |= PG_MODE_WP;
|
||||||
}
|
}
|
||||||
if (env->cr[4] & CR4_PAE_MASK) {
|
if (env->cr[4] & CR4_PAE_MASK) {
|
||||||
pg_mode |= PG_MODE_PAE;
|
pg_mode |= PG_MODE_PAE;
|
||||||
|
if (env->efer & MSR_EFER_NXE) {
|
||||||
|
pg_mode |= PG_MODE_NXE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (env->cr[4] & CR4_PSE_MASK) {
|
if (env->cr[4] & CR4_PSE_MASK) {
|
||||||
pg_mode |= PG_MODE_PSE;
|
pg_mode |= PG_MODE_PSE;
|
||||||
}
|
}
|
||||||
if (env->cr[4] & CR4_PKE_MASK) {
|
|
||||||
pg_mode |= PG_MODE_PKE;
|
|
||||||
}
|
|
||||||
if (env->cr[4] & CR4_PKS_MASK) {
|
|
||||||
pg_mode |= PG_MODE_PKS;
|
|
||||||
}
|
|
||||||
if (env->cr[4] & CR4_SMEP_MASK) {
|
if (env->cr[4] & CR4_SMEP_MASK) {
|
||||||
pg_mode |= PG_MODE_SMEP;
|
pg_mode |= PG_MODE_SMEP;
|
||||||
}
|
}
|
||||||
if (env->cr[4] & CR4_LA57_MASK) {
|
|
||||||
pg_mode |= PG_MODE_LA57;
|
|
||||||
}
|
|
||||||
if (env->hflags & HF_LMA_MASK) {
|
if (env->hflags & HF_LMA_MASK) {
|
||||||
pg_mode |= PG_MODE_LMA;
|
pg_mode |= PG_MODE_LMA;
|
||||||
}
|
if (env->cr[4] & CR4_PKE_MASK) {
|
||||||
if (env->efer & MSR_EFER_NXE) {
|
pg_mode |= PG_MODE_PKE;
|
||||||
pg_mode |= PG_MODE_NXE;
|
}
|
||||||
|
if (env->cr[4] & CR4_PKS_MASK) {
|
||||||
|
pg_mode |= PG_MODE_PKS;
|
||||||
|
}
|
||||||
|
if (env->cr[4] & CR4_LA57_MASK) {
|
||||||
|
pg_mode |= PG_MODE_LA57;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return pg_mode;
|
return pg_mode;
|
||||||
}
|
}
|
||||||
@ -279,9 +282,7 @@ do_check_protect_pse36:
|
|||||||
*prot |= PAGE_EXEC;
|
*prot |= PAGE_EXEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(pg_mode & PG_MODE_LMA)) {
|
if (ptep & PG_USER_MASK) {
|
||||||
pkr = 0;
|
|
||||||
} else if (ptep & PG_USER_MASK) {
|
|
||||||
pkr = pg_mode & PG_MODE_PKE ? env->pkru : 0;
|
pkr = pg_mode & PG_MODE_PKE ? env->pkru : 0;
|
||||||
} else {
|
} else {
|
||||||
pkr = pg_mode & PG_MODE_PKS ? env->pkrs : 0;
|
pkr = pg_mode & PG_MODE_PKS ? env->pkrs : 0;
|
||||||
@ -344,8 +345,7 @@ do_check_protect_pse36:
|
|||||||
if (is_user)
|
if (is_user)
|
||||||
error_code |= PG_ERROR_U_MASK;
|
error_code |= PG_ERROR_U_MASK;
|
||||||
if (is_write1 == 2 &&
|
if (is_write1 == 2 &&
|
||||||
(((pg_mode & PG_MODE_NXE) && (pg_mode & PG_MODE_PAE)) ||
|
((pg_mode & PG_MODE_NXE) || (pg_mode & PG_MODE_SMEP)))
|
||||||
(pg_mode & PG_MODE_SMEP)))
|
|
||||||
error_code |= PG_ERROR_I_D_MASK;
|
error_code |= PG_ERROR_I_D_MASK;
|
||||||
return error_code;
|
return error_code;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user