@@ -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
@@ -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);
@@ -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;
@@ -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,
@@ -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:
@@ -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;
}