All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC v2 0/6] KVM: moving dirty gitmaps to user space!
@ 2010-04-20 10:53 ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 10:53 UTC (permalink / raw)
  To: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA
  Cc: kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA

Hi, this is the v2 of the "moving dirty gitmaps to user space!"

By this patch, I think everything we need becomes clear.
So we want to step forward to be ready for the final version in the
near future: of course, this is dependent on x86 and ppc asm issues.

BTW, by whom I can get ACK for ppc and ia64? I want to add to the Cc
list if possible, thank you.


Patch1: introduce slot level dirty state management
  This patch is independent from other patches and seems to be
  useful without the following parts.

Patch2: introduce wrapper functions to create and destroy dirty bitmaps
  Cleanup patch.

Patch3: introduce a wrapper function to copy dirty bitmaps to user space
  This is for dealing copy_in_user() things cleanly.

Patch4: change mark_page_dirty() to handle endian issues explicitly
  Later, __set_bit() part will be replaced with *_user function.

Patch5: moving dirty bitmaps to user space
  Replace dirty bitmap manipulations with *_user functions.

Patch6: introduce a new API for getting dirty bitmaps
  This is to access dirty bitmaps from user space.


Changelog:
 - suport for all architectures
   We have achived this without pinning.
 - one possible API suggestion
 - temporary copy_in_user like function
 - temporary set_bit_user like function with __get_user() and __put_user()
   We can use this as a generic set_bit_user_non_atomic().
   Of course, we need to optimize this part with arch specific one: we are
   testing some versions for x86 now.

What we are thinking about:
 - about set_bit_user_non_atomic()
   We noticed that ia64 won't need this: see patch1 and patch5.
   So all we have to do is to complete the implementations for x86 and ppc.
   ** x86 and ppc don't include asm-generic uaccess. So we have to put these
      into them separately.

 - about the new api
   There are many possible styles to make use of this work.
   E.g. if we export the both addresses of the two bitmaps,
   we don't need to export them at the switch timing: but we cannot
   reuse the current structures in this case. Which is better?


===

Appendix:

To test the patch 6, we are using the following patch for qemu-kvm.
---
 configure  |    2 +-
 qemu-kvm.c |   22 +++++++++++++++++-----
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/configure b/configure
index be8dac4..0b2d017 100755
--- a/configure
+++ b/configure
@@ -1498,7 +1498,7 @@ fi
 if test "$kvm" != "no" ; then
     cat > $TMPC <<EOF
 #include <linux/kvm.h>
-#if !defined(KVM_API_VERSION) || KVM_API_VERSION < 12 || KVM_API_VERSION > 12
+#if !defined(KVM_API_VERSION) || KVM_API_VERSION < 13 || KVM_API_VERSION > 13
 #error Invalid KVM version
 #endif
 #if !defined(KVM_CAP_USER_MEMORY)
diff --git a/qemu-kvm.c b/qemu-kvm.c
index cc5b352..087adea 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -44,7 +44,7 @@
 #define BUS_MCEERR_AO 5
 #endif
 
-#define EXPECTED_KVM_API_VERSION 12
+#define EXPECTED_KVM_API_VERSION 13
 
 #if EXPECTED_KVM_API_VERSION != KVM_API_VERSION
 #error libkvm: userspace and kernel version mismatch
@@ -684,6 +684,21 @@ static int kvm_get_map(kvm_context_t kvm, int ioctl_num, int slot, void *buf)
     return 0;
 }
 
+static int kvm_switch_map(kvm_context_t kvm, int slot, void **buf)
+{
+    int r;
+    struct kvm_dirty_log log = {
+        .slot = slot,
+    };
+
+    r = kvm_vm_ioctl(kvm_state, KVM_SWITCH_DIRTY_LOG, &log);
+    if (r < 0)
+        return r;
+
+    *buf = (void *)log.addr;
+    return 0;
+}
+
 int kvm_get_dirty_pages(kvm_context_t kvm, unsigned long phys_addr, void *buf)
 {
     int slot;
@@ -706,14 +721,11 @@ int kvm_get_dirty_pages_range(kvm_context_t kvm, unsigned long phys_addr,
     for (i = 0; i < KVM_MAX_NUM_MEM_REGIONS; ++i) {
         if ((slots[i].len && (uint64_t) slots[i].phys_addr >= phys_addr)
             && ((uint64_t) slots[i].phys_addr + slots[i].len <= end_addr)) {
-            buf = qemu_malloc(BITMAP_SIZE(slots[i].len));
-            r = kvm_get_map(kvm, KVM_GET_DIRTY_LOG, i, buf);
+            r = kvm_switch_map(kvm, i, &buf);
             if (r) {
-                qemu_free(buf);
                 return r;
             }
             r = cb(slots[i].phys_addr, slots[i].len, buf, opaque);
-            qemu_free(buf);
             if (r)
                 return r;
         }
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 0/6] KVM: moving dirty gitmaps to user space!
@ 2010-04-20 10:53 ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 10:53 UTC (permalink / raw)
  To: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA
  Cc: kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA

Hi, this is the v2 of the "moving dirty gitmaps to user space!"

By this patch, I think everything we need becomes clear.
So we want to step forward to be ready for the final version in the
near future: of course, this is dependent on x86 and ppc asm issues.

BTW, by whom I can get ACK for ppc and ia64? I want to add to the Cc
list if possible, thank you.


Patch1: introduce slot level dirty state management
  This patch is independent from other patches and seems to be
  useful without the following parts.

Patch2: introduce wrapper functions to create and destroy dirty bitmaps
  Cleanup patch.

Patch3: introduce a wrapper function to copy dirty bitmaps to user space
  This is for dealing copy_in_user() things cleanly.

Patch4: change mark_page_dirty() to handle endian issues explicitly
  Later, __set_bit() part will be replaced with *_user function.

Patch5: moving dirty bitmaps to user space
  Replace dirty bitmap manipulations with *_user functions.

Patch6: introduce a new API for getting dirty bitmaps
  This is to access dirty bitmaps from user space.


Changelog:
 - suport for all architectures
   We have achived this without pinning.
 - one possible API suggestion
 - temporary copy_in_user like function
 - temporary set_bit_user like function with __get_user() and __put_user()
   We can use this as a generic set_bit_user_non_atomic().
   Of course, we need to optimize this part with arch specific one: we are
   testing some versions for x86 now.

What we are thinking about:
 - about set_bit_user_non_atomic()
   We noticed that ia64 won't need this: see patch1 and patch5.
   So all we have to do is to complete the implementations for x86 and ppc.
   ** x86 and ppc don't include asm-generic uaccess. So we have to put these
      into them separately.

 - about the new api
   There are many possible styles to make use of this work.
   E.g. if we export the both addresses of the two bitmaps,
   we don't need to export them at the switch timing: but we cannot
   reuse the current structures in this case. Which is better?


=
Appendix:

To test the patch 6, we are using the following patch for qemu-kvm.
---
 configure  |    2 +-
 qemu-kvm.c |   22 +++++++++++++++++-----
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/configure b/configure
index be8dac4..0b2d017 100755
--- a/configure
+++ b/configure
@@ -1498,7 +1498,7 @@ fi
 if test "$kvm" != "no" ; then
     cat > $TMPC <<EOF
 #include <linux/kvm.h>
-#if !defined(KVM_API_VERSION) || KVM_API_VERSION < 12 || KVM_API_VERSION > 12
+#if !defined(KVM_API_VERSION) || KVM_API_VERSION < 13 || KVM_API_VERSION > 13
 #error Invalid KVM version
 #endif
 #if !defined(KVM_CAP_USER_MEMORY)
diff --git a/qemu-kvm.c b/qemu-kvm.c
index cc5b352..087adea 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -44,7 +44,7 @@
 #define BUS_MCEERR_AO 5
 #endif
 
-#define EXPECTED_KVM_API_VERSION 12
+#define EXPECTED_KVM_API_VERSION 13
 
 #if EXPECTED_KVM_API_VERSION != KVM_API_VERSION
 #error libkvm: userspace and kernel version mismatch
@@ -684,6 +684,21 @@ static int kvm_get_map(kvm_context_t kvm, int ioctl_num, int slot, void *buf)
     return 0;
 }
 
+static int kvm_switch_map(kvm_context_t kvm, int slot, void **buf)
+{
+    int r;
+    struct kvm_dirty_log log = {
+        .slot = slot,
+    };
+
+    r = kvm_vm_ioctl(kvm_state, KVM_SWITCH_DIRTY_LOG, &log);
+    if (r < 0)
+        return r;
+
+    *buf = (void *)log.addr;
+    return 0;
+}
+
 int kvm_get_dirty_pages(kvm_context_t kvm, unsigned long phys_addr, void *buf)
 {
     int slot;
@@ -706,14 +721,11 @@ int kvm_get_dirty_pages_range(kvm_context_t kvm, unsigned long phys_addr,
     for (i = 0; i < KVM_MAX_NUM_MEM_REGIONS; ++i) {
         if ((slots[i].len && (uint64_t) slots[i].phys_addr >= phys_addr)
             && ((uint64_t) slots[i].phys_addr + slots[i].len <= end_addr)) {
-            buf = qemu_malloc(BITMAP_SIZE(slots[i].len));
-            r = kvm_get_map(kvm, KVM_GET_DIRTY_LOG, i, buf);
+            r = kvm_switch_map(kvm, i, &buf);
             if (r) {
-                qemu_free(buf);
                 return r;
             }
             r = cb(slots[i].phys_addr, slots[i].len, buf, opaque);
-            qemu_free(buf);
             if (r)
                 return r;
         }
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 0/6] KVM: moving dirty gitmaps to user space!
@ 2010-04-20 10:53 ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 10:53 UTC (permalink / raw)
  To: kvm-ia64

Hi, this is the v2 of the "moving dirty gitmaps to user space!"

By this patch, I think everything we need becomes clear.
So we want to step forward to be ready for the final version in the
near future: of course, this is dependent on x86 and ppc asm issues.

BTW, by whom I can get ACK for ppc and ia64? I want to add to the Cc
list if possible, thank you.


Patch1: introduce slot level dirty state management
  This patch is independent from other patches and seems to be
  useful without the following parts.

Patch2: introduce wrapper functions to create and destroy dirty bitmaps
  Cleanup patch.

Patch3: introduce a wrapper function to copy dirty bitmaps to user space
  This is for dealing copy_in_user() things cleanly.

Patch4: change mark_page_dirty() to handle endian issues explicitly
  Later, __set_bit() part will be replaced with *_user function.

Patch5: moving dirty bitmaps to user space
  Replace dirty bitmap manipulations with *_user functions.

Patch6: introduce a new API for getting dirty bitmaps
  This is to access dirty bitmaps from user space.


Changelog:
 - suport for all architectures
   We have achived this without pinning.
 - one possible API suggestion
 - temporary copy_in_user like function
 - temporary set_bit_user like function with __get_user() and __put_user()
   We can use this as a generic set_bit_user_non_atomic().
   Of course, we need to optimize this part with arch specific one: we are
   testing some versions for x86 now.

What we are thinking about:
 - about set_bit_user_non_atomic()
   We noticed that ia64 won't need this: see patch1 and patch5.
   So all we have to do is to complete the implementations for x86 and ppc.
   ** x86 and ppc don't include asm-generic uaccess. So we have to put these
      into them separately.

 - about the new api
   There are many possible styles to make use of this work.
   E.g. if we export the both addresses of the two bitmaps,
   we don't need to export them at the switch timing: but we cannot
   reuse the current structures in this case. Which is better?


=
Appendix:

To test the patch 6, we are using the following patch for qemu-kvm.
---
 configure  |    2 +-
 qemu-kvm.c |   22 +++++++++++++++++-----
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/configure b/configure
index be8dac4..0b2d017 100755
--- a/configure
+++ b/configure
@@ -1498,7 +1498,7 @@ fi
 if test "$kvm" != "no" ; then
     cat > $TMPC <<EOF
 #include <linux/kvm.h>
-#if !defined(KVM_API_VERSION) || KVM_API_VERSION < 12 || KVM_API_VERSION > 12
+#if !defined(KVM_API_VERSION) || KVM_API_VERSION < 13 || KVM_API_VERSION > 13
 #error Invalid KVM version
 #endif
 #if !defined(KVM_CAP_USER_MEMORY)
diff --git a/qemu-kvm.c b/qemu-kvm.c
index cc5b352..087adea 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -44,7 +44,7 @@
 #define BUS_MCEERR_AO 5
 #endif
 
-#define EXPECTED_KVM_API_VERSION 12
+#define EXPECTED_KVM_API_VERSION 13
 
 #if EXPECTED_KVM_API_VERSION != KVM_API_VERSION
 #error libkvm: userspace and kernel version mismatch
@@ -684,6 +684,21 @@ static int kvm_get_map(kvm_context_t kvm, int ioctl_num, int slot, void *buf)
     return 0;
 }
 
+static int kvm_switch_map(kvm_context_t kvm, int slot, void **buf)
+{
+    int r;
+    struct kvm_dirty_log log = {
+        .slot = slot,
+    };
+
+    r = kvm_vm_ioctl(kvm_state, KVM_SWITCH_DIRTY_LOG, &log);
+    if (r < 0)
+        return r;
+
+    *buf = (void *)log.addr;
+    return 0;
+}
+
 int kvm_get_dirty_pages(kvm_context_t kvm, unsigned long phys_addr, void *buf)
 {
     int slot;
@@ -706,14 +721,11 @@ int kvm_get_dirty_pages_range(kvm_context_t kvm, unsigned long phys_addr,
     for (i = 0; i < KVM_MAX_NUM_MEM_REGIONS; ++i) {
         if ((slots[i].len && (uint64_t) slots[i].phys_addr >= phys_addr)
             && ((uint64_t) slots[i].phys_addr + slots[i].len <= end_addr)) {
-            buf = qemu_malloc(BITMAP_SIZE(slots[i].len));
-            r = kvm_get_map(kvm, KVM_GET_DIRTY_LOG, i, buf);
+            r = kvm_switch_map(kvm, i, &buf);
             if (r) {
-                qemu_free(buf);
                 return r;
             }
             r = cb(slots[i].phys_addr, slots[i].len, buf, opaque);
-            qemu_free(buf);
             if (r)
                 return r;
         }
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 0/6] KVM: moving dirty gitmaps to user space!
  2010-04-20 10:53 ` Takuya Yoshikawa
  (?)
@ 2010-04-20 10:54   ` Alexander Graf
  -1 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-20 10:54 UTC (permalink / raw)
  To: Takuya Yoshikawa; +Cc: avi, mtosatti, kvm, kvm-ia64, kvm-ppc


On 20.04.2010, at 12:53, Takuya Yoshikawa wrote:

> Hi, this is the v2 of the "moving dirty gitmaps to user space!"
> 
> By this patch, I think everything we need becomes clear.
> So we want to step forward to be ready for the final version in the
> near future: of course, this is dependent on x86 and ppc asm issues.
> 
> BTW, by whom I can get ACK for ppc and ia64? I want to add to the Cc
> list if possible, thank you.

You'd get the ACK for ppc from me.

Do you have a PowerPC box around to test things on? By now it should work on any desktop/server PowerPC system you can find.

Also the only differences on PPC are that we are big endian and usually run 32 bit userspace on 64 bit kernels. So playing with longs is a bad idea :).

Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 0/6] KVM: moving dirty gitmaps to user space!
@ 2010-04-20 10:54   ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-20 10:54 UTC (permalink / raw)
  To: Takuya Yoshikawa; +Cc: avi, mtosatti, kvm, kvm-ia64, kvm-ppc


On 20.04.2010, at 12:53, Takuya Yoshikawa wrote:

> Hi, this is the v2 of the "moving dirty gitmaps to user space!"
> 
> By this patch, I think everything we need becomes clear.
> So we want to step forward to be ready for the final version in the
> near future: of course, this is dependent on x86 and ppc asm issues.
> 
> BTW, by whom I can get ACK for ppc and ia64? I want to add to the Cc
> list if possible, thank you.

You'd get the ACK for ppc from me.

Do you have a PowerPC box around to test things on? By now it should work on any desktop/server PowerPC system you can find.

Also the only differences on PPC are that we are big endian and usually run 32 bit userspace on 64 bit kernels. So playing with longs is a bad idea :).

Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 0/6] KVM: moving dirty gitmaps to user space!
@ 2010-04-20 10:54   ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-20 10:54 UTC (permalink / raw)
  To: kvm-ia64


On 20.04.2010, at 12:53, Takuya Yoshikawa wrote:

> Hi, this is the v2 of the "moving dirty gitmaps to user space!"
> 
> By this patch, I think everything we need becomes clear.
> So we want to step forward to be ready for the final version in the
> near future: of course, this is dependent on x86 and ppc asm issues.
> 
> BTW, by whom I can get ACK for ppc and ia64? I want to add to the Cc
> list if possible, thank you.

You'd get the ACK for ppc from me.

Do you have a PowerPC box around to test things on? By now it should work on any desktop/server PowerPC system you can find.

Also the only differences on PPC are that we are big endian and usually run 32 bit userspace on 64 bit kernels. So playing with longs is a bad idea :).

Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 1/6] KVM: introduce slot level dirty state management
  2010-04-20 10:53 ` Takuya Yoshikawa
  (?)
@ 2010-04-20 10:56   ` Takuya Yoshikawa
  -1 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 10:56 UTC (permalink / raw)
  To: avi, mtosatti; +Cc: kvm, kvm-ia64, kvm-ppc, fernando

This patch introduces is_dirty member for each memory slot.
Using this member, we remove the dirty bitmap scan which is
done in the get_dirty_log function.

This also helps us when we move the dirty bitmaps to user space:
we don't have any good way to check the bitmaps in user space with
low cost, so scanning bitmaps for checking memory slot dirtiness
will not be acceptable.

When we mark the slot dirty:
 - x86 and ppc: at the timing of mark_page_dirty()
 - ia64: at the timing of kvm_ia64_sync_dirty_log()
ia64 uses a different place to store the dirty bitmap and synchronize
it right before the get_dirty_log(). So we use this timing to update
the dirtiness of a memory slot.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
 arch/ia64/kvm/kvm-ia64.c  |   11 +++++++----
 arch/powerpc/kvm/book3s.c |    9 ++++-----
 arch/x86/kvm/x86.c        |    9 +++------
 include/linux/kvm_host.h  |    4 ++--
 virt/kvm/kvm_main.c       |   16 +++++-----------
 5 files changed, 21 insertions(+), 28 deletions(-)

diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index d7bac1f..d60dafe 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -1824,6 +1824,9 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
 	base = memslot->base_gfn / BITS_PER_LONG;
 
 	for (i = 0; i < n/sizeof(long); ++i) {
+		if (dirty_bitmap[base + i])
+			memslot->is_dirty = true;
+
 		memslot->dirty_bitmap[i] = dirty_bitmap[base + i];
 		dirty_bitmap[base + i] = 0;
 	}
@@ -1838,7 +1841,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	int r;
 	unsigned long n;
 	struct kvm_memory_slot *memslot;
-	int is_dirty = 0;
 
 	mutex_lock(&kvm->slots_lock);
 	spin_lock(&kvm->arch.dirty_log_lock);
@@ -1847,16 +1849,17 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	if (r)
 		goto out;
 
-	r = kvm_get_dirty_log(kvm, log, &is_dirty);
+	r = kvm_get_dirty_log(kvm, log);
 	if (r)
 		goto out;
 
+	memslot = &kvm->memslots->memslots[log->slot];
 	/* If nothing is dirty, don't bother messing with page tables. */
-	if (is_dirty) {
+	if (memslot->is_dirty) {
 		kvm_flush_remote_tlbs(kvm);
-		memslot = &kvm->memslots->memslots[log->slot];
 		n = kvm_dirty_bitmap_bytes(memslot);
 		memset(memslot->dirty_bitmap, 0, n);
+		memslot->is_dirty = false;
 	}
 	r = 0;
 out:
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 41c23b6..53b45cf 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -1118,20 +1118,18 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	struct kvm_memory_slot *memslot;
 	struct kvm_vcpu *vcpu;
 	ulong ga, ga_end;
-	int is_dirty = 0;
 	int r;
 	unsigned long n;
 
 	mutex_lock(&kvm->slots_lock);
 
-	r = kvm_get_dirty_log(kvm, log, &is_dirty);
+	r = kvm_get_dirty_log(kvm, log);
 	if (r)
 		goto out;
 
+	memslot = &kvm->memslots->memslots[log->slot];
 	/* If nothing is dirty, don't bother messing with page tables. */
-	if (is_dirty) {
-		memslot = &kvm->memslots->memslots[log->slot];
-
+	if (memslot->is_dirty) {
 		ga = memslot->base_gfn << PAGE_SHIFT;
 		ga_end = ga + (memslot->npages << PAGE_SHIFT);
 
@@ -1140,6 +1138,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 
 		n = kvm_dirty_bitmap_bytes(memslot);
 		memset(memslot->dirty_bitmap, 0, n);
+		memslot->is_dirty = false;
 	}
 
 	r = 0;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 58a96e6..76b23ed 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2724,10 +2724,9 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 				      struct kvm_dirty_log *log)
 {
-	int r, i;
+	int r;
 	struct kvm_memory_slot *memslot;
 	unsigned long n;
-	unsigned long is_dirty = 0;
 	unsigned long *dirty_bitmap = NULL;
 
 	mutex_lock(&kvm->slots_lock);
@@ -2749,11 +2748,8 @@ 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];
-
 	/* If nothing is dirty, don't bother messing with page tables. */
-	if (is_dirty) {
+	if (memslot->is_dirty) {
 		struct kvm_memslots *slots, *old_slots;
 
 		spin_lock(&kvm->mmu_lock);
@@ -2766,6 +2762,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 
 		memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
 		slots->memslots[log->slot].dirty_bitmap = dirty_bitmap;
+		slots->memslots[log->slot].is_dirty = false;
 
 		old_slots = kvm->memslots;
 		rcu_assign_pointer(kvm->memslots, slots);
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 5583063..4446622 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -117,6 +117,7 @@ struct kvm_memory_slot {
 	unsigned long flags;
 	unsigned long *rmap;
 	unsigned long *dirty_bitmap;
+	bool is_dirty;
 	struct {
 		unsigned long rmap_pde;
 		int write_count;
@@ -329,8 +330,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 
 int kvm_dev_ioctl_check_extension(long ext);
 
-int kvm_get_dirty_log(struct kvm *kvm,
-			struct kvm_dirty_log *log, int *is_dirty);
+int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 				struct kvm_dirty_log *log);
 
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 3725605..cc78e07 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -764,13 +764,11 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
 	return kvm_set_memory_region(kvm, mem, user_alloc);
 }
 
-int kvm_get_dirty_log(struct kvm *kvm,
-			struct kvm_dirty_log *log, int *is_dirty)
+int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
 {
 	struct kvm_memory_slot *memslot;
-	int r, i;
+	int r;
 	unsigned long n;
-	unsigned long any = 0;
 
 	r = -EINVAL;
 	if (log->slot >= KVM_MEMORY_SLOTS)
@@ -783,16 +781,10 @@ int kvm_get_dirty_log(struct kvm *kvm,
 
 	n = kvm_dirty_bitmap_bytes(memslot);
 
-	for (i = 0; !any && i < n/sizeof(long); ++i)
-		any = memslot->dirty_bitmap[i];
-
 	r = -EFAULT;
 	if (copy_to_user(log->dirty_bitmap, memslot->dirty_bitmap, n))
 		goto out;
 
-	if (any)
-		*is_dirty = 1;
-
 	r = 0;
 out:
 	return r;
@@ -1189,8 +1181,10 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
 		unsigned long rel_gfn = gfn - memslot->base_gfn;
 
 		/* avoid RMW */
-		if (!generic_test_le_bit(rel_gfn, memslot->dirty_bitmap))
+		if (!generic_test_le_bit(rel_gfn, memslot->dirty_bitmap)) {
 			generic___set_le_bit(rel_gfn, memslot->dirty_bitmap);
+			memslot->is_dirty = true;
+		}
 	}
 }
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 1/6] KVM: introduce slot level dirty state management
@ 2010-04-20 10:56   ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 10:56 UTC (permalink / raw)
  To: avi, mtosatti; +Cc: kvm, kvm-ia64, kvm-ppc, fernando

This patch introduces is_dirty member for each memory slot.
Using this member, we remove the dirty bitmap scan which is
done in the get_dirty_log function.

This also helps us when we move the dirty bitmaps to user space:
we don't have any good way to check the bitmaps in user space with
low cost, so scanning bitmaps for checking memory slot dirtiness
will not be acceptable.

When we mark the slot dirty:
 - x86 and ppc: at the timing of mark_page_dirty()
 - ia64: at the timing of kvm_ia64_sync_dirty_log()
ia64 uses a different place to store the dirty bitmap and synchronize
it right before the get_dirty_log(). So we use this timing to update
the dirtiness of a memory slot.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
 arch/ia64/kvm/kvm-ia64.c  |   11 +++++++----
 arch/powerpc/kvm/book3s.c |    9 ++++-----
 arch/x86/kvm/x86.c        |    9 +++------
 include/linux/kvm_host.h  |    4 ++--
 virt/kvm/kvm_main.c       |   16 +++++-----------
 5 files changed, 21 insertions(+), 28 deletions(-)

diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index d7bac1f..d60dafe 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -1824,6 +1824,9 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
 	base = memslot->base_gfn / BITS_PER_LONG;
 
 	for (i = 0; i < n/sizeof(long); ++i) {
+		if (dirty_bitmap[base + i])
+			memslot->is_dirty = true;
+
 		memslot->dirty_bitmap[i] = dirty_bitmap[base + i];
 		dirty_bitmap[base + i] = 0;
 	}
@@ -1838,7 +1841,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	int r;
 	unsigned long n;
 	struct kvm_memory_slot *memslot;
-	int is_dirty = 0;
 
 	mutex_lock(&kvm->slots_lock);
 	spin_lock(&kvm->arch.dirty_log_lock);
@@ -1847,16 +1849,17 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	if (r)
 		goto out;
 
-	r = kvm_get_dirty_log(kvm, log, &is_dirty);
+	r = kvm_get_dirty_log(kvm, log);
 	if (r)
 		goto out;
 
+	memslot = &kvm->memslots->memslots[log->slot];
 	/* If nothing is dirty, don't bother messing with page tables. */
-	if (is_dirty) {
+	if (memslot->is_dirty) {
 		kvm_flush_remote_tlbs(kvm);
-		memslot = &kvm->memslots->memslots[log->slot];
 		n = kvm_dirty_bitmap_bytes(memslot);
 		memset(memslot->dirty_bitmap, 0, n);
+		memslot->is_dirty = false;
 	}
 	r = 0;
 out:
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 41c23b6..53b45cf 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -1118,20 +1118,18 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	struct kvm_memory_slot *memslot;
 	struct kvm_vcpu *vcpu;
 	ulong ga, ga_end;
-	int is_dirty = 0;
 	int r;
 	unsigned long n;
 
 	mutex_lock(&kvm->slots_lock);
 
-	r = kvm_get_dirty_log(kvm, log, &is_dirty);
+	r = kvm_get_dirty_log(kvm, log);
 	if (r)
 		goto out;
 
+	memslot = &kvm->memslots->memslots[log->slot];
 	/* If nothing is dirty, don't bother messing with page tables. */
-	if (is_dirty) {
-		memslot = &kvm->memslots->memslots[log->slot];
-
+	if (memslot->is_dirty) {
 		ga = memslot->base_gfn << PAGE_SHIFT;
 		ga_end = ga + (memslot->npages << PAGE_SHIFT);
 
@@ -1140,6 +1138,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 
 		n = kvm_dirty_bitmap_bytes(memslot);
 		memset(memslot->dirty_bitmap, 0, n);
+		memslot->is_dirty = false;
 	}
 
 	r = 0;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 58a96e6..76b23ed 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2724,10 +2724,9 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 				      struct kvm_dirty_log *log)
 {
-	int r, i;
+	int r;
 	struct kvm_memory_slot *memslot;
 	unsigned long n;
-	unsigned long is_dirty = 0;
 	unsigned long *dirty_bitmap = NULL;
 
 	mutex_lock(&kvm->slots_lock);
@@ -2749,11 +2748,8 @@ 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];
-
 	/* If nothing is dirty, don't bother messing with page tables. */
-	if (is_dirty) {
+	if (memslot->is_dirty) {
 		struct kvm_memslots *slots, *old_slots;
 
 		spin_lock(&kvm->mmu_lock);
@@ -2766,6 +2762,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 
 		memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
 		slots->memslots[log->slot].dirty_bitmap = dirty_bitmap;
+		slots->memslots[log->slot].is_dirty = false;
 
 		old_slots = kvm->memslots;
 		rcu_assign_pointer(kvm->memslots, slots);
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 5583063..4446622 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -117,6 +117,7 @@ struct kvm_memory_slot {
 	unsigned long flags;
 	unsigned long *rmap;
 	unsigned long *dirty_bitmap;
+	bool is_dirty;
 	struct {
 		unsigned long rmap_pde;
 		int write_count;
@@ -329,8 +330,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 
 int kvm_dev_ioctl_check_extension(long ext);
 
-int kvm_get_dirty_log(struct kvm *kvm,
-			struct kvm_dirty_log *log, int *is_dirty);
+int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 				struct kvm_dirty_log *log);
 
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 3725605..cc78e07 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -764,13 +764,11 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
 	return kvm_set_memory_region(kvm, mem, user_alloc);
 }
 
-int kvm_get_dirty_log(struct kvm *kvm,
-			struct kvm_dirty_log *log, int *is_dirty)
+int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
 {
 	struct kvm_memory_slot *memslot;
-	int r, i;
+	int r;
 	unsigned long n;
-	unsigned long any = 0;
 
 	r = -EINVAL;
 	if (log->slot >= KVM_MEMORY_SLOTS)
@@ -783,16 +781,10 @@ int kvm_get_dirty_log(struct kvm *kvm,
 
 	n = kvm_dirty_bitmap_bytes(memslot);
 
-	for (i = 0; !any && i < n/sizeof(long); ++i)
-		any = memslot->dirty_bitmap[i];
-
 	r = -EFAULT;
 	if (copy_to_user(log->dirty_bitmap, memslot->dirty_bitmap, n))
 		goto out;
 
-	if (any)
-		*is_dirty = 1;
-
 	r = 0;
 out:
 	return r;
@@ -1189,8 +1181,10 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
 		unsigned long rel_gfn = gfn - memslot->base_gfn;
 
 		/* avoid RMW */
-		if (!generic_test_le_bit(rel_gfn, memslot->dirty_bitmap))
+		if (!generic_test_le_bit(rel_gfn, memslot->dirty_bitmap)) {
 			generic___set_le_bit(rel_gfn, memslot->dirty_bitmap);
+			memslot->is_dirty = true;
+		}
 	}
 }
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 1/6] KVM: introduce slot level dirty state management
@ 2010-04-20 10:56   ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 10:56 UTC (permalink / raw)
  To: kvm-ia64

This patch introduces is_dirty member for each memory slot.
Using this member, we remove the dirty bitmap scan which is
done in the get_dirty_log function.

This also helps us when we move the dirty bitmaps to user space:
we don't have any good way to check the bitmaps in user space with
low cost, so scanning bitmaps for checking memory slot dirtiness
will not be acceptable.

When we mark the slot dirty:
 - x86 and ppc: at the timing of mark_page_dirty()
 - ia64: at the timing of kvm_ia64_sync_dirty_log()
ia64 uses a different place to store the dirty bitmap and synchronize
it right before the get_dirty_log(). So we use this timing to update
the dirtiness of a memory slot.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
 arch/ia64/kvm/kvm-ia64.c  |   11 +++++++----
 arch/powerpc/kvm/book3s.c |    9 ++++-----
 arch/x86/kvm/x86.c        |    9 +++------
 include/linux/kvm_host.h  |    4 ++--
 virt/kvm/kvm_main.c       |   16 +++++-----------
 5 files changed, 21 insertions(+), 28 deletions(-)

diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index d7bac1f..d60dafe 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -1824,6 +1824,9 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
 	base = memslot->base_gfn / BITS_PER_LONG;
 
 	for (i = 0; i < n/sizeof(long); ++i) {
+		if (dirty_bitmap[base + i])
+			memslot->is_dirty = true;
+
 		memslot->dirty_bitmap[i] = dirty_bitmap[base + i];
 		dirty_bitmap[base + i] = 0;
 	}
@@ -1838,7 +1841,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	int r;
 	unsigned long n;
 	struct kvm_memory_slot *memslot;
-	int is_dirty = 0;
 
 	mutex_lock(&kvm->slots_lock);
 	spin_lock(&kvm->arch.dirty_log_lock);
@@ -1847,16 +1849,17 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	if (r)
 		goto out;
 
-	r = kvm_get_dirty_log(kvm, log, &is_dirty);
+	r = kvm_get_dirty_log(kvm, log);
 	if (r)
 		goto out;
 
+	memslot = &kvm->memslots->memslots[log->slot];
 	/* If nothing is dirty, don't bother messing with page tables. */
-	if (is_dirty) {
+	if (memslot->is_dirty) {
 		kvm_flush_remote_tlbs(kvm);
-		memslot = &kvm->memslots->memslots[log->slot];
 		n = kvm_dirty_bitmap_bytes(memslot);
 		memset(memslot->dirty_bitmap, 0, n);
+		memslot->is_dirty = false;
 	}
 	r = 0;
 out:
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 41c23b6..53b45cf 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -1118,20 +1118,18 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	struct kvm_memory_slot *memslot;
 	struct kvm_vcpu *vcpu;
 	ulong ga, ga_end;
-	int is_dirty = 0;
 	int r;
 	unsigned long n;
 
 	mutex_lock(&kvm->slots_lock);
 
-	r = kvm_get_dirty_log(kvm, log, &is_dirty);
+	r = kvm_get_dirty_log(kvm, log);
 	if (r)
 		goto out;
 
+	memslot = &kvm->memslots->memslots[log->slot];
 	/* If nothing is dirty, don't bother messing with page tables. */
-	if (is_dirty) {
-		memslot = &kvm->memslots->memslots[log->slot];
-
+	if (memslot->is_dirty) {
 		ga = memslot->base_gfn << PAGE_SHIFT;
 		ga_end = ga + (memslot->npages << PAGE_SHIFT);
 
@@ -1140,6 +1138,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 
 		n = kvm_dirty_bitmap_bytes(memslot);
 		memset(memslot->dirty_bitmap, 0, n);
+		memslot->is_dirty = false;
 	}
 
 	r = 0;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 58a96e6..76b23ed 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2724,10 +2724,9 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 				      struct kvm_dirty_log *log)
 {
-	int r, i;
+	int r;
 	struct kvm_memory_slot *memslot;
 	unsigned long n;
-	unsigned long is_dirty = 0;
 	unsigned long *dirty_bitmap = NULL;
 
 	mutex_lock(&kvm->slots_lock);
@@ -2749,11 +2748,8 @@ 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];
-
 	/* If nothing is dirty, don't bother messing with page tables. */
-	if (is_dirty) {
+	if (memslot->is_dirty) {
 		struct kvm_memslots *slots, *old_slots;
 
 		spin_lock(&kvm->mmu_lock);
@@ -2766,6 +2762,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 
 		memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
 		slots->memslots[log->slot].dirty_bitmap = dirty_bitmap;
+		slots->memslots[log->slot].is_dirty = false;
 
 		old_slots = kvm->memslots;
 		rcu_assign_pointer(kvm->memslots, slots);
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 5583063..4446622 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -117,6 +117,7 @@ struct kvm_memory_slot {
 	unsigned long flags;
 	unsigned long *rmap;
 	unsigned long *dirty_bitmap;
+	bool is_dirty;
 	struct {
 		unsigned long rmap_pde;
 		int write_count;
@@ -329,8 +330,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 
 int kvm_dev_ioctl_check_extension(long ext);
 
-int kvm_get_dirty_log(struct kvm *kvm,
-			struct kvm_dirty_log *log, int *is_dirty);
+int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 				struct kvm_dirty_log *log);
 
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 3725605..cc78e07 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -764,13 +764,11 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
 	return kvm_set_memory_region(kvm, mem, user_alloc);
 }
 
-int kvm_get_dirty_log(struct kvm *kvm,
-			struct kvm_dirty_log *log, int *is_dirty)
+int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
 {
 	struct kvm_memory_slot *memslot;
-	int r, i;
+	int r;
 	unsigned long n;
-	unsigned long any = 0;
 
 	r = -EINVAL;
 	if (log->slot >= KVM_MEMORY_SLOTS)
@@ -783,16 +781,10 @@ int kvm_get_dirty_log(struct kvm *kvm,
 
 	n = kvm_dirty_bitmap_bytes(memslot);
 
-	for (i = 0; !any && i < n/sizeof(long); ++i)
-		any = memslot->dirty_bitmap[i];
-
 	r = -EFAULT;
 	if (copy_to_user(log->dirty_bitmap, memslot->dirty_bitmap, n))
 		goto out;
 
-	if (any)
-		*is_dirty = 1;
-
 	r = 0;
 out:
 	return r;
@@ -1189,8 +1181,10 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
 		unsigned long rel_gfn = gfn - memslot->base_gfn;
 
 		/* avoid RMW */
-		if (!generic_test_le_bit(rel_gfn, memslot->dirty_bitmap))
+		if (!generic_test_le_bit(rel_gfn, memslot->dirty_bitmap)) {
 			generic___set_le_bit(rel_gfn, memslot->dirty_bitmap);
+			memslot->is_dirty = true;
+		}
 	}
 }
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian
  2010-04-20 10:53 ` Takuya Yoshikawa
  (?)
@ 2010-04-20 10:57   ` Takuya Yoshikawa
  -1 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 10:57 UTC (permalink / raw)
  To: kvm-ia64

We are now using generic___set_le_bit() to make dirty bitmaps le.
Though this works well, we have to replace __set_bit() to appropriate
uaccess function to move dirty bitmaps to user space. So this patch
splits generic___set_le_bit() and prepares for that.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
 virt/kvm/kvm_main.c |   16 +++++++++++-----
 1 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 6908304..66c4daf 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1194,6 +1194,15 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
 }
 EXPORT_SYMBOL_GPL(kvm_clear_guest);
 
+static int __mark_page_dirty(unsigned long nr,
+			     unsigned long *dirty_bitmap)
+{
+#ifdef __BIG_ENDIAN
+	nr = nr ^ BITOP_LE_SWIZZLE;
+#endif
+	__set_bit(nr, dirty_bitmap);
+}
+
 void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
 {
 	struct kvm_memory_slot *memslot;
@@ -1203,11 +1212,8 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
 	if (memslot && memslot->dirty_bitmap) {
 		unsigned long rel_gfn = gfn - memslot->base_gfn;
 
-		/* avoid RMW */
-		if (!generic_test_le_bit(rel_gfn, memslot->dirty_bitmap)) {
-			generic___set_le_bit(rel_gfn, memslot->dirty_bitmap);
-			memslot->is_dirty = true;
-		}
+		__mark_page_dirty(rel_gfn, memslot->dirty_bitmap);
+		memslot->is_dirty = true;
 	}
 }
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian
@ 2010-04-20 10:57   ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 10:57 UTC (permalink / raw)
  To: avi, mtosatti; +Cc: kvm, kvm-ia64, kvm-ppc, fernando

We are now using generic___set_le_bit() to make dirty bitmaps le.
Though this works well, we have to replace __set_bit() to appropriate
uaccess function to move dirty bitmaps to user space. So this patch
splits generic___set_le_bit() and prepares for that.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
 virt/kvm/kvm_main.c |   16 +++++++++++-----
 1 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 6908304..66c4daf 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1194,6 +1194,15 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
 }
 EXPORT_SYMBOL_GPL(kvm_clear_guest);
 
+static int __mark_page_dirty(unsigned long nr,
+			     unsigned long *dirty_bitmap)
+{
+#ifdef __BIG_ENDIAN
+	nr = nr ^ BITOP_LE_SWIZZLE;
+#endif
+	__set_bit(nr, dirty_bitmap);
+}
+
 void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
 {
 	struct kvm_memory_slot *memslot;
@@ -1203,11 +1212,8 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
 	if (memslot && memslot->dirty_bitmap) {
 		unsigned long rel_gfn = gfn - memslot->base_gfn;
 
-		/* avoid RMW */
-		if (!generic_test_le_bit(rel_gfn, memslot->dirty_bitmap)) {
-			generic___set_le_bit(rel_gfn, memslot->dirty_bitmap);
-			memslot->is_dirty = true;
-		}
+		__mark_page_dirty(rel_gfn, memslot->dirty_bitmap);
+		memslot->is_dirty = true;
 	}
 }
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 2/6] KVM: introduce wrapper functions to create and destroy dirty bitmaps
  2010-04-20 10:53 ` Takuya Yoshikawa
  (?)
@ 2010-04-20 10:57   ` Takuya Yoshikawa
  -1 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 10:57 UTC (permalink / raw)
  To: avi, mtosatti; +Cc: kvm, kvm-ia64, kvm-ppc, fernando

We will change the vmalloc() and vfree() to do_mmap() and do_munmap()
later. This patch makes it easy and cleanup the code.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
 virt/kvm/kvm_main.c |   27 ++++++++++++++++++++-------
 1 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index cc78e07..40a6888 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -431,6 +431,12 @@ out_err_nodisable:
 	return ERR_PTR(r);
 }
 
+static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot)
+{
+	vfree(memslot->dirty_bitmap);
+	memslot->dirty_bitmap = NULL;
+}
+
 /*
  * Free any memory in @free but not in @dont.
  */
@@ -443,7 +449,7 @@ static void kvm_free_physmem_slot(struct kvm_memory_slot *free,
 		vfree(free->rmap);
 
 	if (!dont || free->dirty_bitmap != dont->dirty_bitmap)
-		vfree(free->dirty_bitmap);
+		kvm_destroy_dirty_bitmap(free);
 
 
 	for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
@@ -454,7 +460,6 @@ static void kvm_free_physmem_slot(struct kvm_memory_slot *free,
 	}
 
 	free->npages = 0;
-	free->dirty_bitmap = NULL;
 	free->rmap = NULL;
 }
 
@@ -516,6 +521,18 @@ static int kvm_vm_release(struct inode *inode, struct file *filp)
 	return 0;
 }
 
+static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot)
+{
+	unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(memslot);
+
+	memslot->dirty_bitmap = vmalloc(dirty_bytes);
+	if (!memslot->dirty_bitmap)
+		return -ENOMEM;
+
+	memset(memslot->dirty_bitmap, 0, dirty_bytes);
+	return 0;
+}
+
 /*
  * Allocate some memory and give it an address in the guest physical address
  * space.
@@ -649,12 +666,8 @@ skip_lpage:
 
 	/* Allocate page dirty bitmap if needed */
 	if ((new.flags & KVM_MEM_LOG_DIRTY_PAGES) && !new.dirty_bitmap) {
-		unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(&new);
-
-		new.dirty_bitmap = vmalloc(dirty_bytes);
-		if (!new.dirty_bitmap)
+		if (kvm_create_dirty_bitmap(&new) < 0)
 			goto out_free;
-		memset(new.dirty_bitmap, 0, dirty_bytes);
 		/* destroy any largepage mappings for dirty tracking */
 		if (old.npages)
 			flush_shadow = 1;
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 2/6] KVM: introduce wrapper functions to create and
@ 2010-04-20 10:57   ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 10:57 UTC (permalink / raw)
  To: avi, mtosatti; +Cc: kvm, kvm-ia64, kvm-ppc, fernando

We will change the vmalloc() and vfree() to do_mmap() and do_munmap()
later. This patch makes it easy and cleanup the code.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
 virt/kvm/kvm_main.c |   27 ++++++++++++++++++++-------
 1 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index cc78e07..40a6888 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -431,6 +431,12 @@ out_err_nodisable:
 	return ERR_PTR(r);
 }
 
+static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot)
+{
+	vfree(memslot->dirty_bitmap);
+	memslot->dirty_bitmap = NULL;
+}
+
 /*
  * Free any memory in @free but not in @dont.
  */
@@ -443,7 +449,7 @@ static void kvm_free_physmem_slot(struct kvm_memory_slot *free,
 		vfree(free->rmap);
 
 	if (!dont || free->dirty_bitmap != dont->dirty_bitmap)
-		vfree(free->dirty_bitmap);
+		kvm_destroy_dirty_bitmap(free);
 
 
 	for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
@@ -454,7 +460,6 @@ static void kvm_free_physmem_slot(struct kvm_memory_slot *free,
 	}
 
 	free->npages = 0;
-	free->dirty_bitmap = NULL;
 	free->rmap = NULL;
 }
 
@@ -516,6 +521,18 @@ static int kvm_vm_release(struct inode *inode, struct file *filp)
 	return 0;
 }
 
+static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot)
+{
+	unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(memslot);
+
+	memslot->dirty_bitmap = vmalloc(dirty_bytes);
+	if (!memslot->dirty_bitmap)
+		return -ENOMEM;
+
+	memset(memslot->dirty_bitmap, 0, dirty_bytes);
+	return 0;
+}
+
 /*
  * Allocate some memory and give it an address in the guest physical address
  * space.
@@ -649,12 +666,8 @@ skip_lpage:
 
 	/* Allocate page dirty bitmap if needed */
 	if ((new.flags & KVM_MEM_LOG_DIRTY_PAGES) && !new.dirty_bitmap) {
-		unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(&new);
-
-		new.dirty_bitmap = vmalloc(dirty_bytes);
-		if (!new.dirty_bitmap)
+		if (kvm_create_dirty_bitmap(&new) < 0)
 			goto out_free;
-		memset(new.dirty_bitmap, 0, dirty_bytes);
 		/* destroy any largepage mappings for dirty tracking */
 		if (old.npages)
 			flush_shadow = 1;
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 2/6] KVM: introduce wrapper functions to create and
@ 2010-04-20 10:57   ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 10:57 UTC (permalink / raw)
  To: kvm-ia64

We will change the vmalloc() and vfree() to do_mmap() and do_munmap()
later. This patch makes it easy and cleanup the code.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
 virt/kvm/kvm_main.c |   27 ++++++++++++++++++++-------
 1 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index cc78e07..40a6888 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -431,6 +431,12 @@ out_err_nodisable:
 	return ERR_PTR(r);
 }
 
+static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot)
+{
+	vfree(memslot->dirty_bitmap);
+	memslot->dirty_bitmap = NULL;
+}
+
 /*
  * Free any memory in @free but not in @dont.
  */
@@ -443,7 +449,7 @@ static void kvm_free_physmem_slot(struct kvm_memory_slot *free,
 		vfree(free->rmap);
 
 	if (!dont || free->dirty_bitmap != dont->dirty_bitmap)
-		vfree(free->dirty_bitmap);
+		kvm_destroy_dirty_bitmap(free);
 
 
 	for (i = 0; i < KVM_NR_PAGE_SIZES - 1; ++i) {
@@ -454,7 +460,6 @@ static void kvm_free_physmem_slot(struct kvm_memory_slot *free,
 	}
 
 	free->npages = 0;
-	free->dirty_bitmap = NULL;
 	free->rmap = NULL;
 }
 
@@ -516,6 +521,18 @@ static int kvm_vm_release(struct inode *inode, struct file *filp)
 	return 0;
 }
 
+static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot)
+{
+	unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(memslot);
+
+	memslot->dirty_bitmap = vmalloc(dirty_bytes);
+	if (!memslot->dirty_bitmap)
+		return -ENOMEM;
+
+	memset(memslot->dirty_bitmap, 0, dirty_bytes);
+	return 0;
+}
+
 /*
  * Allocate some memory and give it an address in the guest physical address
  * space.
@@ -649,12 +666,8 @@ skip_lpage:
 
 	/* Allocate page dirty bitmap if needed */
 	if ((new.flags & KVM_MEM_LOG_DIRTY_PAGES) && !new.dirty_bitmap) {
-		unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(&new);
-
-		new.dirty_bitmap = vmalloc(dirty_bytes);
-		if (!new.dirty_bitmap)
+		if (kvm_create_dirty_bitmap(&new) < 0)
 			goto out_free;
-		memset(new.dirty_bitmap, 0, dirty_bytes);
 		/* destroy any largepage mappings for dirty tracking */
 		if (old.npages)
 			flush_shadow = 1;
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-20 10:58     ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 10:58 UTC (permalink / raw)
  To: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA
  Cc: kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg

We move dirty bitmaps to user space.

 - Allocation and destruction: we use do_mmap() and do_munmap().
   The new bitmap space is twice longer than the original one and we
   use the additional space for double buffering: this makes it
   possible to update the active bitmap while letting the user space
   read the other one safely.

 - Bitmap manipulations: we replace all functions which access dirty
   bitmaps to *_user() functions. Note that some of these should be
   optimized later.

 - For ia64: moving the dirty bitmaps of memory slots does not effect
   much to ia64 because it's using a different space to store bitmaps
   which is directly updated: all we have to change are sync and get
   of dirty log, so we don't need set_bit_user like function for ia64.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
 arch/ia64/kvm/kvm-ia64.c  |   12 ++++-
 arch/powerpc/kvm/book3s.c |    2 +-
 arch/x86/kvm/x86.c        |   24 +++++-----
 include/linux/kvm_host.h  |    5 +-
 virt/kvm/kvm_main.c       |  101 ++++++++++++++++++++++++++++++++++++++++-----
 5 files changed, 116 insertions(+), 28 deletions(-)

diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index d60dafe..c3f0b70 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -1823,11 +1823,19 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
 	n = kvm_dirty_bitmap_bytes(memslot);
 	base = memslot->base_gfn / BITS_PER_LONG;
 
+	r = -EFAULT;
+	if (!access_ok(VERIFY_WRITE, memslot->dirty_bitmap, n))
+		goto out;
+
 	for (i = 0; i < n/sizeof(long); ++i) {
 		if (dirty_bitmap[base + i])
 			memslot->is_dirty = true;
 
-		memslot->dirty_bitmap[i] = dirty_bitmap[base + i];
+		if (__put_user(dirty_bitmap[base + i],
+			       &memslot->dirty_bitmap[i])) {
+			r = -EFAULT;
+			goto out;
+		}
 		dirty_bitmap[base + i] = 0;
 	}
 	r = 0;
@@ -1858,7 +1866,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	if (memslot->is_dirty) {
 		kvm_flush_remote_tlbs(kvm);
 		n = kvm_dirty_bitmap_bytes(memslot);
-		memset(memslot->dirty_bitmap, 0, n);
+		clear_user(memslot->dirty_bitmap, n);
 		memslot->is_dirty = false;
 	}
 	r = 0;
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 53b45cf..b074e19 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -1137,7 +1137,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 			kvmppc_mmu_pte_pflush(vcpu, ga, ga_end);
 
 		n = kvm_dirty_bitmap_bytes(memslot);
-		memset(memslot->dirty_bitmap, 0, n);
+		clear_user(memslot->dirty_bitmap, n);
 		memslot->is_dirty = false;
 	}
 
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 6f0b706..ad55353 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2727,7 +2727,8 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	int r;
 	struct kvm_memory_slot *memslot;
 	unsigned long n;
-	unsigned long *dirty_bitmap = NULL;
+	unsigned long __user *dirty_bitmap;
+	unsigned long __user *dirty_bitmap_old;
 
 	mutex_lock(&kvm->slots_lock);
 
@@ -2742,11 +2743,9 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 
 	n = kvm_dirty_bitmap_bytes(memslot);
 
-	r = -ENOMEM;
-	dirty_bitmap = vmalloc(n);
-	if (!dirty_bitmap)
-		goto out;
-	memset(dirty_bitmap, 0, n);
+	dirty_bitmap = memslot->dirty_bitmap;
+	dirty_bitmap_old = memslot->dirty_bitmap_old;
+	clear_user(dirty_bitmap_old, n);
 
 	/* If nothing is dirty, don't bother messing with page tables. */
 	if (memslot->is_dirty) {
@@ -2756,24 +2755,25 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 		kvm_mmu_slot_remove_write_access(kvm, log->slot);
 		spin_unlock(&kvm->mmu_lock);
 
+		r = -ENOMEM;
 		slots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
 		if (!slots)
-			goto out_free;
+			goto out;
 
 		memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
-		slots->memslots[log->slot].dirty_bitmap = dirty_bitmap;
+		slots->memslots[log->slot].dirty_bitmap = dirty_bitmap_old;
+		slots->memslots[log->slot].dirty_bitmap_old = dirty_bitmap;
 		slots->memslots[log->slot].is_dirty = false;
 
 		old_slots = kvm->memslots;
 		rcu_assign_pointer(kvm->memslots, slots);
 		synchronize_srcu_expedited(&kvm->srcu);
-		dirty_bitmap = old_slots->memslots[log->slot].dirty_bitmap;
 		kfree(old_slots);
+
+		dirty_bitmap_old = dirty_bitmap;
 	}
 
-	r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap, n);
-out_free:
-	vfree(dirty_bitmap);
+	r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap_old, n);
 out:
 	mutex_unlock(&kvm->slots_lock);
 	return r;
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 42b7161..d4d217a 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -116,7 +116,8 @@ struct kvm_memory_slot {
 	unsigned long npages;
 	unsigned long flags;
 	unsigned long *rmap;
-	unsigned long *dirty_bitmap;
+	unsigned long __user *dirty_bitmap;
+	unsigned long __user *dirty_bitmap_old;
 	bool is_dirty;
 	struct {
 		unsigned long rmap_pde;
@@ -331,7 +332,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 int kvm_dev_ioctl_check_extension(long ext);
 
 int kvm_copy_dirty_bitmap(unsigned long __user *to,
-			  const unsigned long *from,
+			  const unsigned long __user *from,
 			  unsigned long bytes);
 int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 66c4daf..9323639 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -433,8 +433,20 @@ out_err_nodisable:
 
 static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot)
 {
-	vfree(memslot->dirty_bitmap);
+	unsigned long user_addr;
+	unsigned long n = kvm_dirty_bitmap_bytes(memslot);
+
+	if (!memslot->dirty_bitmap)
+		return;
+
+	user_addr = min((unsigned long)memslot->dirty_bitmap,
+			(unsigned long)memslot->dirty_bitmap_old);
+	down_write(&current->mm->mmap_sem);
+	do_munmap(current->mm, user_addr, 2 * n);
+	up_write(&current->mm->mmap_sem);
+
 	memslot->dirty_bitmap = NULL;
+	memslot->dirty_bitmap_old = NULL;
 }
 
 /*
@@ -468,8 +480,12 @@ void kvm_free_physmem(struct kvm *kvm)
 	int i;
 	struct kvm_memslots *slots = kvm->memslots;
 
-	for (i = 0; i < slots->nmemslots; ++i)
+	for (i = 0; i < slots->nmemslots; ++i) {
+		/* We don't munmap dirty bitmaps by ourselves. */
+		slots->memslots[i].dirty_bitmap = NULL;
+		slots->memslots[i].dirty_bitmap_old = NULL;
 		kvm_free_physmem_slot(&slots->memslots[i], NULL);
+	}
 
 	kfree(kvm->memslots);
 }
@@ -523,13 +539,22 @@ static int kvm_vm_release(struct inode *inode, struct file *filp)
 
 static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot)
 {
-	unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(memslot);
+	unsigned long user_addr;
+	unsigned long n = kvm_dirty_bitmap_bytes(memslot);
 
-	memslot->dirty_bitmap = vmalloc(dirty_bytes);
-	if (!memslot->dirty_bitmap)
-		return -ENOMEM;
+	down_write(&current->mm->mmap_sem);
+	user_addr = do_mmap(NULL, 0, 2 * n,
+			    PROT_READ | PROT_WRITE,
+			    MAP_PRIVATE | MAP_ANONYMOUS, 0);
+	up_write(&current->mm->mmap_sem);
+
+	if (IS_ERR((void *)user_addr))
+		return PTR_ERR((void *)user_addr);
+
+	memslot->dirty_bitmap = (unsigned long __user *)user_addr;
+	memslot->dirty_bitmap_old = (unsigned long __user *)(user_addr + n);
+	clear_user(memslot->dirty_bitmap, 2 * n);
 
-	memset(memslot->dirty_bitmap, 0, dirty_bytes);
 	return 0;
 }
 
@@ -778,13 +803,45 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
 }
 
 int kvm_copy_dirty_bitmap(unsigned long __user *to,
-			  const unsigned long *from,
+			  const unsigned long __user *from,
 			  unsigned long bytes)
 {
-	if (copy_to_user(to, from, bytes))
+#if defined(CONFIG_X86_64) || defined(CONFIG_PPC64) || defined(CONFIG_IA64)
+	if (copy_in_user(to, from, bytes)) {
+		printk(KERN_WARNING "%s: copy_in_user failed.\n", __func__);
 		return -EFAULT;
+	}
+	return 0;
+#else
+	int num, bufbytes;
+	unsigned long buf[32];
 
+	if (!access_ok(VERIFY_READ, from, bytes) ||
+	    !access_ok(VERIFY_WRITE, to, bytes)) {
+		goto out_fault;
+	}
+
+	bufbytes = sizeof(buf);
+	num = bufbytes / sizeof(buf[0]);
+
+	for (; bytes > bufbytes; bytes -= bufbytes, to += num, from += num) {
+		if (__copy_from_user(buf, from, bufbytes))
+			goto out_fault;
+		if (__copy_to_user(to, buf, bufbytes))
+			goto out_fault;
+	}
+	if (bytes > 0) {
+		if (__copy_from_user(buf, from, bytes))
+			goto out_fault;
+		if (__copy_to_user(to, buf, bytes))
+			goto out_fault;
+	}
 	return 0;
+
+out_fault:
+	printk(KERN_WARNING "%s: copy to(from) user failed.\n", __func__);
+	return -EFAULT;
+#endif
 }
 
 int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
@@ -1194,13 +1251,35 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
 }
 EXPORT_SYMBOL_GPL(kvm_clear_guest);
 
+/*
+ * Please use generic *_user bitops once they become available.
+ * Be careful setting the bit won't be done atomically.
+ */
 static int __mark_page_dirty(unsigned long nr,
-			     unsigned long *dirty_bitmap)
+			     unsigned long __user *dirty_bitmap)
 {
+	unsigned long user_addr;
+	u8 val;
+
 #ifdef __BIG_ENDIAN
 	nr = nr ^ BITOP_LE_SWIZZLE;
 #endif
-	__set_bit(nr, dirty_bitmap);
+	user_addr = (unsigned long)dirty_bitmap + nr / 8;
+	if (!access_ok(VERIFY_WRITE, user_addr, 1))
+		goto out_fault;
+
+	if (__get_user(val, (u8 __user *)user_addr))
+		goto out_fault;
+
+	val |= 1U << (nr % 8);
+	if (__put_user(val, (u8 __user *)user_addr))
+		goto out_fault;
+
+	return 0;
+
+out_fault:
+	printk(KERN_WARNING "%s: setting user bit failed.\n", __func__);
+	return -EFAULT;
 }
 
 void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-20 10:58     ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 10:58 UTC (permalink / raw)
  To: kvm-ia64

We move dirty bitmaps to user space.

 - Allocation and destruction: we use do_mmap() and do_munmap().
   The new bitmap space is twice longer than the original one and we
   use the additional space for double buffering: this makes it
   possible to update the active bitmap while letting the user space
   read the other one safely.

 - Bitmap manipulations: we replace all functions which access dirty
   bitmaps to *_user() functions. Note that some of these should be
   optimized later.

 - For ia64: moving the dirty bitmaps of memory slots does not effect
   much to ia64 because it's using a different space to store bitmaps
   which is directly updated: all we have to change are sync and get
   of dirty log, so we don't need set_bit_user like function for ia64.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
 arch/ia64/kvm/kvm-ia64.c  |   12 ++++-
 arch/powerpc/kvm/book3s.c |    2 +-
 arch/x86/kvm/x86.c        |   24 +++++-----
 include/linux/kvm_host.h  |    5 +-
 virt/kvm/kvm_main.c       |  101 ++++++++++++++++++++++++++++++++++++++++-----
 5 files changed, 116 insertions(+), 28 deletions(-)

diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index d60dafe..c3f0b70 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -1823,11 +1823,19 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
 	n = kvm_dirty_bitmap_bytes(memslot);
 	base = memslot->base_gfn / BITS_PER_LONG;
 
+	r = -EFAULT;
+	if (!access_ok(VERIFY_WRITE, memslot->dirty_bitmap, n))
+		goto out;
+
 	for (i = 0; i < n/sizeof(long); ++i) {
 		if (dirty_bitmap[base + i])
 			memslot->is_dirty = true;
 
-		memslot->dirty_bitmap[i] = dirty_bitmap[base + i];
+		if (__put_user(dirty_bitmap[base + i],
+			       &memslot->dirty_bitmap[i])) {
+			r = -EFAULT;
+			goto out;
+		}
 		dirty_bitmap[base + i] = 0;
 	}
 	r = 0;
@@ -1858,7 +1866,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	if (memslot->is_dirty) {
 		kvm_flush_remote_tlbs(kvm);
 		n = kvm_dirty_bitmap_bytes(memslot);
-		memset(memslot->dirty_bitmap, 0, n);
+		clear_user(memslot->dirty_bitmap, n);
 		memslot->is_dirty = false;
 	}
 	r = 0;
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 53b45cf..b074e19 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -1137,7 +1137,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 			kvmppc_mmu_pte_pflush(vcpu, ga, ga_end);
 
 		n = kvm_dirty_bitmap_bytes(memslot);
-		memset(memslot->dirty_bitmap, 0, n);
+		clear_user(memslot->dirty_bitmap, n);
 		memslot->is_dirty = false;
 	}
 
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 6f0b706..ad55353 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2727,7 +2727,8 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	int r;
 	struct kvm_memory_slot *memslot;
 	unsigned long n;
-	unsigned long *dirty_bitmap = NULL;
+	unsigned long __user *dirty_bitmap;
+	unsigned long __user *dirty_bitmap_old;
 
 	mutex_lock(&kvm->slots_lock);
 
@@ -2742,11 +2743,9 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 
 	n = kvm_dirty_bitmap_bytes(memslot);
 
-	r = -ENOMEM;
-	dirty_bitmap = vmalloc(n);
-	if (!dirty_bitmap)
-		goto out;
-	memset(dirty_bitmap, 0, n);
+	dirty_bitmap = memslot->dirty_bitmap;
+	dirty_bitmap_old = memslot->dirty_bitmap_old;
+	clear_user(dirty_bitmap_old, n);
 
 	/* If nothing is dirty, don't bother messing with page tables. */
 	if (memslot->is_dirty) {
@@ -2756,24 +2755,25 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 		kvm_mmu_slot_remove_write_access(kvm, log->slot);
 		spin_unlock(&kvm->mmu_lock);
 
+		r = -ENOMEM;
 		slots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
 		if (!slots)
-			goto out_free;
+			goto out;
 
 		memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
-		slots->memslots[log->slot].dirty_bitmap = dirty_bitmap;
+		slots->memslots[log->slot].dirty_bitmap = dirty_bitmap_old;
+		slots->memslots[log->slot].dirty_bitmap_old = dirty_bitmap;
 		slots->memslots[log->slot].is_dirty = false;
 
 		old_slots = kvm->memslots;
 		rcu_assign_pointer(kvm->memslots, slots);
 		synchronize_srcu_expedited(&kvm->srcu);
-		dirty_bitmap = old_slots->memslots[log->slot].dirty_bitmap;
 		kfree(old_slots);
+
+		dirty_bitmap_old = dirty_bitmap;
 	}
 
-	r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap, n);
-out_free:
-	vfree(dirty_bitmap);
+	r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap_old, n);
 out:
 	mutex_unlock(&kvm->slots_lock);
 	return r;
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 42b7161..d4d217a 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -116,7 +116,8 @@ struct kvm_memory_slot {
 	unsigned long npages;
 	unsigned long flags;
 	unsigned long *rmap;
-	unsigned long *dirty_bitmap;
+	unsigned long __user *dirty_bitmap;
+	unsigned long __user *dirty_bitmap_old;
 	bool is_dirty;
 	struct {
 		unsigned long rmap_pde;
@@ -331,7 +332,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 int kvm_dev_ioctl_check_extension(long ext);
 
 int kvm_copy_dirty_bitmap(unsigned long __user *to,
-			  const unsigned long *from,
+			  const unsigned long __user *from,
 			  unsigned long bytes);
 int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 66c4daf..9323639 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -433,8 +433,20 @@ out_err_nodisable:
 
 static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot)
 {
-	vfree(memslot->dirty_bitmap);
+	unsigned long user_addr;
+	unsigned long n = kvm_dirty_bitmap_bytes(memslot);
+
+	if (!memslot->dirty_bitmap)
+		return;
+
+	user_addr = min((unsigned long)memslot->dirty_bitmap,
+			(unsigned long)memslot->dirty_bitmap_old);
+	down_write(&current->mm->mmap_sem);
+	do_munmap(current->mm, user_addr, 2 * n);
+	up_write(&current->mm->mmap_sem);
+
 	memslot->dirty_bitmap = NULL;
+	memslot->dirty_bitmap_old = NULL;
 }
 
 /*
@@ -468,8 +480,12 @@ void kvm_free_physmem(struct kvm *kvm)
 	int i;
 	struct kvm_memslots *slots = kvm->memslots;
 
-	for (i = 0; i < slots->nmemslots; ++i)
+	for (i = 0; i < slots->nmemslots; ++i) {
+		/* We don't munmap dirty bitmaps by ourselves. */
+		slots->memslots[i].dirty_bitmap = NULL;
+		slots->memslots[i].dirty_bitmap_old = NULL;
 		kvm_free_physmem_slot(&slots->memslots[i], NULL);
+	}
 
 	kfree(kvm->memslots);
 }
@@ -523,13 +539,22 @@ static int kvm_vm_release(struct inode *inode, struct file *filp)
 
 static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot)
 {
-	unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(memslot);
+	unsigned long user_addr;
+	unsigned long n = kvm_dirty_bitmap_bytes(memslot);
 
-	memslot->dirty_bitmap = vmalloc(dirty_bytes);
-	if (!memslot->dirty_bitmap)
-		return -ENOMEM;
+	down_write(&current->mm->mmap_sem);
+	user_addr = do_mmap(NULL, 0, 2 * n,
+			    PROT_READ | PROT_WRITE,
+			    MAP_PRIVATE | MAP_ANONYMOUS, 0);
+	up_write(&current->mm->mmap_sem);
+
+	if (IS_ERR((void *)user_addr))
+		return PTR_ERR((void *)user_addr);
+
+	memslot->dirty_bitmap = (unsigned long __user *)user_addr;
+	memslot->dirty_bitmap_old = (unsigned long __user *)(user_addr + n);
+	clear_user(memslot->dirty_bitmap, 2 * n);
 
-	memset(memslot->dirty_bitmap, 0, dirty_bytes);
 	return 0;
 }
 
@@ -778,13 +803,45 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
 }
 
 int kvm_copy_dirty_bitmap(unsigned long __user *to,
-			  const unsigned long *from,
+			  const unsigned long __user *from,
 			  unsigned long bytes)
 {
-	if (copy_to_user(to, from, bytes))
+#if defined(CONFIG_X86_64) || defined(CONFIG_PPC64) || defined(CONFIG_IA64)
+	if (copy_in_user(to, from, bytes)) {
+		printk(KERN_WARNING "%s: copy_in_user failed.\n", __func__);
 		return -EFAULT;
+	}
+	return 0;
+#else
+	int num, bufbytes;
+	unsigned long buf[32];
 
+	if (!access_ok(VERIFY_READ, from, bytes) ||
+	    !access_ok(VERIFY_WRITE, to, bytes)) {
+		goto out_fault;
+	}
+
+	bufbytes = sizeof(buf);
+	num = bufbytes / sizeof(buf[0]);
+
+	for (; bytes > bufbytes; bytes -= bufbytes, to += num, from += num) {
+		if (__copy_from_user(buf, from, bufbytes))
+			goto out_fault;
+		if (__copy_to_user(to, buf, bufbytes))
+			goto out_fault;
+	}
+	if (bytes > 0) {
+		if (__copy_from_user(buf, from, bytes))
+			goto out_fault;
+		if (__copy_to_user(to, buf, bytes))
+			goto out_fault;
+	}
 	return 0;
+
+out_fault:
+	printk(KERN_WARNING "%s: copy to(from) user failed.\n", __func__);
+	return -EFAULT;
+#endif
 }
 
 int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
@@ -1194,13 +1251,35 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
 }
 EXPORT_SYMBOL_GPL(kvm_clear_guest);
 
+/*
+ * Please use generic *_user bitops once they become available.
+ * Be careful setting the bit won't be done atomically.
+ */
 static int __mark_page_dirty(unsigned long nr,
-			     unsigned long *dirty_bitmap)
+			     unsigned long __user *dirty_bitmap)
 {
+	unsigned long user_addr;
+	u8 val;
+
 #ifdef __BIG_ENDIAN
 	nr = nr ^ BITOP_LE_SWIZZLE;
 #endif
-	__set_bit(nr, dirty_bitmap);
+	user_addr = (unsigned long)dirty_bitmap + nr / 8;
+	if (!access_ok(VERIFY_WRITE, user_addr, 1))
+		goto out_fault;
+
+	if (__get_user(val, (u8 __user *)user_addr))
+		goto out_fault;
+
+	val |= 1U << (nr % 8);
+	if (__put_user(val, (u8 __user *)user_addr))
+		goto out_fault;
+
+	return 0;
+
+out_fault:
+	printk(KERN_WARNING "%s: setting user bit failed.\n", __func__);
+	return -EFAULT;
 }
 
 void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy dirty bitmaps to user space
       [not found] ` <20100420195349.dab60b1d.yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
  2010-04-20 10:58     ` Takuya Yoshikawa
@ 2010-04-20 10:59     ` Takuya Yoshikawa
  2010-04-20 11:03     ` Takuya Yoshikawa
  2010-04-20 12:05     ` Takuya Yoshikawa
  3 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 10:59 UTC (permalink / raw)
  To: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA
  Cc: kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg

We will replace copy_to_user() to copy_in_user() when we move
the dirty bitmaps to user space.

But sadly, we have copy_in_user() only for 64 bits architectures.
So this function should work as a wrapper to hide ifdefs from outside.
Once we get copy_in_user() for 32 bits architectures, we can remove
this wrapper and use copy_in_user() directly.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
Signed-off-by: Fernando Luis Vazquez Cao <fernando-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
---
 arch/x86/kvm/x86.c       |    4 +---
 include/linux/kvm_host.h |    3 +++
 virt/kvm/kvm_main.c      |   12 +++++++++++-
 3 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 76b23ed..6f0b706 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2771,9 +2771,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 		kfree(old_slots);
 	}
 
-	r = 0;
-	if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n))
-		r = -EFAULT;
+	r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap, n);
 out_free:
 	vfree(dirty_bitmap);
 out:
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 4446622..42b7161 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -330,6 +330,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 
 int kvm_dev_ioctl_check_extension(long ext);
 
+int kvm_copy_dirty_bitmap(unsigned long __user *to,
+			  const unsigned long *from,
+			  unsigned long bytes);
 int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 				struct kvm_dirty_log *log);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 40a6888..6908304 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -777,6 +777,16 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
 	return kvm_set_memory_region(kvm, mem, user_alloc);
 }
 
+int kvm_copy_dirty_bitmap(unsigned long __user *to,
+			  const unsigned long *from,
+			  unsigned long bytes)
+{
+	if (copy_to_user(to, from, bytes))
+		return -EFAULT;
+
+	return 0;
+}
+
 int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
 {
 	struct kvm_memory_slot *memslot;
@@ -795,7 +805,7 @@ int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
 	n = kvm_dirty_bitmap_bytes(memslot);
 
 	r = -EFAULT;
-	if (copy_to_user(log->dirty_bitmap, memslot->dirty_bitmap, n))
+	if (kvm_copy_dirty_bitmap(log->dirty_bitmap, memslot->dirty_bitmap, n))
 		goto out;
 
 	r = 0;
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy dirty
@ 2010-04-20 10:59     ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 10:59 UTC (permalink / raw)
  To: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA
  Cc: kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg

We will replace copy_to_user() to copy_in_user() when we move
the dirty bitmaps to user space.

But sadly, we have copy_in_user() only for 64 bits architectures.
So this function should work as a wrapper to hide ifdefs from outside.
Once we get copy_in_user() for 32 bits architectures, we can remove
this wrapper and use copy_in_user() directly.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
 arch/x86/kvm/x86.c       |    4 +---
 include/linux/kvm_host.h |    3 +++
 virt/kvm/kvm_main.c      |   12 +++++++++++-
 3 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 76b23ed..6f0b706 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2771,9 +2771,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 		kfree(old_slots);
 	}
 
-	r = 0;
-	if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n))
-		r = -EFAULT;
+	r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap, n);
 out_free:
 	vfree(dirty_bitmap);
 out:
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 4446622..42b7161 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -330,6 +330,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 
 int kvm_dev_ioctl_check_extension(long ext);
 
+int kvm_copy_dirty_bitmap(unsigned long __user *to,
+			  const unsigned long *from,
+			  unsigned long bytes);
 int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 				struct kvm_dirty_log *log);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 40a6888..6908304 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -777,6 +777,16 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
 	return kvm_set_memory_region(kvm, mem, user_alloc);
 }
 
+int kvm_copy_dirty_bitmap(unsigned long __user *to,
+			  const unsigned long *from,
+			  unsigned long bytes)
+{
+	if (copy_to_user(to, from, bytes))
+		return -EFAULT;
+
+	return 0;
+}
+
 int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
 {
 	struct kvm_memory_slot *memslot;
@@ -795,7 +805,7 @@ int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
 	n = kvm_dirty_bitmap_bytes(memslot);
 
 	r = -EFAULT;
-	if (copy_to_user(log->dirty_bitmap, memslot->dirty_bitmap, n))
+	if (kvm_copy_dirty_bitmap(log->dirty_bitmap, memslot->dirty_bitmap, n))
 		goto out;
 
 	r = 0;
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy dirty
@ 2010-04-20 10:59     ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 10:59 UTC (permalink / raw)
  To: kvm-ia64

We will replace copy_to_user() to copy_in_user() when we move
the dirty bitmaps to user space.

But sadly, we have copy_in_user() only for 64 bits architectures.
So this function should work as a wrapper to hide ifdefs from outside.
Once we get copy_in_user() for 32 bits architectures, we can remove
this wrapper and use copy_in_user() directly.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
 arch/x86/kvm/x86.c       |    4 +---
 include/linux/kvm_host.h |    3 +++
 virt/kvm/kvm_main.c      |   12 +++++++++++-
 3 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 76b23ed..6f0b706 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2771,9 +2771,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 		kfree(old_slots);
 	}
 
-	r = 0;
-	if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n))
-		r = -EFAULT;
+	r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap, n);
 out_free:
 	vfree(dirty_bitmap);
 out:
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 4446622..42b7161 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -330,6 +330,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 
 int kvm_dev_ioctl_check_extension(long ext);
 
+int kvm_copy_dirty_bitmap(unsigned long __user *to,
+			  const unsigned long *from,
+			  unsigned long bytes);
 int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 				struct kvm_dirty_log *log);
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 40a6888..6908304 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -777,6 +777,16 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
 	return kvm_set_memory_region(kvm, mem, user_alloc);
 }
 
+int kvm_copy_dirty_bitmap(unsigned long __user *to,
+			  const unsigned long *from,
+			  unsigned long bytes)
+{
+	if (copy_to_user(to, from, bytes))
+		return -EFAULT;
+
+	return 0;
+}
+
 int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
 {
 	struct kvm_memory_slot *memslot;
@@ -795,7 +805,7 @@ int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
 	n = kvm_dirty_bitmap_bytes(memslot);
 
 	r = -EFAULT;
-	if (copy_to_user(log->dirty_bitmap, memslot->dirty_bitmap, n))
+	if (kvm_copy_dirty_bitmap(log->dirty_bitmap, memslot->dirty_bitmap, n))
 		goto out;
 
 	r = 0;
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian issues explicitly
@ 2010-04-20 10:57   ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:00 UTC (permalink / raw)
  To: avi, mtosatti; +Cc: kvm, kvm-ia64, kvm-ppc, fernando

We are now using generic___set_le_bit() to make dirty bitmaps le.
Though this works well, we have to replace __set_bit() to appropriate
uaccess function to move dirty bitmaps to user space. So this patch
splits generic___set_le_bit() and prepares for that.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
 virt/kvm/kvm_main.c |   16 +++++++++++-----
 1 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 6908304..66c4daf 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1194,6 +1194,15 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
 }
 EXPORT_SYMBOL_GPL(kvm_clear_guest);
 
+static int __mark_page_dirty(unsigned long nr,
+			     unsigned long *dirty_bitmap)
+{
+#ifdef __BIG_ENDIAN
+	nr = nr ^ BITOP_LE_SWIZZLE;
+#endif
+	__set_bit(nr, dirty_bitmap);
+}
+
 void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
 {
 	struct kvm_memory_slot *memslot;
@@ -1203,11 +1212,8 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
 	if (memslot && memslot->dirty_bitmap) {
 		unsigned long rel_gfn = gfn - memslot->base_gfn;
 
-		/* avoid RMW */
-		if (!generic_test_le_bit(rel_gfn, memslot->dirty_bitmap)) {
-			generic___set_le_bit(rel_gfn, memslot->dirty_bitmap);
-			memslot->is_dirty = true;
-		}
+		__mark_page_dirty(rel_gfn, memslot->dirty_bitmap);
+		memslot->is_dirty = true;
 	}
 }
 
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian issues explicitly
       [not found]   ` <20100420200043.956302db.yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
  2010-04-20 11:00       ` Alexander Graf
@ 2010-04-20 11:00       ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-20 11:00 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA,
	kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg


On 20.04.2010, at 13:00, Takuya Yoshikawa wrote:

> We are now using generic___set_le_bit() to make dirty bitmaps le.
> Though this works well, we have to replace __set_bit() to appropriate
> uaccess function to move dirty bitmaps to user space. So this patch
> splits generic___set_le_bit() and prepares for that.
> 
> Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
> Signed-off-by: Fernando Luis Vazquez Cao <fernando-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
> ---
> virt/kvm/kvm_main.c |   16 +++++++++++-----
> 1 files changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 6908304..66c4daf 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -1194,6 +1194,15 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
> }
> EXPORT_SYMBOL_GPL(kvm_clear_guest);
> 
> +static int __mark_page_dirty(unsigned long nr,
> +			     unsigned long *dirty_bitmap)
> +{
> +#ifdef __BIG_ENDIAN
> +	nr = nr ^ BITOP_LE_SWIZZLE;

Why an XOR here?

Also is this LE set_bit new? I didn't see it when I did the patch back then :).


Alex

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian issues explicitly
@ 2010-04-20 11:00       ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-20 11:00 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA,
	kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg


On 20.04.2010, at 13:00, Takuya Yoshikawa wrote:

> We are now using generic___set_le_bit() to make dirty bitmaps le.
> Though this works well, we have to replace __set_bit() to appropriate
> uaccess function to move dirty bitmaps to user space. So this patch
> splits generic___set_le_bit() and prepares for that.
> 
> Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
> Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
> ---
> virt/kvm/kvm_main.c |   16 +++++++++++-----
> 1 files changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 6908304..66c4daf 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -1194,6 +1194,15 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
> }
> EXPORT_SYMBOL_GPL(kvm_clear_guest);
> 
> +static int __mark_page_dirty(unsigned long nr,
> +			     unsigned long *dirty_bitmap)
> +{
> +#ifdef __BIG_ENDIAN
> +	nr = nr ^ BITOP_LE_SWIZZLE;

Why an XOR here?

Also is this LE set_bit new? I didn't see it when I did the patch back then :).


Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian issues explicitly
@ 2010-04-20 11:00       ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-20 11:00 UTC (permalink / raw)
  To: kvm-ia64


On 20.04.2010, at 13:00, Takuya Yoshikawa wrote:

> We are now using generic___set_le_bit() to make dirty bitmaps le.
> Though this works well, we have to replace __set_bit() to appropriate
> uaccess function to move dirty bitmaps to user space. So this patch
> splits generic___set_le_bit() and prepares for that.
> 
> Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
> Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
> ---
> virt/kvm/kvm_main.c |   16 +++++++++++-----
> 1 files changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 6908304..66c4daf 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -1194,6 +1194,15 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
> }
> EXPORT_SYMBOL_GPL(kvm_clear_guest);
> 
> +static int __mark_page_dirty(unsigned long nr,
> +			     unsigned long *dirty_bitmap)
> +{
> +#ifdef __BIG_ENDIAN
> +	nr = nr ^ BITOP_LE_SWIZZLE;

Why an XOR here?

Also is this LE set_bit new? I didn't see it when I did the patch back then :).


Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-20 10:58     ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:02 UTC (permalink / raw)
  To: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA
  Cc: kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg

We move dirty bitmaps to user space.

 - Allocation and destruction: we use do_mmap() and do_munmap().
   The new bitmap space is twice longer than the original one and we
   use the additional space for double buffering: this makes it
   possible to update the active bitmap while letting the user space
   read the other one safely.

 - Bitmap manipulations: we replace all functions which access dirty
   bitmaps to *_user() functions. Note that some of these should be
   optimized later.

 - For ia64: moving the dirty bitmaps of memory slots does not effect
   much to ia64 because it's using a different space to store bitmaps
   which is directly updated: all we have to change are sync and get
   of dirty log, so we don't need set_bit_user like function for ia64.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
Signed-off-by: Fernando Luis Vazquez Cao <fernando-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
---
 arch/ia64/kvm/kvm-ia64.c  |   12 ++++-
 arch/powerpc/kvm/book3s.c |    2 +-
 arch/x86/kvm/x86.c        |   24 +++++-----
 include/linux/kvm_host.h  |    5 +-
 virt/kvm/kvm_main.c       |  101 ++++++++++++++++++++++++++++++++++++++++-----
 5 files changed, 116 insertions(+), 28 deletions(-)

diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index d60dafe..c3f0b70 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -1823,11 +1823,19 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
 	n = kvm_dirty_bitmap_bytes(memslot);
 	base = memslot->base_gfn / BITS_PER_LONG;
 
+	r = -EFAULT;
+	if (!access_ok(VERIFY_WRITE, memslot->dirty_bitmap, n))
+		goto out;
+
 	for (i = 0; i < n/sizeof(long); ++i) {
 		if (dirty_bitmap[base + i])
 			memslot->is_dirty = true;
 
-		memslot->dirty_bitmap[i] = dirty_bitmap[base + i];
+		if (__put_user(dirty_bitmap[base + i],
+			       &memslot->dirty_bitmap[i])) {
+			r = -EFAULT;
+			goto out;
+		}
 		dirty_bitmap[base + i] = 0;
 	}
 	r = 0;
@@ -1858,7 +1866,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	if (memslot->is_dirty) {
 		kvm_flush_remote_tlbs(kvm);
 		n = kvm_dirty_bitmap_bytes(memslot);
-		memset(memslot->dirty_bitmap, 0, n);
+		clear_user(memslot->dirty_bitmap, n);
 		memslot->is_dirty = false;
 	}
 	r = 0;
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 53b45cf..b074e19 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -1137,7 +1137,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 			kvmppc_mmu_pte_pflush(vcpu, ga, ga_end);
 
 		n = kvm_dirty_bitmap_bytes(memslot);
-		memset(memslot->dirty_bitmap, 0, n);
+		clear_user(memslot->dirty_bitmap, n);
 		memslot->is_dirty = false;
 	}
 
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 6f0b706..ad55353 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2727,7 +2727,8 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	int r;
 	struct kvm_memory_slot *memslot;
 	unsigned long n;
-	unsigned long *dirty_bitmap = NULL;
+	unsigned long __user *dirty_bitmap;
+	unsigned long __user *dirty_bitmap_old;
 
 	mutex_lock(&kvm->slots_lock);
 
@@ -2742,11 +2743,9 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 
 	n = kvm_dirty_bitmap_bytes(memslot);
 
-	r = -ENOMEM;
-	dirty_bitmap = vmalloc(n);
-	if (!dirty_bitmap)
-		goto out;
-	memset(dirty_bitmap, 0, n);
+	dirty_bitmap = memslot->dirty_bitmap;
+	dirty_bitmap_old = memslot->dirty_bitmap_old;
+	clear_user(dirty_bitmap_old, n);
 
 	/* If nothing is dirty, don't bother messing with page tables. */
 	if (memslot->is_dirty) {
@@ -2756,24 +2755,25 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 		kvm_mmu_slot_remove_write_access(kvm, log->slot);
 		spin_unlock(&kvm->mmu_lock);
 
+		r = -ENOMEM;
 		slots = kzalloc(sizeof(struct kvm_memslots), GFP_KERNEL);
 		if (!slots)
-			goto out_free;
+			goto out;
 
 		memcpy(slots, kvm->memslots, sizeof(struct kvm_memslots));
-		slots->memslots[log->slot].dirty_bitmap = dirty_bitmap;
+		slots->memslots[log->slot].dirty_bitmap = dirty_bitmap_old;
+		slots->memslots[log->slot].dirty_bitmap_old = dirty_bitmap;
 		slots->memslots[log->slot].is_dirty = false;
 
 		old_slots = kvm->memslots;
 		rcu_assign_pointer(kvm->memslots, slots);
 		synchronize_srcu_expedited(&kvm->srcu);
-		dirty_bitmap = old_slots->memslots[log->slot].dirty_bitmap;
 		kfree(old_slots);
+
+		dirty_bitmap_old = dirty_bitmap;
 	}
 
-	r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap, n);
-out_free:
-	vfree(dirty_bitmap);
+	r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap_old, n);
 out:
 	mutex_unlock(&kvm->slots_lock);
 	return r;
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 42b7161..d4d217a 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -116,7 +116,8 @@ struct kvm_memory_slot {
 	unsigned long npages;
 	unsigned long flags;
 	unsigned long *rmap;
-	unsigned long *dirty_bitmap;
+	unsigned long __user *dirty_bitmap;
+	unsigned long __user *dirty_bitmap_old;
 	bool is_dirty;
 	struct {
 		unsigned long rmap_pde;
@@ -331,7 +332,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
 int kvm_dev_ioctl_check_extension(long ext);
 
 int kvm_copy_dirty_bitmap(unsigned long __user *to,
-			  const unsigned long *from,
+			  const unsigned long __user *from,
 			  unsigned long bytes);
 int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
 int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 66c4daf..9323639 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -433,8 +433,20 @@ out_err_nodisable:
 
 static void kvm_destroy_dirty_bitmap(struct kvm_memory_slot *memslot)
 {
-	vfree(memslot->dirty_bitmap);
+	unsigned long user_addr;
+	unsigned long n = kvm_dirty_bitmap_bytes(memslot);
+
+	if (!memslot->dirty_bitmap)
+		return;
+
+	user_addr = min((unsigned long)memslot->dirty_bitmap,
+			(unsigned long)memslot->dirty_bitmap_old);
+	down_write(&current->mm->mmap_sem);
+	do_munmap(current->mm, user_addr, 2 * n);
+	up_write(&current->mm->mmap_sem);
+
 	memslot->dirty_bitmap = NULL;
+	memslot->dirty_bitmap_old = NULL;
 }
 
 /*
@@ -468,8 +480,12 @@ void kvm_free_physmem(struct kvm *kvm)
 	int i;
 	struct kvm_memslots *slots = kvm->memslots;
 
-	for (i = 0; i < slots->nmemslots; ++i)
+	for (i = 0; i < slots->nmemslots; ++i) {
+		/* We don't munmap dirty bitmaps by ourselves. */
+		slots->memslots[i].dirty_bitmap = NULL;
+		slots->memslots[i].dirty_bitmap_old = NULL;
 		kvm_free_physmem_slot(&slots->memslots[i], NULL);
+	}
 
 	kfree(kvm->memslots);
 }
@@ -523,13 +539,22 @@ static int kvm_vm_release(struct inode *inode, struct file *filp)
 
 static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot)
 {
-	unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(memslot);
+	unsigned long user_addr;
+	unsigned long n = kvm_dirty_bitmap_bytes(memslot);
 
-	memslot->dirty_bitmap = vmalloc(dirty_bytes);
-	if (!memslot->dirty_bitmap)
-		return -ENOMEM;
+	down_write(&current->mm->mmap_sem);
+	user_addr = do_mmap(NULL, 0, 2 * n,
+			    PROT_READ | PROT_WRITE,
+			    MAP_PRIVATE | MAP_ANONYMOUS, 0);
+	up_write(&current->mm->mmap_sem);
+
+	if (IS_ERR((void *)user_addr))
+		return PTR_ERR((void *)user_addr);
+
+	memslot->dirty_bitmap = (unsigned long __user *)user_addr;
+	memslot->dirty_bitmap_old = (unsigned long __user *)(user_addr + n);
+	clear_user(memslot->dirty_bitmap, 2 * n);
 
-	memset(memslot->dirty_bitmap, 0, dirty_bytes);
 	return 0;
 }
 
@@ -778,13 +803,45 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
 }
 
 int kvm_copy_dirty_bitmap(unsigned long __user *to,
-			  const unsigned long *from,
+			  const unsigned long __user *from,
 			  unsigned long bytes)
 {
-	if (copy_to_user(to, from, bytes))
+#if defined(CONFIG_X86_64) || defined(CONFIG_PPC64) || defined(CONFIG_IA64)
+	if (copy_in_user(to, from, bytes)) {
+		printk(KERN_WARNING "%s: copy_in_user failed.\n", __func__);
 		return -EFAULT;
+	}
+	return 0;
+#else
+	int num, bufbytes;
+	unsigned long buf[32];
 
+	if (!access_ok(VERIFY_READ, from, bytes) ||
+	    !access_ok(VERIFY_WRITE, to, bytes)) {
+		goto out_fault;
+	}
+
+	bufbytes = sizeof(buf);
+	num = bufbytes / sizeof(buf[0]);
+
+	for (; bytes > bufbytes; bytes -= bufbytes, to += num, from += num) {
+		if (__copy_from_user(buf, from, bufbytes))
+			goto out_fault;
+		if (__copy_to_user(to, buf, bufbytes))
+			goto out_fault;
+	}
+	if (bytes > 0) {
+		if (__copy_from_user(buf, from, bytes))
+			goto out_fault;
+		if (__copy_to_user(to, buf, bytes))
+			goto out_fault;
+	}
 	return 0;
+
+out_fault:
+	printk(KERN_WARNING "%s: copy to(from) user failed.\n", __func__);
+	return -EFAULT;
+#endif
 }
 
 int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
@@ -1194,13 +1251,35 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
 }
 EXPORT_SYMBOL_GPL(kvm_clear_guest);
 
+/*
+ * Please use generic *_user bitops once they become available.
+ * Be careful setting the bit won't be done atomically.
+ */
 static int __mark_page_dirty(unsigned long nr,
-			     unsigned long *dirty_bitmap)
+			     unsigned long __user *dirty_bitmap)
 {
+	unsigned long user_addr;
+	u8 val;
+
 #ifdef __BIG_ENDIAN
 	nr = nr ^ BITOP_LE_SWIZZLE;
 #endif
-	__set_bit(nr, dirty_bitmap);
+	user_addr = (unsigned long)dirty_bitmap + nr / 8;
+	if (!access_ok(VERIFY_WRITE, user_addr, 1))
+		goto out_fault;
+
+	if (__get_user(val, (u8 __user *)user_addr))
+		goto out_fault;
+
+	val |= 1U << (nr % 8);
+	if (__put_user(val, (u8 __user *)user_addr))
+		goto out_fault;
+
+	return 0;
+
+out_fault:
+	printk(KERN_WARNING "%s: setting user bit failed.\n", __func__);
+	return -EFAULT;
 }
 
 void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
       [not found] ` <20100420195349.dab60b1d.yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
  2010-04-20 10:58     ` Takuya Yoshikawa
@ 2010-04-20 11:03     ` Takuya Yoshikawa
  2010-04-20 11:03     ` Takuya Yoshikawa
  2010-04-20 12:05     ` Takuya Yoshikawa
  3 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:03 UTC (permalink / raw)
  To: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA
  Cc: kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg

We can now export the addree of the bitmap created by do_mmap()
to user space. For the sake of this, we introduce a new API:

  KVM_SWITCH_DIRTY_LOG: application can use this to trigger the
  switch of the bitmaps and get the address of the bitmap which
  has been used until now. This reduces the copy of the dirty
  bitmap from the kernel.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
Cc: Fernando Luis Vazquez Cao <fernando-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
---
 Documentation/kvm/api.txt |   23 +++++++++++++++++++++++
 arch/ia64/kvm/kvm-ia64.c  |   19 ++++++++++++++-----
 arch/powerpc/kvm/book3s.c |   19 ++++++++++++++-----
 arch/x86/kvm/x86.c        |   32 ++++++++++++++++++++++++++------
 include/linux/kvm.h       |    6 ++++--
 include/linux/kvm_host.h  |    7 ++++---
 virt/kvm/kvm_main.c       |   41 ++++++++++++++++++++++++++++++++++++-----
 7 files changed, 121 insertions(+), 26 deletions(-)

diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt
index baa8fde..f3d1c2a 100644
--- a/Documentation/kvm/api.txt
+++ b/Documentation/kvm/api.txt
@@ -848,6 +848,29 @@ function properly, this is the place to put them.
        __u8  pad[64];
 };
 
+4.37 KVM_SWITCH_DIRTY_LOG (vm ioctl)
+
+Capability: basic
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_dirty_log (in/out)
+Returns: 0 on success, -1 on error
+
+/* for KVM_SWITCH_DIRTY_LOG */
+struct kvm_dirty_log {
+	__u32 slot;
+	__u32 padding;
+	union {
+		void __user *dirty_bitmap; /* one bit per page */
+		__u64 addr;
+	};
+};
+
+Given a memory slot, return the address of 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.
+
 5. The kvm_run structure
 
 Application code obtains a pointer to the kvm_run structure by
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index c3f0b70..04fbb1c 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -1843,8 +1843,8 @@ out:
 	return r;
 }
 
-int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
-		struct kvm_dirty_log *log)
+static int kvm_ia64_update_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log,
+				     bool need_copy)
 {
 	int r;
 	unsigned long n;
@@ -1857,7 +1857,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	if (r)
 		goto out;
 
-	r = kvm_get_dirty_log(kvm, log);
+	r = kvm_update_dirty_log(kvm, log, need_copy);
 	if (r)
 		goto out;
 
@@ -1865,10 +1865,9 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	/* If nothing is dirty, don't bother messing with page tables. */
 	if (memslot->is_dirty) {
 		kvm_flush_remote_tlbs(kvm);
-		n = kvm_dirty_bitmap_bytes(memslot);
-		clear_user(memslot->dirty_bitmap, n);
 		memslot->is_dirty = false;
 	}
+
 	r = 0;
 out:
 	mutex_unlock(&kvm->slots_lock);
@@ -1876,6 +1875,16 @@ out:
 	return r;
 }
 
+int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+	return kvm_ia64_update_dirty_log(kvm, log, true);
+}
+
+int kvm_vm_ioctl_switch_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+	return kvm_ia64_update_dirty_log(kvm, log, false);
+}
+
 int kvm_arch_hardware_setup(void)
 {
 	return 0;
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index b074e19..d813dca 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -1112,8 +1112,9 @@ 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)
+static int kvmppc_update_dirty_log(struct kvm *kvm,
+				   struct kvm_dirty_log *log,
+				   bool need_copy)
 {
 	struct kvm_memory_slot *memslot;
 	struct kvm_vcpu *vcpu;
@@ -1123,7 +1124,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 
 	mutex_lock(&kvm->slots_lock);
 
-	r = kvm_get_dirty_log(kvm, log);
+	r = kvm_update_dirty_log(kvm, log, need_copy);
 	if (r)
 		goto out;
 
@@ -1136,8 +1137,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 		kvm_for_each_vcpu(n, vcpu, kvm)
 			kvmppc_mmu_pte_pflush(vcpu, ga, ga_end);
 
-		n = kvm_dirty_bitmap_bytes(memslot);
-		clear_user(memslot->dirty_bitmap, n);
 		memslot->is_dirty = false;
 	}
 
@@ -1147,6 +1146,16 @@ out:
 	return r;
 }
 
+int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+	return kvmppc_update_dirty_log(kvm, log, true);
+}
+
+int kvm_vm_ioctl_switch_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+	return kvmppc_update_dirty_log(kvm, log, false);
+}
+
 int kvmppc_core_check_processor_compat(void)
 {
 	return 0;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ad55353..45b728c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2718,11 +2718,9 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
 	return 0;
 }
 
-/*
- * 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)
+static int kvm_x86_update_dirty_log(struct kvm *kvm,
+				    struct kvm_dirty_log *log,
+				    bool need_copy)
 {
 	int r;
 	struct kvm_memory_slot *memslot;
@@ -2773,12 +2771,34 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 		dirty_bitmap_old = dirty_bitmap;
 	}
 
-	r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap_old, n);
+	if (need_copy) {
+		r = kvm_copy_dirty_bitmap(log->dirty_bitmap,
+					  dirty_bitmap_old, n);
+	} else {
+		log->addr = (unsigned long)dirty_bitmap_old;
+		r = 0;
+	}
 out:
 	mutex_unlock(&kvm->slots_lock);
 	return r;
 }
 
+/*
+ * 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)
+{
+	return kvm_x86_update_dirty_log(kvm, log, true);
+}
+
+/*
+ * Switch to the next dirty bitmap and return the address of the old one.
+ */
+int kvm_vm_ioctl_switch_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+	return kvm_x86_update_dirty_log(kvm, log, false);
+}
+
 long kvm_arch_vm_ioctl(struct file *filp,
 		       unsigned int ioctl, unsigned long arg)
 {
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 23ea022..9fa6f1e 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -12,7 +12,7 @@
 #include <linux/ioctl.h>
 #include <asm/kvm.h>
 
-#define KVM_API_VERSION 12
+#define KVM_API_VERSION 13
 
 /* *** Deprecated interfaces *** */
 
@@ -318,7 +318,7 @@ struct kvm_dirty_log {
 	__u32 padding1;
 	union {
 		void __user *dirty_bitmap; /* one bit per page */
-		__u64 padding2;
+		__u64 addr;
 	};
 };
 
@@ -524,6 +524,7 @@ struct kvm_enable_cap {
 #define KVM_CAP_PPC_OSI 52
 #define KVM_CAP_PPC_UNSET_IRQ 53
 #define KVM_CAP_ENABLE_CAP 54
+#define KVM_CAP_USER_DIRTY_BITMAP 55
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -620,6 +621,7 @@ struct kvm_clock_data {
 					struct kvm_userspace_memory_region)
 #define KVM_SET_TSS_ADDR          _IO(KVMIO,   0x47)
 #define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO,  0x48, __u64)
+#define KVM_SWITCH_DIRTY_LOG      _IOW(KVMIO,  0x49, struct kvm_dirty_log)
 /* Device model IOC */
 #define KVM_CREATE_IRQCHIP        _IO(KVMIO,   0x60)
 #define KVM_IRQ_LINE              _IOW(KVMIO,  0x61, struct kvm_irq_level)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index d4d217a..addecee 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -334,9 +334,10 @@ int kvm_dev_ioctl_check_extension(long ext);
 int kvm_copy_dirty_bitmap(unsigned long __user *to,
 			  const unsigned long __user *from,
 			  unsigned long bytes);
-int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
-int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
-				struct kvm_dirty_log *log);
+int kvm_update_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log,
+			 bool need_copy);
+int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
+int kvm_vm_ioctl_switch_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
 
 int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
 				   struct
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 9323639..cba133d 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -844,7 +844,8 @@ out_fault:
 #endif
 }
 
-int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+int kvm_update_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log,
+			 bool need_copy)
 {
 	struct kvm_memory_slot *memslot;
 	int r;
@@ -861,9 +862,23 @@ int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
 
 	n = kvm_dirty_bitmap_bytes(memslot);
 
-	r = -EFAULT;
-	if (kvm_copy_dirty_bitmap(log->dirty_bitmap, memslot->dirty_bitmap, n))
-		goto out;
+	if (need_copy) {
+		r = -EFAULT;
+		if (kvm_copy_dirty_bitmap(log->dirty_bitmap,
+					  memslot->dirty_bitmap, n))
+			goto out;
+
+		if (memslot->is_dirty)
+			clear_user(memslot->dirty_bitmap, n);
+	} else {
+		unsigned long __user *dirty_bitmap;
+
+		dirty_bitmap = memslot->dirty_bitmap;
+		clear_user(memslot->dirty_bitmap_old, n);
+		memslot->dirty_bitmap = memslot->dirty_bitmap_old;
+		memslot->dirty_bitmap_old = dirty_bitmap;
+		log->addr = (unsigned long)dirty_bitmap;
+	}
 
 	r = 0;
 out:
@@ -1699,6 +1714,21 @@ static long kvm_vm_ioctl(struct file *filp,
 			goto out;
 		break;
 	}
+	case KVM_SWITCH_DIRTY_LOG: {
+		struct kvm_dirty_log log;
+
+		r = -EFAULT;
+		if (copy_from_user(&log, argp, sizeof log))
+			goto out;
+		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
+		if (r)
+			goto out;
+		r = -EFAULT;
+		if (copy_to_user(argp, &log, sizeof log))
+			goto out;
+		r = 0;
+		break;
+	}
 #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
 	case KVM_REGISTER_COALESCED_MMIO: {
 		struct kvm_coalesced_mmio_zone zone;
@@ -1790,7 +1820,7 @@ static long kvm_vm_compat_ioctl(struct file *filp,
 			goto out;
 		log.slot	 = compat_log.slot;
 		log.padding1	 = compat_log.padding1;
-		log.padding2	 = compat_log.padding2;
+		log.addr	 = compat_log.padding2;
 		log.dirty_bitmap = compat_ptr(compat_log.dirty_bitmap);
 
 		r = kvm_vm_ioctl_get_dirty_log(kvm, &log);
@@ -1879,6 +1909,7 @@ static long kvm_dev_ioctl_check_extension_generic(long arg)
 	case KVM_CAP_SET_BOOT_CPU_ID:
 #endif
 	case KVM_CAP_INTERNAL_ERROR_DATA:
+	case KVM_CAP_USER_DIRTY_BITMAP:
 		return 1;
 #ifdef CONFIG_HAVE_KVM_IRQCHIP
 	case KVM_CAP_IRQ_ROUTING:
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-20 11:03     ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:03 UTC (permalink / raw)
  To: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA
  Cc: kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg

We can now export the addree of the bitmap created by do_mmap()
to user space. For the sake of this, we introduce a new API:

  KVM_SWITCH_DIRTY_LOG: application can use this to trigger the
  switch of the bitmaps and get the address of the bitmap which
  has been used until now. This reduces the copy of the dirty
  bitmap from the kernel.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Cc: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
 Documentation/kvm/api.txt |   23 +++++++++++++++++++++++
 arch/ia64/kvm/kvm-ia64.c  |   19 ++++++++++++++-----
 arch/powerpc/kvm/book3s.c |   19 ++++++++++++++-----
 arch/x86/kvm/x86.c        |   32 ++++++++++++++++++++++++++------
 include/linux/kvm.h       |    6 ++++--
 include/linux/kvm_host.h  |    7 ++++---
 virt/kvm/kvm_main.c       |   41 ++++++++++++++++++++++++++++++++++++-----
 7 files changed, 121 insertions(+), 26 deletions(-)

diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt
index baa8fde..f3d1c2a 100644
--- a/Documentation/kvm/api.txt
+++ b/Documentation/kvm/api.txt
@@ -848,6 +848,29 @@ function properly, this is the place to put them.
        __u8  pad[64];
 };
 
+4.37 KVM_SWITCH_DIRTY_LOG (vm ioctl)
+
+Capability: basic
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_dirty_log (in/out)
+Returns: 0 on success, -1 on error
+
+/* for KVM_SWITCH_DIRTY_LOG */
+struct kvm_dirty_log {
+	__u32 slot;
+	__u32 padding;
+	union {
+		void __user *dirty_bitmap; /* one bit per page */
+		__u64 addr;
+	};
+};
+
+Given a memory slot, return the address of 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.
+
 5. The kvm_run structure
 
 Application code obtains a pointer to the kvm_run structure by
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index c3f0b70..04fbb1c 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -1843,8 +1843,8 @@ out:
 	return r;
 }
 
-int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
-		struct kvm_dirty_log *log)
+static int kvm_ia64_update_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log,
+				     bool need_copy)
 {
 	int r;
 	unsigned long n;
@@ -1857,7 +1857,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	if (r)
 		goto out;
 
-	r = kvm_get_dirty_log(kvm, log);
+	r = kvm_update_dirty_log(kvm, log, need_copy);
 	if (r)
 		goto out;
 
@@ -1865,10 +1865,9 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	/* If nothing is dirty, don't bother messing with page tables. */
 	if (memslot->is_dirty) {
 		kvm_flush_remote_tlbs(kvm);
-		n = kvm_dirty_bitmap_bytes(memslot);
-		clear_user(memslot->dirty_bitmap, n);
 		memslot->is_dirty = false;
 	}
+
 	r = 0;
 out:
 	mutex_unlock(&kvm->slots_lock);
@@ -1876,6 +1875,16 @@ out:
 	return r;
 }
 
+int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+	return kvm_ia64_update_dirty_log(kvm, log, true);
+}
+
+int kvm_vm_ioctl_switch_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+	return kvm_ia64_update_dirty_log(kvm, log, false);
+}
+
 int kvm_arch_hardware_setup(void)
 {
 	return 0;
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index b074e19..d813dca 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -1112,8 +1112,9 @@ 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)
+static int kvmppc_update_dirty_log(struct kvm *kvm,
+				   struct kvm_dirty_log *log,
+				   bool need_copy)
 {
 	struct kvm_memory_slot *memslot;
 	struct kvm_vcpu *vcpu;
@@ -1123,7 +1124,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 
 	mutex_lock(&kvm->slots_lock);
 
-	r = kvm_get_dirty_log(kvm, log);
+	r = kvm_update_dirty_log(kvm, log, need_copy);
 	if (r)
 		goto out;
 
@@ -1136,8 +1137,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 		kvm_for_each_vcpu(n, vcpu, kvm)
 			kvmppc_mmu_pte_pflush(vcpu, ga, ga_end);
 
-		n = kvm_dirty_bitmap_bytes(memslot);
-		clear_user(memslot->dirty_bitmap, n);
 		memslot->is_dirty = false;
 	}
 
@@ -1147,6 +1146,16 @@ out:
 	return r;
 }
 
+int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+	return kvmppc_update_dirty_log(kvm, log, true);
+}
+
+int kvm_vm_ioctl_switch_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+	return kvmppc_update_dirty_log(kvm, log, false);
+}
+
 int kvmppc_core_check_processor_compat(void)
 {
 	return 0;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ad55353..45b728c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2718,11 +2718,9 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
 	return 0;
 }
 
-/*
- * 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)
+static int kvm_x86_update_dirty_log(struct kvm *kvm,
+				    struct kvm_dirty_log *log,
+				    bool need_copy)
 {
 	int r;
 	struct kvm_memory_slot *memslot;
@@ -2773,12 +2771,34 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 		dirty_bitmap_old = dirty_bitmap;
 	}
 
-	r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap_old, n);
+	if (need_copy) {
+		r = kvm_copy_dirty_bitmap(log->dirty_bitmap,
+					  dirty_bitmap_old, n);
+	} else {
+		log->addr = (unsigned long)dirty_bitmap_old;
+		r = 0;
+	}
 out:
 	mutex_unlock(&kvm->slots_lock);
 	return r;
 }
 
+/*
+ * 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)
+{
+	return kvm_x86_update_dirty_log(kvm, log, true);
+}
+
+/*
+ * Switch to the next dirty bitmap and return the address of the old one.
+ */
+int kvm_vm_ioctl_switch_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+	return kvm_x86_update_dirty_log(kvm, log, false);
+}
+
 long kvm_arch_vm_ioctl(struct file *filp,
 		       unsigned int ioctl, unsigned long arg)
 {
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 23ea022..9fa6f1e 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -12,7 +12,7 @@
 #include <linux/ioctl.h>
 #include <asm/kvm.h>
 
-#define KVM_API_VERSION 12
+#define KVM_API_VERSION 13
 
 /* *** Deprecated interfaces *** */
 
@@ -318,7 +318,7 @@ struct kvm_dirty_log {
 	__u32 padding1;
 	union {
 		void __user *dirty_bitmap; /* one bit per page */
-		__u64 padding2;
+		__u64 addr;
 	};
 };
 
@@ -524,6 +524,7 @@ struct kvm_enable_cap {
 #define KVM_CAP_PPC_OSI 52
 #define KVM_CAP_PPC_UNSET_IRQ 53
 #define KVM_CAP_ENABLE_CAP 54
+#define KVM_CAP_USER_DIRTY_BITMAP 55
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -620,6 +621,7 @@ struct kvm_clock_data {
 					struct kvm_userspace_memory_region)
 #define KVM_SET_TSS_ADDR          _IO(KVMIO,   0x47)
 #define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO,  0x48, __u64)
+#define KVM_SWITCH_DIRTY_LOG      _IOW(KVMIO,  0x49, struct kvm_dirty_log)
 /* Device model IOC */
 #define KVM_CREATE_IRQCHIP        _IO(KVMIO,   0x60)
 #define KVM_IRQ_LINE              _IOW(KVMIO,  0x61, struct kvm_irq_level)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index d4d217a..addecee 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -334,9 +334,10 @@ int kvm_dev_ioctl_check_extension(long ext);
 int kvm_copy_dirty_bitmap(unsigned long __user *to,
 			  const unsigned long __user *from,
 			  unsigned long bytes);
-int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
-int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
-				struct kvm_dirty_log *log);
+int kvm_update_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log,
+			 bool need_copy);
+int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
+int kvm_vm_ioctl_switch_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
 
 int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
 				   struct
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 9323639..cba133d 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -844,7 +844,8 @@ out_fault:
 #endif
 }
 
-int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+int kvm_update_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log,
+			 bool need_copy)
 {
 	struct kvm_memory_slot *memslot;
 	int r;
@@ -861,9 +862,23 @@ int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
 
 	n = kvm_dirty_bitmap_bytes(memslot);
 
-	r = -EFAULT;
-	if (kvm_copy_dirty_bitmap(log->dirty_bitmap, memslot->dirty_bitmap, n))
-		goto out;
+	if (need_copy) {
+		r = -EFAULT;
+		if (kvm_copy_dirty_bitmap(log->dirty_bitmap,
+					  memslot->dirty_bitmap, n))
+			goto out;
+
+		if (memslot->is_dirty)
+			clear_user(memslot->dirty_bitmap, n);
+	} else {
+		unsigned long __user *dirty_bitmap;
+
+		dirty_bitmap = memslot->dirty_bitmap;
+		clear_user(memslot->dirty_bitmap_old, n);
+		memslot->dirty_bitmap = memslot->dirty_bitmap_old;
+		memslot->dirty_bitmap_old = dirty_bitmap;
+		log->addr = (unsigned long)dirty_bitmap;
+	}
 
 	r = 0;
 out:
@@ -1699,6 +1714,21 @@ static long kvm_vm_ioctl(struct file *filp,
 			goto out;
 		break;
 	}
+	case KVM_SWITCH_DIRTY_LOG: {
+		struct kvm_dirty_log log;
+
+		r = -EFAULT;
+		if (copy_from_user(&log, argp, sizeof log))
+			goto out;
+		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
+		if (r)
+			goto out;
+		r = -EFAULT;
+		if (copy_to_user(argp, &log, sizeof log))
+			goto out;
+		r = 0;
+		break;
+	}
 #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
 	case KVM_REGISTER_COALESCED_MMIO: {
 		struct kvm_coalesced_mmio_zone zone;
@@ -1790,7 +1820,7 @@ static long kvm_vm_compat_ioctl(struct file *filp,
 			goto out;
 		log.slot	 = compat_log.slot;
 		log.padding1	 = compat_log.padding1;
-		log.padding2	 = compat_log.padding2;
+		log.addr	 = compat_log.padding2;
 		log.dirty_bitmap = compat_ptr(compat_log.dirty_bitmap);
 
 		r = kvm_vm_ioctl_get_dirty_log(kvm, &log);
@@ -1879,6 +1909,7 @@ static long kvm_dev_ioctl_check_extension_generic(long arg)
 	case KVM_CAP_SET_BOOT_CPU_ID:
 #endif
 	case KVM_CAP_INTERNAL_ERROR_DATA:
+	case KVM_CAP_USER_DIRTY_BITMAP:
 		return 1;
 #ifdef CONFIG_HAVE_KVM_IRQCHIP
 	case KVM_CAP_IRQ_ROUTING:
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 141+ messages in thread

* [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-20 11:03     ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:03 UTC (permalink / raw)
  To: kvm-ia64

We can now export the addree of the bitmap created by do_mmap()
to user space. For the sake of this, we introduce a new API:

  KVM_SWITCH_DIRTY_LOG: application can use this to trigger the
  switch of the bitmaps and get the address of the bitmap which
  has been used until now. This reduces the copy of the dirty
  bitmap from the kernel.

Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
Cc: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
---
 Documentation/kvm/api.txt |   23 +++++++++++++++++++++++
 arch/ia64/kvm/kvm-ia64.c  |   19 ++++++++++++++-----
 arch/powerpc/kvm/book3s.c |   19 ++++++++++++++-----
 arch/x86/kvm/x86.c        |   32 ++++++++++++++++++++++++++------
 include/linux/kvm.h       |    6 ++++--
 include/linux/kvm_host.h  |    7 ++++---
 virt/kvm/kvm_main.c       |   41 ++++++++++++++++++++++++++++++++++++-----
 7 files changed, 121 insertions(+), 26 deletions(-)

diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt
index baa8fde..f3d1c2a 100644
--- a/Documentation/kvm/api.txt
+++ b/Documentation/kvm/api.txt
@@ -848,6 +848,29 @@ function properly, this is the place to put them.
        __u8  pad[64];
 };
 
+4.37 KVM_SWITCH_DIRTY_LOG (vm ioctl)
+
+Capability: basic
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_dirty_log (in/out)
+Returns: 0 on success, -1 on error
+
+/* for KVM_SWITCH_DIRTY_LOG */
+struct kvm_dirty_log {
+	__u32 slot;
+	__u32 padding;
+	union {
+		void __user *dirty_bitmap; /* one bit per page */
+		__u64 addr;
+	};
+};
+
+Given a memory slot, return the address of 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.
+
 5. The kvm_run structure
 
 Application code obtains a pointer to the kvm_run structure by
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
index c3f0b70..04fbb1c 100644
--- a/arch/ia64/kvm/kvm-ia64.c
+++ b/arch/ia64/kvm/kvm-ia64.c
@@ -1843,8 +1843,8 @@ out:
 	return r;
 }
 
-int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
-		struct kvm_dirty_log *log)
+static int kvm_ia64_update_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log,
+				     bool need_copy)
 {
 	int r;
 	unsigned long n;
@@ -1857,7 +1857,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	if (r)
 		goto out;
 
-	r = kvm_get_dirty_log(kvm, log);
+	r = kvm_update_dirty_log(kvm, log, need_copy);
 	if (r)
 		goto out;
 
@@ -1865,10 +1865,9 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 	/* If nothing is dirty, don't bother messing with page tables. */
 	if (memslot->is_dirty) {
 		kvm_flush_remote_tlbs(kvm);
-		n = kvm_dirty_bitmap_bytes(memslot);
-		clear_user(memslot->dirty_bitmap, n);
 		memslot->is_dirty = false;
 	}
+
 	r = 0;
 out:
 	mutex_unlock(&kvm->slots_lock);
@@ -1876,6 +1875,16 @@ out:
 	return r;
 }
 
+int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+	return kvm_ia64_update_dirty_log(kvm, log, true);
+}
+
+int kvm_vm_ioctl_switch_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+	return kvm_ia64_update_dirty_log(kvm, log, false);
+}
+
 int kvm_arch_hardware_setup(void)
 {
 	return 0;
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index b074e19..d813dca 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -1112,8 +1112,9 @@ 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)
+static int kvmppc_update_dirty_log(struct kvm *kvm,
+				   struct kvm_dirty_log *log,
+				   bool need_copy)
 {
 	struct kvm_memory_slot *memslot;
 	struct kvm_vcpu *vcpu;
@@ -1123,7 +1124,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 
 	mutex_lock(&kvm->slots_lock);
 
-	r = kvm_get_dirty_log(kvm, log);
+	r = kvm_update_dirty_log(kvm, log, need_copy);
 	if (r)
 		goto out;
 
@@ -1136,8 +1137,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 		kvm_for_each_vcpu(n, vcpu, kvm)
 			kvmppc_mmu_pte_pflush(vcpu, ga, ga_end);
 
-		n = kvm_dirty_bitmap_bytes(memslot);
-		clear_user(memslot->dirty_bitmap, n);
 		memslot->is_dirty = false;
 	}
 
@@ -1147,6 +1146,16 @@ out:
 	return r;
 }
 
+int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+	return kvmppc_update_dirty_log(kvm, log, true);
+}
+
+int kvm_vm_ioctl_switch_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+	return kvmppc_update_dirty_log(kvm, log, false);
+}
+
 int kvmppc_core_check_processor_compat(void)
 {
 	return 0;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index ad55353..45b728c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2718,11 +2718,9 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
 	return 0;
 }
 
-/*
- * 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)
+static int kvm_x86_update_dirty_log(struct kvm *kvm,
+				    struct kvm_dirty_log *log,
+				    bool need_copy)
 {
 	int r;
 	struct kvm_memory_slot *memslot;
@@ -2773,12 +2771,34 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
 		dirty_bitmap_old = dirty_bitmap;
 	}
 
-	r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap_old, n);
+	if (need_copy) {
+		r = kvm_copy_dirty_bitmap(log->dirty_bitmap,
+					  dirty_bitmap_old, n);
+	} else {
+		log->addr = (unsigned long)dirty_bitmap_old;
+		r = 0;
+	}
 out:
 	mutex_unlock(&kvm->slots_lock);
 	return r;
 }
 
+/*
+ * 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)
+{
+	return kvm_x86_update_dirty_log(kvm, log, true);
+}
+
+/*
+ * Switch to the next dirty bitmap and return the address of the old one.
+ */
+int kvm_vm_ioctl_switch_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+{
+	return kvm_x86_update_dirty_log(kvm, log, false);
+}
+
 long kvm_arch_vm_ioctl(struct file *filp,
 		       unsigned int ioctl, unsigned long arg)
 {
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 23ea022..9fa6f1e 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -12,7 +12,7 @@
 #include <linux/ioctl.h>
 #include <asm/kvm.h>
 
-#define KVM_API_VERSION 12
+#define KVM_API_VERSION 13
 
 /* *** Deprecated interfaces *** */
 
@@ -318,7 +318,7 @@ struct kvm_dirty_log {
 	__u32 padding1;
 	union {
 		void __user *dirty_bitmap; /* one bit per page */
-		__u64 padding2;
+		__u64 addr;
 	};
 };
 
@@ -524,6 +524,7 @@ struct kvm_enable_cap {
 #define KVM_CAP_PPC_OSI 52
 #define KVM_CAP_PPC_UNSET_IRQ 53
 #define KVM_CAP_ENABLE_CAP 54
+#define KVM_CAP_USER_DIRTY_BITMAP 55
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -620,6 +621,7 @@ struct kvm_clock_data {
 					struct kvm_userspace_memory_region)
 #define KVM_SET_TSS_ADDR          _IO(KVMIO,   0x47)
 #define KVM_SET_IDENTITY_MAP_ADDR _IOW(KVMIO,  0x48, __u64)
+#define KVM_SWITCH_DIRTY_LOG      _IOW(KVMIO,  0x49, struct kvm_dirty_log)
 /* Device model IOC */
 #define KVM_CREATE_IRQCHIP        _IO(KVMIO,   0x60)
 #define KVM_IRQ_LINE              _IOW(KVMIO,  0x61, struct kvm_irq_level)
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index d4d217a..addecee 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -334,9 +334,10 @@ int kvm_dev_ioctl_check_extension(long ext);
 int kvm_copy_dirty_bitmap(unsigned long __user *to,
 			  const unsigned long __user *from,
 			  unsigned long bytes);
-int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
-int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
-				struct kvm_dirty_log *log);
+int kvm_update_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log,
+			 bool need_copy);
+int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
+int kvm_vm_ioctl_switch_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log);
 
 int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
 				   struct
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 9323639..cba133d 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -844,7 +844,8 @@ out_fault:
 #endif
 }
 
-int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
+int kvm_update_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log,
+			 bool need_copy)
 {
 	struct kvm_memory_slot *memslot;
 	int r;
@@ -861,9 +862,23 @@ int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
 
 	n = kvm_dirty_bitmap_bytes(memslot);
 
-	r = -EFAULT;
-	if (kvm_copy_dirty_bitmap(log->dirty_bitmap, memslot->dirty_bitmap, n))
-		goto out;
+	if (need_copy) {
+		r = -EFAULT;
+		if (kvm_copy_dirty_bitmap(log->dirty_bitmap,
+					  memslot->dirty_bitmap, n))
+			goto out;
+
+		if (memslot->is_dirty)
+			clear_user(memslot->dirty_bitmap, n);
+	} else {
+		unsigned long __user *dirty_bitmap;
+
+		dirty_bitmap = memslot->dirty_bitmap;
+		clear_user(memslot->dirty_bitmap_old, n);
+		memslot->dirty_bitmap = memslot->dirty_bitmap_old;
+		memslot->dirty_bitmap_old = dirty_bitmap;
+		log->addr = (unsigned long)dirty_bitmap;
+	}
 
 	r = 0;
 out:
@@ -1699,6 +1714,21 @@ static long kvm_vm_ioctl(struct file *filp,
 			goto out;
 		break;
 	}
+	case KVM_SWITCH_DIRTY_LOG: {
+		struct kvm_dirty_log log;
+
+		r = -EFAULT;
+		if (copy_from_user(&log, argp, sizeof log))
+			goto out;
+		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
+		if (r)
+			goto out;
+		r = -EFAULT;
+		if (copy_to_user(argp, &log, sizeof log))
+			goto out;
+		r = 0;
+		break;
+	}
 #ifdef KVM_COALESCED_MMIO_PAGE_OFFSET
 	case KVM_REGISTER_COALESCED_MMIO: {
 		struct kvm_coalesced_mmio_zone zone;
@@ -1790,7 +1820,7 @@ static long kvm_vm_compat_ioctl(struct file *filp,
 			goto out;
 		log.slot	 = compat_log.slot;
 		log.padding1	 = compat_log.padding1;
-		log.padding2	 = compat_log.padding2;
+		log.addr	 = compat_log.padding2;
 		log.dirty_bitmap = compat_ptr(compat_log.dirty_bitmap);
 
 		r = kvm_vm_ioctl_get_dirty_log(kvm, &log);
@@ -1879,6 +1909,7 @@ static long kvm_dev_ioctl_check_extension_generic(long arg)
 	case KVM_CAP_SET_BOOT_CPU_ID:
 #endif
 	case KVM_CAP_INTERNAL_ERROR_DATA:
+	case KVM_CAP_USER_DIRTY_BITMAP:
 		return 1;
 #ifdef CONFIG_HAVE_KVM_IRQCHIP
 	case KVM_CAP_IRQ_ROUTING:
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
       [not found]     ` <20100420200225.efca602f.yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
  2010-04-20 11:10         ` Alexander Graf
@ 2010-04-20 11:10         ` Alexander Graf
  1 sibling, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-20 11:10 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA,
	kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg


On 20.04.2010, at 13:02, Takuya Yoshikawa wrote:

> We move dirty bitmaps to user space.
> 
> - Allocation and destruction: we use do_mmap() and do_munmap().
>   The new bitmap space is twice longer than the original one and we
>   use the additional space for double buffering: this makes it
>   possible to update the active bitmap while letting the user space
>   read the other one safely.
> 
> - Bitmap manipulations: we replace all functions which access dirty
>   bitmaps to *_user() functions. Note that some of these should be
>   optimized later.
> 
> - For ia64: moving the dirty bitmaps of memory slots does not effect
>   much to ia64 because it's using a different space to store bitmaps
>   which is directly updated: all we have to change are sync and get
>   of dirty log, so we don't need set_bit_user like function for ia64.
> 
> Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
> Signed-off-by: Fernando Luis Vazquez Cao <fernando-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
> ---
> arch/ia64/kvm/kvm-ia64.c  |   12 ++++-
> arch/powerpc/kvm/book3s.c |    2 +-
> arch/x86/kvm/x86.c        |   24 +++++-----
> include/linux/kvm_host.h  |    5 +-
> virt/kvm/kvm_main.c       |  101 ++++++++++++++++++++++++++++++++++++++++-----
> 5 files changed, 116 insertions(+), 28 deletions(-)
> 
> 

[...]

> @@ -778,13 +803,45 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
> }
> 
> int kvm_copy_dirty_bitmap(unsigned long __user *to,
> -			  const unsigned long *from,
> +			  const unsigned long __user *from,
> 			  unsigned long bytes)
> {
> -	if (copy_to_user(to, from, bytes))
> +#if defined(CONFIG_X86_64) || defined(CONFIG_PPC64) || defined(CONFIG_IA64)

Wouldn't it be better to have a define __HAS_COPY_IN_USER or so? I really dislike writing out all architectures that have this explicitly.

> +	if (copy_in_user(to, from, bytes)) {
> +		printk(KERN_WARNING "%s: copy_in_user failed.\n", __func__);
> 		return -EFAULT;
> +	}
> +	return 0;
> +#else

Worst case I'd at least like to see all the others written out here, so when someone adds a new arch he can at least check if it's supported or not.

> +	int num, bufbytes;
> +	unsigned long buf[32];
> 
> +	if (!access_ok(VERIFY_READ, from, bytes) ||
> +	    !access_ok(VERIFY_WRITE, to, bytes)) {
> +		goto out_fault;
> +	}
> +
> +	bufbytes = sizeof(buf);
> +	num = bufbytes / sizeof(buf[0]);

ARRAY_SIZE?

> +
> +	for (; bytes > bufbytes; bytes -= bufbytes, to += num, from += num) {
> +		if (__copy_from_user(buf, from, bufbytes))
> +			goto out_fault;
> +		if (__copy_to_user(to, buf, bufbytes))
> +			goto out_fault;
> +	}
> +	if (bytes > 0) {
> +		if (__copy_from_user(buf, from, bytes))
> +			goto out_fault;
> +		if (__copy_to_user(to, buf, bytes))
> +			goto out_fault;
> +	}
> 	return 0;
> +
> +out_fault:
> +	printk(KERN_WARNING "%s: copy to(from) user failed.\n", __func__);
> +	return -EFAULT;
> +#endif
> }
> 
> int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
> @@ -1194,13 +1251,35 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
> }
> EXPORT_SYMBOL_GPL(kvm_clear_guest);
> 
> +/*
> + * Please use generic *_user bitops once they become available.
> + * Be careful setting the bit won't be done atomically.
> + */
> static int __mark_page_dirty(unsigned long nr,
> -			     unsigned long *dirty_bitmap)
> +			     unsigned long __user *dirty_bitmap)
> {
> +	unsigned long user_addr;
> +	u8 val;
> +
> #ifdef __BIG_ENDIAN
> 	nr = nr ^ BITOP_LE_SWIZZLE;
> #endif
> -	__set_bit(nr, dirty_bitmap);
> +	user_addr = (unsigned long)dirty_bitmap + nr / 8;

BITS_PER_BYTE

> +	if (!access_ok(VERIFY_WRITE, user_addr, 1))
> +		goto out_fault;
> +
> +	if (__get_user(val, (u8 __user *)user_addr))
> +		goto out_fault;
> +
> +	val |= 1U << (nr % 8);

see above


Alex

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-20 11:10         ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-20 11:10 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA,
	kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg


On 20.04.2010, at 13:02, Takuya Yoshikawa wrote:

> We move dirty bitmaps to user space.
> 
> - Allocation and destruction: we use do_mmap() and do_munmap().
>   The new bitmap space is twice longer than the original one and we
>   use the additional space for double buffering: this makes it
>   possible to update the active bitmap while letting the user space
>   read the other one safely.
> 
> - Bitmap manipulations: we replace all functions which access dirty
>   bitmaps to *_user() functions. Note that some of these should be
>   optimized later.
> 
> - For ia64: moving the dirty bitmaps of memory slots does not effect
>   much to ia64 because it's using a different space to store bitmaps
>   which is directly updated: all we have to change are sync and get
>   of dirty log, so we don't need set_bit_user like function for ia64.
> 
> Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
> Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
> ---
> arch/ia64/kvm/kvm-ia64.c  |   12 ++++-
> arch/powerpc/kvm/book3s.c |    2 +-
> arch/x86/kvm/x86.c        |   24 +++++-----
> include/linux/kvm_host.h  |    5 +-
> virt/kvm/kvm_main.c       |  101 ++++++++++++++++++++++++++++++++++++++++-----
> 5 files changed, 116 insertions(+), 28 deletions(-)
> 
> 

[...]

> @@ -778,13 +803,45 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
> }
> 
> int kvm_copy_dirty_bitmap(unsigned long __user *to,
> -			  const unsigned long *from,
> +			  const unsigned long __user *from,
> 			  unsigned long bytes)
> {
> -	if (copy_to_user(to, from, bytes))
> +#if defined(CONFIG_X86_64) || defined(CONFIG_PPC64) || defined(CONFIG_IA64)

Wouldn't it be better to have a define __HAS_COPY_IN_USER or so? I really dislike writing out all architectures that have this explicitly.

> +	if (copy_in_user(to, from, bytes)) {
> +		printk(KERN_WARNING "%s: copy_in_user failed.\n", __func__);
> 		return -EFAULT;
> +	}
> +	return 0;
> +#else

Worst case I'd at least like to see all the others written out here, so when someone adds a new arch he can at least check if it's supported or not.

> +	int num, bufbytes;
> +	unsigned long buf[32];
> 
> +	if (!access_ok(VERIFY_READ, from, bytes) ||
> +	    !access_ok(VERIFY_WRITE, to, bytes)) {
> +		goto out_fault;
> +	}
> +
> +	bufbytes = sizeof(buf);
> +	num = bufbytes / sizeof(buf[0]);

ARRAY_SIZE?

> +
> +	for (; bytes > bufbytes; bytes -= bufbytes, to += num, from += num) {
> +		if (__copy_from_user(buf, from, bufbytes))
> +			goto out_fault;
> +		if (__copy_to_user(to, buf, bufbytes))
> +			goto out_fault;
> +	}
> +	if (bytes > 0) {
> +		if (__copy_from_user(buf, from, bytes))
> +			goto out_fault;
> +		if (__copy_to_user(to, buf, bytes))
> +			goto out_fault;
> +	}
> 	return 0;
> +
> +out_fault:
> +	printk(KERN_WARNING "%s: copy to(from) user failed.\n", __func__);
> +	return -EFAULT;
> +#endif
> }
> 
> int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
> @@ -1194,13 +1251,35 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
> }
> EXPORT_SYMBOL_GPL(kvm_clear_guest);
> 
> +/*
> + * Please use generic *_user bitops once they become available.
> + * Be careful setting the bit won't be done atomically.
> + */
> static int __mark_page_dirty(unsigned long nr,
> -			     unsigned long *dirty_bitmap)
> +			     unsigned long __user *dirty_bitmap)
> {
> +	unsigned long user_addr;
> +	u8 val;
> +
> #ifdef __BIG_ENDIAN
> 	nr = nr ^ BITOP_LE_SWIZZLE;
> #endif
> -	__set_bit(nr, dirty_bitmap);
> +	user_addr = (unsigned long)dirty_bitmap + nr / 8;

BITS_PER_BYTE

> +	if (!access_ok(VERIFY_WRITE, user_addr, 1))
> +		goto out_fault;
> +
> +	if (__get_user(val, (u8 __user *)user_addr))
> +		goto out_fault;
> +
> +	val |= 1U << (nr % 8);

see above


Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-20 11:10         ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-20 11:10 UTC (permalink / raw)
  To: kvm-ia64


On 20.04.2010, at 13:02, Takuya Yoshikawa wrote:

> We move dirty bitmaps to user space.
> 
> - Allocation and destruction: we use do_mmap() and do_munmap().
>   The new bitmap space is twice longer than the original one and we
>   use the additional space for double buffering: this makes it
>   possible to update the active bitmap while letting the user space
>   read the other one safely.
> 
> - Bitmap manipulations: we replace all functions which access dirty
>   bitmaps to *_user() functions. Note that some of these should be
>   optimized later.
> 
> - For ia64: moving the dirty bitmaps of memory slots does not effect
>   much to ia64 because it's using a different space to store bitmaps
>   which is directly updated: all we have to change are sync and get
>   of dirty log, so we don't need set_bit_user like function for ia64.
> 
> Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
> Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
> ---
> arch/ia64/kvm/kvm-ia64.c  |   12 ++++-
> arch/powerpc/kvm/book3s.c |    2 +-
> arch/x86/kvm/x86.c        |   24 +++++-----
> include/linux/kvm_host.h  |    5 +-
> virt/kvm/kvm_main.c       |  101 ++++++++++++++++++++++++++++++++++++++++-----
> 5 files changed, 116 insertions(+), 28 deletions(-)
> 
> 

[...]

> @@ -778,13 +803,45 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
> }
> 
> int kvm_copy_dirty_bitmap(unsigned long __user *to,
> -			  const unsigned long *from,
> +			  const unsigned long __user *from,
> 			  unsigned long bytes)
> {
> -	if (copy_to_user(to, from, bytes))
> +#if defined(CONFIG_X86_64) || defined(CONFIG_PPC64) || defined(CONFIG_IA64)

Wouldn't it be better to have a define __HAS_COPY_IN_USER or so? I really dislike writing out all architectures that have this explicitly.

> +	if (copy_in_user(to, from, bytes)) {
> +		printk(KERN_WARNING "%s: copy_in_user failed.\n", __func__);
> 		return -EFAULT;
> +	}
> +	return 0;
> +#else

Worst case I'd at least like to see all the others written out here, so when someone adds a new arch he can at least check if it's supported or not.

> +	int num, bufbytes;
> +	unsigned long buf[32];
> 
> +	if (!access_ok(VERIFY_READ, from, bytes) ||
> +	    !access_ok(VERIFY_WRITE, to, bytes)) {
> +		goto out_fault;
> +	}
> +
> +	bufbytes = sizeof(buf);
> +	num = bufbytes / sizeof(buf[0]);

ARRAY_SIZE?

> +
> +	for (; bytes > bufbytes; bytes -= bufbytes, to += num, from += num) {
> +		if (__copy_from_user(buf, from, bufbytes))
> +			goto out_fault;
> +		if (__copy_to_user(to, buf, bufbytes))
> +			goto out_fault;
> +	}
> +	if (bytes > 0) {
> +		if (__copy_from_user(buf, from, bytes))
> +			goto out_fault;
> +		if (__copy_to_user(to, buf, bytes))
> +			goto out_fault;
> +	}
> 	return 0;
> +
> +out_fault:
> +	printk(KERN_WARNING "%s: copy to(from) user failed.\n", __func__);
> +	return -EFAULT;
> +#endif
> }
> 
> int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
> @@ -1194,13 +1251,35 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
> }
> EXPORT_SYMBOL_GPL(kvm_clear_guest);
> 
> +/*
> + * Please use generic *_user bitops once they become available.
> + * Be careful setting the bit won't be done atomically.
> + */
> static int __mark_page_dirty(unsigned long nr,
> -			     unsigned long *dirty_bitmap)
> +			     unsigned long __user *dirty_bitmap)
> {
> +	unsigned long user_addr;
> +	u8 val;
> +
> #ifdef __BIG_ENDIAN
> 	nr = nr ^ BITOP_LE_SWIZZLE;
> #endif
> -	__set_bit(nr, dirty_bitmap);
> +	user_addr = (unsigned long)dirty_bitmap + nr / 8;

BITS_PER_BYTE

> +	if (!access_ok(VERIFY_WRITE, user_addr, 1))
> +		goto out_fault;
> +
> +	if (__get_user(val, (u8 __user *)user_addr))
> +		goto out_fault;
> +
> +	val |= 1U << (nr % 8);

see above


Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 0/6] KVM: moving dirty gitmaps to user space!
       [not found]   ` <C70797C1-08EC-4DBA-9595-4047CAE8E457-l3A5Bk7waGM@public.gmane.org>
  2010-04-20 11:13       ` Takuya Yoshikawa
@ 2010-04-20 11:13       ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:13 UTC (permalink / raw)
  To: Alexander Graf
  Cc: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA,
	kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA

(2010/04/20 19:54), Alexander Graf wrote:
>
> On 20.04.2010, at 12:53, Takuya Yoshikawa wrote:
>
>> Hi, this is the v2 of the "moving dirty gitmaps to user space!"
>>
>> By this patch, I think everything we need becomes clear.
>> So we want to step forward to be ready for the final version in the
>> near future: of course, this is dependent on x86 and ppc asm issues.
>>
>> BTW, by whom I can get ACK for ppc and ia64? I want to add to the Cc
>> list if possible, thank you.
>
> You'd get the ACK for ppc from me.

Thank you, then I will add you to Cc next time!

>
> Do you have a PowerPC box around to test things on? By now it should work on any desktop/server PowerPC system you can find.

Sorry, I have no ppc box here. So at this stage, I am sometimes using cross
compilers to check this can build or not: not enough test now.

And this patch needs arch specific(assembly level) optimization in the future.
So I want to make this development as open as possible.

>
> Also the only differences on PPC are that we are big endian and usually run 32 bit userspace on 64 bit kernels. So playing with longs is a bad idea :).

OK, I'll keep in mind!

>
> Alex
>

   Takuya

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 0/6] KVM: moving dirty gitmaps to user space!
@ 2010-04-20 11:13       ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:13 UTC (permalink / raw)
  To: Alexander Graf
  Cc: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA,
	kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA

(2010/04/20 19:54), Alexander Graf wrote:
>
> On 20.04.2010, at 12:53, Takuya Yoshikawa wrote:
>
>> Hi, this is the v2 of the "moving dirty gitmaps to user space!"
>>
>> By this patch, I think everything we need becomes clear.
>> So we want to step forward to be ready for the final version in the
>> near future: of course, this is dependent on x86 and ppc asm issues.
>>
>> BTW, by whom I can get ACK for ppc and ia64? I want to add to the Cc
>> list if possible, thank you.
>
> You'd get the ACK for ppc from me.

Thank you, then I will add you to Cc next time!

>
> Do you have a PowerPC box around to test things on? By now it should work on any desktop/server PowerPC system you can find.

Sorry, I have no ppc box here. So at this stage, I am sometimes using cross
compilers to check this can build or not: not enough test now.

And this patch needs arch specific(assembly level) optimization in the future.
So I want to make this development as open as possible.

>
> Also the only differences on PPC are that we are big endian and usually run 32 bit userspace on 64 bit kernels. So playing with longs is a bad idea :).

OK, I'll keep in mind!

>
> Alex
>

   Takuya

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 0/6] KVM: moving dirty gitmaps to user space!
@ 2010-04-20 11:13       ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:13 UTC (permalink / raw)
  To: kvm-ia64

(2010/04/20 19:54), Alexander Graf wrote:
>
> On 20.04.2010, at 12:53, Takuya Yoshikawa wrote:
>
>> Hi, this is the v2 of the "moving dirty gitmaps to user space!"
>>
>> By this patch, I think everything we need becomes clear.
>> So we want to step forward to be ready for the final version in the
>> near future: of course, this is dependent on x86 and ppc asm issues.
>>
>> BTW, by whom I can get ACK for ppc and ia64? I want to add to the Cc
>> list if possible, thank you.
>
> You'd get the ACK for ppc from me.

Thank you, then I will add you to Cc next time!

>
> Do you have a PowerPC box around to test things on? By now it should work on any desktop/server PowerPC system you can find.

Sorry, I have no ppc box here. So at this stage, I am sometimes using cross
compilers to check this can build or not: not enough test now.

And this patch needs arch specific(assembly level) optimization in the future.
So I want to make this development as open as possible.

>
> Also the only differences on PPC are that we are big endian and usually run 32 bit userspace on 64 bit kernels. So playing with longs is a bad idea :).

OK, I'll keep in mind!

>
> Alex
>

   Takuya

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
  2010-04-20 11:03     ` Takuya Yoshikawa
  (?)
@ 2010-04-20 11:15       ` Alexander Graf
  -1 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-20 11:15 UTC (permalink / raw)
  To: Takuya Yoshikawa; +Cc: avi, mtosatti, kvm, kvm-ia64, kvm-ppc, fernando


On 20.04.2010, at 13:03, Takuya Yoshikawa wrote:

> We can now export the addree of the bitmap created by do_mmap()
> to user space. For the sake of this, we introduce a new API:
> 
>  KVM_SWITCH_DIRTY_LOG: application can use this to trigger the
>  switch of the bitmaps and get the address of the bitmap which
>  has been used until now. This reduces the copy of the dirty
>  bitmap from the kernel.
> 
> Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
> Cc: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
> ---
> Documentation/kvm/api.txt |   23 +++++++++++++++++++++++
> arch/ia64/kvm/kvm-ia64.c  |   19 ++++++++++++++-----
> arch/powerpc/kvm/book3s.c |   19 ++++++++++++++-----
> arch/x86/kvm/x86.c        |   32 ++++++++++++++++++++++++++------
> include/linux/kvm.h       |    6 ++++--
> include/linux/kvm_host.h  |    7 ++++---
> virt/kvm/kvm_main.c       |   41 ++++++++++++++++++++++++++++++++++++-----
> 7 files changed, 121 insertions(+), 26 deletions(-)
> 

[...]

> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
> index 23ea022..9fa6f1e 100644
> --- a/include/linux/kvm.h
> +++ b/include/linux/kvm.h
> @@ -12,7 +12,7 @@
> #include <linux/ioctl.h>
> #include <asm/kvm.h>
> 
> -#define KVM_API_VERSION 12
> +#define KVM_API_VERSION 13

Is there a way to keep both interfaces around for some time at least? I'd prefer the API version not to change if not _really_ necessary.

To enable the new dirty mapping you could for example use KVM_CAP_ENABLE_CAP :-).


Alex 


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-20 11:15       ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-20 11:15 UTC (permalink / raw)
  To: Takuya Yoshikawa; +Cc: avi, mtosatti, kvm, kvm-ia64, kvm-ppc, fernando


On 20.04.2010, at 13:03, Takuya Yoshikawa wrote:

> We can now export the addree of the bitmap created by do_mmap()
> to user space. For the sake of this, we introduce a new API:
> 
>  KVM_SWITCH_DIRTY_LOG: application can use this to trigger the
>  switch of the bitmaps and get the address of the bitmap which
>  has been used until now. This reduces the copy of the dirty
>  bitmap from the kernel.
> 
> Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
> Cc: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
> ---
> Documentation/kvm/api.txt |   23 +++++++++++++++++++++++
> arch/ia64/kvm/kvm-ia64.c  |   19 ++++++++++++++-----
> arch/powerpc/kvm/book3s.c |   19 ++++++++++++++-----
> arch/x86/kvm/x86.c        |   32 ++++++++++++++++++++++++++------
> include/linux/kvm.h       |    6 ++++--
> include/linux/kvm_host.h  |    7 ++++---
> virt/kvm/kvm_main.c       |   41 ++++++++++++++++++++++++++++++++++++-----
> 7 files changed, 121 insertions(+), 26 deletions(-)
> 

[...]

> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
> index 23ea022..9fa6f1e 100644
> --- a/include/linux/kvm.h
> +++ b/include/linux/kvm.h
> @@ -12,7 +12,7 @@
> #include <linux/ioctl.h>
> #include <asm/kvm.h>
> 
> -#define KVM_API_VERSION 12
> +#define KVM_API_VERSION 13

Is there a way to keep both interfaces around for some time at least? I'd prefer the API version not to change if not _really_ necessary.

To enable the new dirty mapping you could for example use KVM_CAP_ENABLE_CAP :-).


Alex 


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-20 11:15       ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-20 11:15 UTC (permalink / raw)
  To: kvm-ia64


On 20.04.2010, at 13:03, Takuya Yoshikawa wrote:

> We can now export the addree of the bitmap created by do_mmap()
> to user space. For the sake of this, we introduce a new API:
> 
>  KVM_SWITCH_DIRTY_LOG: application can use this to trigger the
>  switch of the bitmaps and get the address of the bitmap which
>  has been used until now. This reduces the copy of the dirty
>  bitmap from the kernel.
> 
> Signed-off-by: Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>
> Cc: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
> ---
> Documentation/kvm/api.txt |   23 +++++++++++++++++++++++
> arch/ia64/kvm/kvm-ia64.c  |   19 ++++++++++++++-----
> arch/powerpc/kvm/book3s.c |   19 ++++++++++++++-----
> arch/x86/kvm/x86.c        |   32 ++++++++++++++++++++++++++------
> include/linux/kvm.h       |    6 ++++--
> include/linux/kvm_host.h  |    7 ++++---
> virt/kvm/kvm_main.c       |   41 ++++++++++++++++++++++++++++++++++++-----
> 7 files changed, 121 insertions(+), 26 deletions(-)
> 

[...]

> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
> index 23ea022..9fa6f1e 100644
> --- a/include/linux/kvm.h
> +++ b/include/linux/kvm.h
> @@ -12,7 +12,7 @@
> #include <linux/ioctl.h>
> #include <asm/kvm.h>
> 
> -#define KVM_API_VERSION 12
> +#define KVM_API_VERSION 13

Is there a way to keep both interfaces around for some time at least? I'd prefer the API version not to change if not _really_ necessary.

To enable the new dirty mapping you could for example use KVM_CAP_ENABLE_CAP :-).


Alex 


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian issues explicitly
  2010-04-20 11:00       ` Alexander Graf
  (?)
@ 2010-04-20 11:20         ` Takuya Yoshikawa
  -1 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:20 UTC (permalink / raw)
  To: Alexander Graf; +Cc: avi, mtosatti, kvm, kvm-ia64, kvm-ppc, fernando

(2010/04/20 20:00), Alexander Graf wrote:
>
> On 20.04.2010, at 13:00, Takuya Yoshikawa wrote:
>
>> We are now using generic___set_le_bit() to make dirty bitmaps le.
>> Though this works well, we have to replace __set_bit() to appropriate
>> uaccess function to move dirty bitmaps to user space. So this patch
>> splits generic___set_le_bit() and prepares for that.
>>
>> Signed-off-by: Takuya Yoshikawa<yoshikawa.takuya@oss.ntt.co.jp>
>> Signed-off-by: Fernando Luis Vazquez Cao<fernando@oss.ntt.co.jp>
>> ---
>> virt/kvm/kvm_main.c |   16 +++++++++++-----
>> 1 files changed, 11 insertions(+), 5 deletions(-)
>>
>> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
>> index 6908304..66c4daf 100644
>> --- a/virt/kvm/kvm_main.c
>> +++ b/virt/kvm/kvm_main.c
>> @@ -1194,6 +1194,15 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
>> }
>> EXPORT_SYMBOL_GPL(kvm_clear_guest);
>>
>> +static int __mark_page_dirty(unsigned long nr,
>> +			     unsigned long *dirty_bitmap)
>> +{
>> +#ifdef __BIG_ENDIAN
>> +	nr = nr ^ BITOP_LE_SWIZZLE;
>
> Why an XOR here?
Ah, might be my cut and paste mistake. I just copied from generic___set_le_bit().

>
> Also is this LE set_bit new? I didn't see it when I did the patch back then :).

Really? I need to check the git log then. This LE set_bit is not new I think.

>
>
> Alex
>


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian
@ 2010-04-20 11:20         ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:20 UTC (permalink / raw)
  To: Alexander Graf; +Cc: avi, mtosatti, kvm, kvm-ia64, kvm-ppc, fernando

(2010/04/20 20:00), Alexander Graf wrote:
>
> On 20.04.2010, at 13:00, Takuya Yoshikawa wrote:
>
>> We are now using generic___set_le_bit() to make dirty bitmaps le.
>> Though this works well, we have to replace __set_bit() to appropriate
>> uaccess function to move dirty bitmaps to user space. So this patch
>> splits generic___set_le_bit() and prepares for that.
>>
>> Signed-off-by: Takuya Yoshikawa<yoshikawa.takuya@oss.ntt.co.jp>
>> Signed-off-by: Fernando Luis Vazquez Cao<fernando@oss.ntt.co.jp>
>> ---
>> virt/kvm/kvm_main.c |   16 +++++++++++-----
>> 1 files changed, 11 insertions(+), 5 deletions(-)
>>
>> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
>> index 6908304..66c4daf 100644
>> --- a/virt/kvm/kvm_main.c
>> +++ b/virt/kvm/kvm_main.c
>> @@ -1194,6 +1194,15 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
>> }
>> EXPORT_SYMBOL_GPL(kvm_clear_guest);
>>
>> +static int __mark_page_dirty(unsigned long nr,
>> +			     unsigned long *dirty_bitmap)
>> +{
>> +#ifdef __BIG_ENDIAN
>> +	nr = nr ^ BITOP_LE_SWIZZLE;
>
> Why an XOR here?
Ah, might be my cut and paste mistake. I just copied from generic___set_le_bit().

>
> Also is this LE set_bit new? I didn't see it when I did the patch back then :).

Really? I need to check the git log then. This LE set_bit is not new I think.

>
>
> Alex
>


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian
@ 2010-04-20 11:20         ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:20 UTC (permalink / raw)
  To: kvm-ia64

(2010/04/20 20:00), Alexander Graf wrote:
>
> On 20.04.2010, at 13:00, Takuya Yoshikawa wrote:
>
>> We are now using generic___set_le_bit() to make dirty bitmaps le.
>> Though this works well, we have to replace __set_bit() to appropriate
>> uaccess function to move dirty bitmaps to user space. So this patch
>> splits generic___set_le_bit() and prepares for that.
>>
>> Signed-off-by: Takuya Yoshikawa<yoshikawa.takuya@oss.ntt.co.jp>
>> Signed-off-by: Fernando Luis Vazquez Cao<fernando@oss.ntt.co.jp>
>> ---
>> virt/kvm/kvm_main.c |   16 +++++++++++-----
>> 1 files changed, 11 insertions(+), 5 deletions(-)
>>
>> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
>> index 6908304..66c4daf 100644
>> --- a/virt/kvm/kvm_main.c
>> +++ b/virt/kvm/kvm_main.c
>> @@ -1194,6 +1194,15 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
>> }
>> EXPORT_SYMBOL_GPL(kvm_clear_guest);
>>
>> +static int __mark_page_dirty(unsigned long nr,
>> +			     unsigned long *dirty_bitmap)
>> +{
>> +#ifdef __BIG_ENDIAN
>> +	nr = nr ^ BITOP_LE_SWIZZLE;
>
> Why an XOR here?
Ah, might be my cut and paste mistake. I just copied from generic___set_le_bit().

>
> Also is this LE set_bit new? I didn't see it when I did the patch back then :).

Really? I need to check the git log then. This LE set_bit is not new I think.

>
>
> Alex
>


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
       [not found]         ` <20234257-D6B8-44A6-BD91-C7B9D0E4970B-l3A5Bk7waGM@public.gmane.org>
  2010-04-20 11:26             ` Takuya Yoshikawa
@ 2010-04-20 11:26             ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:26 UTC (permalink / raw)
  To: Alexander Graf
  Cc: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA,
	kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg

(2010/04/20 20:10), Alexander Graf wrote:
>
> On 20.04.2010, at 13:02, Takuya Yoshikawa wrote:
>
>> We move dirty bitmaps to user space.
>>
>> - Allocation and destruction: we use do_mmap() and do_munmap().
>>    The new bitmap space is twice longer than the original one and we
>>    use the additional space for double buffering: this makes it
>>    possible to update the active bitmap while letting the user space
>>    read the other one safely.
>>
>> - Bitmap manipulations: we replace all functions which access dirty
>>    bitmaps to *_user() functions. Note that some of these should be
>>    optimized later.
>>
>> - For ia64: moving the dirty bitmaps of memory slots does not effect
>>    much to ia64 because it's using a different space to store bitmaps
>>    which is directly updated: all we have to change are sync and get
>>    of dirty log, so we don't need set_bit_user like function for ia64.
>>
>> Signed-off-by: Takuya Yoshikawa<yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
>> Signed-off-by: Fernando Luis Vazquez Cao<fernando-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
>> ---
>> arch/ia64/kvm/kvm-ia64.c  |   12 ++++-
>> arch/powerpc/kvm/book3s.c |    2 +-
>> arch/x86/kvm/x86.c        |   24 +++++-----
>> include/linux/kvm_host.h  |    5 +-
>> virt/kvm/kvm_main.c       |  101 ++++++++++++++++++++++++++++++++++++++++-----
>> 5 files changed, 116 insertions(+), 28 deletions(-)
>>
>>
>
> [...]
>
>> @@ -778,13 +803,45 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
>> }
>>
>> int kvm_copy_dirty_bitmap(unsigned long __user *to,
>> -			  const unsigned long *from,
>> +			  const unsigned long __user *from,
>> 			  unsigned long bytes)
>> {
>> -	if (copy_to_user(to, from, bytes))
>> +#if defined(CONFIG_X86_64) || defined(CONFIG_PPC64) || defined(CONFIG_IA64)
>
> Wouldn't it be better to have a define __HAS_COPY_IN_USER or so? I really dislike writing out all architectures that have this explicitly.

Yes, I completely agree with you: actually, I am not determined to use this finally or not.
The best way is to make generic copy_in_user().

Anyway, yes, next time, I will define macro as you suggest!

>
>> +	if (copy_in_user(to, from, bytes)) {
>> +		printk(KERN_WARNING "%s: copy_in_user failed.\n", __func__);
>> 		return -EFAULT;
>> +	}
>> +	return 0;
>> +#else
>
> Worst case I'd at least like to see all the others written out here, so when someone adds a new arch he can at least check if it's supported or not.
>
>> +	int num, bufbytes;
>> +	unsigned long buf[32];
>>
>> +	if (!access_ok(VERIFY_READ, from, bytes) ||
>> +	    !access_ok(VERIFY_WRITE, to, bytes)) {
>> +		goto out_fault;
>> +	}
>> +
>> +	bufbytes = sizeof(buf);
>> +	num = bufbytes / sizeof(buf[0]);
>
> ARRAY_SIZE?

OK, thanks!

>
>> +
>> +	for (; bytes>  bufbytes; bytes -= bufbytes, to += num, from += num) {
>> +		if (__copy_from_user(buf, from, bufbytes))
>> +			goto out_fault;
>> +		if (__copy_to_user(to, buf, bufbytes))
>> +			goto out_fault;
>> +	}
>> +	if (bytes>  0) {
>> +		if (__copy_from_user(buf, from, bytes))
>> +			goto out_fault;
>> +		if (__copy_to_user(to, buf, bytes))
>> +			goto out_fault;
>> +	}
>> 	return 0;
>> +
>> +out_fault:
>> +	printk(KERN_WARNING "%s: copy to(from) user failed.\n", __func__);
>> +	return -EFAULT;
>> +#endif
>> }
>>
>> int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
>> @@ -1194,13 +1251,35 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
>> }
>> EXPORT_SYMBOL_GPL(kvm_clear_guest);
>>
>> +/*
>> + * Please use generic *_user bitops once they become available.
>> + * Be careful setting the bit won't be done atomically.
>> + */
>> static int __mark_page_dirty(unsigned long nr,
>> -			     unsigned long *dirty_bitmap)
>> +			     unsigned long __user *dirty_bitmap)
>> {
>> +	unsigned long user_addr;
>> +	u8 val;
>> +
>> #ifdef __BIG_ENDIAN
>> 	nr = nr ^ BITOP_LE_SWIZZLE;
>> #endif
>> -	__set_bit(nr, dirty_bitmap);
>> +	user_addr = (unsigned long)dirty_bitmap + nr / 8;
>
> BITS_PER_BYTE
>
>> +	if (!access_ok(VERIFY_WRITE, user_addr, 1))
>> +		goto out_fault;
>> +
>> +	if (__get_user(val, (u8 __user *)user_addr))
>> +		goto out_fault;
>> +
>> +	val |= 1U<<  (nr % 8);
>
> see above
>
>
> Alex
>

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-20 11:26             ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:26 UTC (permalink / raw)
  To: Alexander Graf
  Cc: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA,
	kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg

(2010/04/20 20:10), Alexander Graf wrote:
>
> On 20.04.2010, at 13:02, Takuya Yoshikawa wrote:
>
>> We move dirty bitmaps to user space.
>>
>> - Allocation and destruction: we use do_mmap() and do_munmap().
>>    The new bitmap space is twice longer than the original one and we
>>    use the additional space for double buffering: this makes it
>>    possible to update the active bitmap while letting the user space
>>    read the other one safely.
>>
>> - Bitmap manipulations: we replace all functions which access dirty
>>    bitmaps to *_user() functions. Note that some of these should be
>>    optimized later.
>>
>> - For ia64: moving the dirty bitmaps of memory slots does not effect
>>    much to ia64 because it's using a different space to store bitmaps
>>    which is directly updated: all we have to change are sync and get
>>    of dirty log, so we don't need set_bit_user like function for ia64.
>>
>> Signed-off-by: Takuya Yoshikawa<yoshikawa.takuya@oss.ntt.co.jp>
>> Signed-off-by: Fernando Luis Vazquez Cao<fernando@oss.ntt.co.jp>
>> ---
>> arch/ia64/kvm/kvm-ia64.c  |   12 ++++-
>> arch/powerpc/kvm/book3s.c |    2 +-
>> arch/x86/kvm/x86.c        |   24 +++++-----
>> include/linux/kvm_host.h  |    5 +-
>> virt/kvm/kvm_main.c       |  101 ++++++++++++++++++++++++++++++++++++++++-----
>> 5 files changed, 116 insertions(+), 28 deletions(-)
>>
>>
>
> [...]
>
>> @@ -778,13 +803,45 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
>> }
>>
>> int kvm_copy_dirty_bitmap(unsigned long __user *to,
>> -			  const unsigned long *from,
>> +			  const unsigned long __user *from,
>> 			  unsigned long bytes)
>> {
>> -	if (copy_to_user(to, from, bytes))
>> +#if defined(CONFIG_X86_64) || defined(CONFIG_PPC64) || defined(CONFIG_IA64)
>
> Wouldn't it be better to have a define __HAS_COPY_IN_USER or so? I really dislike writing out all architectures that have this explicitly.

Yes, I completely agree with you: actually, I am not determined to use this finally or not.
The best way is to make generic copy_in_user().

Anyway, yes, next time, I will define macro as you suggest!

>
>> +	if (copy_in_user(to, from, bytes)) {
>> +		printk(KERN_WARNING "%s: copy_in_user failed.\n", __func__);
>> 		return -EFAULT;
>> +	}
>> +	return 0;
>> +#else
>
> Worst case I'd at least like to see all the others written out here, so when someone adds a new arch he can at least check if it's supported or not.
>
>> +	int num, bufbytes;
>> +	unsigned long buf[32];
>>
>> +	if (!access_ok(VERIFY_READ, from, bytes) ||
>> +	    !access_ok(VERIFY_WRITE, to, bytes)) {
>> +		goto out_fault;
>> +	}
>> +
>> +	bufbytes = sizeof(buf);
>> +	num = bufbytes / sizeof(buf[0]);
>
> ARRAY_SIZE?

OK, thanks!

>
>> +
>> +	for (; bytes>  bufbytes; bytes -= bufbytes, to += num, from += num) {
>> +		if (__copy_from_user(buf, from, bufbytes))
>> +			goto out_fault;
>> +		if (__copy_to_user(to, buf, bufbytes))
>> +			goto out_fault;
>> +	}
>> +	if (bytes>  0) {
>> +		if (__copy_from_user(buf, from, bytes))
>> +			goto out_fault;
>> +		if (__copy_to_user(to, buf, bytes))
>> +			goto out_fault;
>> +	}
>> 	return 0;
>> +
>> +out_fault:
>> +	printk(KERN_WARNING "%s: copy to(from) user failed.\n", __func__);
>> +	return -EFAULT;
>> +#endif
>> }
>>
>> int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
>> @@ -1194,13 +1251,35 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
>> }
>> EXPORT_SYMBOL_GPL(kvm_clear_guest);
>>
>> +/*
>> + * Please use generic *_user bitops once they become available.
>> + * Be careful setting the bit won't be done atomically.
>> + */
>> static int __mark_page_dirty(unsigned long nr,
>> -			     unsigned long *dirty_bitmap)
>> +			     unsigned long __user *dirty_bitmap)
>> {
>> +	unsigned long user_addr;
>> +	u8 val;
>> +
>> #ifdef __BIG_ENDIAN
>> 	nr = nr ^ BITOP_LE_SWIZZLE;
>> #endif
>> -	__set_bit(nr, dirty_bitmap);
>> +	user_addr = (unsigned long)dirty_bitmap + nr / 8;
>
> BITS_PER_BYTE
>
>> +	if (!access_ok(VERIFY_WRITE, user_addr, 1))
>> +		goto out_fault;
>> +
>> +	if (__get_user(val, (u8 __user *)user_addr))
>> +		goto out_fault;
>> +
>> +	val |= 1U<<  (nr % 8);
>
> see above
>
>
> Alex
>


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-20 11:26             ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:26 UTC (permalink / raw)
  To: kvm-ia64

(2010/04/20 20:10), Alexander Graf wrote:
>
> On 20.04.2010, at 13:02, Takuya Yoshikawa wrote:
>
>> We move dirty bitmaps to user space.
>>
>> - Allocation and destruction: we use do_mmap() and do_munmap().
>>    The new bitmap space is twice longer than the original one and we
>>    use the additional space for double buffering: this makes it
>>    possible to update the active bitmap while letting the user space
>>    read the other one safely.
>>
>> - Bitmap manipulations: we replace all functions which access dirty
>>    bitmaps to *_user() functions. Note that some of these should be
>>    optimized later.
>>
>> - For ia64: moving the dirty bitmaps of memory slots does not effect
>>    much to ia64 because it's using a different space to store bitmaps
>>    which is directly updated: all we have to change are sync and get
>>    of dirty log, so we don't need set_bit_user like function for ia64.
>>
>> Signed-off-by: Takuya Yoshikawa<yoshikawa.takuya@oss.ntt.co.jp>
>> Signed-off-by: Fernando Luis Vazquez Cao<fernando@oss.ntt.co.jp>
>> ---
>> arch/ia64/kvm/kvm-ia64.c  |   12 ++++-
>> arch/powerpc/kvm/book3s.c |    2 +-
>> arch/x86/kvm/x86.c        |   24 +++++-----
>> include/linux/kvm_host.h  |    5 +-
>> virt/kvm/kvm_main.c       |  101 ++++++++++++++++++++++++++++++++++++++++-----
>> 5 files changed, 116 insertions(+), 28 deletions(-)
>>
>>
>
> [...]
>
>> @@ -778,13 +803,45 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
>> }
>>
>> int kvm_copy_dirty_bitmap(unsigned long __user *to,
>> -			  const unsigned long *from,
>> +			  const unsigned long __user *from,
>> 			  unsigned long bytes)
>> {
>> -	if (copy_to_user(to, from, bytes))
>> +#if defined(CONFIG_X86_64) || defined(CONFIG_PPC64) || defined(CONFIG_IA64)
>
> Wouldn't it be better to have a define __HAS_COPY_IN_USER or so? I really dislike writing out all architectures that have this explicitly.

Yes, I completely agree with you: actually, I am not determined to use this finally or not.
The best way is to make generic copy_in_user().

Anyway, yes, next time, I will define macro as you suggest!

>
>> +	if (copy_in_user(to, from, bytes)) {
>> +		printk(KERN_WARNING "%s: copy_in_user failed.\n", __func__);
>> 		return -EFAULT;
>> +	}
>> +	return 0;
>> +#else
>
> Worst case I'd at least like to see all the others written out here, so when someone adds a new arch he can at least check if it's supported or not.
>
>> +	int num, bufbytes;
>> +	unsigned long buf[32];
>>
>> +	if (!access_ok(VERIFY_READ, from, bytes) ||
>> +	    !access_ok(VERIFY_WRITE, to, bytes)) {
>> +		goto out_fault;
>> +	}
>> +
>> +	bufbytes = sizeof(buf);
>> +	num = bufbytes / sizeof(buf[0]);
>
> ARRAY_SIZE?

OK, thanks!

>
>> +
>> +	for (; bytes>  bufbytes; bytes -= bufbytes, to += num, from += num) {
>> +		if (__copy_from_user(buf, from, bufbytes))
>> +			goto out_fault;
>> +		if (__copy_to_user(to, buf, bufbytes))
>> +			goto out_fault;
>> +	}
>> +	if (bytes>  0) {
>> +		if (__copy_from_user(buf, from, bytes))
>> +			goto out_fault;
>> +		if (__copy_to_user(to, buf, bytes))
>> +			goto out_fault;
>> +	}
>> 	return 0;
>> +
>> +out_fault:
>> +	printk(KERN_WARNING "%s: copy to(from) user failed.\n", __func__);
>> +	return -EFAULT;
>> +#endif
>> }
>>
>> int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
>> @@ -1194,13 +1251,35 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
>> }
>> EXPORT_SYMBOL_GPL(kvm_clear_guest);
>>
>> +/*
>> + * Please use generic *_user bitops once they become available.
>> + * Be careful setting the bit won't be done atomically.
>> + */
>> static int __mark_page_dirty(unsigned long nr,
>> -			     unsigned long *dirty_bitmap)
>> +			     unsigned long __user *dirty_bitmap)
>> {
>> +	unsigned long user_addr;
>> +	u8 val;
>> +
>> #ifdef __BIG_ENDIAN
>> 	nr = nr ^ BITOP_LE_SWIZZLE;
>> #endif
>> -	__set_bit(nr, dirty_bitmap);
>> +	user_addr = (unsigned long)dirty_bitmap + nr / 8;
>
> BITS_PER_BYTE
>
>> +	if (!access_ok(VERIFY_WRITE, user_addr, 1))
>> +		goto out_fault;
>> +
>> +	if (__get_user(val, (u8 __user *)user_addr))
>> +		goto out_fault;
>> +
>> +	val |= 1U<<  (nr % 8);
>
> see above
>
>
> Alex
>


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
       [not found]           ` <4BCD90FE.9060300-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
  2010-04-20 11:33               ` Alexander Graf
@ 2010-04-20 11:33               ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-20 11:33 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA,
	kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg


On 20.04.2010, at 13:33, Takuya Yoshikawa wrote:

> (2010/04/20 20:15), Alexander Graf wrote:
>> 
>> On 20.04.2010, at 13:03, Takuya Yoshikawa wrote:
>> 
>>> We can now export the addree of the bitmap created by do_mmap()
>>> to user space. For the sake of this, we introduce a new API:
>>> 
>>>  KVM_SWITCH_DIRTY_LOG: application can use this to trigger the
>>>  switch of the bitmaps and get the address of the bitmap which
>>>  has been used until now. This reduces the copy of the dirty
>>>  bitmap from the kernel.
>>> 
>>> Signed-off-by: Takuya Yoshikawa<yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
>>> Cc: Fernando Luis Vazquez Cao<fernando-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
>>> ---
>>> Documentation/kvm/api.txt |   23 +++++++++++++++++++++++
>>> arch/ia64/kvm/kvm-ia64.c  |   19 ++++++++++++++-----
>>> arch/powerpc/kvm/book3s.c |   19 ++++++++++++++-----
>>> arch/x86/kvm/x86.c        |   32 ++++++++++++++++++++++++++------
>>> include/linux/kvm.h       |    6 ++++--
>>> include/linux/kvm_host.h  |    7 ++++---
>>> virt/kvm/kvm_main.c       |   41 ++++++++++++++++++++++++++++++++++++-----
>>> 7 files changed, 121 insertions(+), 26 deletions(-)
>>> 
>> 
>> [...]
>> 
>>> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
>>> index 23ea022..9fa6f1e 100644
>>> --- a/include/linux/kvm.h
>>> +++ b/include/linux/kvm.h
>>> @@ -12,7 +12,7 @@
>>> #include<linux/ioctl.h>
>>> #include<asm/kvm.h>
>>> 
>>> -#define KVM_API_VERSION 12
>>> +#define KVM_API_VERSION 13
>> 
>> Is there a way to keep both interfaces around for some time at least? I'd prefer the API version not to change if not _really_ necessary.
>> 
>> To enable the new dirty mapping you could for example use KVM_CAP_ENABLE_CAP :-).
> 
> Thanks, I did not know what is the appropriate way for this kind of change.
> 
> I just read the comments in the kvm.h and thought I had to update the number whenever
> I added some entries to kvm.h .

The rule of thumb is:

KVM_API_VERSION change -> complete breakage. No way to run older userspace on newer kernels.
new CAP -> optional feature

If I read correctly you're changing quite a few existing interfaces, so old userspace wouldn't work anymore. Hence I'm proposing using activating the new way of dirty logging optionally.

Alex

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-20 11:33               ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-20 11:33 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA,
	kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg


On 20.04.2010, at 13:33, Takuya Yoshikawa wrote:

> (2010/04/20 20:15), Alexander Graf wrote:
>> 
>> On 20.04.2010, at 13:03, Takuya Yoshikawa wrote:
>> 
>>> We can now export the addree of the bitmap created by do_mmap()
>>> to user space. For the sake of this, we introduce a new API:
>>> 
>>>  KVM_SWITCH_DIRTY_LOG: application can use this to trigger the
>>>  switch of the bitmaps and get the address of the bitmap which
>>>  has been used until now. This reduces the copy of the dirty
>>>  bitmap from the kernel.
>>> 
>>> Signed-off-by: Takuya Yoshikawa<yoshikawa.takuya@oss.ntt.co.jp>
>>> Cc: Fernando Luis Vazquez Cao<fernando@oss.ntt.co.jp>
>>> ---
>>> Documentation/kvm/api.txt |   23 +++++++++++++++++++++++
>>> arch/ia64/kvm/kvm-ia64.c  |   19 ++++++++++++++-----
>>> arch/powerpc/kvm/book3s.c |   19 ++++++++++++++-----
>>> arch/x86/kvm/x86.c        |   32 ++++++++++++++++++++++++++------
>>> include/linux/kvm.h       |    6 ++++--
>>> include/linux/kvm_host.h  |    7 ++++---
>>> virt/kvm/kvm_main.c       |   41 ++++++++++++++++++++++++++++++++++++-----
>>> 7 files changed, 121 insertions(+), 26 deletions(-)
>>> 
>> 
>> [...]
>> 
>>> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
>>> index 23ea022..9fa6f1e 100644
>>> --- a/include/linux/kvm.h
>>> +++ b/include/linux/kvm.h
>>> @@ -12,7 +12,7 @@
>>> #include<linux/ioctl.h>
>>> #include<asm/kvm.h>
>>> 
>>> -#define KVM_API_VERSION 12
>>> +#define KVM_API_VERSION 13
>> 
>> Is there a way to keep both interfaces around for some time at least? I'd prefer the API version not to change if not _really_ necessary.
>> 
>> To enable the new dirty mapping you could for example use KVM_CAP_ENABLE_CAP :-).
> 
> Thanks, I did not know what is the appropriate way for this kind of change.
> 
> I just read the comments in the kvm.h and thought I had to update the number whenever
> I added some entries to kvm.h .

The rule of thumb is:

KVM_API_VERSION change -> complete breakage. No way to run older userspace on newer kernels.
new CAP -> optional feature

If I read correctly you're changing quite a few existing interfaces, so old userspace wouldn't work anymore. Hence I'm proposing using activating the new way of dirty logging optionally.

Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-20 11:33               ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-20 11:33 UTC (permalink / raw)
  To: kvm-ia64


On 20.04.2010, at 13:33, Takuya Yoshikawa wrote:

> (2010/04/20 20:15), Alexander Graf wrote:
>> 
>> On 20.04.2010, at 13:03, Takuya Yoshikawa wrote:
>> 
>>> We can now export the addree of the bitmap created by do_mmap()
>>> to user space. For the sake of this, we introduce a new API:
>>> 
>>>  KVM_SWITCH_DIRTY_LOG: application can use this to trigger the
>>>  switch of the bitmaps and get the address of the bitmap which
>>>  has been used until now. This reduces the copy of the dirty
>>>  bitmap from the kernel.
>>> 
>>> Signed-off-by: Takuya Yoshikawa<yoshikawa.takuya@oss.ntt.co.jp>
>>> Cc: Fernando Luis Vazquez Cao<fernando@oss.ntt.co.jp>
>>> ---
>>> Documentation/kvm/api.txt |   23 +++++++++++++++++++++++
>>> arch/ia64/kvm/kvm-ia64.c  |   19 ++++++++++++++-----
>>> arch/powerpc/kvm/book3s.c |   19 ++++++++++++++-----
>>> arch/x86/kvm/x86.c        |   32 ++++++++++++++++++++++++++------
>>> include/linux/kvm.h       |    6 ++++--
>>> include/linux/kvm_host.h  |    7 ++++---
>>> virt/kvm/kvm_main.c       |   41 ++++++++++++++++++++++++++++++++++++-----
>>> 7 files changed, 121 insertions(+), 26 deletions(-)
>>> 
>> 
>> [...]
>> 
>>> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
>>> index 23ea022..9fa6f1e 100644
>>> --- a/include/linux/kvm.h
>>> +++ b/include/linux/kvm.h
>>> @@ -12,7 +12,7 @@
>>> #include<linux/ioctl.h>
>>> #include<asm/kvm.h>
>>> 
>>> -#define KVM_API_VERSION 12
>>> +#define KVM_API_VERSION 13
>> 
>> Is there a way to keep both interfaces around for some time at least? I'd prefer the API version not to change if not _really_ necessary.
>> 
>> To enable the new dirty mapping you could for example use KVM_CAP_ENABLE_CAP :-).
> 
> Thanks, I did not know what is the appropriate way for this kind of change.
> 
> I just read the comments in the kvm.h and thought I had to update the number whenever
> I added some entries to kvm.h .

The rule of thumb is:

KVM_API_VERSION change -> complete breakage. No way to run older userspace on newer kernels.
new CAP -> optional feature

If I read correctly you're changing quite a few existing interfaces, so old userspace wouldn't work anymore. Hence I'm proposing using activating the new way of dirty logging optionally.

Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
       [not found]       ` <480E8E1E-32BD-429E-96C8-5AA69A8BDDF3-l3A5Bk7waGM@public.gmane.org>
  2010-04-20 11:33           ` Takuya Yoshikawa
@ 2010-04-20 11:33           ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:33 UTC (permalink / raw)
  To: Alexander Graf
  Cc: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA,
	kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg

(2010/04/20 20:15), Alexander Graf wrote:
>
> On 20.04.2010, at 13:03, Takuya Yoshikawa wrote:
>
>> We can now export the addree of the bitmap created by do_mmap()
>> to user space. For the sake of this, we introduce a new API:
>>
>>   KVM_SWITCH_DIRTY_LOG: application can use this to trigger the
>>   switch of the bitmaps and get the address of the bitmap which
>>   has been used until now. This reduces the copy of the dirty
>>   bitmap from the kernel.
>>
>> Signed-off-by: Takuya Yoshikawa<yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
>> Cc: Fernando Luis Vazquez Cao<fernando-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
>> ---
>> Documentation/kvm/api.txt |   23 +++++++++++++++++++++++
>> arch/ia64/kvm/kvm-ia64.c  |   19 ++++++++++++++-----
>> arch/powerpc/kvm/book3s.c |   19 ++++++++++++++-----
>> arch/x86/kvm/x86.c        |   32 ++++++++++++++++++++++++++------
>> include/linux/kvm.h       |    6 ++++--
>> include/linux/kvm_host.h  |    7 ++++---
>> virt/kvm/kvm_main.c       |   41 ++++++++++++++++++++++++++++++++++++-----
>> 7 files changed, 121 insertions(+), 26 deletions(-)
>>
>
> [...]
>
>> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
>> index 23ea022..9fa6f1e 100644
>> --- a/include/linux/kvm.h
>> +++ b/include/linux/kvm.h
>> @@ -12,7 +12,7 @@
>> #include<linux/ioctl.h>
>> #include<asm/kvm.h>
>>
>> -#define KVM_API_VERSION 12
>> +#define KVM_API_VERSION 13
>
> Is there a way to keep both interfaces around for some time at least? I'd prefer the API version not to change if not _really_ necessary.
>
> To enable the new dirty mapping you could for example use KVM_CAP_ENABLE_CAP :-).

Thanks, I did not know what is the appropriate way for this kind of change.

I just read the comments in the kvm.h and thought I had to update the number whenever
I added some entries to kvm.h .


>
>
> Alex
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-20 11:33           ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:33 UTC (permalink / raw)
  To: Alexander Graf
  Cc: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA,
	kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg

(2010/04/20 20:15), Alexander Graf wrote:
>
> On 20.04.2010, at 13:03, Takuya Yoshikawa wrote:
>
>> We can now export the addree of the bitmap created by do_mmap()
>> to user space. For the sake of this, we introduce a new API:
>>
>>   KVM_SWITCH_DIRTY_LOG: application can use this to trigger the
>>   switch of the bitmaps and get the address of the bitmap which
>>   has been used until now. This reduces the copy of the dirty
>>   bitmap from the kernel.
>>
>> Signed-off-by: Takuya Yoshikawa<yoshikawa.takuya@oss.ntt.co.jp>
>> Cc: Fernando Luis Vazquez Cao<fernando@oss.ntt.co.jp>
>> ---
>> Documentation/kvm/api.txt |   23 +++++++++++++++++++++++
>> arch/ia64/kvm/kvm-ia64.c  |   19 ++++++++++++++-----
>> arch/powerpc/kvm/book3s.c |   19 ++++++++++++++-----
>> arch/x86/kvm/x86.c        |   32 ++++++++++++++++++++++++++------
>> include/linux/kvm.h       |    6 ++++--
>> include/linux/kvm_host.h  |    7 ++++---
>> virt/kvm/kvm_main.c       |   41 ++++++++++++++++++++++++++++++++++++-----
>> 7 files changed, 121 insertions(+), 26 deletions(-)
>>
>
> [...]
>
>> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
>> index 23ea022..9fa6f1e 100644
>> --- a/include/linux/kvm.h
>> +++ b/include/linux/kvm.h
>> @@ -12,7 +12,7 @@
>> #include<linux/ioctl.h>
>> #include<asm/kvm.h>
>>
>> -#define KVM_API_VERSION 12
>> +#define KVM_API_VERSION 13
>
> Is there a way to keep both interfaces around for some time at least? I'd prefer the API version not to change if not _really_ necessary.
>
> To enable the new dirty mapping you could for example use KVM_CAP_ENABLE_CAP :-).

Thanks, I did not know what is the appropriate way for this kind of change.

I just read the comments in the kvm.h and thought I had to update the number whenever
I added some entries to kvm.h .


>
>
> Alex
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-20 11:33           ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:33 UTC (permalink / raw)
  To: kvm-ia64

(2010/04/20 20:15), Alexander Graf wrote:
>
> On 20.04.2010, at 13:03, Takuya Yoshikawa wrote:
>
>> We can now export the addree of the bitmap created by do_mmap()
>> to user space. For the sake of this, we introduce a new API:
>>
>>   KVM_SWITCH_DIRTY_LOG: application can use this to trigger the
>>   switch of the bitmaps and get the address of the bitmap which
>>   has been used until now. This reduces the copy of the dirty
>>   bitmap from the kernel.
>>
>> Signed-off-by: Takuya Yoshikawa<yoshikawa.takuya@oss.ntt.co.jp>
>> Cc: Fernando Luis Vazquez Cao<fernando@oss.ntt.co.jp>
>> ---
>> Documentation/kvm/api.txt |   23 +++++++++++++++++++++++
>> arch/ia64/kvm/kvm-ia64.c  |   19 ++++++++++++++-----
>> arch/powerpc/kvm/book3s.c |   19 ++++++++++++++-----
>> arch/x86/kvm/x86.c        |   32 ++++++++++++++++++++++++++------
>> include/linux/kvm.h       |    6 ++++--
>> include/linux/kvm_host.h  |    7 ++++---
>> virt/kvm/kvm_main.c       |   41 ++++++++++++++++++++++++++++++++++++-----
>> 7 files changed, 121 insertions(+), 26 deletions(-)
>>
>
> [...]
>
>> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
>> index 23ea022..9fa6f1e 100644
>> --- a/include/linux/kvm.h
>> +++ b/include/linux/kvm.h
>> @@ -12,7 +12,7 @@
>> #include<linux/ioctl.h>
>> #include<asm/kvm.h>
>>
>> -#define KVM_API_VERSION 12
>> +#define KVM_API_VERSION 13
>
> Is there a way to keep both interfaces around for some time at least? I'd prefer the API version not to change if not _really_ necessary.
>
> To enable the new dirty mapping you could for example use KVM_CAP_ENABLE_CAP :-).

Thanks, I did not know what is the appropriate way for this kind of change.

I just read the comments in the kvm.h and thought I had to update the number whenever
I added some entries to kvm.h .


>
>
> Alex
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
  2010-04-20 11:33               ` Alexander Graf
  (?)
@ 2010-04-20 11:44                 ` Takuya Yoshikawa
  -1 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:44 UTC (permalink / raw)
  To: Alexander Graf; +Cc: avi, mtosatti, kvm, kvm-ia64, kvm-ppc, fernando

(2010/04/20 20:33), Alexander Graf wrote:
>>>>
>>>> -#define KVM_API_VERSION 12
>>>> +#define KVM_API_VERSION 13
>>>
>>> Is there a way to keep both interfaces around for some time at least? I'd prefer the API version not to change if not _really_ necessary.
>>>
>>> To enable the new dirty mapping you could for example use KVM_CAP_ENABLE_CAP :-).
>>
>> Thanks, I did not know what is the appropriate way for this kind of change.
>>
>> I just read the comments in the kvm.h and thought I had to update the number whenever
>> I added some entries to kvm.h .
>
> The rule of thumb is:
>
> KVM_API_VERSION change ->  complete breakage. No way to run older userspace on newer kernels.
> new CAP ->  optional feature
>
> If I read correctly you're changing quite a few existing interfaces, so old userspace wouldn't work anymore. Hence I'm proposing using activating the new way of dirty logging optionally.
>
> Alex
>

The fact is, I am trying to keep the existing interfaces completely(KVM_API_VERSION part is my mistake).

For x86, I have checked that current qemu works without any change.
I mean we can use get_dirty_log() as is.

And as you propose, we can determine which api(swith_* or get_*) we use optionally.

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-20 11:44                 ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:44 UTC (permalink / raw)
  To: Alexander Graf; +Cc: avi, mtosatti, kvm, kvm-ia64, kvm-ppc, fernando

(2010/04/20 20:33), Alexander Graf wrote:
>>>>
>>>> -#define KVM_API_VERSION 12
>>>> +#define KVM_API_VERSION 13
>>>
>>> Is there a way to keep both interfaces around for some time at least? I'd prefer the API version not to change if not _really_ necessary.
>>>
>>> To enable the new dirty mapping you could for example use KVM_CAP_ENABLE_CAP :-).
>>
>> Thanks, I did not know what is the appropriate way for this kind of change.
>>
>> I just read the comments in the kvm.h and thought I had to update the number whenever
>> I added some entries to kvm.h .
>
> The rule of thumb is:
>
> KVM_API_VERSION change ->  complete breakage. No way to run older userspace on newer kernels.
> new CAP ->  optional feature
>
> If I read correctly you're changing quite a few existing interfaces, so old userspace wouldn't work anymore. Hence I'm proposing using activating the new way of dirty logging optionally.
>
> Alex
>

The fact is, I am trying to keep the existing interfaces completely(KVM_API_VERSION part is my mistake).

For x86, I have checked that current qemu works without any change.
I mean we can use get_dirty_log() as is.

And as you propose, we can determine which api(swith_* or get_*) we use optionally.

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-20 11:44                 ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 11:44 UTC (permalink / raw)
  To: kvm-ia64

(2010/04/20 20:33), Alexander Graf wrote:
>>>>
>>>> -#define KVM_API_VERSION 12
>>>> +#define KVM_API_VERSION 13
>>>
>>> Is there a way to keep both interfaces around for some time at least? I'd prefer the API version not to change if not _really_ necessary.
>>>
>>> To enable the new dirty mapping you could for example use KVM_CAP_ENABLE_CAP :-).
>>
>> Thanks, I did not know what is the appropriate way for this kind of change.
>>
>> I just read the comments in the kvm.h and thought I had to update the number whenever
>> I added some entries to kvm.h .
>
> The rule of thumb is:
>
> KVM_API_VERSION change ->  complete breakage. No way to run older userspace on newer kernels.
> new CAP ->  optional feature
>
> If I read correctly you're changing quite a few existing interfaces, so old userspace wouldn't work anymore. Hence I'm proposing using activating the new way of dirty logging optionally.
>
> Alex
>

The fact is, I am trying to keep the existing interfaces completely(KVM_API_VERSION part is my mistake).

For x86, I have checked that current qemu works without any change.
I mean we can use get_dirty_log() as is.

And as you propose, we can determine which api(swith_* or get_*) we use optionally.

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 0/6] KVM: moving dirty gitmaps to user space!
       [not found] ` <20100420195349.dab60b1d.yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
  2010-04-20 10:58     ` Takuya Yoshikawa
@ 2010-04-20 12:05     ` Takuya Yoshikawa
  2010-04-20 11:03     ` Takuya Yoshikawa
  2010-04-20 12:05     ` Takuya Yoshikawa
  3 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 12:05 UTC (permalink / raw)
  To: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA,
	Fernando Luis Vázquez Cao
  Cc: kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA

Fernando, sorry I have changed some part of this series and forgot to
change your Signed-off-by to Cc for some parts.

So please give me any comments(objections) as replies to this mail thread.


Thanks,
   Takuya


(2010/04/20 19:53), Takuya Yoshikawa wrote:
> Hi, this is the v2 of the "moving dirty gitmaps to user space!"
>
> By this patch, I think everything we need becomes clear.
> So we want to step forward to be ready for the final version in the
> near future: of course, this is dependent on x86 and ppc asm issues.
>
> BTW, by whom I can get ACK for ppc and ia64? I want to add to the Cc
> list if possible, thank you.
>
>
> Patch1: introduce slot level dirty state management
>    This patch is independent from other patches and seems to be
>    useful without the following parts.
>
> Patch2: introduce wrapper functions to create and destroy dirty bitmaps
>    Cleanup patch.
>
> Patch3: introduce a wrapper function to copy dirty bitmaps to user space
>    This is for dealing copy_in_user() things cleanly.
>
> Patch4: change mark_page_dirty() to handle endian issues explicitly
>    Later, __set_bit() part will be replaced with *_user function.
>
> Patch5: moving dirty bitmaps to user space
>    Replace dirty bitmap manipulations with *_user functions.
>
> Patch6: introduce a new API for getting dirty bitmaps
>    This is to access dirty bitmaps from user space.
>
>
> Changelog:
>   - suport for all architectures
>     We have achived this without pinning.
>   - one possible API suggestion
>   - temporary copy_in_user like function
>   - temporary set_bit_user like function with __get_user() and __put_user()
>     We can use this as a generic set_bit_user_non_atomic().
>     Of course, we need to optimize this part with arch specific one: we are
>     testing some versions for x86 now.
>
> What we are thinking about:
>   - about set_bit_user_non_atomic()
>     We noticed that ia64 won't need this: see patch1 and patch5.
>     So all we have to do is to complete the implementations for x86 and ppc.
>     ** x86 and ppc don't include asm-generic uaccess. So we have to put these
>        into them separately.
>
>   - about the new api
>     There are many possible styles to make use of this work.
>     E.g. if we export the both addresses of the two bitmaps,
>     we don't need to export them at the switch timing: but we cannot
>     reuse the current structures in this case. Which is better?
>
>
> ===
>
> Appendix:
>
> To test the patch 6, we are using the following patch for qemu-kvm.
> ---
>   configure  |    2 +-
>   qemu-kvm.c |   22 +++++++++++++++++-----
>   2 files changed, 18 insertions(+), 6 deletions(-)
>
> diff --git a/configure b/configure
> index be8dac4..0b2d017 100755
> --- a/configure
> +++ b/configure
> @@ -1498,7 +1498,7 @@ fi
>   if test "$kvm" != "no" ; then
>       cat>  $TMPC<<EOF
>   #include<linux/kvm.h>
> -#if !defined(KVM_API_VERSION) || KVM_API_VERSION<  12 || KVM_API_VERSION>  12
> +#if !defined(KVM_API_VERSION) || KVM_API_VERSION<  13 || KVM_API_VERSION>  13
>   #error Invalid KVM version
>   #endif
>   #if !defined(KVM_CAP_USER_MEMORY)
> diff --git a/qemu-kvm.c b/qemu-kvm.c
> index cc5b352..087adea 100644
> --- a/qemu-kvm.c
> +++ b/qemu-kvm.c
> @@ -44,7 +44,7 @@
>   #define BUS_MCEERR_AO 5
>   #endif
>
> -#define EXPECTED_KVM_API_VERSION 12
> +#define EXPECTED_KVM_API_VERSION 13
>
>   #if EXPECTED_KVM_API_VERSION != KVM_API_VERSION
>   #error libkvm: userspace and kernel version mismatch
> @@ -684,6 +684,21 @@ static int kvm_get_map(kvm_context_t kvm, int ioctl_num, int slot, void *buf)
>       return 0;
>   }
>
> +static int kvm_switch_map(kvm_context_t kvm, int slot, void **buf)
> +{
> +    int r;
> +    struct kvm_dirty_log log = {
> +        .slot = slot,
> +    };
> +
> +    r = kvm_vm_ioctl(kvm_state, KVM_SWITCH_DIRTY_LOG,&log);
> +    if (r<  0)
> +        return r;
> +
> +    *buf = (void *)log.addr;
> +    return 0;
> +}
> +
>   int kvm_get_dirty_pages(kvm_context_t kvm, unsigned long phys_addr, void *buf)
>   {
>       int slot;
> @@ -706,14 +721,11 @@ int kvm_get_dirty_pages_range(kvm_context_t kvm, unsigned long phys_addr,
>       for (i = 0; i<  KVM_MAX_NUM_MEM_REGIONS; ++i) {
>           if ((slots[i].len&&  (uint64_t) slots[i].phys_addr>= phys_addr)
>               &&  ((uint64_t) slots[i].phys_addr + slots[i].len<= end_addr)) {
> -            buf = qemu_malloc(BITMAP_SIZE(slots[i].len));
> -            r = kvm_get_map(kvm, KVM_GET_DIRTY_LOG, i, buf);
> +            r = kvm_switch_map(kvm, i,&buf);
>               if (r) {
> -                qemu_free(buf);
>                   return r;
>               }
>               r = cb(slots[i].phys_addr, slots[i].len, buf, opaque);
> -            qemu_free(buf);
>               if (r)
>                   return r;
>           }

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 0/6] KVM: moving dirty gitmaps to user space!
@ 2010-04-20 12:05     ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 12:05 UTC (permalink / raw)
  To: avi-H+wXaHxf7aLQT0dZR+AlfA, mtosatti-H+wXaHxf7aLQT0dZR+AlfA,
	Fernando Luis Vázquez Cao
  Cc: kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA

Fernando, sorry I have changed some part of this series and forgot to
change your Signed-off-by to Cc for some parts.

So please give me any comments(objections) as replies to this mail thread.


Thanks,
   Takuya


(2010/04/20 19:53), Takuya Yoshikawa wrote:
> Hi, this is the v2 of the "moving dirty gitmaps to user space!"
>
> By this patch, I think everything we need becomes clear.
> So we want to step forward to be ready for the final version in the
> near future: of course, this is dependent on x86 and ppc asm issues.
>
> BTW, by whom I can get ACK for ppc and ia64? I want to add to the Cc
> list if possible, thank you.
>
>
> Patch1: introduce slot level dirty state management
>    This patch is independent from other patches and seems to be
>    useful without the following parts.
>
> Patch2: introduce wrapper functions to create and destroy dirty bitmaps
>    Cleanup patch.
>
> Patch3: introduce a wrapper function to copy dirty bitmaps to user space
>    This is for dealing copy_in_user() things cleanly.
>
> Patch4: change mark_page_dirty() to handle endian issues explicitly
>    Later, __set_bit() part will be replaced with *_user function.
>
> Patch5: moving dirty bitmaps to user space
>    Replace dirty bitmap manipulations with *_user functions.
>
> Patch6: introduce a new API for getting dirty bitmaps
>    This is to access dirty bitmaps from user space.
>
>
> Changelog:
>   - suport for all architectures
>     We have achived this without pinning.
>   - one possible API suggestion
>   - temporary copy_in_user like function
>   - temporary set_bit_user like function with __get_user() and __put_user()
>     We can use this as a generic set_bit_user_non_atomic().
>     Of course, we need to optimize this part with arch specific one: we are
>     testing some versions for x86 now.
>
> What we are thinking about:
>   - about set_bit_user_non_atomic()
>     We noticed that ia64 won't need this: see patch1 and patch5.
>     So all we have to do is to complete the implementations for x86 and ppc.
>     ** x86 and ppc don't include asm-generic uaccess. So we have to put these
>        into them separately.
>
>   - about the new api
>     There are many possible styles to make use of this work.
>     E.g. if we export the both addresses of the two bitmaps,
>     we don't need to export them at the switch timing: but we cannot
>     reuse the current structures in this case. Which is better?
>
>
> =>
> Appendix:
>
> To test the patch 6, we are using the following patch for qemu-kvm.
> ---
>   configure  |    2 +-
>   qemu-kvm.c |   22 +++++++++++++++++-----
>   2 files changed, 18 insertions(+), 6 deletions(-)
>
> diff --git a/configure b/configure
> index be8dac4..0b2d017 100755
> --- a/configure
> +++ b/configure
> @@ -1498,7 +1498,7 @@ fi
>   if test "$kvm" != "no" ; then
>       cat>  $TMPC<<EOF
>   #include<linux/kvm.h>
> -#if !defined(KVM_API_VERSION) || KVM_API_VERSION<  12 || KVM_API_VERSION>  12
> +#if !defined(KVM_API_VERSION) || KVM_API_VERSION<  13 || KVM_API_VERSION>  13
>   #error Invalid KVM version
>   #endif
>   #if !defined(KVM_CAP_USER_MEMORY)
> diff --git a/qemu-kvm.c b/qemu-kvm.c
> index cc5b352..087adea 100644
> --- a/qemu-kvm.c
> +++ b/qemu-kvm.c
> @@ -44,7 +44,7 @@
>   #define BUS_MCEERR_AO 5
>   #endif
>
> -#define EXPECTED_KVM_API_VERSION 12
> +#define EXPECTED_KVM_API_VERSION 13
>
>   #if EXPECTED_KVM_API_VERSION != KVM_API_VERSION
>   #error libkvm: userspace and kernel version mismatch
> @@ -684,6 +684,21 @@ static int kvm_get_map(kvm_context_t kvm, int ioctl_num, int slot, void *buf)
>       return 0;
>   }
>
> +static int kvm_switch_map(kvm_context_t kvm, int slot, void **buf)
> +{
> +    int r;
> +    struct kvm_dirty_log log = {
> +        .slot = slot,
> +    };
> +
> +    r = kvm_vm_ioctl(kvm_state, KVM_SWITCH_DIRTY_LOG,&log);
> +    if (r<  0)
> +        return r;
> +
> +    *buf = (void *)log.addr;
> +    return 0;
> +}
> +
>   int kvm_get_dirty_pages(kvm_context_t kvm, unsigned long phys_addr, void *buf)
>   {
>       int slot;
> @@ -706,14 +721,11 @@ int kvm_get_dirty_pages_range(kvm_context_t kvm, unsigned long phys_addr,
>       for (i = 0; i<  KVM_MAX_NUM_MEM_REGIONS; ++i) {
>           if ((slots[i].len&&  (uint64_t) slots[i].phys_addr>= phys_addr)
>               &&  ((uint64_t) slots[i].phys_addr + slots[i].len<= end_addr)) {
> -            buf = qemu_malloc(BITMAP_SIZE(slots[i].len));
> -            r = kvm_get_map(kvm, KVM_GET_DIRTY_LOG, i, buf);
> +            r = kvm_switch_map(kvm, i,&buf);
>               if (r) {
> -                qemu_free(buf);
>                   return r;
>               }
>               r = cb(slots[i].phys_addr, slots[i].len, buf, opaque);
> -            qemu_free(buf);
>               if (r)
>                   return r;
>           }


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 0/6] KVM: moving dirty gitmaps to user space!
@ 2010-04-20 12:05     ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-20 12:05 UTC (permalink / raw)
  To: kvm-ia64

Fernando, sorry I have changed some part of this series and forgot to
change your Signed-off-by to Cc for some parts.

So please give me any comments(objections) as replies to this mail thread.


Thanks,
   Takuya


(2010/04/20 19:53), Takuya Yoshikawa wrote:
> Hi, this is the v2 of the "moving dirty gitmaps to user space!"
>
> By this patch, I think everything we need becomes clear.
> So we want to step forward to be ready for the final version in the
> near future: of course, this is dependent on x86 and ppc asm issues.
>
> BTW, by whom I can get ACK for ppc and ia64? I want to add to the Cc
> list if possible, thank you.
>
>
> Patch1: introduce slot level dirty state management
>    This patch is independent from other patches and seems to be
>    useful without the following parts.
>
> Patch2: introduce wrapper functions to create and destroy dirty bitmaps
>    Cleanup patch.
>
> Patch3: introduce a wrapper function to copy dirty bitmaps to user space
>    This is for dealing copy_in_user() things cleanly.
>
> Patch4: change mark_page_dirty() to handle endian issues explicitly
>    Later, __set_bit() part will be replaced with *_user function.
>
> Patch5: moving dirty bitmaps to user space
>    Replace dirty bitmap manipulations with *_user functions.
>
> Patch6: introduce a new API for getting dirty bitmaps
>    This is to access dirty bitmaps from user space.
>
>
> Changelog:
>   - suport for all architectures
>     We have achived this without pinning.
>   - one possible API suggestion
>   - temporary copy_in_user like function
>   - temporary set_bit_user like function with __get_user() and __put_user()
>     We can use this as a generic set_bit_user_non_atomic().
>     Of course, we need to optimize this part with arch specific one: we are
>     testing some versions for x86 now.
>
> What we are thinking about:
>   - about set_bit_user_non_atomic()
>     We noticed that ia64 won't need this: see patch1 and patch5.
>     So all we have to do is to complete the implementations for x86 and ppc.
>     ** x86 and ppc don't include asm-generic uaccess. So we have to put these
>        into them separately.
>
>   - about the new api
>     There are many possible styles to make use of this work.
>     E.g. if we export the both addresses of the two bitmaps,
>     we don't need to export them at the switch timing: but we cannot
>     reuse the current structures in this case. Which is better?
>
>
> =>
> Appendix:
>
> To test the patch 6, we are using the following patch for qemu-kvm.
> ---
>   configure  |    2 +-
>   qemu-kvm.c |   22 +++++++++++++++++-----
>   2 files changed, 18 insertions(+), 6 deletions(-)
>
> diff --git a/configure b/configure
> index be8dac4..0b2d017 100755
> --- a/configure
> +++ b/configure
> @@ -1498,7 +1498,7 @@ fi
>   if test "$kvm" != "no" ; then
>       cat>  $TMPC<<EOF
>   #include<linux/kvm.h>
> -#if !defined(KVM_API_VERSION) || KVM_API_VERSION<  12 || KVM_API_VERSION>  12
> +#if !defined(KVM_API_VERSION) || KVM_API_VERSION<  13 || KVM_API_VERSION>  13
>   #error Invalid KVM version
>   #endif
>   #if !defined(KVM_CAP_USER_MEMORY)
> diff --git a/qemu-kvm.c b/qemu-kvm.c
> index cc5b352..087adea 100644
> --- a/qemu-kvm.c
> +++ b/qemu-kvm.c
> @@ -44,7 +44,7 @@
>   #define BUS_MCEERR_AO 5
>   #endif
>
> -#define EXPECTED_KVM_API_VERSION 12
> +#define EXPECTED_KVM_API_VERSION 13
>
>   #if EXPECTED_KVM_API_VERSION != KVM_API_VERSION
>   #error libkvm: userspace and kernel version mismatch
> @@ -684,6 +684,21 @@ static int kvm_get_map(kvm_context_t kvm, int ioctl_num, int slot, void *buf)
>       return 0;
>   }
>
> +static int kvm_switch_map(kvm_context_t kvm, int slot, void **buf)
> +{
> +    int r;
> +    struct kvm_dirty_log log = {
> +        .slot = slot,
> +    };
> +
> +    r = kvm_vm_ioctl(kvm_state, KVM_SWITCH_DIRTY_LOG,&log);
> +    if (r<  0)
> +        return r;
> +
> +    *buf = (void *)log.addr;
> +    return 0;
> +}
> +
>   int kvm_get_dirty_pages(kvm_context_t kvm, unsigned long phys_addr, void *buf)
>   {
>       int slot;
> @@ -706,14 +721,11 @@ int kvm_get_dirty_pages_range(kvm_context_t kvm, unsigned long phys_addr,
>       for (i = 0; i<  KVM_MAX_NUM_MEM_REGIONS; ++i) {
>           if ((slots[i].len&&  (uint64_t) slots[i].phys_addr>= phys_addr)
>               &&  ((uint64_t) slots[i].phys_addr + slots[i].len<= end_addr)) {
> -            buf = qemu_malloc(BITMAP_SIZE(slots[i].len));
> -            r = kvm_get_map(kvm, KVM_GET_DIRTY_LOG, i, buf);
> +            r = kvm_switch_map(kvm, i,&buf);
>               if (r) {
> -                qemu_free(buf);
>                   return r;
>               }
>               r = cb(slots[i].phys_addr, slots[i].len, buf, opaque);
> -            qemu_free(buf);
>               if (r)
>                   return r;
>           }


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
  2010-04-20 11:03     ` Takuya Yoshikawa
  (?)
@ 2010-04-21  8:29       ` 
  -1 siblings, 0 replies; 141+ messages in thread
From: Fernando Luis Vázquez Cao @ 2010-04-21  8:29 UTC (permalink / raw)
  To: Takuya Yoshikawa; +Cc: avi, mtosatti, kvm, kvm-ia64, kvm-ppc

On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>  	__u32 padding1;
>  	union {
>  		void __user *dirty_bitmap; /* one bit per page */
> -		__u64 padding2;
> +		__u64 addr;

This can break on x86_32 and x86_64-compat. addr is a long not a __u64.


> +	case KVM_SWITCH_DIRTY_LOG: {
> +		struct kvm_dirty_log log;
> +
> +		r = -EFAULT;
> +		if (copy_from_user(&log, argp, sizeof log))
> +			goto out;
> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
> +		if (r)
> +			goto out;
> +		r = -EFAULT;
> +		if (copy_to_user(argp, &log, sizeof log))
> +			goto out;
> +		r = 0;
> +		break;
> +	}

In x86_64-compat mode we are handling 32bit user-space addresses
so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-21  8:29       ` 
  0 siblings, 0 replies; 141+ messages in thread
From:  @ 2010-04-21  8:29 UTC (permalink / raw)
  To: Takuya Yoshikawa; +Cc: avi, mtosatti, kvm, kvm-ia64, kvm-ppc

On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>  	__u32 padding1;
>  	union {
>  		void __user *dirty_bitmap; /* one bit per page */
> -		__u64 padding2;
> +		__u64 addr;

This can break on x86_32 and x86_64-compat. addr is a long not a __u64.


> +	case KVM_SWITCH_DIRTY_LOG: {
> +		struct kvm_dirty_log log;
> +
> +		r = -EFAULT;
> +		if (copy_from_user(&log, argp, sizeof log))
> +			goto out;
> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
> +		if (r)
> +			goto out;
> +		r = -EFAULT;
> +		if (copy_to_user(argp, &log, sizeof log))
> +			goto out;
> +		r = 0;
> +		break;
> +	}

In x86_64-compat mode we are handling 32bit user-space addresses
so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-21  8:29       ` 
  0 siblings, 0 replies; 141+ messages in thread
From:  @ 2010-04-21  8:29 UTC (permalink / raw)
  To: kvm-ia64

On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>  	__u32 padding1;
>  	union {
>  		void __user *dirty_bitmap; /* one bit per page */
> -		__u64 padding2;
> +		__u64 addr;

This can break on x86_32 and x86_64-compat. addr is a long not a __u64.


> +	case KVM_SWITCH_DIRTY_LOG: {
> +		struct kvm_dirty_log log;
> +
> +		r = -EFAULT;
> +		if (copy_from_user(&log, argp, sizeof log))
> +			goto out;
> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
> +		if (r)
> +			goto out;
> +		r = -EFAULT;
> +		if (copy_to_user(argp, &log, sizeof log))
> +			goto out;
> +		r = 0;
> +		break;
> +	}

In x86_64-compat mode we are handling 32bit user-space addresses
so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
  2010-04-21  8:29       ` 
  (?)
@ 2010-04-21  9:41         ` Alexander Graf
  -1 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-21  9:41 UTC (permalink / raw)
  To: Fernando Luis Vázquez Cao
  Cc: Takuya Yoshikawa, avi, mtosatti, kvm, kvm-ia64, kvm-ppc


On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:

> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>> 	__u32 padding1;
>> 	union {
>> 		void __user *dirty_bitmap; /* one bit per page */
>> -		__u64 padding2;
>> +		__u64 addr;
> 
> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.

So the high 32 bits are zero. Where's the problem?

> 
> 
>> +	case KVM_SWITCH_DIRTY_LOG: {
>> +		struct kvm_dirty_log log;
>> +
>> +		r = -EFAULT;
>> +		if (copy_from_user(&log, argp, sizeof log))
>> +			goto out;
>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>> +		if (r)
>> +			goto out;
>> +		r = -EFAULT;
>> +		if (copy_to_user(argp, &log, sizeof log))
>> +			goto out;
>> +		r = 0;
>> +		break;
>> +	}
> 
> In x86_64-compat mode we are handling 32bit user-space addresses
> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.

The compat code just forwards everything to the generic ioctls.

Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-21  9:41         ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-21  9:41 UTC (permalink / raw)
  To: Fernando Luis Vázquez Cao
  Cc: Takuya Yoshikawa, avi, mtosatti, kvm, kvm-ia64, kvm-ppc


On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:

> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>> 	__u32 padding1;
>> 	union {
>> 		void __user *dirty_bitmap; /* one bit per page */
>> -		__u64 padding2;
>> +		__u64 addr;
> 
> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.

So the high 32 bits are zero. Where's the problem?

> 
> 
>> +	case KVM_SWITCH_DIRTY_LOG: {
>> +		struct kvm_dirty_log log;
>> +
>> +		r = -EFAULT;
>> +		if (copy_from_user(&log, argp, sizeof log))
>> +			goto out;
>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>> +		if (r)
>> +			goto out;
>> +		r = -EFAULT;
>> +		if (copy_to_user(argp, &log, sizeof log))
>> +			goto out;
>> +		r = 0;
>> +		break;
>> +	}
> 
> In x86_64-compat mode we are handling 32bit user-space addresses
> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.

The compat code just forwards everything to the generic ioctls.

Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-21  9:41         ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-21  9:41 UTC (permalink / raw)
  To: kvm-ia64


On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:

> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>> 	__u32 padding1;
>> 	union {
>> 		void __user *dirty_bitmap; /* one bit per page */
>> -		__u64 padding2;
>> +		__u64 addr;
> 
> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.

So the high 32 bits are zero. Where's the problem?

> 
> 
>> +	case KVM_SWITCH_DIRTY_LOG: {
>> +		struct kvm_dirty_log log;
>> +
>> +		r = -EFAULT;
>> +		if (copy_from_user(&log, argp, sizeof log))
>> +			goto out;
>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>> +		if (r)
>> +			goto out;
>> +		r = -EFAULT;
>> +		if (copy_to_user(argp, &log, sizeof log))
>> +			goto out;
>> +		r = 0;
>> +		break;
>> +	}
> 
> In x86_64-compat mode we are handling 32bit user-space addresses
> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.

The compat code just forwards everything to the generic ioctls.

Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy dirty bitmaps to user space
       [not found]     ` <20100420195913.ac44281c.yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
  2010-04-21 11:12         ` Avi Kivity
@ 2010-04-21 11:12         ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-21 11:12 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	fernando-gVGce1chcLdL9jVzuh4AOg

On 04/20/2010 01:59 PM, Takuya Yoshikawa wrote:
> We will replace copy_to_user() to copy_in_user() when we move
> the dirty bitmaps to user space.
>
> But sadly, we have copy_in_user() only for 64 bits architectures.
> So this function should work as a wrapper to hide ifdefs from outside.
> Once we get copy_in_user() for 32 bits architectures, we can remove
> this wrapper and use copy_in_user() directly.
>    

I prefer a generic copy_in_user() instead of having multiple paths in kvm.

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy
@ 2010-04-21 11:12         ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-21 11:12 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	fernando-gVGce1chcLdL9jVzuh4AOg

On 04/20/2010 01:59 PM, Takuya Yoshikawa wrote:
> We will replace copy_to_user() to copy_in_user() when we move
> the dirty bitmaps to user space.
>
> But sadly, we have copy_in_user() only for 64 bits architectures.
> So this function should work as a wrapper to hide ifdefs from outside.
> Once we get copy_in_user() for 32 bits architectures, we can remove
> this wrapper and use copy_in_user() directly.
>    

I prefer a generic copy_in_user() instead of having multiple paths in kvm.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy
@ 2010-04-21 11:12         ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-21 11:12 UTC (permalink / raw)
  To: kvm-ia64

On 04/20/2010 01:59 PM, Takuya Yoshikawa wrote:
> We will replace copy_to_user() to copy_in_user() when we move
> the dirty bitmaps to user space.
>
> But sadly, we have copy_in_user() only for 64 bits architectures.
> So this function should work as a wrapper to hide ifdefs from outside.
> Once we get copy_in_user() for 32 bits architectures, we can remove
> this wrapper and use copy_in_user() directly.
>    

I prefer a generic copy_in_user() instead of having multiple paths in kvm.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian issues explicitly
  2010-04-20 10:57   ` [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian Takuya Yoshikawa
  (?)
@ 2010-04-21 11:15     ` Avi Kivity
  -1 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-21 11:15 UTC (permalink / raw)
  To: Takuya Yoshikawa; +Cc: mtosatti, kvm, kvm-ia64, kvm-ppc, fernando

On 04/20/2010 02:00 PM, Takuya Yoshikawa wrote:
> We are now using generic___set_le_bit() to make dirty bitmaps le.
> Though this works well, we have to replace __set_bit() to appropriate
> uaccess function to move dirty bitmaps to user space. So this patch
> splits generic___set_le_bit() and prepares for that.
>    
>
> +static int __mark_page_dirty(unsigned long nr,
> +			     unsigned long *dirty_bitmap)
> +{
> +#ifdef __BIG_ENDIAN
> +	nr = nr ^ BITOP_LE_SWIZZLE;
> +#endif
> +	__set_bit(nr, dirty_bitmap);
>    

Why not introduce __set_le_bit_user() along with __set_bit_user()?  kvm 
shouldn't do endian corrections when they can be done in generic code.

> +}
> +
>   void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
>   {
>   	struct kvm_memory_slot *memslot;
> @@ -1203,11 +1212,8 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
>   	if (memslot&&  memslot->dirty_bitmap) {
>   		unsigned long rel_gfn = gfn - memslot->base_gfn;
>
> -		/* avoid RMW */
> -		if (!generic_test_le_bit(rel_gfn, memslot->dirty_bitmap)) {
> -			generic___set_le_bit(rel_gfn, memslot->dirty_bitmap);
> -			memslot->is_dirty = true;
> -		}
>    

You're also dropping the RMW avoidance.  This is fine, but deserves at 
least a note in the changelog (or a separate patch).

> +		__mark_page_dirty(rel_gfn, memslot->dirty_bitmap);
> +		memslot->is_dirty = true;
>   	}
>   }
>
>    


-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian
@ 2010-04-21 11:15     ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-21 11:15 UTC (permalink / raw)
  To: Takuya Yoshikawa; +Cc: mtosatti, kvm, kvm-ia64, kvm-ppc, fernando

On 04/20/2010 02:00 PM, Takuya Yoshikawa wrote:
> We are now using generic___set_le_bit() to make dirty bitmaps le.
> Though this works well, we have to replace __set_bit() to appropriate
> uaccess function to move dirty bitmaps to user space. So this patch
> splits generic___set_le_bit() and prepares for that.
>    
>
> +static int __mark_page_dirty(unsigned long nr,
> +			     unsigned long *dirty_bitmap)
> +{
> +#ifdef __BIG_ENDIAN
> +	nr = nr ^ BITOP_LE_SWIZZLE;
> +#endif
> +	__set_bit(nr, dirty_bitmap);
>    

Why not introduce __set_le_bit_user() along with __set_bit_user()?  kvm 
shouldn't do endian corrections when they can be done in generic code.

> +}
> +
>   void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
>   {
>   	struct kvm_memory_slot *memslot;
> @@ -1203,11 +1212,8 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
>   	if (memslot&&  memslot->dirty_bitmap) {
>   		unsigned long rel_gfn = gfn - memslot->base_gfn;
>
> -		/* avoid RMW */
> -		if (!generic_test_le_bit(rel_gfn, memslot->dirty_bitmap)) {
> -			generic___set_le_bit(rel_gfn, memslot->dirty_bitmap);
> -			memslot->is_dirty = true;
> -		}
>    

You're also dropping the RMW avoidance.  This is fine, but deserves at 
least a note in the changelog (or a separate patch).

> +		__mark_page_dirty(rel_gfn, memslot->dirty_bitmap);
> +		memslot->is_dirty = true;
>   	}
>   }
>
>    


-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian
@ 2010-04-21 11:15     ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-21 11:15 UTC (permalink / raw)
  To: kvm-ia64

On 04/20/2010 02:00 PM, Takuya Yoshikawa wrote:
> We are now using generic___set_le_bit() to make dirty bitmaps le.
> Though this works well, we have to replace __set_bit() to appropriate
> uaccess function to move dirty bitmaps to user space. So this patch
> splits generic___set_le_bit() and prepares for that.
>    
>
> +static int __mark_page_dirty(unsigned long nr,
> +			     unsigned long *dirty_bitmap)
> +{
> +#ifdef __BIG_ENDIAN
> +	nr = nr ^ BITOP_LE_SWIZZLE;
> +#endif
> +	__set_bit(nr, dirty_bitmap);
>    

Why not introduce __set_le_bit_user() along with __set_bit_user()?  kvm 
shouldn't do endian corrections when they can be done in generic code.

> +}
> +
>   void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
>   {
>   	struct kvm_memory_slot *memslot;
> @@ -1203,11 +1212,8 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn)
>   	if (memslot&&  memslot->dirty_bitmap) {
>   		unsigned long rel_gfn = gfn - memslot->base_gfn;
>
> -		/* avoid RMW */
> -		if (!generic_test_le_bit(rel_gfn, memslot->dirty_bitmap)) {
> -			generic___set_le_bit(rel_gfn, memslot->dirty_bitmap);
> -			memslot->is_dirty = true;
> -		}
>    

You're also dropping the RMW avoidance.  This is fine, but deserves at 
least a note in the changelog (or a separate patch).

> +		__mark_page_dirty(rel_gfn, memslot->dirty_bitmap);
> +		memslot->is_dirty = true;
>   	}
>   }
>
>    


-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
       [not found]     ` <20100420200225.efca602f.yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
  2010-04-20 11:10         ` Alexander Graf
@ 2010-04-21 11:26         ` Avi Kivity
  1 sibling, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-21 11:26 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	fernando-gVGce1chcLdL9jVzuh4AOg

On 04/20/2010 02:02 PM, Takuya Yoshikawa wrote:
> We move dirty bitmaps to user space.
>
>   - Allocation and destruction: we use do_mmap() and do_munmap().
>     The new bitmap space is twice longer than the original one and we
>     use the additional space for double buffering: this makes it
>     possible to update the active bitmap while letting the user space
>     read the other one safely.
>
>   - Bitmap manipulations: we replace all functions which access dirty
>     bitmaps to *_user() functions. Note that some of these should be
>     optimized later.
>
>   - For ia64: moving the dirty bitmaps of memory slots does not effect
>     much to ia64 because it's using a different space to store bitmaps
>     which is directly updated: all we have to change are sync and get
>     of dirty log, so we don't need set_bit_user like function for ia64.
>
> Signed-off-by: Takuya Yoshikawa<yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
> Signed-off-by: Fernando Luis Vazquez Cao<fernando-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
> ---
>   arch/ia64/kvm/kvm-ia64.c  |   12 ++++-
>   arch/powerpc/kvm/book3s.c |    2 +-
>   arch/x86/kvm/x86.c        |   24 +++++-----
>   include/linux/kvm_host.h  |    5 +-
>   virt/kvm/kvm_main.c       |  101 ++++++++++++++++++++++++++++++++++++++++-----
>   5 files changed, 116 insertions(+), 28 deletions(-)
>
> diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
> index d60dafe..c3f0b70 100644
> --- a/arch/ia64/kvm/kvm-ia64.c
> +++ b/arch/ia64/kvm/kvm-ia64.c
> @@ -1823,11 +1823,19 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
>   	n = kvm_dirty_bitmap_bytes(memslot);
>   	base = memslot->base_gfn / BITS_PER_LONG;
>
> +	r = -EFAULT;
> +	if (!access_ok(VERIFY_WRITE, memslot->dirty_bitmap, n))
> +		goto out;
> +
>   	for (i = 0; i<  n/sizeof(long); ++i) {
>   		if (dirty_bitmap[base + i])
>   			memslot->is_dirty = true;
>
> -		memslot->dirty_bitmap[i] = dirty_bitmap[base + i];
> +		if (__put_user(dirty_bitmap[base + i],
> +			&memslot->dirty_bitmap[i])) {
> +			r = -EFAULT;
> +			goto out;
> +		}
>   		dirty_bitmap[base + i] = 0;
>   	}
>   	r = 0;
> @@ -1858,7 +1866,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
>   	if (memslot->is_dirty) {
>   		kvm_flush_remote_tlbs(kvm);
>   		n = kvm_dirty_bitmap_bytes(memslot);
> -		memset(memslot->dirty_bitmap, 0, n);
> +		clear_user(memslot->dirty_bitmap, n);
>   		memslot->is_dirty = false;
>    

Does this need an error check?


> @@ -468,8 +480,12 @@ void kvm_free_physmem(struct kvm *kvm)
>   	int i;
>   	struct kvm_memslots *slots = kvm->memslots;
>
> -	for (i = 0; i<  slots->nmemslots; ++i)
> +	for (i = 0; i<  slots->nmemslots; ++i) {
> +		/* We don't munmap dirty bitmaps by ourselves. */
>    

Why not?  If we allocated them, we have to free them.

> +		slots->memslots[i].dirty_bitmap = NULL;
> +		slots->memslots[i].dirty_bitmap_old = NULL;
>   		kvm_free_physmem_slot(&slots->memslots[i], NULL);
> +	}
>
>   	kfree(kvm->memslots);
>   }
> @@ -523,13 +539,22 @@ static int kvm_vm_release(struct inode *inode, struct file *filp)
>
>   static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot)
>   {
> -	unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(memslot);
> +	unsigned long user_addr;
> +	unsigned long n = kvm_dirty_bitmap_bytes(memslot);
>
> -	memslot->dirty_bitmap = vmalloc(dirty_bytes);
> -	if (!memslot->dirty_bitmap)
> -		return -ENOMEM;
> +	down_write(&current->mm->mmap_sem);
> +	user_addr = do_mmap(NULL, 0, 2 * n,
> +			    PROT_READ | PROT_WRITE,
> +			    MAP_PRIVATE | MAP_ANONYMOUS, 0);
> +	up_write(&current->mm->mmap_sem);
> +
> +	if (IS_ERR((void *)user_addr))
> +		return PTR_ERR((void *)user_addr);
> +
> +	memslot->dirty_bitmap = (unsigned long __user *)user_addr;
> +	memslot->dirty_bitmap_old = (unsigned long __user *)(user_addr + n);
> +	clear_user(memslot->dirty_bitmap, 2 * n);
>    

Error check.

>
> -	memset(memslot->dirty_bitmap, 0, dirty_bytes);
>   	return 0;
>   }
>
> @@ -778,13 +803,45 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
>   }
>
>   int kvm_copy_dirty_bitmap(unsigned long __user *to,
> -			  const unsigned long *from,
> +			  const unsigned long __user *from,
>   			  unsigned long bytes)
>   {
> -	if (copy_to_user(to, from, bytes))
> +#if defined(CONFIG_X86_64) || defined(CONFIG_PPC64) || defined(CONFIG_IA64)
> +	if (copy_in_user(to, from, bytes)) {
> +		printk(KERN_WARNING "%s: copy_in_user failed.\n", __func__);
>   		return -EFAULT;
> +	}
> +	return 0;
> +#else
> +	int num, bufbytes;
> +	unsigned long buf[32];
>
> +	if (!access_ok(VERIFY_READ, from, bytes) ||
> +	    !access_ok(VERIFY_WRITE, to, bytes)) {
> +		goto out_fault;
> +	}
> +
> +	bufbytes = sizeof(buf);
> +	num = bufbytes / sizeof(buf[0]);
> +
> +	for (; bytes>  bufbytes; bytes -= bufbytes, to += num, from += num) {
> +		if (__copy_from_user(buf, from, bufbytes))
> +			goto out_fault;
> +		if (__copy_to_user(to, buf, bufbytes))
> +			goto out_fault;
> +	}
> +	if (bytes>  0) {
> +		if (__copy_from_user(buf, from, bytes))
> +			goto out_fault;
> +		if (__copy_to_user(to, buf, bytes))
> +			goto out_fault;
> +	}
>   	return 0;
> +
> +out_fault:
> +	printk(KERN_WARNING "%s: copy to(from) user failed.\n", __func__);
> +	return -EFAULT;
> +#endif
>   }
>    

This really wants to be hidden in lib/.

>
>   int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
> @@ -1194,13 +1251,35 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
>   }
>   EXPORT_SYMBOL_GPL(kvm_clear_guest);
>
> +/*
> + * Please use generic *_user bitops once they become available.
> + * Be careful setting the bit won't be done atomically.
> + */
>    

Please introduce the user bitops as part of this patchset.

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-21 11:26         ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-21 11:26 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	fernando-gVGce1chcLdL9jVzuh4AOg

On 04/20/2010 02:02 PM, Takuya Yoshikawa wrote:
> We move dirty bitmaps to user space.
>
>   - Allocation and destruction: we use do_mmap() and do_munmap().
>     The new bitmap space is twice longer than the original one and we
>     use the additional space for double buffering: this makes it
>     possible to update the active bitmap while letting the user space
>     read the other one safely.
>
>   - Bitmap manipulations: we replace all functions which access dirty
>     bitmaps to *_user() functions. Note that some of these should be
>     optimized later.
>
>   - For ia64: moving the dirty bitmaps of memory slots does not effect
>     much to ia64 because it's using a different space to store bitmaps
>     which is directly updated: all we have to change are sync and get
>     of dirty log, so we don't need set_bit_user like function for ia64.
>
> Signed-off-by: Takuya Yoshikawa<yoshikawa.takuya@oss.ntt.co.jp>
> Signed-off-by: Fernando Luis Vazquez Cao<fernando@oss.ntt.co.jp>
> ---
>   arch/ia64/kvm/kvm-ia64.c  |   12 ++++-
>   arch/powerpc/kvm/book3s.c |    2 +-
>   arch/x86/kvm/x86.c        |   24 +++++-----
>   include/linux/kvm_host.h  |    5 +-
>   virt/kvm/kvm_main.c       |  101 ++++++++++++++++++++++++++++++++++++++++-----
>   5 files changed, 116 insertions(+), 28 deletions(-)
>
> diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
> index d60dafe..c3f0b70 100644
> --- a/arch/ia64/kvm/kvm-ia64.c
> +++ b/arch/ia64/kvm/kvm-ia64.c
> @@ -1823,11 +1823,19 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
>   	n = kvm_dirty_bitmap_bytes(memslot);
>   	base = memslot->base_gfn / BITS_PER_LONG;
>
> +	r = -EFAULT;
> +	if (!access_ok(VERIFY_WRITE, memslot->dirty_bitmap, n))
> +		goto out;
> +
>   	for (i = 0; i<  n/sizeof(long); ++i) {
>   		if (dirty_bitmap[base + i])
>   			memslot->is_dirty = true;
>
> -		memslot->dirty_bitmap[i] = dirty_bitmap[base + i];
> +		if (__put_user(dirty_bitmap[base + i],
> +			&memslot->dirty_bitmap[i])) {
> +			r = -EFAULT;
> +			goto out;
> +		}
>   		dirty_bitmap[base + i] = 0;
>   	}
>   	r = 0;
> @@ -1858,7 +1866,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
>   	if (memslot->is_dirty) {
>   		kvm_flush_remote_tlbs(kvm);
>   		n = kvm_dirty_bitmap_bytes(memslot);
> -		memset(memslot->dirty_bitmap, 0, n);
> +		clear_user(memslot->dirty_bitmap, n);
>   		memslot->is_dirty = false;
>    

Does this need an error check?


> @@ -468,8 +480,12 @@ void kvm_free_physmem(struct kvm *kvm)
>   	int i;
>   	struct kvm_memslots *slots = kvm->memslots;
>
> -	for (i = 0; i<  slots->nmemslots; ++i)
> +	for (i = 0; i<  slots->nmemslots; ++i) {
> +		/* We don't munmap dirty bitmaps by ourselves. */
>    

Why not?  If we allocated them, we have to free them.

> +		slots->memslots[i].dirty_bitmap = NULL;
> +		slots->memslots[i].dirty_bitmap_old = NULL;
>   		kvm_free_physmem_slot(&slots->memslots[i], NULL);
> +	}
>
>   	kfree(kvm->memslots);
>   }
> @@ -523,13 +539,22 @@ static int kvm_vm_release(struct inode *inode, struct file *filp)
>
>   static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot)
>   {
> -	unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(memslot);
> +	unsigned long user_addr;
> +	unsigned long n = kvm_dirty_bitmap_bytes(memslot);
>
> -	memslot->dirty_bitmap = vmalloc(dirty_bytes);
> -	if (!memslot->dirty_bitmap)
> -		return -ENOMEM;
> +	down_write(&current->mm->mmap_sem);
> +	user_addr = do_mmap(NULL, 0, 2 * n,
> +			    PROT_READ | PROT_WRITE,
> +			    MAP_PRIVATE | MAP_ANONYMOUS, 0);
> +	up_write(&current->mm->mmap_sem);
> +
> +	if (IS_ERR((void *)user_addr))
> +		return PTR_ERR((void *)user_addr);
> +
> +	memslot->dirty_bitmap = (unsigned long __user *)user_addr;
> +	memslot->dirty_bitmap_old = (unsigned long __user *)(user_addr + n);
> +	clear_user(memslot->dirty_bitmap, 2 * n);
>    

Error check.

>
> -	memset(memslot->dirty_bitmap, 0, dirty_bytes);
>   	return 0;
>   }
>
> @@ -778,13 +803,45 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
>   }
>
>   int kvm_copy_dirty_bitmap(unsigned long __user *to,
> -			  const unsigned long *from,
> +			  const unsigned long __user *from,
>   			  unsigned long bytes)
>   {
> -	if (copy_to_user(to, from, bytes))
> +#if defined(CONFIG_X86_64) || defined(CONFIG_PPC64) || defined(CONFIG_IA64)
> +	if (copy_in_user(to, from, bytes)) {
> +		printk(KERN_WARNING "%s: copy_in_user failed.\n", __func__);
>   		return -EFAULT;
> +	}
> +	return 0;
> +#else
> +	int num, bufbytes;
> +	unsigned long buf[32];
>
> +	if (!access_ok(VERIFY_READ, from, bytes) ||
> +	    !access_ok(VERIFY_WRITE, to, bytes)) {
> +		goto out_fault;
> +	}
> +
> +	bufbytes = sizeof(buf);
> +	num = bufbytes / sizeof(buf[0]);
> +
> +	for (; bytes>  bufbytes; bytes -= bufbytes, to += num, from += num) {
> +		if (__copy_from_user(buf, from, bufbytes))
> +			goto out_fault;
> +		if (__copy_to_user(to, buf, bufbytes))
> +			goto out_fault;
> +	}
> +	if (bytes>  0) {
> +		if (__copy_from_user(buf, from, bytes))
> +			goto out_fault;
> +		if (__copy_to_user(to, buf, bytes))
> +			goto out_fault;
> +	}
>   	return 0;
> +
> +out_fault:
> +	printk(KERN_WARNING "%s: copy to(from) user failed.\n", __func__);
> +	return -EFAULT;
> +#endif
>   }
>    

This really wants to be hidden in lib/.

>
>   int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
> @@ -1194,13 +1251,35 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
>   }
>   EXPORT_SYMBOL_GPL(kvm_clear_guest);
>
> +/*
> + * Please use generic *_user bitops once they become available.
> + * Be careful setting the bit won't be done atomically.
> + */
>    

Please introduce the user bitops as part of this patchset.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-21 11:26         ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-21 11:26 UTC (permalink / raw)
  To: kvm-ia64

On 04/20/2010 02:02 PM, Takuya Yoshikawa wrote:
> We move dirty bitmaps to user space.
>
>   - Allocation and destruction: we use do_mmap() and do_munmap().
>     The new bitmap space is twice longer than the original one and we
>     use the additional space for double buffering: this makes it
>     possible to update the active bitmap while letting the user space
>     read the other one safely.
>
>   - Bitmap manipulations: we replace all functions which access dirty
>     bitmaps to *_user() functions. Note that some of these should be
>     optimized later.
>
>   - For ia64: moving the dirty bitmaps of memory slots does not effect
>     much to ia64 because it's using a different space to store bitmaps
>     which is directly updated: all we have to change are sync and get
>     of dirty log, so we don't need set_bit_user like function for ia64.
>
> Signed-off-by: Takuya Yoshikawa<yoshikawa.takuya@oss.ntt.co.jp>
> Signed-off-by: Fernando Luis Vazquez Cao<fernando@oss.ntt.co.jp>
> ---
>   arch/ia64/kvm/kvm-ia64.c  |   12 ++++-
>   arch/powerpc/kvm/book3s.c |    2 +-
>   arch/x86/kvm/x86.c        |   24 +++++-----
>   include/linux/kvm_host.h  |    5 +-
>   virt/kvm/kvm_main.c       |  101 ++++++++++++++++++++++++++++++++++++++++-----
>   5 files changed, 116 insertions(+), 28 deletions(-)
>
> diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c
> index d60dafe..c3f0b70 100644
> --- a/arch/ia64/kvm/kvm-ia64.c
> +++ b/arch/ia64/kvm/kvm-ia64.c
> @@ -1823,11 +1823,19 @@ static int kvm_ia64_sync_dirty_log(struct kvm *kvm,
>   	n = kvm_dirty_bitmap_bytes(memslot);
>   	base = memslot->base_gfn / BITS_PER_LONG;
>
> +	r = -EFAULT;
> +	if (!access_ok(VERIFY_WRITE, memslot->dirty_bitmap, n))
> +		goto out;
> +
>   	for (i = 0; i<  n/sizeof(long); ++i) {
>   		if (dirty_bitmap[base + i])
>   			memslot->is_dirty = true;
>
> -		memslot->dirty_bitmap[i] = dirty_bitmap[base + i];
> +		if (__put_user(dirty_bitmap[base + i],
> +			&memslot->dirty_bitmap[i])) {
> +			r = -EFAULT;
> +			goto out;
> +		}
>   		dirty_bitmap[base + i] = 0;
>   	}
>   	r = 0;
> @@ -1858,7 +1866,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
>   	if (memslot->is_dirty) {
>   		kvm_flush_remote_tlbs(kvm);
>   		n = kvm_dirty_bitmap_bytes(memslot);
> -		memset(memslot->dirty_bitmap, 0, n);
> +		clear_user(memslot->dirty_bitmap, n);
>   		memslot->is_dirty = false;
>    

Does this need an error check?


> @@ -468,8 +480,12 @@ void kvm_free_physmem(struct kvm *kvm)
>   	int i;
>   	struct kvm_memslots *slots = kvm->memslots;
>
> -	for (i = 0; i<  slots->nmemslots; ++i)
> +	for (i = 0; i<  slots->nmemslots; ++i) {
> +		/* We don't munmap dirty bitmaps by ourselves. */
>    

Why not?  If we allocated them, we have to free them.

> +		slots->memslots[i].dirty_bitmap = NULL;
> +		slots->memslots[i].dirty_bitmap_old = NULL;
>   		kvm_free_physmem_slot(&slots->memslots[i], NULL);
> +	}
>
>   	kfree(kvm->memslots);
>   }
> @@ -523,13 +539,22 @@ static int kvm_vm_release(struct inode *inode, struct file *filp)
>
>   static int kvm_create_dirty_bitmap(struct kvm_memory_slot *memslot)
>   {
> -	unsigned long dirty_bytes = kvm_dirty_bitmap_bytes(memslot);
> +	unsigned long user_addr;
> +	unsigned long n = kvm_dirty_bitmap_bytes(memslot);
>
> -	memslot->dirty_bitmap = vmalloc(dirty_bytes);
> -	if (!memslot->dirty_bitmap)
> -		return -ENOMEM;
> +	down_write(&current->mm->mmap_sem);
> +	user_addr = do_mmap(NULL, 0, 2 * n,
> +			    PROT_READ | PROT_WRITE,
> +			    MAP_PRIVATE | MAP_ANONYMOUS, 0);
> +	up_write(&current->mm->mmap_sem);
> +
> +	if (IS_ERR((void *)user_addr))
> +		return PTR_ERR((void *)user_addr);
> +
> +	memslot->dirty_bitmap = (unsigned long __user *)user_addr;
> +	memslot->dirty_bitmap_old = (unsigned long __user *)(user_addr + n);
> +	clear_user(memslot->dirty_bitmap, 2 * n);
>    

Error check.

>
> -	memset(memslot->dirty_bitmap, 0, dirty_bytes);
>   	return 0;
>   }
>
> @@ -778,13 +803,45 @@ int kvm_vm_ioctl_set_memory_region(struct kvm *kvm,
>   }
>
>   int kvm_copy_dirty_bitmap(unsigned long __user *to,
> -			  const unsigned long *from,
> +			  const unsigned long __user *from,
>   			  unsigned long bytes)
>   {
> -	if (copy_to_user(to, from, bytes))
> +#if defined(CONFIG_X86_64) || defined(CONFIG_PPC64) || defined(CONFIG_IA64)
> +	if (copy_in_user(to, from, bytes)) {
> +		printk(KERN_WARNING "%s: copy_in_user failed.\n", __func__);
>   		return -EFAULT;
> +	}
> +	return 0;
> +#else
> +	int num, bufbytes;
> +	unsigned long buf[32];
>
> +	if (!access_ok(VERIFY_READ, from, bytes) ||
> +	    !access_ok(VERIFY_WRITE, to, bytes)) {
> +		goto out_fault;
> +	}
> +
> +	bufbytes = sizeof(buf);
> +	num = bufbytes / sizeof(buf[0]);
> +
> +	for (; bytes>  bufbytes; bytes -= bufbytes, to += num, from += num) {
> +		if (__copy_from_user(buf, from, bufbytes))
> +			goto out_fault;
> +		if (__copy_to_user(to, buf, bufbytes))
> +			goto out_fault;
> +	}
> +	if (bytes>  0) {
> +		if (__copy_from_user(buf, from, bytes))
> +			goto out_fault;
> +		if (__copy_to_user(to, buf, bytes))
> +			goto out_fault;
> +	}
>   	return 0;
> +
> +out_fault:
> +	printk(KERN_WARNING "%s: copy to(from) user failed.\n", __func__);
> +	return -EFAULT;
> +#endif
>   }
>    

This really wants to be hidden in lib/.

>
>   int kvm_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
> @@ -1194,13 +1251,35 @@ int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len)
>   }
>   EXPORT_SYMBOL_GPL(kvm_clear_guest);
>
> +/*
> + * Please use generic *_user bitops once they become available.
> + * Be careful setting the bit won't be done atomically.
> + */
>    

Please introduce the user bitops as part of this patchset.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
       [not found]     ` <20100420200353.2d2a6dec.yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
  2010-04-21 11:46         ` Avi Kivity
@ 2010-04-21 11:46         ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-21 11:46 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	fernando-gVGce1chcLdL9jVzuh4AOg

On 04/20/2010 02:03 PM, Takuya Yoshikawa wrote:
> We can now export the addree of the bitmap created by do_mmap()
> to user space. For the sake of this, we introduce a new API:
>
>    KVM_SWITCH_DIRTY_LOG: application can use this to trigger the
>    switch of the bitmaps and get the address of the bitmap which
>    has been used until now. This reduces the copy of the dirty
>    bitmap from the kernel.
>
>
> diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt
> index baa8fde..f3d1c2a 100644
> --- a/Documentation/kvm/api.txt
> +++ b/Documentation/kvm/api.txt
> @@ -848,6 +848,29 @@ function properly, this is the place to put them.
>          __u8  pad[64];
>   };
>
> +4.37 KVM_SWITCH_DIRTY_LOG (vm ioctl)
> +
> +Capability: basic
>    

Capability: basic means that this is available on all kvm versions, 
which isn't the case.  This should say KVM_CAP_USER_DIRTY_BITMAP.
> +Architectures: x86
>    

All architecures...

> +Type: vm ioctl
> +Parameters: struct kvm_dirty_log (in/out)
> +Returns: 0 on success, -1 on error
> +
> +/* for KVM_SWITCH_DIRTY_LOG */
> +struct kvm_dirty_log {
> +	__u32 slot;
> +	__u32 padding;
>    

Please put a flags field here (and verify it is zero in the ioctl 
implementation).  This allows us to extend it later.

> +	union {
> +		void __user *dirty_bitmap; /* one bit per page */
> +		__u64 addr;
> +	};
>    

Just make dirty_bitmap a __u64.  With the union there is the risk that 
someone forgets to zero the structure so we get some random bits in the 
pointer, and also issues with big endian and s390 compat.

Reserve some extra space here for future expansion.

Hm.  I see that this is the existing kvm_dirty_log structure.  So we 
can't play with it, ignore my comments about it.

> +};
> +
> +Given a memory slot, return the address of 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.
>    

Document that bitmaps but be aligned and padded to 64-bits to avoid 
32-on-64 issues.  Explain that dirty_bitmap will be the next returned 
(do we actually need the return value?  userspace can simply remember it 
from the last call).

How is the dirty log set when we start logging?  With kernel allocated 
bitmaps this isn't a problem, but with user allocated bitmaps?

> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index ad55353..45b728c 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -2718,11 +2718,9 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
>   	return 0;
>   }
>
> -/*
> - * 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)
> +static int kvm_x86_update_dirty_log(struct kvm *kvm,
> +				    struct kvm_dirty_log *log,
> +				    bool need_copy)
>   {
>   	int r;
>   	struct kvm_memory_slot *memslot;
> @@ -2773,12 +2771,34 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
>   		dirty_bitmap_old = dirty_bitmap;
>   	}
>
> -	r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap_old, n);
> +	if (need_copy) {
> +		r = kvm_copy_dirty_bitmap(log->dirty_bitmap,
> +					  dirty_bitmap_old, n);
> +	} else {
> +		log->addr = (unsigned long)dirty_bitmap_old;
> +		r = 0;
> +	}
>    

Instead of passing need_copy everywhere, you might check a flag in 
log->.  You'll need a flag to know whether to munmap() or not, no?

> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
> index 23ea022..9fa6f1e 100644
> --- a/include/linux/kvm.h
> +++ b/include/linux/kvm.h
> @@ -12,7 +12,7 @@
>   #include<linux/ioctl.h>
>   #include<asm/kvm.h>
>
> -#define KVM_API_VERSION 12
> +#define KVM_API_VERSION 13
>    

As Alex says, this breaks all known userspace.

>
>   /* *** Deprecated interfaces *** */
>
> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>   	__u32 padding1;
>   	union {
>   		void __user *dirty_bitmap; /* one bit per page */
> -		__u64 padding2;
> +		__u64 addr;
>   	};
>   };
>    

Update the comment above to note it applies to KVM_SWITCH_DIRTY_LOG.

> @@ -1699,6 +1714,21 @@ static long kvm_vm_ioctl(struct file *filp,
>   			goto out;
>   		break;
>   	}
> +	case KVM_SWITCH_DIRTY_LOG: {
> +		struct kvm_dirty_log log;
> +
> +		r = -EFAULT;
> +		if (copy_from_user(&log, argp, sizeof log))
> +			goto out;
> +		r = kvm_vm_ioctl_switch_dirty_log(kvm,&log);
> +		if (r)
> +			goto out;
> +		r = -EFAULT;
> +		if (copy_to_user(argp,&log, sizeof log))
> +			goto out;
> +		r = 0;
>    

You return 0, contrary to the documentation...

-- 
error compiling committee.c: too many arguments to function

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-21 11:46         ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-21 11:46 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	fernando-gVGce1chcLdL9jVzuh4AOg

On 04/20/2010 02:03 PM, Takuya Yoshikawa wrote:
> We can now export the addree of the bitmap created by do_mmap()
> to user space. For the sake of this, we introduce a new API:
>
>    KVM_SWITCH_DIRTY_LOG: application can use this to trigger the
>    switch of the bitmaps and get the address of the bitmap which
>    has been used until now. This reduces the copy of the dirty
>    bitmap from the kernel.
>
>
> diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt
> index baa8fde..f3d1c2a 100644
> --- a/Documentation/kvm/api.txt
> +++ b/Documentation/kvm/api.txt
> @@ -848,6 +848,29 @@ function properly, this is the place to put them.
>          __u8  pad[64];
>   };
>
> +4.37 KVM_SWITCH_DIRTY_LOG (vm ioctl)
> +
> +Capability: basic
>    

Capability: basic means that this is available on all kvm versions, 
which isn't the case.  This should say KVM_CAP_USER_DIRTY_BITMAP.
> +Architectures: x86
>    

All architecures...

> +Type: vm ioctl
> +Parameters: struct kvm_dirty_log (in/out)
> +Returns: 0 on success, -1 on error
> +
> +/* for KVM_SWITCH_DIRTY_LOG */
> +struct kvm_dirty_log {
> +	__u32 slot;
> +	__u32 padding;
>    

Please put a flags field here (and verify it is zero in the ioctl 
implementation).  This allows us to extend it later.

> +	union {
> +		void __user *dirty_bitmap; /* one bit per page */
> +		__u64 addr;
> +	};
>    

Just make dirty_bitmap a __u64.  With the union there is the risk that 
someone forgets to zero the structure so we get some random bits in the 
pointer, and also issues with big endian and s390 compat.

Reserve some extra space here for future expansion.

Hm.  I see that this is the existing kvm_dirty_log structure.  So we 
can't play with it, ignore my comments about it.

> +};
> +
> +Given a memory slot, return the address of 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.
>    

Document that bitmaps but be aligned and padded to 64-bits to avoid 
32-on-64 issues.  Explain that dirty_bitmap will be the next returned 
(do we actually need the return value?  userspace can simply remember it 
from the last call).

How is the dirty log set when we start logging?  With kernel allocated 
bitmaps this isn't a problem, but with user allocated bitmaps?

> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index ad55353..45b728c 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -2718,11 +2718,9 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
>   	return 0;
>   }
>
> -/*
> - * 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)
> +static int kvm_x86_update_dirty_log(struct kvm *kvm,
> +				    struct kvm_dirty_log *log,
> +				    bool need_copy)
>   {
>   	int r;
>   	struct kvm_memory_slot *memslot;
> @@ -2773,12 +2771,34 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
>   		dirty_bitmap_old = dirty_bitmap;
>   	}
>
> -	r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap_old, n);
> +	if (need_copy) {
> +		r = kvm_copy_dirty_bitmap(log->dirty_bitmap,
> +					  dirty_bitmap_old, n);
> +	} else {
> +		log->addr = (unsigned long)dirty_bitmap_old;
> +		r = 0;
> +	}
>    

Instead of passing need_copy everywhere, you might check a flag in 
log->.  You'll need a flag to know whether to munmap() or not, no?

> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
> index 23ea022..9fa6f1e 100644
> --- a/include/linux/kvm.h
> +++ b/include/linux/kvm.h
> @@ -12,7 +12,7 @@
>   #include<linux/ioctl.h>
>   #include<asm/kvm.h>
>
> -#define KVM_API_VERSION 12
> +#define KVM_API_VERSION 13
>    

As Alex says, this breaks all known userspace.

>
>   /* *** Deprecated interfaces *** */
>
> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>   	__u32 padding1;
>   	union {
>   		void __user *dirty_bitmap; /* one bit per page */
> -		__u64 padding2;
> +		__u64 addr;
>   	};
>   };
>    

Update the comment above to note it applies to KVM_SWITCH_DIRTY_LOG.

> @@ -1699,6 +1714,21 @@ static long kvm_vm_ioctl(struct file *filp,
>   			goto out;
>   		break;
>   	}
> +	case KVM_SWITCH_DIRTY_LOG: {
> +		struct kvm_dirty_log log;
> +
> +		r = -EFAULT;
> +		if (copy_from_user(&log, argp, sizeof log))
> +			goto out;
> +		r = kvm_vm_ioctl_switch_dirty_log(kvm,&log);
> +		if (r)
> +			goto out;
> +		r = -EFAULT;
> +		if (copy_to_user(argp,&log, sizeof log))
> +			goto out;
> +		r = 0;
>    

You return 0, contrary to the documentation...

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-21 11:46         ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-21 11:46 UTC (permalink / raw)
  To: kvm-ia64

On 04/20/2010 02:03 PM, Takuya Yoshikawa wrote:
> We can now export the addree of the bitmap created by do_mmap()
> to user space. For the sake of this, we introduce a new API:
>
>    KVM_SWITCH_DIRTY_LOG: application can use this to trigger the
>    switch of the bitmaps and get the address of the bitmap which
>    has been used until now. This reduces the copy of the dirty
>    bitmap from the kernel.
>
>
> diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt
> index baa8fde..f3d1c2a 100644
> --- a/Documentation/kvm/api.txt
> +++ b/Documentation/kvm/api.txt
> @@ -848,6 +848,29 @@ function properly, this is the place to put them.
>          __u8  pad[64];
>   };
>
> +4.37 KVM_SWITCH_DIRTY_LOG (vm ioctl)
> +
> +Capability: basic
>    

Capability: basic means that this is available on all kvm versions, 
which isn't the case.  This should say KVM_CAP_USER_DIRTY_BITMAP.
> +Architectures: x86
>    

All architecures...

> +Type: vm ioctl
> +Parameters: struct kvm_dirty_log (in/out)
> +Returns: 0 on success, -1 on error
> +
> +/* for KVM_SWITCH_DIRTY_LOG */
> +struct kvm_dirty_log {
> +	__u32 slot;
> +	__u32 padding;
>    

Please put a flags field here (and verify it is zero in the ioctl 
implementation).  This allows us to extend it later.

> +	union {
> +		void __user *dirty_bitmap; /* one bit per page */
> +		__u64 addr;
> +	};
>    

Just make dirty_bitmap a __u64.  With the union there is the risk that 
someone forgets to zero the structure so we get some random bits in the 
pointer, and also issues with big endian and s390 compat.

Reserve some extra space here for future expansion.

Hm.  I see that this is the existing kvm_dirty_log structure.  So we 
can't play with it, ignore my comments about it.

> +};
> +
> +Given a memory slot, return the address of 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.
>    

Document that bitmaps but be aligned and padded to 64-bits to avoid 
32-on-64 issues.  Explain that dirty_bitmap will be the next returned 
(do we actually need the return value?  userspace can simply remember it 
from the last call).

How is the dirty log set when we start logging?  With kernel allocated 
bitmaps this isn't a problem, but with user allocated bitmaps?

> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index ad55353..45b728c 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -2718,11 +2718,9 @@ static int kvm_vm_ioctl_reinject(struct kvm *kvm,
>   	return 0;
>   }
>
> -/*
> - * 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)
> +static int kvm_x86_update_dirty_log(struct kvm *kvm,
> +				    struct kvm_dirty_log *log,
> +				    bool need_copy)
>   {
>   	int r;
>   	struct kvm_memory_slot *memslot;
> @@ -2773,12 +2771,34 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
>   		dirty_bitmap_old = dirty_bitmap;
>   	}
>
> -	r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap_old, n);
> +	if (need_copy) {
> +		r = kvm_copy_dirty_bitmap(log->dirty_bitmap,
> +					  dirty_bitmap_old, n);
> +	} else {
> +		log->addr = (unsigned long)dirty_bitmap_old;
> +		r = 0;
> +	}
>    

Instead of passing need_copy everywhere, you might check a flag in 
log->.  You'll need a flag to know whether to munmap() or not, no?

> diff --git a/include/linux/kvm.h b/include/linux/kvm.h
> index 23ea022..9fa6f1e 100644
> --- a/include/linux/kvm.h
> +++ b/include/linux/kvm.h
> @@ -12,7 +12,7 @@
>   #include<linux/ioctl.h>
>   #include<asm/kvm.h>
>
> -#define KVM_API_VERSION 12
> +#define KVM_API_VERSION 13
>    

As Alex says, this breaks all known userspace.

>
>   /* *** Deprecated interfaces *** */
>
> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>   	__u32 padding1;
>   	union {
>   		void __user *dirty_bitmap; /* one bit per page */
> -		__u64 padding2;
> +		__u64 addr;
>   	};
>   };
>    

Update the comment above to note it applies to KVM_SWITCH_DIRTY_LOG.

> @@ -1699,6 +1714,21 @@ static long kvm_vm_ioctl(struct file *filp,
>   			goto out;
>   		break;
>   	}
> +	case KVM_SWITCH_DIRTY_LOG: {
> +		struct kvm_dirty_log log;
> +
> +		r = -EFAULT;
> +		if (copy_from_user(&log, argp, sizeof log))
> +			goto out;
> +		r = kvm_vm_ioctl_switch_dirty_log(kvm,&log);
> +		if (r)
> +			goto out;
> +		r = -EFAULT;
> +		if (copy_to_user(argp,&log, sizeof log))
> +			goto out;
> +		r = 0;
>    

You return 0, contrary to the documentation...

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
  2010-04-21  9:41         ` Alexander Graf
  (?)
@ 2010-04-22  2:45           ` 
  -1 siblings, 0 replies; 141+ messages in thread
From: Fernando Luis Vázquez Cao @ 2010-04-22  2:45 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Takuya Yoshikawa, avi, mtosatti, kvm, kvm-ia64, kvm-ppc

On 04/21/2010 06:41 PM, Alexander Graf wrote:
> On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:
> 
>> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>>> 	__u32 padding1;
>>> 	union {
>>> 		void __user *dirty_bitmap; /* one bit per page */
>>> -		__u64 padding2;
>>> +		__u64 addr;
>>
>> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.
> 
> So the high 32 bits are zero. Where's the problem?

If we are careful enough to cast the addr appropriately we should be fine,
even if we keep the padding field in the union. I am not saying that it
breaks 32 architectures but that it can potentially be problematic.

>>> +	case KVM_SWITCH_DIRTY_LOG: {
>>> +		struct kvm_dirty_log log;
>>> +
>>> +		r = -EFAULT;
>>> +		if (copy_from_user(&log, argp, sizeof log))
>>> +			goto out;
>>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>>> +		if (r)
>>> +			goto out;
>>> +		r = -EFAULT;
>>> +		if (copy_to_user(argp, &log, sizeof log))
>>> +			goto out;
>>> +		r = 0;
>>> +		break;
>>> +	}
>>
>> In x86_64-compat mode we are handling 32bit user-space addresses
>> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.
> 
> The compat code just forwards everything to the generic ioctls.

The compat code uses struct compat_kvm_dirty_log instead of
struct kvm_dirty_log to communicate with user space so
the necessary conversions needs to be done before invoking
the generic ioctl (see KVM_GET_DIRTY_LOG in kvm_vm_compat_ioctl).

By the way we probable should move the definition of struct
compat_kvm_dirty_log to a header file.

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-22  2:45           ` 
  0 siblings, 0 replies; 141+ messages in thread
From:  @ 2010-04-22  2:45 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Takuya Yoshikawa, avi, mtosatti, kvm, kvm-ia64, kvm-ppc

On 04/21/2010 06:41 PM, Alexander Graf wrote:
> On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:
> 
>> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>>> 	__u32 padding1;
>>> 	union {
>>> 		void __user *dirty_bitmap; /* one bit per page */
>>> -		__u64 padding2;
>>> +		__u64 addr;
>>
>> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.
> 
> So the high 32 bits are zero. Where's the problem?

If we are careful enough to cast the addr appropriately we should be fine,
even if we keep the padding field in the union. I am not saying that it
breaks 32 architectures but that it can potentially be problematic.

>>> +	case KVM_SWITCH_DIRTY_LOG: {
>>> +		struct kvm_dirty_log log;
>>> +
>>> +		r = -EFAULT;
>>> +		if (copy_from_user(&log, argp, sizeof log))
>>> +			goto out;
>>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>>> +		if (r)
>>> +			goto out;
>>> +		r = -EFAULT;
>>> +		if (copy_to_user(argp, &log, sizeof log))
>>> +			goto out;
>>> +		r = 0;
>>> +		break;
>>> +	}
>>
>> In x86_64-compat mode we are handling 32bit user-space addresses
>> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.
> 
> The compat code just forwards everything to the generic ioctls.

The compat code uses struct compat_kvm_dirty_log instead of
struct kvm_dirty_log to communicate with user space so
the necessary conversions needs to be done before invoking
the generic ioctl (see KVM_GET_DIRTY_LOG in kvm_vm_compat_ioctl).

By the way we probable should move the definition of struct
compat_kvm_dirty_log to a header file.

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-22  2:45           ` 
  0 siblings, 0 replies; 141+ messages in thread
From:  @ 2010-04-22  2:45 UTC (permalink / raw)
  To: kvm-ia64

On 04/21/2010 06:41 PM, Alexander Graf wrote:
> On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:
> 
>> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>>> 	__u32 padding1;
>>> 	union {
>>> 		void __user *dirty_bitmap; /* one bit per page */
>>> -		__u64 padding2;
>>> +		__u64 addr;
>>
>> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.
> 
> So the high 32 bits are zero. Where's the problem?

If we are careful enough to cast the addr appropriately we should be fine,
even if we keep the padding field in the union. I am not saying that it
breaks 32 architectures but that it can potentially be problematic.

>>> +	case KVM_SWITCH_DIRTY_LOG: {
>>> +		struct kvm_dirty_log log;
>>> +
>>> +		r = -EFAULT;
>>> +		if (copy_from_user(&log, argp, sizeof log))
>>> +			goto out;
>>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>>> +		if (r)
>>> +			goto out;
>>> +		r = -EFAULT;
>>> +		if (copy_to_user(argp, &log, sizeof log))
>>> +			goto out;
>>> +		r = 0;
>>> +		break;
>>> +	}
>>
>> In x86_64-compat mode we are handling 32bit user-space addresses
>> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.
> 
> The compat code just forwards everything to the generic ioctls.

The compat code uses struct compat_kvm_dirty_log instead of
struct kvm_dirty_log to communicate with user space so
the necessary conversions needs to be done before invoking
the generic ioctl (see KVM_GET_DIRTY_LOG in kvm_vm_compat_ioctl).

By the way we probable should move the definition of struct
compat_kvm_dirty_log to a header file.

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
       [not found]           ` <4BCFB862.7010509-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
  2010-04-22  6:09               ` 
@ 2010-04-22  6:09               ` 
  0 siblings, 0 replies; 141+ messages in thread
From: Fernando Luis Vázquez Cao @ 2010-04-22  6:09 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Takuya Yoshikawa, avi-H+wXaHxf7aLQT0dZR+AlfA,
	mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA

On 04/22/2010 11:45 AM, Fernando Luis Vázquez Cao wrote:
> On 04/21/2010 06:41 PM, Alexander Graf wrote:
>> On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:
>>
>>> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>>>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>>>> 	__u32 padding1;
>>>> 	union {
>>>> 		void __user *dirty_bitmap; /* one bit per page */
>>>> -		__u64 padding2;
>>>> +		__u64 addr;
>>>
>>> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.
>>
>> So the high 32 bits are zero. Where's the problem?
> 
> If we are careful enough to cast the addr appropriately we should be fine,
> even if we keep the padding field in the union. I am not saying that it
> breaks 32 architectures but that it can potentially be problematic.
> 
>>>> +	case KVM_SWITCH_DIRTY_LOG: {
>>>> +		struct kvm_dirty_log log;
>>>> +
>>>> +		r = -EFAULT;
>>>> +		if (copy_from_user(&log, argp, sizeof log))
>>>> +			goto out;
>>>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>>>> +		if (r)
>>>> +			goto out;
>>>> +		r = -EFAULT;
>>>> +		if (copy_to_user(argp, &log, sizeof log))
>>>> +			goto out;
>>>> +		r = 0;
>>>> +		break;
>>>> +	}
>>>
>>> In x86_64-compat mode we are handling 32bit user-space addresses
>>> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.
>>
>> The compat code just forwards everything to the generic ioctls.
> 
> The compat code uses struct compat_kvm_dirty_log instead of
> struct kvm_dirty_log to communicate with user space so
> the necessary conversions needs to be done before invoking
> the generic ioctl (see KVM_GET_DIRTY_LOG in kvm_vm_compat_ioctl).
> 
> By the way we probable should move the definition of struct
> compat_kvm_dirty_log to a header file.

It seems that it was you and Arnd who added the kvm_vm compat ioctl :-).
Are you considering a different approach to tackle the issues that we
have with a big-endian userspace?

Thanks,

Fernando

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-22  6:09               ` 
  0 siblings, 0 replies; 141+ messages in thread
From:  @ 2010-04-22  6:09 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Takuya Yoshikawa, avi-H+wXaHxf7aLQT0dZR+AlfA,
	mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA

On 04/22/2010 11:45 AM, Fernando Luis Vázquez Cao wrote:
> On 04/21/2010 06:41 PM, Alexander Graf wrote:
>> On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:
>>
>>> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>>>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>>>> 	__u32 padding1;
>>>> 	union {
>>>> 		void __user *dirty_bitmap; /* one bit per page */
>>>> -		__u64 padding2;
>>>> +		__u64 addr;
>>>
>>> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.
>>
>> So the high 32 bits are zero. Where's the problem?
> 
> If we are careful enough to cast the addr appropriately we should be fine,
> even if we keep the padding field in the union. I am not saying that it
> breaks 32 architectures but that it can potentially be problematic.
> 
>>>> +	case KVM_SWITCH_DIRTY_LOG: {
>>>> +		struct kvm_dirty_log log;
>>>> +
>>>> +		r = -EFAULT;
>>>> +		if (copy_from_user(&log, argp, sizeof log))
>>>> +			goto out;
>>>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>>>> +		if (r)
>>>> +			goto out;
>>>> +		r = -EFAULT;
>>>> +		if (copy_to_user(argp, &log, sizeof log))
>>>> +			goto out;
>>>> +		r = 0;
>>>> +		break;
>>>> +	}
>>>
>>> In x86_64-compat mode we are handling 32bit user-space addresses
>>> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.
>>
>> The compat code just forwards everything to the generic ioctls.
> 
> The compat code uses struct compat_kvm_dirty_log instead of
> struct kvm_dirty_log to communicate with user space so
> the necessary conversions needs to be done before invoking
> the generic ioctl (see KVM_GET_DIRTY_LOG in kvm_vm_compat_ioctl).
> 
> By the way we probable should move the definition of struct
> compat_kvm_dirty_log to a header file.

It seems that it was you and Arnd who added the kvm_vm compat ioctl :-).
Are you considering a different approach to tackle the issues that we
have with a big-endian userspace?

Thanks,

Fernando

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-22  6:09               ` 
  0 siblings, 0 replies; 141+ messages in thread
From:  @ 2010-04-22  6:09 UTC (permalink / raw)
  To: kvm-ia64

On 04/22/2010 11:45 AM, Fernando Luis Vázquez Cao wrote:
> On 04/21/2010 06:41 PM, Alexander Graf wrote:
>> On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:
>>
>>> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>>>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>>>> 	__u32 padding1;
>>>> 	union {
>>>> 		void __user *dirty_bitmap; /* one bit per page */
>>>> -		__u64 padding2;
>>>> +		__u64 addr;
>>>
>>> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.
>>
>> So the high 32 bits are zero. Where's the problem?
> 
> If we are careful enough to cast the addr appropriately we should be fine,
> even if we keep the padding field in the union. I am not saying that it
> breaks 32 architectures but that it can potentially be problematic.
> 
>>>> +	case KVM_SWITCH_DIRTY_LOG: {
>>>> +		struct kvm_dirty_log log;
>>>> +
>>>> +		r = -EFAULT;
>>>> +		if (copy_from_user(&log, argp, sizeof log))
>>>> +			goto out;
>>>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>>>> +		if (r)
>>>> +			goto out;
>>>> +		r = -EFAULT;
>>>> +		if (copy_to_user(argp, &log, sizeof log))
>>>> +			goto out;
>>>> +		r = 0;
>>>> +		break;
>>>> +	}
>>>
>>> In x86_64-compat mode we are handling 32bit user-space addresses
>>> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.
>>
>> The compat code just forwards everything to the generic ioctls.
> 
> The compat code uses struct compat_kvm_dirty_log instead of
> struct kvm_dirty_log to communicate with user space so
> the necessary conversions needs to be done before invoking
> the generic ioctl (see KVM_GET_DIRTY_LOG in kvm_vm_compat_ioctl).
> 
> By the way we probable should move the definition of struct
> compat_kvm_dirty_log to a header file.

It seems that it was you and Arnd who added the kvm_vm compat ioctl :-).
Are you considering a different approach to tackle the issues that we
have with a big-endian userspace?

Thanks,

Fernando

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy dirty bitmaps to user space
  2010-04-21 11:12         ` Avi Kivity
  (?)
@ 2010-04-22  8:57           ` Takuya Yoshikawa
  -1 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-22  8:57 UTC (permalink / raw)
  To: Avi Kivity; +Cc: mtosatti, kvm, kvm-ia64, kvm-ppc, fernando

(2010/04/21 20:12), Avi Kivity wrote:
> On 04/20/2010 01:59 PM, Takuya Yoshikawa wrote:
>> We will replace copy_to_user() to copy_in_user() when we move
>> the dirty bitmaps to user space.
>>
>> But sadly, we have copy_in_user() only for 64 bits architectures.
>> So this function should work as a wrapper to hide ifdefs from outside.
>> Once we get copy_in_user() for 32 bits architectures, we can remove
>> this wrapper and use copy_in_user() directly.
>
> I prefer a generic copy_in_user() instead of having multiple paths in kvm.
>

I do too :).

I checked ppc64's copy_in_user().
It looks like just using __copy_tofrom_user() and it is also implemented
for ppc32, IIUC.

So yes, we may not need to implement it by ourselves!

Just ask them to make it useful for 32bit too.



And about x86_32 copy_in_user().

They are using copy_user_generic() which is implemented only for 64bit.

So I'll show them current copy_from_user() and copy_to_user() version and
see their response.

If rejected, though I hope not, please give me another option, OK?


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy
@ 2010-04-22  8:57           ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-22  8:57 UTC (permalink / raw)
  To: Avi Kivity; +Cc: mtosatti, kvm, kvm-ia64, kvm-ppc, fernando

(2010/04/21 20:12), Avi Kivity wrote:
> On 04/20/2010 01:59 PM, Takuya Yoshikawa wrote:
>> We will replace copy_to_user() to copy_in_user() when we move
>> the dirty bitmaps to user space.
>>
>> But sadly, we have copy_in_user() only for 64 bits architectures.
>> So this function should work as a wrapper to hide ifdefs from outside.
>> Once we get copy_in_user() for 32 bits architectures, we can remove
>> this wrapper and use copy_in_user() directly.
>
> I prefer a generic copy_in_user() instead of having multiple paths in kvm.
>

I do too :).

I checked ppc64's copy_in_user().
It looks like just using __copy_tofrom_user() and it is also implemented
for ppc32, IIUC.

So yes, we may not need to implement it by ourselves!

Just ask them to make it useful for 32bit too.



And about x86_32 copy_in_user().

They are using copy_user_generic() which is implemented only for 64bit.

So I'll show them current copy_from_user() and copy_to_user() version and
see their response.

If rejected, though I hope not, please give me another option, OK?


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy
@ 2010-04-22  8:57           ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-22  8:57 UTC (permalink / raw)
  To: kvm-ia64

(2010/04/21 20:12), Avi Kivity wrote:
> On 04/20/2010 01:59 PM, Takuya Yoshikawa wrote:
>> We will replace copy_to_user() to copy_in_user() when we move
>> the dirty bitmaps to user space.
>>
>> But sadly, we have copy_in_user() only for 64 bits architectures.
>> So this function should work as a wrapper to hide ifdefs from outside.
>> Once we get copy_in_user() for 32 bits architectures, we can remove
>> this wrapper and use copy_in_user() directly.
>
> I prefer a generic copy_in_user() instead of having multiple paths in kvm.
>

I do too :).

I checked ppc64's copy_in_user().
It looks like just using __copy_tofrom_user() and it is also implemented
for ppc32, IIUC.

So yes, we may not need to implement it by ourselves!

Just ask them to make it useful for 32bit too.



And about x86_32 copy_in_user().

They are using copy_user_generic() which is implemented only for 64bit.

So I'll show them current copy_from_user() and copy_to_user() version and
see their response.

If rejected, though I hope not, please give me another option, OK?


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
       [not found]         ` <4BCEE0E4.6060707-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  2010-04-22  9:07             ` Takuya Yoshikawa
@ 2010-04-22  9:07             ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-22  9:07 UTC (permalink / raw)
  To: Avi Kivity
  Cc: mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	fernando-gVGce1chcLdL9jVzuh4AOg

(2010/04/21 20:26), Avi Kivity wrote:

>> r = 0;
>> @@ -1858,7 +1866,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
>> if (memslot->is_dirty) {
>> kvm_flush_remote_tlbs(kvm);
>> n = kvm_dirty_bitmap_bytes(memslot);
>> - memset(memslot->dirty_bitmap, 0, n);
>> + clear_user(memslot->dirty_bitmap, n);
>> memslot->is_dirty = false;
>
> Does this need an error check?

Yes, sorry I forgot.

>
>
>> @@ -468,8 +480,12 @@ void kvm_free_physmem(struct kvm *kvm)
>> int i;
>> struct kvm_memslots *slots = kvm->memslots;
>>
>> - for (i = 0; i< slots->nmemslots; ++i)
>> + for (i = 0; i< slots->nmemslots; ++i) {
>> + /* We don't munmap dirty bitmaps by ourselves. */
>
> Why not? If we allocated them, we have to free them.

In the case of VM destruction, when qemu process exits, it conflicts
with the work of the usual (process) destructor's job.

I struggled with this problem before sending the first version.

So I have to differentiate the slot release and qemu process exit.



>
>> + slots->memslots[i].dirty_bitmap = NULL;
>> + slots->memslots[i].dirty_bitmap_old = NULL;
>> kvm_free_physmem_slot(&slots->memslots[i], NULL);
>> + }
>>
>>
>> +/*
>> + * Please use generic *_user bitops once they become available.
>> + * Be careful setting the bit won't be done atomically.
>> + */
>
> Please introduce the user bitops as part of this patchset.
>

OK, I will do in the next version. In this RFC, I would be happy if I can
know the overall design is right or not.

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-22  9:07             ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-22  9:07 UTC (permalink / raw)
  To: Avi Kivity
  Cc: mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	fernando-gVGce1chcLdL9jVzuh4AOg

(2010/04/21 20:26), Avi Kivity wrote:

>> r = 0;
>> @@ -1858,7 +1866,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
>> if (memslot->is_dirty) {
>> kvm_flush_remote_tlbs(kvm);
>> n = kvm_dirty_bitmap_bytes(memslot);
>> - memset(memslot->dirty_bitmap, 0, n);
>> + clear_user(memslot->dirty_bitmap, n);
>> memslot->is_dirty = false;
>
> Does this need an error check?

Yes, sorry I forgot.

>
>
>> @@ -468,8 +480,12 @@ void kvm_free_physmem(struct kvm *kvm)
>> int i;
>> struct kvm_memslots *slots = kvm->memslots;
>>
>> - for (i = 0; i< slots->nmemslots; ++i)
>> + for (i = 0; i< slots->nmemslots; ++i) {
>> + /* We don't munmap dirty bitmaps by ourselves. */
>
> Why not? If we allocated them, we have to free them.

In the case of VM destruction, when qemu process exits, it conflicts
with the work of the usual (process) destructor's job.

I struggled with this problem before sending the first version.

So I have to differentiate the slot release and qemu process exit.



>
>> + slots->memslots[i].dirty_bitmap = NULL;
>> + slots->memslots[i].dirty_bitmap_old = NULL;
>> kvm_free_physmem_slot(&slots->memslots[i], NULL);
>> + }
>>
>>
>> +/*
>> + * Please use generic *_user bitops once they become available.
>> + * Be careful setting the bit won't be done atomically.
>> + */
>
> Please introduce the user bitops as part of this patchset.
>

OK, I will do in the next version. In this RFC, I would be happy if I can
know the overall design is right or not.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-22  9:07             ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-22  9:07 UTC (permalink / raw)
  To: kvm-ia64

(2010/04/21 20:26), Avi Kivity wrote:

>> r = 0;
>> @@ -1858,7 +1866,7 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm,
>> if (memslot->is_dirty) {
>> kvm_flush_remote_tlbs(kvm);
>> n = kvm_dirty_bitmap_bytes(memslot);
>> - memset(memslot->dirty_bitmap, 0, n);
>> + clear_user(memslot->dirty_bitmap, n);
>> memslot->is_dirty = false;
>
> Does this need an error check?

Yes, sorry I forgot.

>
>
>> @@ -468,8 +480,12 @@ void kvm_free_physmem(struct kvm *kvm)
>> int i;
>> struct kvm_memslots *slots = kvm->memslots;
>>
>> - for (i = 0; i< slots->nmemslots; ++i)
>> + for (i = 0; i< slots->nmemslots; ++i) {
>> + /* We don't munmap dirty bitmaps by ourselves. */
>
> Why not? If we allocated them, we have to free them.

In the case of VM destruction, when qemu process exits, it conflicts
with the work of the usual (process) destructor's job.

I struggled with this problem before sending the first version.

So I have to differentiate the slot release and qemu process exit.



>
>> + slots->memslots[i].dirty_bitmap = NULL;
>> + slots->memslots[i].dirty_bitmap_old = NULL;
>> kvm_free_physmem_slot(&slots->memslots[i], NULL);
>> + }
>>
>>
>> +/*
>> + * Please use generic *_user bitops once they become available.
>> + * Be careful setting the bit won't be done atomically.
>> + */
>
> Please introduce the user bitops as part of this patchset.
>

OK, I will do in the next version. In this RFC, I would be happy if I can
know the overall design is right or not.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
       [not found]         ` <4BCEE579.9020206-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  2010-04-22  9:34             ` Takuya Yoshikawa
@ 2010-04-22  9:34             ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-22  9:34 UTC (permalink / raw)
  To: Avi Kivity
  Cc: mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	fernando-gVGce1chcLdL9jVzuh4AOg

Thanks, I can know basic rules about kvm/api .

(2010/04/21 20:46), Avi Kivity wrote:

>
>> +Type: vm ioctl
>> +Parameters: struct kvm_dirty_log (in/out)
>> +Returns: 0 on success, -1 on error
>> +
>> +/* for KVM_SWITCH_DIRTY_LOG */
>> +struct kvm_dirty_log {
>> + __u32 slot;
>> + __u32 padding;
>
> Please put a flags field here (and verify it is zero in the ioctl
> implementation). This allows us to extend it later.
>
>> + union {
>> + void __user *dirty_bitmap; /* one bit per page */
>> + __u64 addr;
>> + };
>
> Just make dirty_bitmap a __u64. With the union there is the risk that
> someone forgets to zero the structure so we get some random bits in the
> pointer, and also issues with big endian and s390 compat.
>
> Reserve some extra space here for future expansion.
>
> Hm. I see that this is the existing kvm_dirty_log structure. So we can't
> play with it, ignore my comments about it.

So, introducing a new structure to export(and get) two bitmap addresses
with a flag is the thing?

1. Qemu calls ioctl to get the two addresses.
2. Qemu calls ioctl to make KVM switch the dirty bitmaps.
    --> in this case, qemu have to change the address got in step 1.
    ...
3. Qemu calls ioctl(we can reuse 1. with different command flag) to free the bitmaps.


In my plan, we don't let qemu malloc() dirty bitmaps: at least, I want to make that
another patch set because this patch set already has some dependencies to other issues.

But, yes, I can make the struct considering the future expansion if it needed.


>>
>> - r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap_old, n);
>> + if (need_copy) {
>> + r = kvm_copy_dirty_bitmap(log->dirty_bitmap,
>> + dirty_bitmap_old, n);
>> + } else {
>> + log->addr = (unsigned long)dirty_bitmap_old;
>> + r = 0;
>> + }
>
> Instead of passing need_copy everywhere, you might check a flag in
> log->. You'll need a flag to know whether to munmap() or not, no?

To judge munmap() or not, putting in the memory slot's flag may be
more useful.

But as you suggest, we won't use kvm_dirty_log so parameters will change.

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-22  9:34             ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-22  9:34 UTC (permalink / raw)
  To: Avi Kivity
  Cc: mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	fernando-gVGce1chcLdL9jVzuh4AOg

Thanks, I can know basic rules about kvm/api .

(2010/04/21 20:46), Avi Kivity wrote:

>
>> +Type: vm ioctl
>> +Parameters: struct kvm_dirty_log (in/out)
>> +Returns: 0 on success, -1 on error
>> +
>> +/* for KVM_SWITCH_DIRTY_LOG */
>> +struct kvm_dirty_log {
>> + __u32 slot;
>> + __u32 padding;
>
> Please put a flags field here (and verify it is zero in the ioctl
> implementation). This allows us to extend it later.
>
>> + union {
>> + void __user *dirty_bitmap; /* one bit per page */
>> + __u64 addr;
>> + };
>
> Just make dirty_bitmap a __u64. With the union there is the risk that
> someone forgets to zero the structure so we get some random bits in the
> pointer, and also issues with big endian and s390 compat.
>
> Reserve some extra space here for future expansion.
>
> Hm. I see that this is the existing kvm_dirty_log structure. So we can't
> play with it, ignore my comments about it.

So, introducing a new structure to export(and get) two bitmap addresses
with a flag is the thing?

1. Qemu calls ioctl to get the two addresses.
2. Qemu calls ioctl to make KVM switch the dirty bitmaps.
    --> in this case, qemu have to change the address got in step 1.
    ...
3. Qemu calls ioctl(we can reuse 1. with different command flag) to free the bitmaps.


In my plan, we don't let qemu malloc() dirty bitmaps: at least, I want to make that
another patch set because this patch set already has some dependencies to other issues.

But, yes, I can make the struct considering the future expansion if it needed.


>>
>> - r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap_old, n);
>> + if (need_copy) {
>> + r = kvm_copy_dirty_bitmap(log->dirty_bitmap,
>> + dirty_bitmap_old, n);
>> + } else {
>> + log->addr = (unsigned long)dirty_bitmap_old;
>> + r = 0;
>> + }
>
> Instead of passing need_copy everywhere, you might check a flag in
> log->. You'll need a flag to know whether to munmap() or not, no?

To judge munmap() or not, putting in the memory slot's flag may be
more useful.

But as you suggest, we won't use kvm_dirty_log so parameters will change.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-22  9:34             ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-22  9:34 UTC (permalink / raw)
  To: kvm-ia64

Thanks, I can know basic rules about kvm/api .

(2010/04/21 20:46), Avi Kivity wrote:

>
>> +Type: vm ioctl
>> +Parameters: struct kvm_dirty_log (in/out)
>> +Returns: 0 on success, -1 on error
>> +
>> +/* for KVM_SWITCH_DIRTY_LOG */
>> +struct kvm_dirty_log {
>> + __u32 slot;
>> + __u32 padding;
>
> Please put a flags field here (and verify it is zero in the ioctl
> implementation). This allows us to extend it later.
>
>> + union {
>> + void __user *dirty_bitmap; /* one bit per page */
>> + __u64 addr;
>> + };
>
> Just make dirty_bitmap a __u64. With the union there is the risk that
> someone forgets to zero the structure so we get some random bits in the
> pointer, and also issues with big endian and s390 compat.
>
> Reserve some extra space here for future expansion.
>
> Hm. I see that this is the existing kvm_dirty_log structure. So we can't
> play with it, ignore my comments about it.

So, introducing a new structure to export(and get) two bitmap addresses
with a flag is the thing?

1. Qemu calls ioctl to get the two addresses.
2. Qemu calls ioctl to make KVM switch the dirty bitmaps.
    --> in this case, qemu have to change the address got in step 1.
    ...
3. Qemu calls ioctl(we can reuse 1. with different command flag) to free the bitmaps.


In my plan, we don't let qemu malloc() dirty bitmaps: at least, I want to make that
another patch set because this patch set already has some dependencies to other issues.

But, yes, I can make the struct considering the future expansion if it needed.


>>
>> - r = kvm_copy_dirty_bitmap(log->dirty_bitmap, dirty_bitmap_old, n);
>> + if (need_copy) {
>> + r = kvm_copy_dirty_bitmap(log->dirty_bitmap,
>> + dirty_bitmap_old, n);
>> + } else {
>> + log->addr = (unsigned long)dirty_bitmap_old;
>> + r = 0;
>> + }
>
> Instead of passing need_copy everywhere, you might check a flag in
> log->. You'll need a flag to know whether to munmap() or not, no?

To judge munmap() or not, putting in the memory slot's flag may be
more useful.

But as you suggest, we won't use kvm_dirty_log so parameters will change.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
       [not found]               ` <4BCFE805.5040500-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
  2010-04-22 23:29                   ` Alexander Graf
@ 2010-04-22 23:29                   ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-22 23:29 UTC (permalink / raw)
  To: Fernando Luis Vázquez Cao
  Cc: Takuya Yoshikawa, avi-H+wXaHxf7aLQT0dZR+AlfA,
	mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA


On 22.04.2010, at 08:09, Fernando Luis Vázquez Cao wrote:

> On 04/22/2010 11:45 AM, Fernando Luis Vázquez Cao wrote:
>> On 04/21/2010 06:41 PM, Alexander Graf wrote:
>>> On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:
>>> 
>>>> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>>>>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>>>>> 	__u32 padding1;
>>>>> 	union {
>>>>> 		void __user *dirty_bitmap; /* one bit per page */
>>>>> -		__u64 padding2;
>>>>> +		__u64 addr;
>>>> 
>>>> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.
>>> 
>>> So the high 32 bits are zero. Where's the problem?
>> 
>> If we are careful enough to cast the addr appropriately we should be fine,
>> even if we keep the padding field in the union. I am not saying that it
>> breaks 32 architectures but that it can potentially be problematic.
>> 
>>>>> +	case KVM_SWITCH_DIRTY_LOG: {
>>>>> +		struct kvm_dirty_log log;
>>>>> +
>>>>> +		r = -EFAULT;
>>>>> +		if (copy_from_user(&log, argp, sizeof log))
>>>>> +			goto out;
>>>>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>>>>> +		if (r)
>>>>> +			goto out;
>>>>> +		r = -EFAULT;
>>>>> +		if (copy_to_user(argp, &log, sizeof log))
>>>>> +			goto out;
>>>>> +		r = 0;
>>>>> +		break;
>>>>> +	}
>>>> 
>>>> In x86_64-compat mode we are handling 32bit user-space addresses
>>>> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.
>>> 
>>> The compat code just forwards everything to the generic ioctls.
>> 
>> The compat code uses struct compat_kvm_dirty_log instead of
>> struct kvm_dirty_log to communicate with user space so
>> the necessary conversions needs to be done before invoking
>> the generic ioctl (see KVM_GET_DIRTY_LOG in kvm_vm_compat_ioctl).
>> 
>> By the way we probable should move the definition of struct
>> compat_kvm_dirty_log to a header file.
> 
> It seems that it was you and Arnd who added the kvm_vm compat ioctl :-).
> Are you considering a different approach to tackle the issues that we
> have with a big-endian userspace?

IIRC the issue was a pointer inside of a nested structure, no?


Alex

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-22 23:29                   ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-22 23:29 UTC (permalink / raw)
  To: Fernando Luis Vázquez Cao
  Cc: Takuya Yoshikawa, avi-H+wXaHxf7aLQT0dZR+AlfA,
	mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA


On 22.04.2010, at 08:09, Fernando Luis Vázquez Cao wrote:

> On 04/22/2010 11:45 AM, Fernando Luis Vázquez Cao wrote:
>> On 04/21/2010 06:41 PM, Alexander Graf wrote:
>>> On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:
>>> 
>>>> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>>>>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>>>>> 	__u32 padding1;
>>>>> 	union {
>>>>> 		void __user *dirty_bitmap; /* one bit per page */
>>>>> -		__u64 padding2;
>>>>> +		__u64 addr;
>>>> 
>>>> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.
>>> 
>>> So the high 32 bits are zero. Where's the problem?
>> 
>> If we are careful enough to cast the addr appropriately we should be fine,
>> even if we keep the padding field in the union. I am not saying that it
>> breaks 32 architectures but that it can potentially be problematic.
>> 
>>>>> +	case KVM_SWITCH_DIRTY_LOG: {
>>>>> +		struct kvm_dirty_log log;
>>>>> +
>>>>> +		r = -EFAULT;
>>>>> +		if (copy_from_user(&log, argp, sizeof log))
>>>>> +			goto out;
>>>>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>>>>> +		if (r)
>>>>> +			goto out;
>>>>> +		r = -EFAULT;
>>>>> +		if (copy_to_user(argp, &log, sizeof log))
>>>>> +			goto out;
>>>>> +		r = 0;
>>>>> +		break;
>>>>> +	}
>>>> 
>>>> In x86_64-compat mode we are handling 32bit user-space addresses
>>>> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.
>>> 
>>> The compat code just forwards everything to the generic ioctls.
>> 
>> The compat code uses struct compat_kvm_dirty_log instead of
>> struct kvm_dirty_log to communicate with user space so
>> the necessary conversions needs to be done before invoking
>> the generic ioctl (see KVM_GET_DIRTY_LOG in kvm_vm_compat_ioctl).
>> 
>> By the way we probable should move the definition of struct
>> compat_kvm_dirty_log to a header file.
> 
> It seems that it was you and Arnd who added the kvm_vm compat ioctl :-).
> Are you considering a different approach to tackle the issues that we
> have with a big-endian userspace?

IIRC the issue was a pointer inside of a nested structure, no?


Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-22 23:29                   ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-22 23:29 UTC (permalink / raw)
  To: kvm-ia64


On 22.04.2010, at 08:09, Fernando Luis Vázquez Cao wrote:

> On 04/22/2010 11:45 AM, Fernando Luis Vázquez Cao wrote:
>> On 04/21/2010 06:41 PM, Alexander Graf wrote:
>>> On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:
>>> 
>>>> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>>>>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>>>>> 	__u32 padding1;
>>>>> 	union {
>>>>> 		void __user *dirty_bitmap; /* one bit per page */
>>>>> -		__u64 padding2;
>>>>> +		__u64 addr;
>>>> 
>>>> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.
>>> 
>>> So the high 32 bits are zero. Where's the problem?
>> 
>> If we are careful enough to cast the addr appropriately we should be fine,
>> even if we keep the padding field in the union. I am not saying that it
>> breaks 32 architectures but that it can potentially be problematic.
>> 
>>>>> +	case KVM_SWITCH_DIRTY_LOG: {
>>>>> +		struct kvm_dirty_log log;
>>>>> +
>>>>> +		r = -EFAULT;
>>>>> +		if (copy_from_user(&log, argp, sizeof log))
>>>>> +			goto out;
>>>>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>>>>> +		if (r)
>>>>> +			goto out;
>>>>> +		r = -EFAULT;
>>>>> +		if (copy_to_user(argp, &log, sizeof log))
>>>>> +			goto out;
>>>>> +		r = 0;
>>>>> +		break;
>>>>> +	}
>>>> 
>>>> In x86_64-compat mode we are handling 32bit user-space addresses
>>>> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.
>>> 
>>> The compat code just forwards everything to the generic ioctls.
>> 
>> The compat code uses struct compat_kvm_dirty_log instead of
>> struct kvm_dirty_log to communicate with user space so
>> the necessary conversions needs to be done before invoking
>> the generic ioctl (see KVM_GET_DIRTY_LOG in kvm_vm_compat_ioctl).
>> 
>> By the way we probable should move the definition of struct
>> compat_kvm_dirty_log to a header file.
> 
> It seems that it was you and Arnd who added the kvm_vm compat ioctl :-).
> Are you considering a different approach to tackle the issues that we
> have with a big-endian userspace?

IIRC the issue was a pointer inside of a nested structure, no?


Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
  2010-04-22 23:29                   ` Alexander Graf
  (?)
@ 2010-04-23 10:17                     ` 
  -1 siblings, 0 replies; 141+ messages in thread
From: Fernando Luis Vázquez Cao @ 2010-04-23 10:17 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Takuya Yoshikawa, avi, mtosatti, kvm, kvm-ia64, kvm-ppc

On 04/23/2010 08:29 AM, Alexander Graf wrote:
> 
> On 22.04.2010, at 08:09, Fernando Luis Vázquez Cao wrote:
> 
>> On 04/22/2010 11:45 AM, Fernando Luis Vázquez Cao wrote:
>>> On 04/21/2010 06:41 PM, Alexander Graf wrote:
>>>> On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:
>>>>
>>>>> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>>>>>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>>>>>> 	__u32 padding1;
>>>>>> 	union {
>>>>>> 		void __user *dirty_bitmap; /* one bit per page */
>>>>>> -		__u64 padding2;
>>>>>> +		__u64 addr;
>>>>>
>>>>> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.
>>>>
>>>> So the high 32 bits are zero. Where's the problem?
>>>
>>> If we are careful enough to cast the addr appropriately we should be fine,
>>> even if we keep the padding field in the union. I am not saying that it
>>> breaks 32 architectures but that it can potentially be problematic.
>>>
>>>>>> +	case KVM_SWITCH_DIRTY_LOG: {
>>>>>> +		struct kvm_dirty_log log;
>>>>>> +
>>>>>> +		r = -EFAULT;
>>>>>> +		if (copy_from_user(&log, argp, sizeof log))
>>>>>> +			goto out;
>>>>>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>>>>>> +		if (r)
>>>>>> +			goto out;
>>>>>> +		r = -EFAULT;
>>>>>> +		if (copy_to_user(argp, &log, sizeof log))
>>>>>> +			goto out;
>>>>>> +		r = 0;
>>>>>> +		break;
>>>>>> +	}
>>>>>
>>>>> In x86_64-compat mode we are handling 32bit user-space addresses
>>>>> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.
>>>>
>>>> The compat code just forwards everything to the generic ioctls.
>>>
>>> The compat code uses struct compat_kvm_dirty_log instead of
>>> struct kvm_dirty_log to communicate with user space so
>>> the necessary conversions needs to be done before invoking
>>> the generic ioctl (see KVM_GET_DIRTY_LOG in kvm_vm_compat_ioctl).
>>>
>>> By the way we probable should move the definition of struct
>>> compat_kvm_dirty_log to a header file.
>>
>> It seems that it was you and Arnd who added the kvm_vm compat ioctl :-).
>> Are you considering a different approach to tackle the issues that we
>> have with a big-endian userspace?
> 
> IIRC the issue was a pointer inside of a nested structure, no?

I would say the reason is that if we did not convert the user-space pointer to
a "void *" kvm_get_dirty_log() would end up copying the dirty log to

(log->dirty_bitmap << 32) | 0x00000000

Am I missing something?

Thanks,

Fernando

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-23 10:17                     ` 
  0 siblings, 0 replies; 141+ messages in thread
From:  @ 2010-04-23 10:17 UTC (permalink / raw)
  To: Alexander Graf; +Cc: Takuya Yoshikawa, avi, mtosatti, kvm, kvm-ia64, kvm-ppc

On 04/23/2010 08:29 AM, Alexander Graf wrote:
> 
> On 22.04.2010, at 08:09, Fernando Luis Vázquez Cao wrote:
> 
>> On 04/22/2010 11:45 AM, Fernando Luis Vázquez Cao wrote:
>>> On 04/21/2010 06:41 PM, Alexander Graf wrote:
>>>> On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:
>>>>
>>>>> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>>>>>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>>>>>> 	__u32 padding1;
>>>>>> 	union {
>>>>>> 		void __user *dirty_bitmap; /* one bit per page */
>>>>>> -		__u64 padding2;
>>>>>> +		__u64 addr;
>>>>>
>>>>> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.
>>>>
>>>> So the high 32 bits are zero. Where's the problem?
>>>
>>> If we are careful enough to cast the addr appropriately we should be fine,
>>> even if we keep the padding field in the union. I am not saying that it
>>> breaks 32 architectures but that it can potentially be problematic.
>>>
>>>>>> +	case KVM_SWITCH_DIRTY_LOG: {
>>>>>> +		struct kvm_dirty_log log;
>>>>>> +
>>>>>> +		r = -EFAULT;
>>>>>> +		if (copy_from_user(&log, argp, sizeof log))
>>>>>> +			goto out;
>>>>>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>>>>>> +		if (r)
>>>>>> +			goto out;
>>>>>> +		r = -EFAULT;
>>>>>> +		if (copy_to_user(argp, &log, sizeof log))
>>>>>> +			goto out;
>>>>>> +		r = 0;
>>>>>> +		break;
>>>>>> +	}
>>>>>
>>>>> In x86_64-compat mode we are handling 32bit user-space addresses
>>>>> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.
>>>>
>>>> The compat code just forwards everything to the generic ioctls.
>>>
>>> The compat code uses struct compat_kvm_dirty_log instead of
>>> struct kvm_dirty_log to communicate with user space so
>>> the necessary conversions needs to be done before invoking
>>> the generic ioctl (see KVM_GET_DIRTY_LOG in kvm_vm_compat_ioctl).
>>>
>>> By the way we probable should move the definition of struct
>>> compat_kvm_dirty_log to a header file.
>>
>> It seems that it was you and Arnd who added the kvm_vm compat ioctl :-).
>> Are you considering a different approach to tackle the issues that we
>> have with a big-endian userspace?
> 
> IIRC the issue was a pointer inside of a nested structure, no?

I would say the reason is that if we did not convert the user-space pointer to
a "void *" kvm_get_dirty_log() would end up copying the dirty log to

(log->dirty_bitmap << 32) | 0x00000000

Am I missing something?

Thanks,

Fernando

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-23 10:17                     ` 
  0 siblings, 0 replies; 141+ messages in thread
From:  @ 2010-04-23 10:17 UTC (permalink / raw)
  To: kvm-ia64

On 04/23/2010 08:29 AM, Alexander Graf wrote:
> 
> On 22.04.2010, at 08:09, Fernando Luis Vázquez Cao wrote:
> 
>> On 04/22/2010 11:45 AM, Fernando Luis Vázquez Cao wrote:
>>> On 04/21/2010 06:41 PM, Alexander Graf wrote:
>>>> On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:
>>>>
>>>>> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>>>>>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>>>>>> 	__u32 padding1;
>>>>>> 	union {
>>>>>> 		void __user *dirty_bitmap; /* one bit per page */
>>>>>> -		__u64 padding2;
>>>>>> +		__u64 addr;
>>>>>
>>>>> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.
>>>>
>>>> So the high 32 bits are zero. Where's the problem?
>>>
>>> If we are careful enough to cast the addr appropriately we should be fine,
>>> even if we keep the padding field in the union. I am not saying that it
>>> breaks 32 architectures but that it can potentially be problematic.
>>>
>>>>>> +	case KVM_SWITCH_DIRTY_LOG: {
>>>>>> +		struct kvm_dirty_log log;
>>>>>> +
>>>>>> +		r = -EFAULT;
>>>>>> +		if (copy_from_user(&log, argp, sizeof log))
>>>>>> +			goto out;
>>>>>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>>>>>> +		if (r)
>>>>>> +			goto out;
>>>>>> +		r = -EFAULT;
>>>>>> +		if (copy_to_user(argp, &log, sizeof log))
>>>>>> +			goto out;
>>>>>> +		r = 0;
>>>>>> +		break;
>>>>>> +	}
>>>>>
>>>>> In x86_64-compat mode we are handling 32bit user-space addresses
>>>>> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.
>>>>
>>>> The compat code just forwards everything to the generic ioctls.
>>>
>>> The compat code uses struct compat_kvm_dirty_log instead of
>>> struct kvm_dirty_log to communicate with user space so
>>> the necessary conversions needs to be done before invoking
>>> the generic ioctl (see KVM_GET_DIRTY_LOG in kvm_vm_compat_ioctl).
>>>
>>> By the way we probable should move the definition of struct
>>> compat_kvm_dirty_log to a header file.
>>
>> It seems that it was you and Arnd who added the kvm_vm compat ioctl :-).
>> Are you considering a different approach to tackle the issues that we
>> have with a big-endian userspace?
> 
> IIRC the issue was a pointer inside of a nested structure, no?

I would say the reason is that if we did not convert the user-space pointer to
a "void *" kvm_get_dirty_log() would end up copying the dirty log to

(log->dirty_bitmap << 32) | 0x00000000

Am I missing something?

Thanks,

Fernando

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
  2010-04-23 10:17                     ` 
  (?)
@ 2010-04-23 10:20                       ` Alexander Graf
  -1 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-23 10:20 UTC (permalink / raw)
  To: Fernando Luis Vázquez Cao
  Cc: Takuya Yoshikawa, avi, mtosatti, kvm, kvm-ia64, kvm-ppc


On 23.04.2010, at 12:17, Fernando Luis Vázquez Cao wrote:

> On 04/23/2010 08:29 AM, Alexander Graf wrote:
>> 
>> On 22.04.2010, at 08:09, Fernando Luis Vázquez Cao wrote:
>> 
>>> On 04/22/2010 11:45 AM, Fernando Luis Vázquez Cao wrote:
>>>> On 04/21/2010 06:41 PM, Alexander Graf wrote:
>>>>> On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:
>>>>> 
>>>>>> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>>>>>>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>>>>>>> 	__u32 padding1;
>>>>>>> 	union {
>>>>>>> 		void __user *dirty_bitmap; /* one bit per page */
>>>>>>> -		__u64 padding2;
>>>>>>> +		__u64 addr;
>>>>>> 
>>>>>> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.
>>>>> 
>>>>> So the high 32 bits are zero. Where's the problem?
>>>> 
>>>> If we are careful enough to cast the addr appropriately we should be fine,
>>>> even if we keep the padding field in the union. I am not saying that it
>>>> breaks 32 architectures but that it can potentially be problematic.
>>>> 
>>>>>>> +	case KVM_SWITCH_DIRTY_LOG: {
>>>>>>> +		struct kvm_dirty_log log;
>>>>>>> +
>>>>>>> +		r = -EFAULT;
>>>>>>> +		if (copy_from_user(&log, argp, sizeof log))
>>>>>>> +			goto out;
>>>>>>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>>>>>>> +		if (r)
>>>>>>> +			goto out;
>>>>>>> +		r = -EFAULT;
>>>>>>> +		if (copy_to_user(argp, &log, sizeof log))
>>>>>>> +			goto out;
>>>>>>> +		r = 0;
>>>>>>> +		break;
>>>>>>> +	}
>>>>>> 
>>>>>> In x86_64-compat mode we are handling 32bit user-space addresses
>>>>>> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.
>>>>> 
>>>>> The compat code just forwards everything to the generic ioctls.
>>>> 
>>>> The compat code uses struct compat_kvm_dirty_log instead of
>>>> struct kvm_dirty_log to communicate with user space so
>>>> the necessary conversions needs to be done before invoking
>>>> the generic ioctl (see KVM_GET_DIRTY_LOG in kvm_vm_compat_ioctl).
>>>> 
>>>> By the way we probable should move the definition of struct
>>>> compat_kvm_dirty_log to a header file.
>>> 
>>> It seems that it was you and Arnd who added the kvm_vm compat ioctl :-).
>>> Are you considering a different approach to tackle the issues that we
>>> have with a big-endian userspace?
>> 
>> IIRC the issue was a pointer inside of a nested structure, no?
> 
> I would say the reason is that if we did not convert the user-space pointer to
> a "void *" kvm_get_dirty_log() would end up copying the dirty log to
> 
> (log->dirty_bitmap << 32) | 0x00000000

Well yes, that was the problem. If we always set the __u64 value to the pointer we're safe though.

union {
  void *p;
  __u64 q;
}

void x(void *r)
{
  // breaks:
  p = r;

  // works:
  q = (ulong)r;
}

Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-23 10:20                       ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-23 10:20 UTC (permalink / raw)
  To: Fernando Luis Vázquez Cao
  Cc: Takuya Yoshikawa, avi, mtosatti, kvm, kvm-ia64, kvm-ppc


On 23.04.2010, at 12:17, Fernando Luis Vázquez Cao wrote:

> On 04/23/2010 08:29 AM, Alexander Graf wrote:
>> 
>> On 22.04.2010, at 08:09, Fernando Luis Vázquez Cao wrote:
>> 
>>> On 04/22/2010 11:45 AM, Fernando Luis Vázquez Cao wrote:
>>>> On 04/21/2010 06:41 PM, Alexander Graf wrote:
>>>>> On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:
>>>>> 
>>>>>> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>>>>>>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>>>>>>> 	__u32 padding1;
>>>>>>> 	union {
>>>>>>> 		void __user *dirty_bitmap; /* one bit per page */
>>>>>>> -		__u64 padding2;
>>>>>>> +		__u64 addr;
>>>>>> 
>>>>>> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.
>>>>> 
>>>>> So the high 32 bits are zero. Where's the problem?
>>>> 
>>>> If we are careful enough to cast the addr appropriately we should be fine,
>>>> even if we keep the padding field in the union. I am not saying that it
>>>> breaks 32 architectures but that it can potentially be problematic.
>>>> 
>>>>>>> +	case KVM_SWITCH_DIRTY_LOG: {
>>>>>>> +		struct kvm_dirty_log log;
>>>>>>> +
>>>>>>> +		r = -EFAULT;
>>>>>>> +		if (copy_from_user(&log, argp, sizeof log))
>>>>>>> +			goto out;
>>>>>>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>>>>>>> +		if (r)
>>>>>>> +			goto out;
>>>>>>> +		r = -EFAULT;
>>>>>>> +		if (copy_to_user(argp, &log, sizeof log))
>>>>>>> +			goto out;
>>>>>>> +		r = 0;
>>>>>>> +		break;
>>>>>>> +	}
>>>>>> 
>>>>>> In x86_64-compat mode we are handling 32bit user-space addresses
>>>>>> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.
>>>>> 
>>>>> The compat code just forwards everything to the generic ioctls.
>>>> 
>>>> The compat code uses struct compat_kvm_dirty_log instead of
>>>> struct kvm_dirty_log to communicate with user space so
>>>> the necessary conversions needs to be done before invoking
>>>> the generic ioctl (see KVM_GET_DIRTY_LOG in kvm_vm_compat_ioctl).
>>>> 
>>>> By the way we probable should move the definition of struct
>>>> compat_kvm_dirty_log to a header file.
>>> 
>>> It seems that it was you and Arnd who added the kvm_vm compat ioctl :-).
>>> Are you considering a different approach to tackle the issues that we
>>> have with a big-endian userspace?
>> 
>> IIRC the issue was a pointer inside of a nested structure, no?
> 
> I would say the reason is that if we did not convert the user-space pointer to
> a "void *" kvm_get_dirty_log() would end up copying the dirty log to
> 
> (log->dirty_bitmap << 32) | 0x00000000

Well yes, that was the problem. If we always set the __u64 value to the pointer we're safe though.

union {
  void *p;
  __u64 q;
}

void x(void *r)
{
  // breaks:
  p = r;

  // works:
  q = (ulong)r;
}

Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-23 10:20                       ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-23 10:20 UTC (permalink / raw)
  To: kvm-ia64


On 23.04.2010, at 12:17, Fernando Luis Vázquez Cao wrote:

> On 04/23/2010 08:29 AM, Alexander Graf wrote:
>> 
>> On 22.04.2010, at 08:09, Fernando Luis Vázquez Cao wrote:
>> 
>>> On 04/22/2010 11:45 AM, Fernando Luis Vázquez Cao wrote:
>>>> On 04/21/2010 06:41 PM, Alexander Graf wrote:
>>>>> On 21.04.2010, at 10:29, Fernando Luis Vázquez Cao wrote:
>>>>> 
>>>>>> On 04/20/2010 08:03 PM, Takuya Yoshikawa wrote:
>>>>>>> @@ -318,7 +318,7 @@ struct kvm_dirty_log {
>>>>>>> 	__u32 padding1;
>>>>>>> 	union {
>>>>>>> 		void __user *dirty_bitmap; /* one bit per page */
>>>>>>> -		__u64 padding2;
>>>>>>> +		__u64 addr;
>>>>>> 
>>>>>> This can break on x86_32 and x86_64-compat. addr is a long not a __u64.
>>>>> 
>>>>> So the high 32 bits are zero. Where's the problem?
>>>> 
>>>> If we are careful enough to cast the addr appropriately we should be fine,
>>>> even if we keep the padding field in the union. I am not saying that it
>>>> breaks 32 architectures but that it can potentially be problematic.
>>>> 
>>>>>>> +	case KVM_SWITCH_DIRTY_LOG: {
>>>>>>> +		struct kvm_dirty_log log;
>>>>>>> +
>>>>>>> +		r = -EFAULT;
>>>>>>> +		if (copy_from_user(&log, argp, sizeof log))
>>>>>>> +			goto out;
>>>>>>> +		r = kvm_vm_ioctl_switch_dirty_log(kvm, &log);
>>>>>>> +		if (r)
>>>>>>> +			goto out;
>>>>>>> +		r = -EFAULT;
>>>>>>> +		if (copy_to_user(argp, &log, sizeof log))
>>>>>>> +			goto out;
>>>>>>> +		r = 0;
>>>>>>> +		break;
>>>>>>> +	}
>>>>>> 
>>>>>> In x86_64-compat mode we are handling 32bit user-space addresses
>>>>>> so we need the compat counterpart of KVM_SWITCH_DIRTY_LOG too.
>>>>> 
>>>>> The compat code just forwards everything to the generic ioctls.
>>>> 
>>>> The compat code uses struct compat_kvm_dirty_log instead of
>>>> struct kvm_dirty_log to communicate with user space so
>>>> the necessary conversions needs to be done before invoking
>>>> the generic ioctl (see KVM_GET_DIRTY_LOG in kvm_vm_compat_ioctl).
>>>> 
>>>> By the way we probable should move the definition of struct
>>>> compat_kvm_dirty_log to a header file.
>>> 
>>> It seems that it was you and Arnd who added the kvm_vm compat ioctl :-).
>>> Are you considering a different approach to tackle the issues that we
>>> have with a big-endian userspace?
>> 
>> IIRC the issue was a pointer inside of a nested structure, no?
> 
> I would say the reason is that if we did not convert the user-space pointer to
> a "void *" kvm_get_dirty_log() would end up copying the dirty log to
> 
> (log->dirty_bitmap << 32) | 0x00000000

Well yes, that was the problem. If we always set the __u64 value to the pointer we're safe though.

union {
  void *p;
  __u64 q;
}

void x(void *r)
{
  // breaks:
  p = r;

  // works:
  q = (ulong)r;
}

Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy dirty bitmaps to user space
       [not found]           ` <4BD00F64.4020405-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
  2010-04-23 10:26               ` Avi Kivity
@ 2010-04-23 10:26               ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 10:26 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	fernando-gVGce1chcLdL9jVzuh4AOg

On 04/22/2010 11:57 AM, Takuya Yoshikawa wrote:
>
> And about x86_32 copy_in_user().
>
> They are using copy_user_generic() which is implemented only for 64bit.
>
> So I'll show them current copy_from_user() and copy_to_user() version and
> see their response.
>
> If rejected, though I hope not, please give me another option, OK?
>

If we can justify it, I doubt it will be rejected, but in case it does, 
we'll work something out.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy
@ 2010-04-23 10:26               ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 10:26 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	fernando-gVGce1chcLdL9jVzuh4AOg

On 04/22/2010 11:57 AM, Takuya Yoshikawa wrote:
>
> And about x86_32 copy_in_user().
>
> They are using copy_user_generic() which is implemented only for 64bit.
>
> So I'll show them current copy_from_user() and copy_to_user() version and
> see their response.
>
> If rejected, though I hope not, please give me another option, OK?
>

If we can justify it, I doubt it will be rejected, but in case it does, 
we'll work something out.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy
@ 2010-04-23 10:26               ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 10:26 UTC (permalink / raw)
  To: kvm-ia64

On 04/22/2010 11:57 AM, Takuya Yoshikawa wrote:
>
> And about x86_32 copy_in_user().
>
> They are using copy_user_generic() which is implemented only for 64bit.
>
> So I'll show them current copy_from_user() and copy_to_user() version and
> see their response.
>
> If rejected, though I hope not, please give me another option, OK?
>

If we can justify it, I doubt it will be rejected, but in case it does, 
we'll work something out.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
  2010-04-22  9:07             ` Takuya Yoshikawa
  (?)
@ 2010-04-23 10:28               ` Avi Kivity
  -1 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 10:28 UTC (permalink / raw)
  To: Takuya Yoshikawa; +Cc: mtosatti, kvm, kvm-ia64, kvm-ppc, fernando

On 04/22/2010 12:07 PM, Takuya Yoshikawa wrote:
>
>>
>>> + slots->memslots[i].dirty_bitmap = NULL;
>>> + slots->memslots[i].dirty_bitmap_old = NULL;
>>> kvm_free_physmem_slot(&slots->memslots[i], NULL);
>>> + }
>>>
>>>
>>> +/*
>>> + * Please use generic *_user bitops once they become available.
>>> + * Be careful setting the bit won't be done atomically.
>>> + */
>>
>> Please introduce the user bitops as part of this patchset.
>>
>
> OK, I will do in the next version. In this RFC, I would be happy if I can
> know the overall design is right or not.
>

Everything looks reasonable to me.

Do you have performance numbers?  I'm interested in both measurements of 
KVM_SWITCH_DIRTY_LOG under various conditions and macro benchmarks (for 
example, total guest throughput improvement under Kemari).

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-23 10:28               ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 10:28 UTC (permalink / raw)
  To: Takuya Yoshikawa; +Cc: mtosatti, kvm, kvm-ia64, kvm-ppc, fernando

On 04/22/2010 12:07 PM, Takuya Yoshikawa wrote:
>
>>
>>> + slots->memslots[i].dirty_bitmap = NULL;
>>> + slots->memslots[i].dirty_bitmap_old = NULL;
>>> kvm_free_physmem_slot(&slots->memslots[i], NULL);
>>> + }
>>>
>>>
>>> +/*
>>> + * Please use generic *_user bitops once they become available.
>>> + * Be careful setting the bit won't be done atomically.
>>> + */
>>
>> Please introduce the user bitops as part of this patchset.
>>
>
> OK, I will do in the next version. In this RFC, I would be happy if I can
> know the overall design is right or not.
>

Everything looks reasonable to me.

Do you have performance numbers?  I'm interested in both measurements of 
KVM_SWITCH_DIRTY_LOG under various conditions and macro benchmarks (for 
example, total guest throughput improvement under Kemari).

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-23 10:28               ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 10:28 UTC (permalink / raw)
  To: kvm-ia64

On 04/22/2010 12:07 PM, Takuya Yoshikawa wrote:
>
>>
>>> + slots->memslots[i].dirty_bitmap = NULL;
>>> + slots->memslots[i].dirty_bitmap_old = NULL;
>>> kvm_free_physmem_slot(&slots->memslots[i], NULL);
>>> + }
>>>
>>>
>>> +/*
>>> + * Please use generic *_user bitops once they become available.
>>> + * Be careful setting the bit won't be done atomically.
>>> + */
>>
>> Please introduce the user bitops as part of this patchset.
>>
>
> OK, I will do in the next version. In this RFC, I would be happy if I can
> know the overall design is right or not.
>

Everything looks reasonable to me.

Do you have performance numbers?  I'm interested in both measurements of 
KVM_SWITCH_DIRTY_LOG under various conditions and macro benchmarks (for 
example, total guest throughput improvement under Kemari).

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
       [not found]               ` <4BD17665.5090101-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  2010-04-23 11:14                   ` Takuya Yoshikawa
@ 2010-04-23 11:14                   ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-23 11:14 UTC (permalink / raw)
  To: Avi Kivity
  Cc: mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	fernando-gVGce1chcLdL9jVzuh4AOg, Yoshiaki Tamura

(2010/04/23 19:28), Avi Kivity wrote:

>>
>> OK, I will do in the next version. In this RFC, I would be happy if I can
>> know the overall design is right or not.
>>
>
> Everything looks reasonable to me.
>

Thank you!

> Do you have performance numbers? I'm interested in both measurements of
> KVM_SWITCH_DIRTY_LOG under various conditions and macro benchmarks (for
> example, total guest throughput improvement under Kemari).
>

Currently, I'm just checking the performance visually.
   - on laptops, we can feel the speed directly: my favorite is installing
     ubuntu or debian by alternate installers

   - live migration with heavy work load

Now that I've got the overall design, I want to measure the performance by numbers.


About performance under Kemari: we(oss.ntt.co.jp staffs: me and Fernando) are
now concentrating on improving the basic live-migration infrastructures and
they(lab.ntt.co.jp staffs) are working hard for building Kemari itself.

   - We are also interested in using live-migration with HA software and this needs
     light, stable live-migration: same as Kemari!


So measuring Kemari's performance with our patch-set will need some more time,
** How about Tamura-san? **


So at this stage, I'll show you performance improvement(I hope to improve) by
another test cases.

If possible next week!

Thanks,
   Takuya

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-23 11:14                   ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-23 11:14 UTC (permalink / raw)
  To: Avi Kivity
  Cc: mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	fernando-gVGce1chcLdL9jVzuh4AOg, Yoshiaki Tamura

(2010/04/23 19:28), Avi Kivity wrote:

>>
>> OK, I will do in the next version. In this RFC, I would be happy if I can
>> know the overall design is right or not.
>>
>
> Everything looks reasonable to me.
>

Thank you!

> Do you have performance numbers? I'm interested in both measurements of
> KVM_SWITCH_DIRTY_LOG under various conditions and macro benchmarks (for
> example, total guest throughput improvement under Kemari).
>

Currently, I'm just checking the performance visually.
   - on laptops, we can feel the speed directly: my favorite is installing
     ubuntu or debian by alternate installers

   - live migration with heavy work load

Now that I've got the overall design, I want to measure the performance by numbers.


About performance under Kemari: we(oss.ntt.co.jp staffs: me and Fernando) are
now concentrating on improving the basic live-migration infrastructures and
they(lab.ntt.co.jp staffs) are working hard for building Kemari itself.

   - We are also interested in using live-migration with HA software and this needs
     light, stable live-migration: same as Kemari!


So measuring Kemari's performance with our patch-set will need some more time,
** How about Tamura-san? **


So at this stage, I'll show you performance improvement(I hope to improve) by
another test cases.

If possible next week!

Thanks,
   Takuya


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-23 11:14                   ` Takuya Yoshikawa
  0 siblings, 0 replies; 141+ messages in thread
From: Takuya Yoshikawa @ 2010-04-23 11:14 UTC (permalink / raw)
  To: kvm-ia64

(2010/04/23 19:28), Avi Kivity wrote:

>>
>> OK, I will do in the next version. In this RFC, I would be happy if I can
>> know the overall design is right or not.
>>
>
> Everything looks reasonable to me.
>

Thank you!

> Do you have performance numbers? I'm interested in both measurements of
> KVM_SWITCH_DIRTY_LOG under various conditions and macro benchmarks (for
> example, total guest throughput improvement under Kemari).
>

Currently, I'm just checking the performance visually.
   - on laptops, we can feel the speed directly: my favorite is installing
     ubuntu or debian by alternate installers

   - live migration with heavy work load

Now that I've got the overall design, I want to measure the performance by numbers.


About performance under Kemari: we(oss.ntt.co.jp staffs: me and Fernando) are
now concentrating on improving the basic live-migration infrastructures and
they(lab.ntt.co.jp staffs) are working hard for building Kemari itself.

   - We are also interested in using live-migration with HA software and this needs
     light, stable live-migration: same as Kemari!


So measuring Kemari's performance with our patch-set will need some more time,
** How about Tamura-san? **


So at this stage, I'll show you performance improvement(I hope to improve) by
another test cases.

If possible next week!

Thanks,
   Takuya


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
       [not found]                   ` <4BD1812E.6030707-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
  2010-04-23 11:29                       ` Yoshiaki Tamura
@ 2010-04-23 11:29                       ` Yoshiaki Tamura
  0 siblings, 0 replies; 141+ messages in thread
From: Yoshiaki Tamura @ 2010-04-23 11:29 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: Avi Kivity, mtosatti-H+wXaHxf7aLQT0dZR+AlfA,
	kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg

2010/4/23 Takuya Yoshikawa <yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>:
> (2010/04/23 19:28), Avi Kivity wrote:
>
>>>
>>> OK, I will do in the next version. In this RFC, I would be happy if I can
>>> know the overall design is right or not.
>>>
>>
>> Everything looks reasonable to me.
>>
>
> Thank you!
>
>> Do you have performance numbers? I'm interested in both measurements of
>> KVM_SWITCH_DIRTY_LOG under various conditions and macro benchmarks (for
>> example, total guest throughput improvement under Kemari).
>>
>
> Currently, I'm just checking the performance visually.
>  - on laptops, we can feel the speed directly: my favorite is installing
>    ubuntu or debian by alternate installers
>
>  - live migration with heavy work load
>
> Now that I've got the overall design, I want to measure the performance by
> numbers.
>
>
> About performance under Kemari: we(oss.ntt.co.jp staffs: me and Fernando)
> are
> now concentrating on improving the basic live-migration infrastructures and
> they(lab.ntt.co.jp staffs) are working hard for building Kemari itself.
>
>  - We are also interested in using live-migration with HA software and this
> needs
>    light, stable live-migration: same as Kemari!
>
>
> So measuring Kemari's performance with our patch-set will need some more
> time,
> ** How about Tamura-san? **

You can measure your patch quite easy.

1. Run a simple program that malloc huge size (2GB for example), then
go into infinite loop that touches each in a really bad manner, like
only touch odd page numbers.
2. Start live migration which usually won't finish. Similar with Kemari.
3. Measure the response time of your ioctl().

I used 1 and 2 to measure dirty physmap speed up in QEMU.

Thanks,

Yoshi

> So at this stage, I'll show you performance improvement(I hope to improve)
> by
> another test cases.
>
> If possible next week!
>
> Thanks,
>  Takuya
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-23 11:29                       ` Yoshiaki Tamura
  0 siblings, 0 replies; 141+ messages in thread
From: Yoshiaki Tamura @ 2010-04-23 11:29 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: Avi Kivity, mtosatti-H+wXaHxf7aLQT0dZR+AlfA,
	kvm-u79uwXL29TY76Z2rM5mHXA, kvm-ia64-u79uwXL29TY76Z2rM5mHXA,
	kvm-ppc-u79uwXL29TY76Z2rM5mHXA, fernando-gVGce1chcLdL9jVzuh4AOg

2010/4/23 Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>:
> (2010/04/23 19:28), Avi Kivity wrote:
>
>>>
>>> OK, I will do in the next version. In this RFC, I would be happy if I can
>>> know the overall design is right or not.
>>>
>>
>> Everything looks reasonable to me.
>>
>
> Thank you!
>
>> Do you have performance numbers? I'm interested in both measurements of
>> KVM_SWITCH_DIRTY_LOG under various conditions and macro benchmarks (for
>> example, total guest throughput improvement under Kemari).
>>
>
> Currently, I'm just checking the performance visually.
>  - on laptops, we can feel the speed directly: my favorite is installing
>    ubuntu or debian by alternate installers
>
>  - live migration with heavy work load
>
> Now that I've got the overall design, I want to measure the performance by
> numbers.
>
>
> About performance under Kemari: we(oss.ntt.co.jp staffs: me and Fernando)
> are
> now concentrating on improving the basic live-migration infrastructures and
> they(lab.ntt.co.jp staffs) are working hard for building Kemari itself.
>
>  - We are also interested in using live-migration with HA software and this
> needs
>    light, stable live-migration: same as Kemari!
>
>
> So measuring Kemari's performance with our patch-set will need some more
> time,
> ** How about Tamura-san? **

You can measure your patch quite easy.

1. Run a simple program that malloc huge size (2GB for example), then
go into infinite loop that touches each in a really bad manner, like
only touch odd page numbers.
2. Start live migration which usually won't finish. Similar with Kemari.
3. Measure the response time of your ioctl().

I used 1 and 2 to measure dirty physmap speed up in QEMU.

Thanks,

Yoshi

> So at this stage, I'll show you performance improvement(I hope to improve)
> by
> another test cases.
>
> If possible next week!
>
> Thanks,
>  Takuya
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-23 11:29                       ` Yoshiaki Tamura
  0 siblings, 0 replies; 141+ messages in thread
From: Yoshiaki Tamura @ 2010-04-23 11:29 UTC (permalink / raw)
  To: kvm-ia64

2010/4/23 Takuya Yoshikawa <yoshikawa.takuya@oss.ntt.co.jp>:
> (2010/04/23 19:28), Avi Kivity wrote:
>
>>>
>>> OK, I will do in the next version. In this RFC, I would be happy if I can
>>> know the overall design is right or not.
>>>
>>
>> Everything looks reasonable to me.
>>
>
> Thank you!
>
>> Do you have performance numbers? I'm interested in both measurements of
>> KVM_SWITCH_DIRTY_LOG under various conditions and macro benchmarks (for
>> example, total guest throughput improvement under Kemari).
>>
>
> Currently, I'm just checking the performance visually.
>  - on laptops, we can feel the speed directly: my favorite is installing
>    ubuntu or debian by alternate installers
>
>  - live migration with heavy work load
>
> Now that I've got the overall design, I want to measure the performance by
> numbers.
>
>
> About performance under Kemari: we(oss.ntt.co.jp staffs: me and Fernando)
> are
> now concentrating on improving the basic live-migration infrastructures and
> they(lab.ntt.co.jp staffs) are working hard for building Kemari itself.
>
>  - We are also interested in using live-migration with HA software and this
> needs
>    light, stable live-migration: same as Kemari!
>
>
> So measuring Kemari's performance with our patch-set will need some more
> time,
> ** How about Tamura-san? **

You can measure your patch quite easy.

1. Run a simple program that malloc huge size (2GB for example), then
go into infinite loop that touches each in a really bad manner, like
only touch odd page numbers.
2. Start live migration which usually won't finish. Similar with Kemari.
3. Measure the response time of your ioctl().

I used 1 and 2 to measure dirty physmap speed up in QEMU.

Thanks,

Yoshi

> So at this stage, I'll show you performance improvement(I hope to improve)
> by
> another test cases.
>
> If possible next week!
>
> Thanks,
>  Takuya
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
  2010-04-23 11:14                   ` Takuya Yoshikawa
  (?)
@ 2010-04-23 11:45                     ` Avi Kivity
  -1 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 11:45 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: mtosatti, kvm, kvm-ia64, kvm-ppc, fernando, Yoshiaki Tamura

On 04/23/2010 02:14 PM, Takuya Yoshikawa wrote:
>
>> Do you have performance numbers? I'm interested in both measurements of
>> KVM_SWITCH_DIRTY_LOG under various conditions and macro benchmarks (for
>> example, total guest throughput improvement under Kemari).
>>
>
> Currently, I'm just checking the performance visually.
>   - on laptops, we can feel the speed directly: my favorite is installing
>     ubuntu or debian by alternate installers
>
>   - live migration with heavy work load
>
> Now that I've got the overall design, I want to measure the 
> performance by numbers.
>
>
> About performance under Kemari: we(oss.ntt.co.jp staffs: me and 
> Fernando) are
> now concentrating on improving the basic live-migration 
> infrastructures and
> they(lab.ntt.co.jp staffs) are working hard for building Kemari itself.
>
>   - We are also interested in using live-migration with HA software 
> and this needs
>     light, stable live-migration: same as Kemari!
>

General live migration improvements are also interesting, I just the 
improvement would be more pronounced under Kemari.  Looking forward to 
seeing the results.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-23 11:45                     ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 11:45 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: mtosatti, kvm, kvm-ia64, kvm-ppc, fernando, Yoshiaki Tamura

On 04/23/2010 02:14 PM, Takuya Yoshikawa wrote:
>
>> Do you have performance numbers? I'm interested in both measurements of
>> KVM_SWITCH_DIRTY_LOG under various conditions and macro benchmarks (for
>> example, total guest throughput improvement under Kemari).
>>
>
> Currently, I'm just checking the performance visually.
>   - on laptops, we can feel the speed directly: my favorite is installing
>     ubuntu or debian by alternate installers
>
>   - live migration with heavy work load
>
> Now that I've got the overall design, I want to measure the 
> performance by numbers.
>
>
> About performance under Kemari: we(oss.ntt.co.jp staffs: me and 
> Fernando) are
> now concentrating on improving the basic live-migration 
> infrastructures and
> they(lab.ntt.co.jp staffs) are working hard for building Kemari itself.
>
>   - We are also interested in using live-migration with HA software 
> and this needs
>     light, stable live-migration: same as Kemari!
>

General live migration improvements are also interesting, I just the 
improvement would be more pronounced under Kemari.  Looking forward to 
seeing the results.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space
@ 2010-04-23 11:45                     ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 11:45 UTC (permalink / raw)
  To: kvm-ia64

On 04/23/2010 02:14 PM, Takuya Yoshikawa wrote:
>
>> Do you have performance numbers? I'm interested in both measurements of
>> KVM_SWITCH_DIRTY_LOG under various conditions and macro benchmarks (for
>> example, total guest throughput improvement under Kemari).
>>
>
> Currently, I'm just checking the performance visually.
>   - on laptops, we can feel the speed directly: my favorite is installing
>     ubuntu or debian by alternate installers
>
>   - live migration with heavy work load
>
> Now that I've got the overall design, I want to measure the 
> performance by numbers.
>
>
> About performance under Kemari: we(oss.ntt.co.jp staffs: me and 
> Fernando) are
> now concentrating on improving the basic live-migration 
> infrastructures and
> they(lab.ntt.co.jp staffs) are working hard for building Kemari itself.
>
>   - We are also interested in using live-migration with HA software 
> and this needs
>     light, stable live-migration: same as Kemari!
>

General live migration improvements are also interesting, I just the 
improvement would be more pronounced under Kemari.  Looking forward to 
seeing the results.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
       [not found]                       ` <9B7714E9-7244-4569-B8DB-B3E31E680CAF-l3A5Bk7waGM@public.gmane.org>
  2010-04-23 11:57                           ` Avi Kivity
@ 2010-04-23 11:57                           ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 11:57 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	Arnd Bergmann

On 04/23/2010 01:20 PM, Alexander Graf wrote:
>
>> I would say the reason is that if we did not convert the user-space pointer to
>> a "void *" kvm_get_dirty_log() would end up copying the dirty log to
>>
>> (log->dirty_bitmap<<  32) | 0x00000000
>>      
> Well yes, that was the problem. If we always set the __u64 value to the pointer we're safe though.
>
> union {
>    void *p;
>    __u64 q;
> }
>
> void x(void *r)
> {
>    // breaks:
>    p = r;
>
>    // works:
>    q = (ulong)r;
> }
>    

In that case it's better to avoid p altogether, since users will 
naturally assign to the pointer.

Using a 64-bit integer avoids the problem (though perhaps not sufficient 
for s390, Arnd?)

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-23 11:57                           ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 11:57 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	Arnd Bergmann

On 04/23/2010 01:20 PM, Alexander Graf wrote:
>
>> I would say the reason is that if we did not convert the user-space pointer to
>> a "void *" kvm_get_dirty_log() would end up copying the dirty log to
>>
>> (log->dirty_bitmap<<  32) | 0x00000000
>>      
> Well yes, that was the problem. If we always set the __u64 value to the pointer we're safe though.
>
> union {
>    void *p;
>    __u64 q;
> }
>
> void x(void *r)
> {
>    // breaks:
>    p = r;
>
>    // works:
>    q = (ulong)r;
> }
>    

In that case it's better to avoid p altogether, since users will 
naturally assign to the pointer.

Using a 64-bit integer avoids the problem (though perhaps not sufficient 
for s390, Arnd?)

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-23 11:57                           ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 11:57 UTC (permalink / raw)
  To: kvm-ia64

On 04/23/2010 01:20 PM, Alexander Graf wrote:
>
>> I would say the reason is that if we did not convert the user-space pointer to
>> a "void *" kvm_get_dirty_log() would end up copying the dirty log to
>>
>> (log->dirty_bitmap<<  32) | 0x00000000
>>      
> Well yes, that was the problem. If we always set the __u64 value to the pointer we're safe though.
>
> union {
>    void *p;
>    __u64 q;
> }
>
> void x(void *r)
> {
>    // breaks:
>    p = r;
>
>    // works:
>    q = (ulong)r;
> }
>    

In that case it's better to avoid p altogether, since users will 
naturally assign to the pointer.

Using a 64-bit integer avoids the problem (though perhaps not sufficient 
for s390, Arnd?)

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
       [not found]             ` <4BD0181C.6020900-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
  2010-04-23 11:58                 ` Avi Kivity
@ 2010-04-23 11:58                 ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 11:58 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	fernando-gVGce1chcLdL9jVzuh4AOg

On 04/22/2010 12:34 PM, Takuya Yoshikawa wrote:
> Thanks, I can know basic rules about kvm/api .
>
> (2010/04/21 20:46), Avi Kivity wrote:
>
>>
>>> +Type: vm ioctl
>>> +Parameters: struct kvm_dirty_log (in/out)
>>> +Returns: 0 on success, -1 on error
>>> +
>>> +/* for KVM_SWITCH_DIRTY_LOG */
>>> +struct kvm_dirty_log {
>>> + __u32 slot;
>>> + __u32 padding;
>>
>> Please put a flags field here (and verify it is zero in the ioctl
>> implementation). This allows us to extend it later.
>>
>>> + union {
>>> + void __user *dirty_bitmap; /* one bit per page */
>>> + __u64 addr;
>>> + };
>>
>> Just make dirty_bitmap a __u64. With the union there is the risk that
>> someone forgets to zero the structure so we get some random bits in the
>> pointer, and also issues with big endian and s390 compat.
>>
>> Reserve some extra space here for future expansion.
>>
>> Hm. I see that this is the existing kvm_dirty_log structure. So we can't
>> play with it, ignore my comments about it.
>
> So, introducing a new structure to export(and get) two bitmap addresses
> with a flag is the thing?
>
> 1. Qemu calls ioctl to get the two addresses.
> 2. Qemu calls ioctl to make KVM switch the dirty bitmaps.
>    --> in this case, qemu have to change the address got in step 1.
>    ...
> 3. Qemu calls ioctl(we can reuse 1. with different command flag) to 
> free the bitmaps.
>
>
> In my plan, we don't let qemu malloc() dirty bitmaps: at least, I want 
> to make that
> another patch set because this patch set already has some dependencies 
> to other issues.
>
> But, yes, I can make the struct considering the future expansion if it 
> needed.

I guess it's better, since this patch is a "future expansion" of 
KVN_GET_DIRTY_LOG.  If we had a flags field and some room there, we 
could keep the old ioctl.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-23 11:58                 ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 11:58 UTC (permalink / raw)
  To: Takuya Yoshikawa
  Cc: mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	fernando-gVGce1chcLdL9jVzuh4AOg

On 04/22/2010 12:34 PM, Takuya Yoshikawa wrote:
> Thanks, I can know basic rules about kvm/api .
>
> (2010/04/21 20:46), Avi Kivity wrote:
>
>>
>>> +Type: vm ioctl
>>> +Parameters: struct kvm_dirty_log (in/out)
>>> +Returns: 0 on success, -1 on error
>>> +
>>> +/* for KVM_SWITCH_DIRTY_LOG */
>>> +struct kvm_dirty_log {
>>> + __u32 slot;
>>> + __u32 padding;
>>
>> Please put a flags field here (and verify it is zero in the ioctl
>> implementation). This allows us to extend it later.
>>
>>> + union {
>>> + void __user *dirty_bitmap; /* one bit per page */
>>> + __u64 addr;
>>> + };
>>
>> Just make dirty_bitmap a __u64. With the union there is the risk that
>> someone forgets to zero the structure so we get some random bits in the
>> pointer, and also issues with big endian and s390 compat.
>>
>> Reserve some extra space here for future expansion.
>>
>> Hm. I see that this is the existing kvm_dirty_log structure. So we can't
>> play with it, ignore my comments about it.
>
> So, introducing a new structure to export(and get) two bitmap addresses
> with a flag is the thing?
>
> 1. Qemu calls ioctl to get the two addresses.
> 2. Qemu calls ioctl to make KVM switch the dirty bitmaps.
>    --> in this case, qemu have to change the address got in step 1.
>    ...
> 3. Qemu calls ioctl(we can reuse 1. with different command flag) to 
> free the bitmaps.
>
>
> In my plan, we don't let qemu malloc() dirty bitmaps: at least, I want 
> to make that
> another patch set because this patch set already has some dependencies 
> to other issues.
>
> But, yes, I can make the struct considering the future expansion if it 
> needed.

I guess it's better, since this patch is a "future expansion" of 
KVN_GET_DIRTY_LOG.  If we had a flags field and some room there, we 
could keep the old ioctl.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-23 11:58                 ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 11:58 UTC (permalink / raw)
  To: kvm-ia64

On 04/22/2010 12:34 PM, Takuya Yoshikawa wrote:
> Thanks, I can know basic rules about kvm/api .
>
> (2010/04/21 20:46), Avi Kivity wrote:
>
>>
>>> +Type: vm ioctl
>>> +Parameters: struct kvm_dirty_log (in/out)
>>> +Returns: 0 on success, -1 on error
>>> +
>>> +/* for KVM_SWITCH_DIRTY_LOG */
>>> +struct kvm_dirty_log {
>>> + __u32 slot;
>>> + __u32 padding;
>>
>> Please put a flags field here (and verify it is zero in the ioctl
>> implementation). This allows us to extend it later.
>>
>>> + union {
>>> + void __user *dirty_bitmap; /* one bit per page */
>>> + __u64 addr;
>>> + };
>>
>> Just make dirty_bitmap a __u64. With the union there is the risk that
>> someone forgets to zero the structure so we get some random bits in the
>> pointer, and also issues with big endian and s390 compat.
>>
>> Reserve some extra space here for future expansion.
>>
>> Hm. I see that this is the existing kvm_dirty_log structure. So we can't
>> play with it, ignore my comments about it.
>
> So, introducing a new structure to export(and get) two bitmap addresses
> with a flag is the thing?
>
> 1. Qemu calls ioctl to get the two addresses.
> 2. Qemu calls ioctl to make KVM switch the dirty bitmaps.
>    --> in this case, qemu have to change the address got in step 1.
>    ...
> 3. Qemu calls ioctl(we can reuse 1. with different command flag) to 
> free the bitmaps.
>
>
> In my plan, we don't let qemu malloc() dirty bitmaps: at least, I want 
> to make that
> another patch set because this patch set already has some dependencies 
> to other issues.
>
> But, yes, I can make the struct considering the future expansion if it 
> needed.

I guess it's better, since this patch is a "future expansion" of 
KVN_GET_DIRTY_LOG.  If we had a flags field and some room there, we 
could keep the old ioctl.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
       [not found]                           ` <4BD18B1D.1080604-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  2010-04-23 12:26                               ` Alexander Graf
@ 2010-04-23 12:26                               ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-23 12:26 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	Arnd Bergmann


On 23.04.2010, at 13:57, Avi Kivity wrote:

> On 04/23/2010 01:20 PM, Alexander Graf wrote:
>> 
>>> I would say the reason is that if we did not convert the user-space pointer to
>>> a "void *" kvm_get_dirty_log() would end up copying the dirty log to
>>> 
>>> (log->dirty_bitmap<<  32) | 0x00000000
>>>     
>> Well yes, that was the problem. If we always set the __u64 value to the pointer we're safe though.
>> 
>> union {
>>   void *p;
>>   __u64 q;
>> }
>> 
>> void x(void *r)
>> {
>>   // breaks:
>>   p = r;
>> 
>>   // works:
>>   q = (ulong)r;
>> }
>>   
> 
> In that case it's better to avoid p altogether, since users will naturally assign to the pointer.
> 
> Using a 64-bit integer avoids the problem (though perhaps not sufficient for s390, Arnd?)

We only support 64 bit on S390, so we should be safe here. Even if not, compat mode has 31 bits pointers, so padding them to 64 bit should work too.


Alex

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-23 12:26                               ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-23 12:26 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA,
	Arnd Bergmann


On 23.04.2010, at 13:57, Avi Kivity wrote:

> On 04/23/2010 01:20 PM, Alexander Graf wrote:
>> 
>>> I would say the reason is that if we did not convert the user-space pointer to
>>> a "void *" kvm_get_dirty_log() would end up copying the dirty log to
>>> 
>>> (log->dirty_bitmap<<  32) | 0x00000000
>>>     
>> Well yes, that was the problem. If we always set the __u64 value to the pointer we're safe though.
>> 
>> union {
>>   void *p;
>>   __u64 q;
>> }
>> 
>> void x(void *r)
>> {
>>   // breaks:
>>   p = r;
>> 
>>   // works:
>>   q = (ulong)r;
>> }
>>   
> 
> In that case it's better to avoid p altogether, since users will naturally assign to the pointer.
> 
> Using a 64-bit integer avoids the problem (though perhaps not sufficient for s390, Arnd?)

We only support 64 bit on S390, so we should be safe here. Even if not, compat mode has 31 bits pointers, so padding them to 64 bit should work too.


Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-23 12:26                               ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-23 12:26 UTC (permalink / raw)
  To: kvm-ia64


On 23.04.2010, at 13:57, Avi Kivity wrote:

> On 04/23/2010 01:20 PM, Alexander Graf wrote:
>> 
>>> I would say the reason is that if we did not convert the user-space pointer to
>>> a "void *" kvm_get_dirty_log() would end up copying the dirty log to
>>> 
>>> (log->dirty_bitmap<<  32) | 0x00000000
>>>     
>> Well yes, that was the problem. If we always set the __u64 value to the pointer we're safe though.
>> 
>> union {
>>   void *p;
>>   __u64 q;
>> }
>> 
>> void x(void *r)
>> {
>>   // breaks:
>>   p = r;
>> 
>>   // works:
>>   q = (ulong)r;
>> }
>>   
> 
> In that case it's better to avoid p altogether, since users will naturally assign to the pointer.
> 
> Using a 64-bit integer avoids the problem (though perhaps not sufficient for s390, Arnd?)

We only support 64 bit on S390, so we should be safe here. Even if not, compat mode has 31 bits pointers, so padding them to 64 bit should work too.


Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
  2010-04-23 11:57                           ` Avi Kivity
  (?)
@ 2010-04-23 12:27                             ` Arnd Bergmann
  -1 siblings, 0 replies; 141+ messages in thread
From: Arnd Bergmann @ 2010-04-23 12:27 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Alexander Graf, Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti, kvm, kvm-ia64, kvm-ppc

On Friday 23 April 2010, Avi Kivity wrote:
> On 04/23/2010 01:20 PM, Alexander Graf wrote:
> >
> >> I would say the reason is that if we did not convert the user-space pointer to
> >> a "void *" kvm_get_dirty_log() would end up copying the dirty log to
> >>
> >> (log->dirty_bitmap<<  32) | 0x00000000
> >>      
> > Well yes, that was the problem. If we always set the __u64 value to the pointer we're safe though.
> >
> > union {
> >    void *p;
> >    __u64 q;
> > }
> >
> > void x(void *r)
> > {
> >    // breaks:
> >    p = r;
> >
> >    // works:
> >    q = (ulong)r;
> > }
> >    
> 
> In that case it's better to avoid p altogether, since users will 
> naturally assign to the pointer.

Right.
 
> Using a 64-bit integer avoids the problem (though perhaps not sufficient 
> for s390, Arnd?)

When there is only a __u64 for the address, it will work on s390 as well,
gcc is smart enough to clear the upper bit on a cast from long to pointer.

The simple rule is to never put any 'long' or pointer into data structures
that you pass to an ioctl, and to add padding to multiples of 64 bit to
align the data structure for the x86 alignment problem.

	Arnd

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-23 12:27                             ` Arnd Bergmann
  0 siblings, 0 replies; 141+ messages in thread
From: Arnd Bergmann @ 2010-04-23 12:27 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Alexander Graf, Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti, kvm, kvm-ia64, kvm-ppc

On Friday 23 April 2010, Avi Kivity wrote:
> On 04/23/2010 01:20 PM, Alexander Graf wrote:
> >
> >> I would say the reason is that if we did not convert the user-space pointer to
> >> a "void *" kvm_get_dirty_log() would end up copying the dirty log to
> >>
> >> (log->dirty_bitmap<<  32) | 0x00000000
> >>      
> > Well yes, that was the problem. If we always set the __u64 value to the pointer we're safe though.
> >
> > union {
> >    void *p;
> >    __u64 q;
> > }
> >
> > void x(void *r)
> > {
> >    // breaks:
> >    p = r;
> >
> >    // works:
> >    q = (ulong)r;
> > }
> >    
> 
> In that case it's better to avoid p altogether, since users will 
> naturally assign to the pointer.

Right.
 
> Using a 64-bit integer avoids the problem (though perhaps not sufficient 
> for s390, Arnd?)

When there is only a __u64 for the address, it will work on s390 as well,
gcc is smart enough to clear the upper bit on a cast from long to pointer.

The simple rule is to never put any 'long' or pointer into data structures
that you pass to an ioctl, and to add padding to multiples of 64 bit to
align the data structure for the x86 alignment problem.

	Arnd

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-23 12:27                             ` Arnd Bergmann
  0 siblings, 0 replies; 141+ messages in thread
From: Arnd Bergmann @ 2010-04-23 12:27 UTC (permalink / raw)
  To: kvm-ia64

On Friday 23 April 2010, Avi Kivity wrote:
> On 04/23/2010 01:20 PM, Alexander Graf wrote:
> >
> >> I would say the reason is that if we did not convert the user-space pointer to
> >> a "void *" kvm_get_dirty_log() would end up copying the dirty log to
> >>
> >> (log->dirty_bitmap<<  32) | 0x00000000
> >>      
> > Well yes, that was the problem. If we always set the __u64 value to the pointer we're safe though.
> >
> > union {
> >    void *p;
> >    __u64 q;
> > }
> >
> > void x(void *r)
> > {
> >    // breaks:
> >    p = r;
> >
> >    // works:
> >    q = (ulong)r;
> > }
> >    
> 
> In that case it's better to avoid p altogether, since users will 
> naturally assign to the pointer.

Right.
 
> Using a 64-bit integer avoids the problem (though perhaps not sufficient 
> for s390, Arnd?)

When there is only a __u64 for the address, it will work on s390 as well,
gcc is smart enough to clear the upper bit on a cast from long to pointer.

The simple rule is to never put any 'long' or pointer into data structures
that you pass to an ioctl, and to add padding to multiples of 64 bit to
align the data structure for the x86 alignment problem.

	Arnd

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
  2010-04-23 12:27                             ` Arnd Bergmann
  (?)
@ 2010-04-23 12:42                               ` Avi Kivity
  -1 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 12:42 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Alexander Graf, Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti, kvm, kvm-ia64, kvm-ppc

On 04/23/2010 03:27 PM, Arnd Bergmann wrote:
>
>> Using a 64-bit integer avoids the problem (though perhaps not sufficient
>> for s390, Arnd?)
>>      
> When there is only a __u64 for the address, it will work on s390 as well,
> gcc is smart enough to clear the upper bit on a cast from long to pointer.
>    

Ah, much more convenient than compat_ioctl.  I assume it part of the 
ABI, not a gccism?

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-23 12:42                               ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 12:42 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Alexander Graf, Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti, kvm, kvm-ia64, kvm-ppc

On 04/23/2010 03:27 PM, Arnd Bergmann wrote:
>
>> Using a 64-bit integer avoids the problem (though perhaps not sufficient
>> for s390, Arnd?)
>>      
> When there is only a __u64 for the address, it will work on s390 as well,
> gcc is smart enough to clear the upper bit on a cast from long to pointer.
>    

Ah, much more convenient than compat_ioctl.  I assume it part of the 
ABI, not a gccism?

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-23 12:42                               ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 12:42 UTC (permalink / raw)
  To: kvm-ia64

On 04/23/2010 03:27 PM, Arnd Bergmann wrote:
>
>> Using a 64-bit integer avoids the problem (though perhaps not sufficient
>> for s390, Arnd?)
>>      
> When there is only a __u64 for the address, it will work on s390 as well,
> gcc is smart enough to clear the upper bit on a cast from long to pointer.
>    

Ah, much more convenient than compat_ioctl.  I assume it part of the 
ABI, not a gccism?

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
  2010-04-23 12:42                               ` Avi Kivity
  (?)
@ 2010-04-23 12:46                                 ` Arnd Bergmann
  -1 siblings, 0 replies; 141+ messages in thread
From: Arnd Bergmann @ 2010-04-23 12:46 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Alexander Graf, Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti, kvm, kvm-ia64, kvm-ppc

On Friday 23 April 2010, Avi Kivity wrote:
> On 04/23/2010 03:27 PM, Arnd Bergmann wrote:
> >
> >> Using a 64-bit integer avoids the problem (though perhaps not sufficient
> >> for s390, Arnd?)
> >>      
> > When there is only a __u64 for the address, it will work on s390 as well,
> > gcc is smart enough to clear the upper bit on a cast from long to pointer.
> >    
> 
> Ah, much more convenient than compat_ioctl.  I assume it part of the 
> ABI, not a gccism?

I don't think it's part of the ABI, but it's required to guarantee
that code like this works:

int compare_pointer(void *a, void *b)
{
	unsigned long ai = (unsigned long)a, bi = (unsigned long)b;

	return ai == bi; /* true if a and b point to the same object */
}

We certainly rely on this already.

	Arnd

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-23 12:46                                 ` Arnd Bergmann
  0 siblings, 0 replies; 141+ messages in thread
From: Arnd Bergmann @ 2010-04-23 12:46 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Alexander Graf, Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti, kvm, kvm-ia64, kvm-ppc

On Friday 23 April 2010, Avi Kivity wrote:
> On 04/23/2010 03:27 PM, Arnd Bergmann wrote:
> >
> >> Using a 64-bit integer avoids the problem (though perhaps not sufficient
> >> for s390, Arnd?)
> >>      
> > When there is only a __u64 for the address, it will work on s390 as well,
> > gcc is smart enough to clear the upper bit on a cast from long to pointer.
> >    
> 
> Ah, much more convenient than compat_ioctl.  I assume it part of the 
> ABI, not a gccism?

I don't think it's part of the ABI, but it's required to guarantee
that code like this works:

int compare_pointer(void *a, void *b)
{
	unsigned long ai = (unsigned long)a, bi = (unsigned long)b;

	return ai = bi; /* true if a and b point to the same object */
}

We certainly rely on this already.

	Arnd

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-23 12:46                                 ` Arnd Bergmann
  0 siblings, 0 replies; 141+ messages in thread
From: Arnd Bergmann @ 2010-04-23 12:46 UTC (permalink / raw)
  To: kvm-ia64

On Friday 23 April 2010, Avi Kivity wrote:
> On 04/23/2010 03:27 PM, Arnd Bergmann wrote:
> >
> >> Using a 64-bit integer avoids the problem (though perhaps not sufficient
> >> for s390, Arnd?)
> >>      
> > When there is only a __u64 for the address, it will work on s390 as well,
> > gcc is smart enough to clear the upper bit on a cast from long to pointer.
> >    
> 
> Ah, much more convenient than compat_ioctl.  I assume it part of the 
> ABI, not a gccism?

I don't think it's part of the ABI, but it's required to guarantee
that code like this works:

int compare_pointer(void *a, void *b)
{
	unsigned long ai = (unsigned long)a, bi = (unsigned long)b;

	return ai = bi; /* true if a and b point to the same object */
}

We certainly rely on this already.

	Arnd

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
  2010-04-23 12:46                                 ` Arnd Bergmann
  (?)
@ 2010-04-23 12:53                                   ` Avi Kivity
  -1 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 12:53 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Alexander Graf, Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti, kvm, kvm-ia64, kvm-ppc

On 04/23/2010 03:46 PM, Arnd Bergmann wrote:
> On Friday 23 April 2010, Avi Kivity wrote:
>    
>> On 04/23/2010 03:27 PM, Arnd Bergmann wrote:
>>      
>>>        
>>>> Using a 64-bit integer avoids the problem (though perhaps not sufficient
>>>> for s390, Arnd?)
>>>>
>>>>          
>>> When there is only a __u64 for the address, it will work on s390 as well,
>>> gcc is smart enough to clear the upper bit on a cast from long to pointer.
>>>
>>>        
>> Ah, much more convenient than compat_ioctl.  I assume it part of the
>> ABI, not a gccism?
>>      
> I don't think it's part of the ABI, but it's required to guarantee
> that code like this works:
>
> int compare_pointer(void *a, void *b)
> {
> 	unsigned long ai = (unsigned long)a, bi = (unsigned long)b;
>
> 	return ai == bi; /* true if a and b point to the same object */
> }
>
> We certainly rely on this already.
>    

Ah so the 31st bit is optional as far as userspace is concerned?  What 
does it mean? (just curious)

What happens on the opposite conversion?  is it restored?

What about

int compare_pointer(void *a, void *b)
{
	unsigned long ai = (unsigned long)a;
	void *aia = (void *)ai;

	return a == b; /* true if a and b point to the same object */
}


Does gcc mask the big in pointer comparisons as well?

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-23 12:53                                   ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 12:53 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Alexander Graf, Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti, kvm, kvm-ia64, kvm-ppc

On 04/23/2010 03:46 PM, Arnd Bergmann wrote:
> On Friday 23 April 2010, Avi Kivity wrote:
>    
>> On 04/23/2010 03:27 PM, Arnd Bergmann wrote:
>>      
>>>        
>>>> Using a 64-bit integer avoids the problem (though perhaps not sufficient
>>>> for s390, Arnd?)
>>>>
>>>>          
>>> When there is only a __u64 for the address, it will work on s390 as well,
>>> gcc is smart enough to clear the upper bit on a cast from long to pointer.
>>>
>>>        
>> Ah, much more convenient than compat_ioctl.  I assume it part of the
>> ABI, not a gccism?
>>      
> I don't think it's part of the ABI, but it's required to guarantee
> that code like this works:
>
> int compare_pointer(void *a, void *b)
> {
> 	unsigned long ai = (unsigned long)a, bi = (unsigned long)b;
>
> 	return ai = bi; /* true if a and b point to the same object */
> }
>
> We certainly rely on this already.
>    

Ah so the 31st bit is optional as far as userspace is concerned?  What 
does it mean? (just curious)

What happens on the opposite conversion?  is it restored?

What about

int compare_pointer(void *a, void *b)
{
	unsigned long ai = (unsigned long)a;
	void *aia = (void *)ai;

	return a = b; /* true if a and b point to the same object */
}


Does gcc mask the big in pointer comparisons as well?

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-23 12:53                                   ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 12:53 UTC (permalink / raw)
  To: kvm-ia64

On 04/23/2010 03:46 PM, Arnd Bergmann wrote:
> On Friday 23 April 2010, Avi Kivity wrote:
>    
>> On 04/23/2010 03:27 PM, Arnd Bergmann wrote:
>>      
>>>        
>>>> Using a 64-bit integer avoids the problem (though perhaps not sufficient
>>>> for s390, Arnd?)
>>>>
>>>>          
>>> When there is only a __u64 for the address, it will work on s390 as well,
>>> gcc is smart enough to clear the upper bit on a cast from long to pointer.
>>>
>>>        
>> Ah, much more convenient than compat_ioctl.  I assume it part of the
>> ABI, not a gccism?
>>      
> I don't think it's part of the ABI, but it's required to guarantee
> that code like this works:
>
> int compare_pointer(void *a, void *b)
> {
> 	unsigned long ai = (unsigned long)a, bi = (unsigned long)b;
>
> 	return ai = bi; /* true if a and b point to the same object */
> }
>
> We certainly rely on this already.
>    

Ah so the 31st bit is optional as far as userspace is concerned?  What 
does it mean? (just curious)

What happens on the opposite conversion?  is it restored?

What about

int compare_pointer(void *a, void *b)
{
	unsigned long ai = (unsigned long)a;
	void *aia = (void *)ai;

	return a = b; /* true if a and b point to the same object */
}


Does gcc mask the big in pointer comparisons as well?

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
       [not found]                                   ` <4BD19831.5000405-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  2010-04-23 12:59                                       ` Alexander Graf
@ 2010-04-23 12:59                                       ` Alexander Graf
  1 sibling, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-23 12:59 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Arnd Bergmann, Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA


On 23.04.2010, at 14:53, Avi Kivity wrote:

> On 04/23/2010 03:46 PM, Arnd Bergmann wrote:
>> On Friday 23 April 2010, Avi Kivity wrote:
>>   
>>> On 04/23/2010 03:27 PM, Arnd Bergmann wrote:
>>>     
>>>>       
>>>>> Using a 64-bit integer avoids the problem (though perhaps not sufficient
>>>>> for s390, Arnd?)
>>>>> 
>>>>>         
>>>> When there is only a __u64 for the address, it will work on s390 as well,
>>>> gcc is smart enough to clear the upper bit on a cast from long to pointer.
>>>> 
>>>>       
>>> Ah, much more convenient than compat_ioctl.  I assume it part of the
>>> ABI, not a gccism?
>>>     
>> I don't think it's part of the ABI, but it's required to guarantee
>> that code like this works:
>> 
>> int compare_pointer(void *a, void *b)
>> {
>> 	unsigned long ai = (unsigned long)a, bi = (unsigned long)b;
>> 
>> 	return ai == bi; /* true if a and b point to the same object */
>> }
>> 
>> We certainly rely on this already.
>>   
> 
> Ah so the 31st bit is optional as far as userspace is concerned?  What does it mean? (just curious)

The 0x80000000 bit declares that a pointer is in 24-bit mode, so that applications can use the spare upper bits for random data.

See http://en.wikipedia.org/wiki/31-bit for an explanation.

Alex

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-23 12:59                                       ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-23 12:59 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Arnd Bergmann, Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA


On 23.04.2010, at 14:53, Avi Kivity wrote:

> On 04/23/2010 03:46 PM, Arnd Bergmann wrote:
>> On Friday 23 April 2010, Avi Kivity wrote:
>>   
>>> On 04/23/2010 03:27 PM, Arnd Bergmann wrote:
>>>     
>>>>       
>>>>> Using a 64-bit integer avoids the problem (though perhaps not sufficient
>>>>> for s390, Arnd?)
>>>>> 
>>>>>         
>>>> When there is only a __u64 for the address, it will work on s390 as well,
>>>> gcc is smart enough to clear the upper bit on a cast from long to pointer.
>>>> 
>>>>       
>>> Ah, much more convenient than compat_ioctl.  I assume it part of the
>>> ABI, not a gccism?
>>>     
>> I don't think it's part of the ABI, but it's required to guarantee
>> that code like this works:
>> 
>> int compare_pointer(void *a, void *b)
>> {
>> 	unsigned long ai = (unsigned long)a, bi = (unsigned long)b;
>> 
>> 	return ai = bi; /* true if a and b point to the same object */
>> }
>> 
>> We certainly rely on this already.
>>   
> 
> Ah so the 31st bit is optional as far as userspace is concerned?  What does it mean? (just curious)

The 0x80000000 bit declares that a pointer is in 24-bit mode, so that applications can use the spare upper bits for random data.

See http://en.wikipedia.org/wiki/31-bit for an explanation.

Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-23 12:59                                       ` Alexander Graf
  0 siblings, 0 replies; 141+ messages in thread
From: Alexander Graf @ 2010-04-23 12:59 UTC (permalink / raw)
  To: kvm-ia64


On 23.04.2010, at 14:53, Avi Kivity wrote:

> On 04/23/2010 03:46 PM, Arnd Bergmann wrote:
>> On Friday 23 April 2010, Avi Kivity wrote:
>>   
>>> On 04/23/2010 03:27 PM, Arnd Bergmann wrote:
>>>     
>>>>       
>>>>> Using a 64-bit integer avoids the problem (though perhaps not sufficient
>>>>> for s390, Arnd?)
>>>>> 
>>>>>         
>>>> When there is only a __u64 for the address, it will work on s390 as well,
>>>> gcc is smart enough to clear the upper bit on a cast from long to pointer.
>>>> 
>>>>       
>>> Ah, much more convenient than compat_ioctl.  I assume it part of the
>>> ABI, not a gccism?
>>>     
>> I don't think it's part of the ABI, but it's required to guarantee
>> that code like this works:
>> 
>> int compare_pointer(void *a, void *b)
>> {
>> 	unsigned long ai = (unsigned long)a, bi = (unsigned long)b;
>> 
>> 	return ai = bi; /* true if a and b point to the same object */
>> }
>> 
>> We certainly rely on this already.
>>   
> 
> Ah so the 31st bit is optional as far as userspace is concerned?  What does it mean? (just curious)

The 0x80000000 bit declares that a pointer is in 24-bit mode, so that applications can use the spare upper bits for random data.

See http://en.wikipedia.org/wiki/31-bit for an explanation.

Alex


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
       [not found]                                   ` <4BD19831.5000405-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
  2010-04-23 12:59                                       ` Alexander Graf
@ 2010-04-23 13:12                                       ` Arnd Bergmann
  1 sibling, 0 replies; 141+ messages in thread
From: Arnd Bergmann @ 2010-04-23 13:12 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Alexander Graf, Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA

On Friday 23 April 2010, Avi Kivity wrote:
> Ah so the 31st bit is optional as far as userspace is concerned?  What 
> does it mean? (just curious)

On data pointers it's ignored. When you branch to a function, this bit
determines whether the target function is run in 24 or 31 bit mode.
This allows linking to legacy code on older operating systems that
also support 24 bit libraries.

> What happens on the opposite conversion?  is it restored?
> 
> What about
> 
> int compare_pointer(void *a, void *b)
> {
>         unsigned long ai = (unsigned long)a;
>         void *aia = (void *)ai;
> 
>         return a == b; /* true if a and b point to the same object */
> }

Some instructions set the bit, others clear it, so aia and a may not
be bitwise identical.

> Does gcc mask the big in pointer comparisons as well?

Yes. To stay in the above example:

a == aia;					/* true */
(unsigned long)a == (unsigned long)aia;		/* true */
*(unsigned long *)&a == *(unsigned long *)&aia; /* undefined on s390 */

	Arnd

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-23 13:12                                       ` Arnd Bergmann
  0 siblings, 0 replies; 141+ messages in thread
From: Arnd Bergmann @ 2010-04-23 13:12 UTC (permalink / raw)
  To: Avi Kivity
  Cc: Alexander Graf, Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA

On Friday 23 April 2010, Avi Kivity wrote:
> Ah so the 31st bit is optional as far as userspace is concerned?  What 
> does it mean? (just curious)

On data pointers it's ignored. When you branch to a function, this bit
determines whether the target function is run in 24 or 31 bit mode.
This allows linking to legacy code on older operating systems that
also support 24 bit libraries.

> What happens on the opposite conversion?  is it restored?
> 
> What about
> 
> int compare_pointer(void *a, void *b)
> {
>         unsigned long ai = (unsigned long)a;
>         void *aia = (void *)ai;
> 
>         return a = b; /* true if a and b point to the same object */
> }

Some instructions set the bit, others clear it, so aia and a may not
be bitwise identical.

> Does gcc mask the big in pointer comparisons as well?

Yes. To stay in the above example:

a = aia;					/* true */
(unsigned long)a = (unsigned long)aia;		/* true */
*(unsigned long *)&a = *(unsigned long *)&aia; /* undefined on s390 */

	Arnd

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
@ 2010-04-23 13:12                                       ` Arnd Bergmann
  0 siblings, 0 replies; 141+ messages in thread
From: Arnd Bergmann @ 2010-04-23 13:12 UTC (permalink / raw)
  To: kvm-ia64

On Friday 23 April 2010, Avi Kivity wrote:
> Ah so the 31st bit is optional as far as userspace is concerned?  What 
> does it mean? (just curious)

On data pointers it's ignored. When you branch to a function, this bit
determines whether the target function is run in 24 or 31 bit mode.
This allows linking to legacy code on older operating systems that
also support 24 bit libraries.

> What happens on the opposite conversion?  is it restored?
> 
> What about
> 
> int compare_pointer(void *a, void *b)
> {
>         unsigned long ai = (unsigned long)a;
>         void *aia = (void *)ai;
> 
>         return a = b; /* true if a and b point to the same object */
> }

Some instructions set the bit, others clear it, so aia and a may not
be bitwise identical.

> Does gcc mask the big in pointer comparisons as well?

Yes. To stay in the above example:

a = aia;					/* true */
(unsigned long)a = (unsigned long)aia;		/* true */
*(unsigned long *)&a = *(unsigned long *)&aia; /* undefined on s390 */

	Arnd

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps
       [not found]                                       ` <9557F344-EC7C-450F-AED9-5BB865C08650-l3A5Bk7waGM@public.gmane.org>
  2010-04-23 13:20                                           ` Avi Kivity
@ 2010-04-23 13:20                                           ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 13:20 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Arnd Bergmann, Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA

On 04/23/2010 03:59 PM, Alexander Graf wrote:
>
>> Ah so the 31st bit is optional as far as userspace is concerned?  What does it mean? (just curious)
>>      
> The 0x80000000 bit declares that a pointer is in 24-bit mode, so that applications can use the spare upper bits for random data.
>
> See http://en.wikipedia.org/wiki/31-bit for an explanation.
>    

Interesting.  Luckily AMD made the top 16 bits of pointers reserved in 
x86-64.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.

^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-23 13:20                                           ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 13:20 UTC (permalink / raw)
  To: Alexander Graf
  Cc: Arnd Bergmann, Fernando Luis Vázquez Cao, Takuya Yoshikawa,
	mtosatti-H+wXaHxf7aLQT0dZR+AlfA, kvm-u79uwXL29TY76Z2rM5mHXA,
	kvm-ia64-u79uwXL29TY76Z2rM5mHXA, kvm-ppc-u79uwXL29TY76Z2rM5mHXA

On 04/23/2010 03:59 PM, Alexander Graf wrote:
>
>> Ah so the 31st bit is optional as far as userspace is concerned?  What does it mean? (just curious)
>>      
> The 0x80000000 bit declares that a pointer is in 24-bit mode, so that applications can use the spare upper bits for random data.
>
> See http://en.wikipedia.org/wiki/31-bit for an explanation.
>    

Interesting.  Luckily AMD made the top 16 bits of pointers reserved in 
x86-64.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

* Re: [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty
@ 2010-04-23 13:20                                           ` Avi Kivity
  0 siblings, 0 replies; 141+ messages in thread
From: Avi Kivity @ 2010-04-23 13:20 UTC (permalink / raw)
  To: kvm-ia64

On 04/23/2010 03:59 PM, Alexander Graf wrote:
>
>> Ah so the 31st bit is optional as far as userspace is concerned?  What does it mean? (just curious)
>>      
> The 0x80000000 bit declares that a pointer is in 24-bit mode, so that applications can use the spare upper bits for random data.
>
> See http://en.wikipedia.org/wiki/31-bit for an explanation.
>    

Interesting.  Luckily AMD made the top 16 bits of pointers reserved in 
x86-64.

-- 
Do not meddle in the internals of kernels, for they are subtle and quick to panic.


^ permalink raw reply	[flat|nested] 141+ messages in thread

end of thread, other threads:[~2010-04-23 13:20 UTC | newest]

Thread overview: 141+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-04-20 10:53 [PATCH RFC v2 0/6] KVM: moving dirty gitmaps to user space! Takuya Yoshikawa
2010-04-20 10:53 ` Takuya Yoshikawa
2010-04-20 10:53 ` Takuya Yoshikawa
2010-04-20 10:54 ` Alexander Graf
2010-04-20 10:54   ` Alexander Graf
2010-04-20 10:54   ` Alexander Graf
     [not found]   ` <C70797C1-08EC-4DBA-9595-4047CAE8E457-l3A5Bk7waGM@public.gmane.org>
2010-04-20 11:13     ` Takuya Yoshikawa
2010-04-20 11:13       ` Takuya Yoshikawa
2010-04-20 11:13       ` Takuya Yoshikawa
2010-04-20 10:56 ` [PATCH RFC v2 1/6] KVM: introduce slot level dirty state management Takuya Yoshikawa
2010-04-20 10:56   ` Takuya Yoshikawa
2010-04-20 10:56   ` Takuya Yoshikawa
2010-04-20 10:57 ` [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian Takuya Yoshikawa
2010-04-20 11:00   ` [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian issues explicitly Takuya Yoshikawa
2010-04-20 10:57   ` [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian Takuya Yoshikawa
     [not found]   ` <20100420200043.956302db.yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
2010-04-20 11:00     ` [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian issues explicitly Alexander Graf
2010-04-20 11:00       ` Alexander Graf
2010-04-20 11:00       ` Alexander Graf
2010-04-20 11:20       ` Takuya Yoshikawa
2010-04-20 11:20         ` [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian Takuya Yoshikawa
2010-04-20 11:20         ` Takuya Yoshikawa
2010-04-21 11:15   ` [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian issues explicitly Avi Kivity
2010-04-21 11:15     ` [PATCH RFC v2 4/6] KVM: change mark_page_dirty() to handle endian Avi Kivity
2010-04-21 11:15     ` Avi Kivity
2010-04-20 10:57 ` [PATCH RFC v2 2/6] KVM: introduce wrapper functions to create and destroy dirty bitmaps Takuya Yoshikawa
2010-04-20 10:57   ` [PATCH RFC v2 2/6] KVM: introduce wrapper functions to create and Takuya Yoshikawa
2010-04-20 10:57   ` Takuya Yoshikawa
     [not found] ` <20100420195349.dab60b1d.yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
2010-04-20 10:58   ` [PATCH RFC v2 5/6] KVM: moving dirty bitmaps to user space Takuya Yoshikawa
2010-04-20 11:02     ` Takuya Yoshikawa
2010-04-20 10:58     ` Takuya Yoshikawa
     [not found]     ` <20100420200225.efca602f.yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
2010-04-20 11:10       ` Alexander Graf
2010-04-20 11:10         ` Alexander Graf
2010-04-20 11:10         ` Alexander Graf
     [not found]         ` <20234257-D6B8-44A6-BD91-C7B9D0E4970B-l3A5Bk7waGM@public.gmane.org>
2010-04-20 11:26           ` Takuya Yoshikawa
2010-04-20 11:26             ` Takuya Yoshikawa
2010-04-20 11:26             ` Takuya Yoshikawa
2010-04-21 11:26       ` Avi Kivity
2010-04-21 11:26         ` Avi Kivity
2010-04-21 11:26         ` Avi Kivity
     [not found]         ` <4BCEE0E4.6060707-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-04-22  9:07           ` Takuya Yoshikawa
2010-04-22  9:07             ` Takuya Yoshikawa
2010-04-22  9:07             ` Takuya Yoshikawa
2010-04-23 10:28             ` Avi Kivity
2010-04-23 10:28               ` Avi Kivity
2010-04-23 10:28               ` Avi Kivity
     [not found]               ` <4BD17665.5090101-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-04-23 11:14                 ` Takuya Yoshikawa
2010-04-23 11:14                   ` Takuya Yoshikawa
2010-04-23 11:14                   ` Takuya Yoshikawa
     [not found]                   ` <4BD1812E.6030707-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
2010-04-23 11:29                     ` Yoshiaki Tamura
2010-04-23 11:29                       ` Yoshiaki Tamura
2010-04-23 11:29                       ` Yoshiaki Tamura
2010-04-23 11:45                   ` Avi Kivity
2010-04-23 11:45                     ` Avi Kivity
2010-04-23 11:45                     ` Avi Kivity
2010-04-20 10:59   ` [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy " Takuya Yoshikawa
2010-04-20 10:59     ` [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy dirty Takuya Yoshikawa
2010-04-20 10:59     ` Takuya Yoshikawa
     [not found]     ` <20100420195913.ac44281c.yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
2010-04-21 11:12       ` [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy dirty bitmaps to user space Avi Kivity
2010-04-21 11:12         ` [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy Avi Kivity
2010-04-21 11:12         ` Avi Kivity
2010-04-22  8:57         ` [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy dirty bitmaps to user space Takuya Yoshikawa
2010-04-22  8:57           ` [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy Takuya Yoshikawa
2010-04-22  8:57           ` Takuya Yoshikawa
     [not found]           ` <4BD00F64.4020405-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
2010-04-23 10:26             ` [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy dirty bitmaps to user space Avi Kivity
2010-04-23 10:26               ` [PATCH RFC v2 3/6] KVM: introduce a wrapper function to copy Avi Kivity
2010-04-23 10:26               ` Avi Kivity
2010-04-20 11:03   ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps Takuya Yoshikawa
2010-04-20 11:03     ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty Takuya Yoshikawa
2010-04-20 11:03     ` Takuya Yoshikawa
2010-04-20 11:15     ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps Alexander Graf
2010-04-20 11:15       ` Alexander Graf
2010-04-20 11:15       ` Alexander Graf
     [not found]       ` <480E8E1E-32BD-429E-96C8-5AA69A8BDDF3-l3A5Bk7waGM@public.gmane.org>
2010-04-20 11:33         ` Takuya Yoshikawa
2010-04-20 11:33           ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty Takuya Yoshikawa
2010-04-20 11:33           ` Takuya Yoshikawa
     [not found]           ` <4BCD90FE.9060300-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
2010-04-20 11:33             ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps Alexander Graf
2010-04-20 11:33               ` Alexander Graf
2010-04-20 11:33               ` Alexander Graf
2010-04-20 11:44               ` Takuya Yoshikawa
2010-04-20 11:44                 ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty Takuya Yoshikawa
2010-04-20 11:44                 ` Takuya Yoshikawa
2010-04-21  8:29     ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps Fernando Luis Vázquez Cao
2010-04-21  8:29       ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty 
2010-04-21  8:29       ` 
2010-04-21  9:41       ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps Alexander Graf
2010-04-21  9:41         ` Alexander Graf
2010-04-21  9:41         ` Alexander Graf
2010-04-22  2:45         ` Fernando Luis Vázquez Cao
2010-04-22  2:45           ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty 
2010-04-22  2:45           ` 
     [not found]           ` <4BCFB862.7010509-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
2010-04-22  6:09             ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps Fernando Luis Vázquez Cao
2010-04-22  6:09               ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty 
2010-04-22  6:09               ` 
     [not found]               ` <4BCFE805.5040500-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
2010-04-22 23:29                 ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps Alexander Graf
2010-04-22 23:29                   ` Alexander Graf
2010-04-22 23:29                   ` Alexander Graf
2010-04-23 10:17                   ` Fernando Luis Vázquez Cao
2010-04-23 10:17                     ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty 
2010-04-23 10:17                     ` 
2010-04-23 10:20                     ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps Alexander Graf
2010-04-23 10:20                       ` Alexander Graf
2010-04-23 10:20                       ` Alexander Graf
     [not found]                       ` <9B7714E9-7244-4569-B8DB-B3E31E680CAF-l3A5Bk7waGM@public.gmane.org>
2010-04-23 11:57                         ` Avi Kivity
2010-04-23 11:57                           ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty Avi Kivity
2010-04-23 11:57                           ` Avi Kivity
     [not found]                           ` <4BD18B1D.1080604-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-04-23 12:26                             ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps Alexander Graf
2010-04-23 12:26                               ` Alexander Graf
2010-04-23 12:26                               ` Alexander Graf
2010-04-23 12:27                           ` Arnd Bergmann
2010-04-23 12:27                             ` Arnd Bergmann
2010-04-23 12:27                             ` Arnd Bergmann
2010-04-23 12:42                             ` Avi Kivity
2010-04-23 12:42                               ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty Avi Kivity
2010-04-23 12:42                               ` Avi Kivity
2010-04-23 12:46                               ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps Arnd Bergmann
2010-04-23 12:46                                 ` Arnd Bergmann
2010-04-23 12:46                                 ` Arnd Bergmann
2010-04-23 12:53                                 ` Avi Kivity
2010-04-23 12:53                                   ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty Avi Kivity
2010-04-23 12:53                                   ` Avi Kivity
     [not found]                                   ` <4BD19831.5000405-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-04-23 12:59                                     ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps Alexander Graf
2010-04-23 12:59                                       ` Alexander Graf
2010-04-23 12:59                                       ` Alexander Graf
     [not found]                                       ` <9557F344-EC7C-450F-AED9-5BB865C08650-l3A5Bk7waGM@public.gmane.org>
2010-04-23 13:20                                         ` Avi Kivity
2010-04-23 13:20                                           ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty Avi Kivity
2010-04-23 13:20                                           ` Avi Kivity
2010-04-23 13:12                                     ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps Arnd Bergmann
2010-04-23 13:12                                       ` Arnd Bergmann
2010-04-23 13:12                                       ` Arnd Bergmann
     [not found]     ` <20100420200353.2d2a6dec.yoshikawa.takuya-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
2010-04-21 11:46       ` Avi Kivity
2010-04-21 11:46         ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty Avi Kivity
2010-04-21 11:46         ` Avi Kivity
     [not found]         ` <4BCEE579.9020206-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-04-22  9:34           ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps Takuya Yoshikawa
2010-04-22  9:34             ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty Takuya Yoshikawa
2010-04-22  9:34             ` Takuya Yoshikawa
     [not found]             ` <4BD0181C.6020900-gVGce1chcLdL9jVzuh4AOg@public.gmane.org>
2010-04-23 11:58               ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty bitmaps Avi Kivity
2010-04-23 11:58                 ` [PATCH RFC v2 6/6] KVM: introduce a new API for getting dirty Avi Kivity
2010-04-23 11:58                 ` Avi Kivity
2010-04-20 12:05   ` [PATCH RFC v2 0/6] KVM: moving dirty gitmaps to user space! Takuya Yoshikawa
2010-04-20 12:05     ` Takuya Yoshikawa
2010-04-20 12:05     ` Takuya Yoshikawa

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.