]> git.proxmox.com Git - qemu.git/commitdiff
dirty ram page handling fixes
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 21 Aug 2005 19:12:28 +0000 (19:12 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sun, 21 Aug 2005 19:12:28 +0000 (19:12 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1559 c046a42c-6fe2-441c-8c8c-71466251a162

exec.c

diff --git a/exec.c b/exec.c
index c75c23eb05745e1ef4c0380a70880afda225a3cd..3466c9df7b6708005728eb122d387d39a80de78c 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -1492,12 +1492,12 @@ static void tlb_protect_code(CPUState *env, ram_addr_t ram_addr,
     tlb_protect_code1(&env->tlb_write[0][i], vaddr);
     tlb_protect_code1(&env->tlb_write[1][i], vaddr);
 
-    phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] &= ~CODE_DIRTY_FLAG;
 #ifdef USE_KQEMU
     if (env->kqemu_enabled) {
         kqemu_set_notdirty(env, ram_addr);
     }
 #endif
+    phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] &= ~CODE_DIRTY_FLAG;
     
 #if !defined(CONFIG_SOFTMMU)
     /* NOTE: as we generated the code for this page, it is already at
@@ -1541,19 +1541,23 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
     length = end - start;
     if (length == 0)
         return;
-    mask = ~dirty_flags;
-    p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
     len = length >> TARGET_PAGE_BITS;
-    for(i = 0; i < len; i++)
-        p[i] &= mask;
-
     env = cpu_single_env;
 #ifdef USE_KQEMU
     if (env->kqemu_enabled) {
-        for(i = 0; i < len; i++)
-            kqemu_set_notdirty(env, (unsigned long)i << TARGET_PAGE_BITS);
+        ram_addr_t addr;
+        addr = start;
+        for(i = 0; i < len; i++) {
+            kqemu_set_notdirty(env, addr);
+            addr += TARGET_PAGE_SIZE;
+        }
     }
 #endif
+    mask = ~dirty_flags;
+    p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
+    for(i = 0; i < len; i++)
+        p[i] &= mask;
+
     /* we modify the TLB cache so that the dirty bit will be set again
        when accessing the range */
     start1 = start + (unsigned long)phys_ram_base;
@@ -1633,8 +1637,6 @@ static inline void tlb_set_dirty(unsigned long addr, target_ulong vaddr)
     CPUState *env = cpu_single_env;
     int i;
 
-    phys_ram_dirty[(addr - (unsigned long)phys_ram_base) >> TARGET_PAGE_BITS] = 0xff;
-
     addr &= TARGET_PAGE_MASK;
     i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
     tlb_set_dirty1(&env->tlb_write[0][i], addr);
@@ -2005,8 +2007,11 @@ static void notdirty_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t
 #endif
     }
     stb_p((uint8_t *)(long)addr, val);
-    /* we set the page as dirty only if the code has been flushed */
-    if (dirty_flags & CODE_DIRTY_FLAG)
+    dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
+    phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
+    /* we remove the notdirty callback only if the code has been
+       flushed */
+    if (dirty_flags == 0xff)
         tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);
 }
 
@@ -2023,8 +2028,11 @@ static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t
 #endif
     }
     stw_p((uint8_t *)(long)addr, val);
-    /* we set the page as dirty only if the code has been flushed */
-    if (dirty_flags & CODE_DIRTY_FLAG)
+    dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
+    phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
+    /* we remove the notdirty callback only if the code has been
+       flushed */
+    if (dirty_flags == 0xff)
         tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);
 }
 
@@ -2041,8 +2049,11 @@ static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t
 #endif
     }
     stl_p((uint8_t *)(long)addr, val);
-    /* we set the page as dirty only if the code has been flushed */
-    if (dirty_flags & CODE_DIRTY_FLAG)
+    dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
+    phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
+    /* we remove the notdirty callback only if the code has been
+       flushed */
+    if (dirty_flags == 0xff)
         tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);
 }
 
@@ -2207,7 +2218,8 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
                     /* invalidate code */
                     tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
                     /* set dirty bit */
-                    phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 0xff;
+                    phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |= 
+                        (0xff & ~CODE_DIRTY_FLAG);
                 }
             }
         } else {
@@ -2327,7 +2339,8 @@ void stl_phys(target_phys_addr_t addr, uint32_t val)
             /* invalidate code */
             tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
             /* set dirty bit */
-            phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 0xff;
+            phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
+                (0xff & ~CODE_DIRTY_FLAG);
         }
     }
 }