From patchwork Mon May 24 03:59:49 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cam Macdonell X-Patchwork-Id: 53366 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C61D1B7D49 for ; Mon, 24 May 2010 14:01:12 +1000 (EST) Received: from localhost ([127.0.0.1]:36713 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OGOqj-0004Y2-Sn for incoming@patchwork.ozlabs.org; Mon, 24 May 2010 00:01:09 -0400 Received: from [140.186.70.92] (port=47721 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OGOpp-0004Xm-Hj for qemu-devel@nongnu.org; Mon, 24 May 2010 00:00:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OGOpn-0004SA-0K for qemu-devel@nongnu.org; Mon, 24 May 2010 00:00:13 -0400 Received: from fleet.cs.ualberta.ca ([129.128.22.22]:49645) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OGOpm-0004Oh-Mm for qemu-devel@nongnu.org; Mon, 24 May 2010 00:00:10 -0400 Received: from localhost.localdomain (st-brides.cs.ualberta.ca [129.128.23.21]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp-auth.cs.ualberta.ca (Postfix) with ESMTP id 3A55528066; Sun, 23 May 2010 21:59:58 -0600 (MDT) From: Cam Macdonell To: kvm@vger.kernel.org Date: Sun, 23 May 2010 21:59:49 -0600 Message-Id: <1274673590-32288-1-git-send-email-cam@cs.ualberta.ca> X-Mailer: git-send-email 1.6.3.2.198.g6096d X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) Cc: Cam Macdonell , qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH RFC 1/2] Change phys_ram_dirty to phys_ram_status X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org The phys_ram_dirty array consists of 8-bit values for storing 3 dirty bits. Change to more generic phys_ram_flags and use lower 4-bits for dirty status and leave upper 4 for other uses of marking memory pages. One potential use for upper bits is to mark certain device pages to not be migrated. Some functions such as cpu_physical_memory_get_dirty_flags() may need to be renamed to cpu_physical_memory_get_flags(). But I wanted to solicite feedback before making more widespread changes. Cam --- cpu-all.h | 16 +++++++++------- exec.c | 36 ++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/cpu-all.h b/cpu-all.h index 52a1817..a4bb4fb 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -856,7 +856,7 @@ target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr); /* memory API */ extern int phys_ram_fd; -extern uint8_t *phys_ram_dirty; +extern uint8_t *phys_ram_flags; extern ram_addr_t ram_size; extern ram_addr_t last_ram_offset; @@ -885,32 +885,34 @@ extern int mem_prealloc; #define CODE_DIRTY_FLAG 0x02 #define MIGRATION_DIRTY_FLAG 0x08 +#define DIRTY_ALL_FLAG (VGA_DIRTY_FLAG | CODE_DIRTY_FLAG | MIGRATION_DIRTY_FLAG) + /* read dirty bit (return 0 or 1) */ static inline int cpu_physical_memory_is_dirty(ram_addr_t addr) { - return phys_ram_dirty[addr >> TARGET_PAGE_BITS] == 0xff; + return phys_ram_flags[addr >> TARGET_PAGE_BITS] == DIRTY_ALL_FLAG; } static inline int cpu_physical_memory_get_dirty_flags(ram_addr_t addr) { - return phys_ram_dirty[addr >> TARGET_PAGE_BITS]; + return phys_ram_flags[addr >> TARGET_PAGE_BITS]; } static inline int cpu_physical_memory_get_dirty(ram_addr_t addr, int dirty_flags) { - return phys_ram_dirty[addr >> TARGET_PAGE_BITS] & dirty_flags; + return phys_ram_flags[addr >> TARGET_PAGE_BITS] & dirty_flags; } static inline void cpu_physical_memory_set_dirty(ram_addr_t addr) { - phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 0xff; + phys_ram_flags[addr >> TARGET_PAGE_BITS] = DIRTY_ALL_FLAG; } static inline int cpu_physical_memory_set_dirty_flags(ram_addr_t addr, int dirty_flags) { - return phys_ram_dirty[addr >> TARGET_PAGE_BITS] |= dirty_flags; + return phys_ram_flags[addr >> TARGET_PAGE_BITS] |= dirty_flags; } static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start, @@ -922,7 +924,7 @@ static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start, len = length >> TARGET_PAGE_BITS; mask = ~dirty_flags; - p = phys_ram_dirty + (start >> TARGET_PAGE_BITS); + p = phys_ram_flags + (start >> TARGET_PAGE_BITS); for (i = 0; i < len; i++) { p[i] &= mask; } diff --git a/exec.c b/exec.c index a72d681..07dc8b6 100644 --- a/exec.c +++ b/exec.c @@ -116,7 +116,7 @@ uint8_t *code_gen_ptr; #if !defined(CONFIG_USER_ONLY) int phys_ram_fd; -uint8_t *phys_ram_dirty; +uint8_t *phys_ram_flags; static int in_migration; typedef struct RAMBlock { @@ -2796,10 +2796,10 @@ ram_addr_t qemu_ram_map(ram_addr_t size, void *host) new_block->next = ram_blocks; ram_blocks = new_block; - phys_ram_dirty = qemu_realloc(phys_ram_dirty, + phys_ram_flags = qemu_realloc(phys_ram_flags, (last_ram_offset + size) >> TARGET_PAGE_BITS); - memset(phys_ram_dirty + (last_ram_offset >> TARGET_PAGE_BITS), - 0xff, size >> TARGET_PAGE_BITS); + memset(phys_ram_flags + (last_ram_offset >> TARGET_PAGE_BITS), + DIRTY_ALL_FLAG, size >> TARGET_PAGE_BITS); last_ram_offset += size; @@ -2848,10 +2848,10 @@ ram_addr_t qemu_ram_alloc(ram_addr_t size) new_block->next = ram_blocks; ram_blocks = new_block; - phys_ram_dirty = qemu_realloc(phys_ram_dirty, + phys_ram_flags = qemu_realloc(phys_ram_flags, (last_ram_offset + size) >> TARGET_PAGE_BITS); - memset(phys_ram_dirty + (last_ram_offset >> TARGET_PAGE_BITS), - 0xff, size >> TARGET_PAGE_BITS); + memset(phys_ram_flags + (last_ram_offset >> TARGET_PAGE_BITS), + DIRTY_ALL_FLAG, size >> TARGET_PAGE_BITS); last_ram_offset += size; @@ -3019,11 +3019,11 @@ static void notdirty_mem_writeb(void *opaque, target_phys_addr_t ram_addr, #endif } stb_p(qemu_get_ram_ptr(ram_addr), val); - dirty_flags |= (0xff & ~CODE_DIRTY_FLAG); + dirty_flags |= (DIRTY_ALL_FLAG & ~CODE_DIRTY_FLAG); cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags); /* we remove the notdirty callback only if the code has been flushed */ - if (dirty_flags == 0xff) + if (dirty_flags == DIRTY_ALL_FLAG) tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr); } @@ -3039,11 +3039,11 @@ static void notdirty_mem_writew(void *opaque, target_phys_addr_t ram_addr, #endif } stw_p(qemu_get_ram_ptr(ram_addr), val); - dirty_flags |= (0xff & ~CODE_DIRTY_FLAG); + dirty_flags |= (DIRTY_ALL_FLAG & ~CODE_DIRTY_FLAG); cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags); /* we remove the notdirty callback only if the code has been flushed */ - if (dirty_flags == 0xff) + if (dirty_flags == DIRTY_ALL_FLAG) tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr); } @@ -3059,11 +3059,11 @@ static void notdirty_mem_writel(void *opaque, target_phys_addr_t ram_addr, #endif } stl_p(qemu_get_ram_ptr(ram_addr), val); - dirty_flags |= (0xff & ~CODE_DIRTY_FLAG); + dirty_flags |= (DIRTY_ALL_FLAG & ~CODE_DIRTY_FLAG); cpu_physical_memory_set_dirty_flags(ram_addr, dirty_flags); /* we remove the notdirty callback only if the code has been flushed */ - if (dirty_flags == 0xff) + if (dirty_flags == DIRTY_ALL_FLAG) tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr); } @@ -3480,7 +3480,7 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, tb_invalidate_phys_page_range(addr1, addr1 + l, 0); /* set dirty bit */ cpu_physical_memory_set_dirty_flags( - addr1, (0xff & ~CODE_DIRTY_FLAG)); + addr1, (DIRTY_ALL_FLAG & ~CODE_DIRTY_FLAG)); } /* qemu doesn't execute guest code directly, but kvm does therefore flush instruction caches */ @@ -3694,7 +3694,7 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len, tb_invalidate_phys_page_range(addr1, addr1 + l, 0); /* set dirty bit */ cpu_physical_memory_set_dirty_flags( - addr1, (0xff & ~CODE_DIRTY_FLAG)); + addr1, (DIRTY_ALL_FLAG & ~CODE_DIRTY_FLAG)); } addr1 += l; access_len -= l; @@ -3855,7 +3855,7 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val) tb_invalidate_phys_page_range(addr1, addr1 + 4, 0); /* set dirty bit */ cpu_physical_memory_set_dirty_flags( - addr1, (0xff & ~CODE_DIRTY_FLAG)); + addr1, (DIRTY_ALL_FLAG & ~CODE_DIRTY_FLAG)); } } } @@ -3924,7 +3924,7 @@ void stl_phys(target_phys_addr_t addr, uint32_t val) tb_invalidate_phys_page_range(addr1, addr1 + 4, 0); /* set dirty bit */ cpu_physical_memory_set_dirty_flags(addr1, - (0xff & ~CODE_DIRTY_FLAG)); + (DIRTY_ALL_FLAG & ~CODE_DIRTY_FLAG)); } } } @@ -3967,7 +3967,7 @@ void stw_phys(target_phys_addr_t addr, uint32_t val) tb_invalidate_phys_page_range(addr1, addr1 + 2, 0); /* set dirty bit */ cpu_physical_memory_set_dirty_flags(addr1, - (0xff & ~CODE_DIRTY_FLAG)); + (DIRTY_ALL_FLAG & ~CODE_DIRTY_FLAG)); } } }