Commit f23db1692be35affcd4dc00a9c44caebb8831d4f

Authored by bellard
1 parent 3f20e1dd

dirty ram page handling fixes


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1559 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 31 additions and 18 deletions
@@ -1492,12 +1492,12 @@ static void tlb_protect_code(CPUState *env, ram_addr_t ram_addr, @@ -1492,12 +1492,12 @@ static void tlb_protect_code(CPUState *env, ram_addr_t ram_addr,
1492 tlb_protect_code1(&env->tlb_write[0][i], vaddr); 1492 tlb_protect_code1(&env->tlb_write[0][i], vaddr);
1493 tlb_protect_code1(&env->tlb_write[1][i], vaddr); 1493 tlb_protect_code1(&env->tlb_write[1][i], vaddr);
1494 1494
1495 - phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] &= ~CODE_DIRTY_FLAG;  
1496 #ifdef USE_KQEMU 1495 #ifdef USE_KQEMU
1497 if (env->kqemu_enabled) { 1496 if (env->kqemu_enabled) {
1498 kqemu_set_notdirty(env, ram_addr); 1497 kqemu_set_notdirty(env, ram_addr);
1499 } 1498 }
1500 #endif 1499 #endif
  1500 + phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] &= ~CODE_DIRTY_FLAG;
1501 1501
1502 #if !defined(CONFIG_SOFTMMU) 1502 #if !defined(CONFIG_SOFTMMU)
1503 /* NOTE: as we generated the code for this page, it is already at 1503 /* 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, @@ -1541,19 +1541,23 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
1541 length = end - start; 1541 length = end - start;
1542 if (length == 0) 1542 if (length == 0)
1543 return; 1543 return;
1544 - mask = ~dirty_flags;  
1545 - p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);  
1546 len = length >> TARGET_PAGE_BITS; 1544 len = length >> TARGET_PAGE_BITS;
1547 - for(i = 0; i < len; i++)  
1548 - p[i] &= mask;  
1549 -  
1550 env = cpu_single_env; 1545 env = cpu_single_env;
1551 #ifdef USE_KQEMU 1546 #ifdef USE_KQEMU
1552 if (env->kqemu_enabled) { 1547 if (env->kqemu_enabled) {
1553 - for(i = 0; i < len; i++)  
1554 - kqemu_set_notdirty(env, (unsigned long)i << TARGET_PAGE_BITS); 1548 + ram_addr_t addr;
  1549 + addr = start;
  1550 + for(i = 0; i < len; i++) {
  1551 + kqemu_set_notdirty(env, addr);
  1552 + addr += TARGET_PAGE_SIZE;
  1553 + }
1555 } 1554 }
1556 #endif 1555 #endif
  1556 + mask = ~dirty_flags;
  1557 + p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
  1558 + for(i = 0; i < len; i++)
  1559 + p[i] &= mask;
  1560 +
1557 /* we modify the TLB cache so that the dirty bit will be set again 1561 /* we modify the TLB cache so that the dirty bit will be set again
1558 when accessing the range */ 1562 when accessing the range */
1559 start1 = start + (unsigned long)phys_ram_base; 1563 start1 = start + (unsigned long)phys_ram_base;
@@ -1633,8 +1637,6 @@ static inline void tlb_set_dirty(unsigned long addr, target_ulong vaddr) @@ -1633,8 +1637,6 @@ static inline void tlb_set_dirty(unsigned long addr, target_ulong vaddr)
1633 CPUState *env = cpu_single_env; 1637 CPUState *env = cpu_single_env;
1634 int i; 1638 int i;
1635 1639
1636 - phys_ram_dirty[(addr - (unsigned long)phys_ram_base) >> TARGET_PAGE_BITS] = 0xff;  
1637 -  
1638 addr &= TARGET_PAGE_MASK; 1640 addr &= TARGET_PAGE_MASK;
1639 i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 1641 i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1640 tlb_set_dirty1(&env->tlb_write[0][i], addr); 1642 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 @@ -2005,8 +2007,11 @@ static void notdirty_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t
2005 #endif 2007 #endif
2006 } 2008 }
2007 stb_p((uint8_t *)(long)addr, val); 2009 stb_p((uint8_t *)(long)addr, val);
2008 - /* we set the page as dirty only if the code has been flushed */  
2009 - if (dirty_flags & CODE_DIRTY_FLAG) 2010 + dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
  2011 + phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
  2012 + /* we remove the notdirty callback only if the code has been
  2013 + flushed */
  2014 + if (dirty_flags == 0xff)
2010 tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr); 2015 tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);
2011 } 2016 }
2012 2017
@@ -2023,8 +2028,11 @@ static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t @@ -2023,8 +2028,11 @@ static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t
2023 #endif 2028 #endif
2024 } 2029 }
2025 stw_p((uint8_t *)(long)addr, val); 2030 stw_p((uint8_t *)(long)addr, val);
2026 - /* we set the page as dirty only if the code has been flushed */  
2027 - if (dirty_flags & CODE_DIRTY_FLAG) 2031 + dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
  2032 + phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
  2033 + /* we remove the notdirty callback only if the code has been
  2034 + flushed */
  2035 + if (dirty_flags == 0xff)
2028 tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr); 2036 tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);
2029 } 2037 }
2030 2038
@@ -2041,8 +2049,11 @@ static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t @@ -2041,8 +2049,11 @@ static void notdirty_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t
2041 #endif 2049 #endif
2042 } 2050 }
2043 stl_p((uint8_t *)(long)addr, val); 2051 stl_p((uint8_t *)(long)addr, val);
2044 - /* we set the page as dirty only if the code has been flushed */  
2045 - if (dirty_flags & CODE_DIRTY_FLAG) 2052 + dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
  2053 + phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
  2054 + /* we remove the notdirty callback only if the code has been
  2055 + flushed */
  2056 + if (dirty_flags == 0xff)
2046 tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr); 2057 tlb_set_dirty(addr, cpu_single_env->mem_write_vaddr);
2047 } 2058 }
2048 2059
@@ -2207,7 +2218,8 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, @@ -2207,7 +2218,8 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
2207 /* invalidate code */ 2218 /* invalidate code */
2208 tb_invalidate_phys_page_range(addr1, addr1 + l, 0); 2219 tb_invalidate_phys_page_range(addr1, addr1 + l, 0);
2209 /* set dirty bit */ 2220 /* set dirty bit */
2210 - phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 0xff; 2221 + phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
  2222 + (0xff & ~CODE_DIRTY_FLAG);
2211 } 2223 }
2212 } 2224 }
2213 } else { 2225 } else {
@@ -2327,7 +2339,8 @@ void stl_phys(target_phys_addr_t addr, uint32_t val) @@ -2327,7 +2339,8 @@ void stl_phys(target_phys_addr_t addr, uint32_t val)
2327 /* invalidate code */ 2339 /* invalidate code */
2328 tb_invalidate_phys_page_range(addr1, addr1 + 4, 0); 2340 tb_invalidate_phys_page_range(addr1, addr1 + 4, 0);
2329 /* set dirty bit */ 2341 /* set dirty bit */
2330 - phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] = 0xff; 2342 + phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |=
  2343 + (0xff & ~CODE_DIRTY_FLAG);
2331 } 2344 }
2332 } 2345 }
2333 } 2346 }