summaryrefslogtreecommitdiffstats
path: root/target-i386/helper.c
diff options
context:
space:
mode:
authorPeter Maydell2016-04-08 11:25:22 +0200
committerPeter Maydell2016-04-08 11:25:22 +0200
commit28ee01269e910c68fb75ff780c9d84e0c34e0d66 (patch)
treec875d6ec0887fba0e4d70e2d3d3b876331a97d7f /target-i386/helper.c
parentMerge remote-tracking branch 'remotes/mdroth/tags/qga-pull-2016-04-07-tag' in... (diff)
parenttarget-i386: check for PKU even for non-writable pages (diff)
downloadqemu-28ee01269e910c68fb75ff780c9d84e0c34e0d66.tar.gz
qemu-28ee01269e910c68fb75ff780c9d84e0c34e0d66.tar.xz
qemu-28ee01269e910c68fb75ff780c9d84e0c34e0d66.zip
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* NBD fixes from Alex and Eric * Debug code bitrot from Emilio * HPET fix from Bill * ps2kbd fix from Hervé * PKU fix from myself * Coverity fixes from Gonglei * More memory.txt update from Jiangang * .gitignore maintenance from Changlong # gpg: Signature made Thu 07 Apr 2016 23:08:12 BST using RSA key ID 78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" * remotes/bonzini/tags/for-upstream: target-i386: check for PKU even for non-writable pages tests: ignore test-logging translate-all: add missing fold of tb_ctx into tcg_ctx hostmem-file: fix memory leak spapr: fix possible Negative array index read nbd: do not hang nbd_wr_syncv if outside a coroutine and no available data nbd: Don't kill server when client requests unknown option nbd: Fix NBD unsupported options qemu-nbd: Document -x option nbd: Improve debug traces on little-endian nbd: Avoid bitrot in TRACE() usage nbd: Return correct error for write to read-only export docs: fix typo in memory.txt hw/timer: Revert "hpet: inverse polarity when pin above ISA_NUM_IRQS" ps2kbd: default to scancode_set 2, as with KBD_CMD_RESET Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-i386/helper.c')
-rw-r--r--target-i386/helper.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 575583942a..bf3e76207e 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -919,29 +919,31 @@ do_check_protect_pse36:
!((env->cr[4] & CR4_SMEP_MASK) && (ptep & PG_USER_MASK)))) {
prot |= PAGE_EXEC;
}
-
- if ((prot & (1 << is_write1)) == 0) {
- goto do_fault_protect;
- }
-
if ((env->cr[4] & CR4_PKE_MASK) && (env->hflags & HF_LMA_MASK) &&
(ptep & PG_USER_MASK) && env->pkru) {
uint32_t pk = (pte & PG_PKRU_MASK) >> PG_PKRU_BIT;
uint32_t pkru_ad = (env->pkru >> pk * 2) & 1;
uint32_t pkru_wd = (env->pkru >> pk * 2) & 2;
+ uint32_t pkru_prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
if (pkru_ad) {
- prot &= ~(PAGE_READ | PAGE_WRITE);
+ pkru_prot &= ~(PAGE_READ | PAGE_WRITE);
} else if (pkru_wd && (is_user || env->cr[0] & CR0_WP_MASK)) {
- prot &= ~PAGE_WRITE;
+ pkru_prot &= ~PAGE_WRITE;
}
- if ((prot & (1 << is_write1)) == 0) {
+
+ prot &= pkru_prot;
+ if ((pkru_prot & (1 << is_write1)) == 0) {
assert(is_write1 != 2);
error_code |= PG_ERROR_PK_MASK;
goto do_fault_protect;
}
}
+ if ((prot & (1 << is_write1)) == 0) {
+ goto do_fault_protect;
+ }
+
/* yes, it can! */
is_dirty = is_write && !(pte & PG_DIRTY_MASK);
if (!(pte & PG_ACCESSED_MASK) || is_dirty) {