From patchwork Mon Feb 8 10:22:18 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: OHMURA Kei X-Patchwork-Id: 77700 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o18ANibX020136 for ; Mon, 8 Feb 2010 10:23:45 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754414Ab0BHKXn (ORCPT ); Mon, 8 Feb 2010 05:23:43 -0500 Received: from tama500.ecl.ntt.co.jp ([129.60.39.148]:41694 "EHLO tama500.ecl.ntt.co.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753675Ab0BHKXk (ORCPT ); Mon, 8 Feb 2010 05:23:40 -0500 Received: from mfs6.rdh.ecl.ntt.co.jp (mfs6.rdh.ecl.ntt.co.jp [129.60.39.149]) by tama500.ecl.ntt.co.jp (8.14.3/8.14.3) with ESMTP id o18ANDaq026960; Mon, 8 Feb 2010 19:23:13 +0900 (JST) Received: from mfs6.rdh.ecl.ntt.co.jp (localhost [127.0.0.1]) by mfs6.rdh.ecl.ntt.co.jp (Postfix) with ESMTP id 974925E64; Mon, 8 Feb 2010 19:23:13 +0900 (JST) Received: from dmailsv1.y.ecl.ntt.co.jp (dmailsv1.y.ecl.ntt.co.jp [129.60.53.14]) by mfs6.rdh.ecl.ntt.co.jp (Postfix) with ESMTP id 8DA5B5C66; Mon, 8 Feb 2010 19:23:13 +0900 (JST) Received: from mailsv02.y.ecl.ntt.co.jp by dmailsv1.y.ecl.ntt.co.jp (8.14.3/dmailsv1-2.1) with ESMTP id o18ANDwM001699; Mon, 8 Feb 2010 19:23:13 +0900 (JST) Received: from localhost by mailsv02.y.ecl.ntt.co.jp (8.14.3/Lab-1.7) with ESMTP id o18ANCxb000444; Mon, 8 Feb 2010 19:23:12 +0900 (JST) Message-ID: <4B6FE5DA.6000502@lab.ntt.co.jp> Date: Mon, 08 Feb 2010 19:22:18 +0900 From: OHMURA Kei User-Agent: Thunderbird 2.0.0.23 (Windows/20090812) MIME-Version: 1.0 To: kvm@vger.kernel.org, qemu-devel@nongnu.org CC: avi@redhat.com, Jan Kiszka , anthony@codemonkey.ws, ohmura.kei@lab.ntt.co.jp Subject: [PATCH 1/3] qemu-kvm: Wrap phys_ram_dirty with additional inline functions. Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Mon, 08 Feb 2010 10:23:45 +0000 (UTC) diff --git a/cpu-all.h b/cpu-all.h index 8ed76c7..2251f14 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -168,6 +168,33 @@ typedef union { } CPU_QuadU; #endif +static inline unsigned long unroll_flags_to_ul(int flags) +{ + unsigned long ret = 0, flags_ul = (unsigned long)flags; + +#if TARGET_LONG_SIZE == 4 + ret |= flags_ul << 0; + ret |= flags_ul << 8; + ret |= flags_ul << 16; + ret |= flags_ul << 24; +#elif TARGET_LONG_SIZE == 8 + ret |= flags_ul << 0; + ret |= flags_ul << 8; + ret |= flags_ul << 16; + ret |= flags_ul << 24; + ret |= flags_ul << 32; + ret |= flags_ul << 40; + ret |= flags_ul << 48; + ret |= flags_ul << 56; +#else + int i; + for (i = 0; i < sizeof(unsigned long); i++) + ret |= flags_ul << (i * 8); +#endif + + return ret; +} + /* CPU memory access without any memory or io remapping */ /* @@ -847,6 +874,7 @@ int cpu_str_to_log_mask(const char *str); extern int phys_ram_fd; extern uint8_t *phys_ram_dirty; +extern int *phys_ram_dirty_by_word; extern ram_addr_t ram_size; extern ram_addr_t last_ram_offset; extern uint8_t *bios_mem; @@ -882,6 +910,11 @@ static inline int cpu_physical_memory_is_dirty(ram_addr_t addr) return phys_ram_dirty[addr >> TARGET_PAGE_BITS] == 0xff; } +static inline int cpu_physical_memory_get_dirty_flags(ram_addr_t addr) +{ + return phys_ram_dirty[addr >> TARGET_PAGE_BITS]; +} + static inline int cpu_physical_memory_get_dirty(ram_addr_t addr, int dirty_flags) { @@ -890,9 +923,50 @@ static inline int cpu_physical_memory_get_dirty(ram_addr_t addr, static inline void cpu_physical_memory_set_dirty(ram_addr_t addr) { + if (phys_ram_dirty[addr >> TARGET_PAGE_BITS] != 0xff) + ++phys_ram_dirty_by_word[(addr >> TARGET_PAGE_BITS) / + TARGET_LONG_BITS]; + phys_ram_dirty[addr >> TARGET_PAGE_BITS] = 0xff; } +static inline int cpu_physical_memory_set_dirty_flags(ram_addr_t addr, + int dirty_flags) +{ + if ((phys_ram_dirty[addr >> TARGET_PAGE_BITS] != 0xff) && + ((phys_ram_dirty[addr >> TARGET_PAGE_BITS] | dirty_flags) == 0xff)) + ++phys_ram_dirty_by_word[(addr >> TARGET_PAGE_BITS) / + TARGET_LONG_BITS]; + + return phys_ram_dirty[addr >> TARGET_PAGE_BITS] |= dirty_flags; +} + +static inline void cpu_physical_memory_mask_dirty_range(ram_addr_t start, + int length, + int dirty_flags) +{ + int i, mask, len, *pw; + uint8_t *p; + + len = length >> TARGET_PAGE_BITS; + mask = ~dirty_flags; + p = phys_ram_dirty + (start >> TARGET_PAGE_BITS); + pw = phys_ram_dirty_by_word + (start >> TARGET_PAGE_BITS) / + TARGET_LONG_BITS; + + for (i = 0; i < len; i++) { + if (p[i] == 0xff) + --pw[i / TARGET_LONG_BITS]; + p[i] &= mask; + } +} + +int cpu_physical_memory_get_dirty_range(ram_addr_t start, ram_addr_t end, + int dirty_flags); + +int cpu_physical_memory_get_non_dirty_range(ram_addr_t start, ram_addr_t end, + int dirty_flags); + void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end, int dirty_flags); void cpu_tlb_update_dirty(CPUState *env); diff --git a/cpu-defs.h b/cpu-defs.h index cf502e9..8e89e96 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -37,6 +37,7 @@ #endif #define TARGET_LONG_SIZE (TARGET_LONG_BITS / 8) +#define TARGET_LONG_ALIGN(addr) (((addr) + TARGET_LONG_BITS - 1) / TARGET_LONG_BITS) /* target_ulong is the type of a virtual address */ #if TARGET_LONG_SIZE == 4