diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2004-01-13 00:00:25 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2004-01-13 00:00:25 +0000 |
commit | c8135d9af670d091359cb8b03f594c7591f199ec (patch) | |
tree | d83dc83efb835d20f23bf7de8ab527a3c17befaa /target-i386/helper2.c | |
parent | 9e62fd7f26d522f77f2a56bda6033c73bf286e07 (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/helper2.c')
-rw-r--r-- | target-i386/helper2.c | 19 |
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: |