Blame SOURCES/kvm-migration-Fix-non-multiple-of-page-size-migration.patch

76daa3
From d05a64ddd01fa11fed479a2e249ed46c93207f9e Mon Sep 17 00:00:00 2001
76daa3
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
76daa3
Date: Thu, 18 May 2017 11:17:26 +0200
76daa3
Subject: [PATCH 19/27] migration: Fix non-multiple of page size migration
76daa3
76daa3
RH-Author: Dr. David Alan Gilbert <dgilbert@redhat.com>
76daa3
Message-id: <20170518111727.7433-2-dgilbert@redhat.com>
76daa3
Patchwork-id: 75314
76daa3
O-Subject: [RHEL-7.4 qemu-kvm-rhev PATCH 1/2] migration: Fix non-multiple of page size migration
76daa3
Bugzilla: 1449037
76daa3
RH-Acked-by: Juan Quintela <quintela@redhat.com>
76daa3
RH-Acked-by: Peter Xu <peterx@redhat.com>
76daa3
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
76daa3
76daa3
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
76daa3
76daa3
Unfortunately it's legal to create a VM with a RAM size that's
76daa3
not a multiple of the underlying host page or huge page size.
76daa3
Recently I'd changed things to always send host sized pages,
76daa3
and that breaks if we have say a 1025MB guest on 2MB hugepages.
76daa3
76daa3
Unfortunately we can't just make that illegal since it would break
76daa3
migration from/to existing oddly configured VMs.
76daa3
76daa3
Symptom: qemu-system-x86_64: Illegal RAM offset 40100000
76daa3
     as it transmits the fraction of the hugepage after the end
76daa3
     of the RAMBlock (may also cause a crash on the source
76daa3
     - possibly due to clearing bits after the bitmap)
76daa3
76daa3
Reported-by:  Yumei Huang <yuhuang@redhat.com>
76daa3
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
76daa3
Conflicts
76daa3
     Cleanup in HEAD got rid of pss->offset; so use pss->offset
76daa3
     in our 2.9 world
76daa3
76daa3
Upstream URL:
76daa3
http://lists.nongnu.org/archive/html/qemu-devel/2017-05/msg04392.html
76daa3
Upstream Message-Id: <20170518172453.32599-2-quintela@redhat.com>
76daa3
76daa3
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
76daa3
---
76daa3
 migration/ram.c | 10 +++++++++-
76daa3
 1 file changed, 9 insertions(+), 1 deletion(-)
76daa3
76daa3
diff --git a/migration/ram.c b/migration/ram.c
76daa3
index de1e0a3..3661bc8 100644
76daa3
--- a/migration/ram.c
76daa3
+++ b/migration/ram.c
76daa3
@@ -1304,6 +1304,13 @@ static int ram_save_target_page(MigrationState *ms, QEMUFile *f,
76daa3
  *                     block.
76daa3
  *
76daa3
  * Returns: Number of pages written.
76daa3
+ * Starting at *offset send pages up to the end of the current host
76daa3
+ * page. It's valid for the initial offset to point into the middle of
76daa3
+ * a host page in which case the remainder of the hostpage is sent.
76daa3
+ * Only dirty target pages are sent. Note that the host page size may
76daa3
+ * be a huge page for this block.
76daa3
+ * The saving stops at the boundary of the used_length of the block
76daa3
+ * if the RAMBlock isn't a multiple of the host page size.
76daa3
  *
76daa3
  * @f: QEMUFile where to send the data
76daa3
  * @block: pointer to block that contains the page we want to send
76daa3
@@ -1332,7 +1339,8 @@ static int ram_save_host_page(MigrationState *ms, QEMUFile *f,
76daa3
         pages += tmppages;
76daa3
         pss->offset += TARGET_PAGE_SIZE;
76daa3
         dirty_ram_abs += TARGET_PAGE_SIZE;
76daa3
-    } while (pss->offset & (pagesize - 1));
76daa3
+    } while ((pss->offset & (pagesize - 1)) &&
76daa3
+             offset_in_ramblock(pss->block, pss->offset));
76daa3
 
76daa3
     /* The offset we leave with is the last one we looked at */
76daa3
     pss->offset -= TARGET_PAGE_SIZE;
76daa3
-- 
76daa3
1.8.3.1
76daa3