summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo Bonzini2022-02-25 15:42:06 +0100
committerPaolo Bonzini2022-03-15 11:26:20 +0100
commit991ec97625e1281ba22bd81426a7226a76baf60a (patch)
treed30558e13ba3207b9f2b7a6886c43d89e512b4fc
parentkvm/msi: do explicit commit when adding msi routes (diff)
downloadqemu-991ec97625e1281ba22bd81426a7226a76baf60a.tar.gz
qemu-991ec97625e1281ba22bd81426a7226a76baf60a.tar.xz
qemu-991ec97625e1281ba22bd81426a7226a76baf60a.zip
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>
-rw-r--r--target/i386/tcg/sysemu/excp_helper.c34
1 files changed, 17 insertions, 17 deletions
diff --git a/target/i386/tcg/sysemu/excp_helper.c b/target/i386/tcg/sysemu/excp_helper.c
index 5627772e7c..6f1fbe667b 100644
--- a/target/i386/tcg/sysemu/excp_helper.c
+++ b/target/i386/tcg/sysemu/excp_helper.c
@@ -25,32 +25,35 @@
int get_pg_mode(CPUX86State *env)
{
int pg_mode = 0;
+ if (!(env->cr[0] & CR0_PG_MASK)) {
+ return 0;
+ }
if (env->cr[0] & CR0_WP_MASK) {
pg_mode |= PG_MODE_WP;
}
if (env->cr[4] & CR4_PAE_MASK) {
pg_mode |= PG_MODE_PAE;
+ if (env->efer & MSR_EFER_NXE) {
+ pg_mode |= PG_MODE_NXE;
+ }
}
if (env->cr[4] & CR4_PSE_MASK) {
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) {
pg_mode |= PG_MODE_SMEP;
}
- if (env->cr[4] & CR4_LA57_MASK) {
- pg_mode |= PG_MODE_LA57;
- }
if (env->hflags & HF_LMA_MASK) {
pg_mode |= PG_MODE_LMA;
- }
- if (env->efer & MSR_EFER_NXE) {
- pg_mode |= PG_MODE_NXE;
+ 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_LA57_MASK) {
+ pg_mode |= PG_MODE_LA57;
+ }
}
return pg_mode;
}
@@ -279,9 +282,7 @@ do_check_protect_pse36:
*prot |= PAGE_EXEC;
}
- if (!(pg_mode & PG_MODE_LMA)) {
- pkr = 0;
- } else if (ptep & PG_USER_MASK) {
+ if (ptep & PG_USER_MASK) {
pkr = pg_mode & PG_MODE_PKE ? env->pkru : 0;
} else {
pkr = pg_mode & PG_MODE_PKS ? env->pkrs : 0;
@@ -344,8 +345,7 @@ do_check_protect_pse36:
if (is_user)
error_code |= PG_ERROR_U_MASK;
if (is_write1 == 2 &&
- (((pg_mode & PG_MODE_NXE) && (pg_mode & PG_MODE_PAE)) ||
- (pg_mode & PG_MODE_SMEP)))
+ ((pg_mode & PG_MODE_NXE) || (pg_mode & PG_MODE_SMEP)))
error_code |= PG_ERROR_I_D_MASK;
return error_code;
}