From patchwork Wed Feb 24 08:45:44 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Takuya Yoshikawa X-Patchwork-Id: 81658 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 o1O8gnXC010943 for ; Wed, 24 Feb 2010 08:42:49 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755316Ab0BXImr (ORCPT ); Wed, 24 Feb 2010 03:42:47 -0500 Received: from serv2.oss.ntt.co.jp ([222.151.198.100]:54818 "EHLO serv2.oss.ntt.co.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755054Ab0BXImq (ORCPT ); Wed, 24 Feb 2010 03:42:46 -0500 Received: from serv2.oss.ntt.co.jp (localhost [127.0.0.1]) by serv2.oss.ntt.co.jp (Postfix) with ESMTP id C920B2481D6; Wed, 24 Feb 2010 17:42:45 +0900 (JST) Received: from serv1.oss.ntt.co.jp (serv1.oss.ntt.co.jp [172.19.0.2]) by serv2.oss.ntt.co.jp (Postfix) with ESMTP id B7F8F2481AE; Wed, 24 Feb 2010 17:42:45 +0900 (JST) Received: from yshtky3.kern.oss.ntt.co.jp (unknown [172.17.1.124]) by serv1.oss.ntt.co.jp (Postfix) with SMTP id 9891411C0A3; Wed, 24 Feb 2010 17:42:45 +0900 (JST) Date: Wed, 24 Feb 2010 17:45:44 +0900 From: Takuya Yoshikawa To: avi@redhat.com, mtosatti@redhat.com Cc: kvm@vger.kernel.org Subject: [PATCH 1/1] KVM: make get dirty log ioctl return the first dirty page's position Message-Id: <20100224174544.64a67b3a.yoshikawa.takuya@oss.ntt.co.jp> In-Reply-To: <20100224174303.881da4f4.yoshikawa.takuya@oss.ntt.co.jp> References: <20100224174303.881da4f4.yoshikawa.takuya@oss.ntt.co.jp> X-Mailer: Sylpheed 2.6.0 (GTK+ 2.16.1; i486-pc-linux-gnu) Mime-Version: 1.0 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]); Wed, 24 Feb 2010 08:42:49 +0000 (UTC) diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt index d170cb4..7ebfd7c 100644 --- a/Documentation/kvm/api.txt +++ b/Documentation/kvm/api.txt @@ -201,7 +201,7 @@ Capability: basic Architectures: x86 Type: vm ioctl Parameters: struct kvm_dirty_log (in/out) -Returns: 0 on success, -1 on error +Returns: first dirty page position on success, -1 on error /* for KVM_GET_DIRTY_LOG */ struct kvm_dirty_log { @@ -215,8 +215,10 @@ struct kvm_dirty_log { Given a memory slot, return a bitmap containing any pages dirtied since the last call to this ioctl. Bit 0 is the first page in the -memory slot. Ensure the entire structure is cleared to avoid padding -issues. +memory slot. The return value ensures that the contents of the +bitmap whose indexes, when you access as unsigned long array, are +less than this are clean. Ensure the entire structure is cleared +to avoid padding issues. 4.8 KVM_SET_MEMORY_ALIAS diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index 26e0e08..ae78301 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c @@ -1828,7 +1828,7 @@ out: } int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, - struct kvm_dirty_log *log) + struct kvm_dirty_log *log) { int r; int n; @@ -1843,7 +1843,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, goto out; r = kvm_get_dirty_log(kvm, log, &is_dirty); - if (r) + if (r < 0) goto out; /* If nothing is dirty, don't bother messing with page tables. */ @@ -1853,7 +1853,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; memset(memslot->dirty_bitmap, 0, n); } - r = 0; out: mutex_unlock(&kvm->slots_lock); spin_unlock(&kvm->arch.dirty_log_lock); diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 794c94b..6ffd6f2 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -1065,7 +1065,7 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, * Get (and clear) the dirty memory log for a memory slot. */ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, - struct kvm_dirty_log *log) + struct kvm_dirty_log *log) { struct kvm_memory_slot *memslot; struct kvm_vcpu *vcpu; @@ -1076,7 +1076,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, mutex_lock(&kvm->slots_lock); r = kvm_get_dirty_log(kvm, log, &is_dirty); - if (r) + if (r < 0) goto out; /* If nothing is dirty, don't bother messing with page tables. */ @@ -1093,7 +1093,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, memset(memslot->dirty_bitmap, 0, n); } - r = 0; out: mutex_unlock(&kvm->slots_lock); return r; diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 8f09959..640ce77 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -136,7 +136,7 @@ int kvm_dev_ioctl_check_extension(long ext) int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) { - return 0; + return -ENOSYS; } long kvm_arch_vm_ioctl(struct file *filp, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e25a522..8068ee9 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2694,13 +2694,14 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm, /* * Get (and clear) the dirty memory log for a memory slot. + * Return the first dirty page position on success. */ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, - struct kvm_dirty_log *log) + struct kvm_dirty_log *log) { int r, n, i; struct kvm_memory_slot *memslot; - unsigned long is_dirty = 0; + bool is_dirty; unsigned long *dirty_bitmap = NULL; mutex_lock(&kvm->slots_lock); @@ -2722,8 +2723,12 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, goto out; memset(dirty_bitmap, 0, n); - for (i = 0; !is_dirty && i < n/sizeof(long); i++) - is_dirty = memslot->dirty_bitmap[i]; + for (i = 0, is_dirty = false; i < n/sizeof(long); i++) { + if (memslot->dirty_bitmap[i]) { + is_dirty = true; + break; + } + } /* If nothing is dirty, don't bother messing with page tables. */ if (is_dirty) { @@ -2747,7 +2752,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, kfree(old_slots); } - r = 0; + r = i; if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n)) r = -EFAULT; out_free: diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 548f925..4b715c9 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -769,7 +769,6 @@ int kvm_get_dirty_log(struct kvm *kvm, struct kvm_memory_slot *memslot; int r, i; int n; - unsigned long any = 0; r = -EINVAL; if (log->slot >= KVM_MEMORY_SLOTS) @@ -782,17 +781,18 @@ int kvm_get_dirty_log(struct kvm *kvm, n = ALIGN(memslot->npages, BITS_PER_LONG) / 8; - for (i = 0; !any && i < n/sizeof(long); ++i) - any = memslot->dirty_bitmap[i]; + for (i = 0; i < n/sizeof(long); ++i) { + if (memslot->dirty_bitmap[i]) { + *is_dirty = 1; + break; + } + } r = -EFAULT; if (copy_to_user(log->dirty_bitmap, memslot->dirty_bitmap, n)) goto out; - if (any) - *is_dirty = 1; - - r = 0; + r = i; out: return r; } @@ -1592,7 +1592,7 @@ static long kvm_vm_ioctl(struct file *filp, if (copy_from_user(&log, argp, sizeof log)) goto out; r = kvm_vm_ioctl_get_dirty_log(kvm, &log); - if (r) + if (r < 0) goto out; break; } @@ -1693,7 +1693,7 @@ static long kvm_vm_compat_ioctl(struct file *filp, log.dirty_bitmap = compat_ptr(compat_log.dirty_bitmap); r = kvm_vm_ioctl_get_dirty_log(kvm, &log); - if (r) + if (r < 0) goto out; break; }