Patchwork [master,stable] vhost: fix dirty page handling

login
register
mail settings
Submitter Michael S. Tsirkin
Date March 16, 2011, 10:09 a.m.
Message ID <20110316100909.GA12895@redhat.com>
Download mbox | patch
Permalink /patch/87222/
State New
Headers show

Comments

Michael S. Tsirkin - March 16, 2011, 10:09 a.m.
vhost was passing a physical address to cpu_physical_memory_set_dirty,
which is wrong: we need to translate to ram address first.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

Note: this lead to crashes during migration, so the patch
is needed on the stable branch too.

---
 hw/vhost.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)
Juan Quintela - March 16, 2011, 12:53 p.m.
"Michael S. Tsirkin" <mst@redhat.com> wrote:
> vhost was passing a physical address to cpu_physical_memory_set_dirty,
> which is wrong: we need to translate to ram address first.
>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>
> Note: this lead to crashes during migration, so the patch
> is needed on the stable branch too.

Reviewed-by: Juan Quintela <quintela@redhat.com>

We have been having strange migration corruptions for some time, this
can explain what was going on.

> ---
>  hw/vhost.c |    4 +++-
>  1 files changed, 3 insertions(+), 1 deletions(-)
>
> diff --git a/hw/vhost.c b/hw/vhost.c
> index aaa34e4..97a1299 100644
> --- a/hw/vhost.c
> +++ b/hw/vhost.c
> @@ -49,8 +49,10 @@ static void vhost_dev_sync_region(struct vhost_dev *dev,
>          log = __sync_fetch_and_and(from, 0);
>          while ((bit = sizeof(log) > sizeof(int) ?
>                  ffsll(log) : ffs(log))) {
> +            ram_addr_t ram_addr;
>              bit -= 1;
> -            cpu_physical_memory_set_dirty(addr + bit * VHOST_LOG_PAGE);
> +            ram_addr = cpu_get_physical_page_desc(addr + bit * VHOST_LOG_PAGE);
> +            cpu_physical_memory_set_dirty(ram_addr);
>              log &= ~(0x1ull << bit);
>          }
>          addr += VHOST_LOG_CHUNK;
<#secure method=pgpmime mode=sign>
Alex Williamson - March 16, 2011, 2:17 p.m.
On Wed, 2011-03-16 at 12:09 +0200, Michael S. Tsirkin wrote:
> vhost was passing a physical address to cpu_physical_memory_set_dirty,
> which is wrong: we need to translate to ram address first.
> 
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> 
> Note: this lead to crashes during migration, so the patch
> is needed on the stable branch too.
> 
> ---
>  hw/vhost.c |    4 +++-
>  1 files changed, 3 insertions(+), 1 deletions(-)
> 
> diff --git a/hw/vhost.c b/hw/vhost.c
> index aaa34e4..97a1299 100644
> --- a/hw/vhost.c
> +++ b/hw/vhost.c
> @@ -49,8 +49,10 @@ static void vhost_dev_sync_region(struct vhost_dev *dev,
>          log = __sync_fetch_and_and(from, 0);
>          while ((bit = sizeof(log) > sizeof(int) ?
>                  ffsll(log) : ffs(log))) {
> +            ram_addr_t ram_addr;
>              bit -= 1;
> -            cpu_physical_memory_set_dirty(addr + bit * VHOST_LOG_PAGE);
> +            ram_addr = cpu_get_physical_page_desc(addr + bit * VHOST_LOG_PAGE);
> +            cpu_physical_memory_set_dirty(ram_addr);
>              log &= ~(0x1ull << bit);
>          }
>          addr += VHOST_LOG_CHUNK;

Reviewed-by: Alex Williamson <alex.williamson@redhat.com>

Patch

diff --git a/hw/vhost.c b/hw/vhost.c
index aaa34e4..97a1299 100644
--- a/hw/vhost.c
+++ b/hw/vhost.c
@@ -49,8 +49,10 @@  static void vhost_dev_sync_region(struct vhost_dev *dev,
         log = __sync_fetch_and_and(from, 0);
         while ((bit = sizeof(log) > sizeof(int) ?
                 ffsll(log) : ffs(log))) {
+            ram_addr_t ram_addr;
             bit -= 1;
-            cpu_physical_memory_set_dirty(addr + bit * VHOST_LOG_PAGE);
+            ram_addr = cpu_get_physical_page_desc(addr + bit * VHOST_LOG_PAGE);
+            cpu_physical_memory_set_dirty(ram_addr);
             log &= ~(0x1ull << bit);
         }
         addr += VHOST_LOG_CHUNK;