aboutsummaryrefslogtreecommitdiff
path: root/target-i386
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2004-01-13 00:00:25 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2004-01-13 00:00:25 +0000
commitc8135d9af670d091359cb8b03f594c7591f199ec (patch)
treed83dc83efb835d20f23bf7de8ab527a3c17befaa /target-i386
parent9e62fd7f26d522f77f2a56bda6033c73bf286e07 (diff)
fixed subtle bug: in some cases PG_DIRTY was not set correctly
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@547 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-i386')
-rw-r--r--target-i386/helper2.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/target-i386/helper2.c b/target-i386/helper2.c
index fcceb1de56..2feccc3459 100644
--- a/target-i386/helper2.c
+++ b/target-i386/helper2.c
@@ -348,15 +348,20 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr,
page_size = 4096;
virt_addr = addr & ~0xfff;
}
+
/* the page can be put in the TLB */
prot = PROT_READ;
- if (is_user) {
- if (pte & PG_RW_MASK)
- prot |= PROT_WRITE;
- } else {
- if (!(env->cr[0] & CR0_WP_MASK) || !(pte & PG_USER_MASK) ||
- (pte & PG_RW_MASK))
- prot |= PROT_WRITE;
+ if (pte & PG_DIRTY_MASK) {
+ /* only set write access if already dirty... otherwise wait
+ for dirty access */
+ if (is_user) {
+ if (pte & PG_RW_MASK)
+ prot |= PROT_WRITE;
+ } else {
+ if (!(env->cr[0] & CR0_WP_MASK) || !(pte & PG_USER_MASK) ||
+ (pte & PG_RW_MASK))
+ prot |= PROT_WRITE;
+ }
}
do_mapping: