9ae3a8
From 2a3a2063076b590d9ef81a7d7cdc71520647734b Mon Sep 17 00:00:00 2001
9ae3a8
From: Laszlo Ersek <lersek@redhat.com>
9ae3a8
Date: Tue, 9 Sep 2014 16:04:57 +0200
9ae3a8
Subject: [PATCH 07/12] pflash_cfi01: write flash contents to bdrv on incoming migration
9ae3a8
9ae3a8
Message-id: <1410278697-29800-2-git-send-email-lersek@redhat.com>
9ae3a8
Patchwork-id: 60923
9ae3a8
O-Subject: [RHEL-7.1 qemu-kvm PATCH 1/1] pflash_cfi01: write flash contents to bdrv on incoming migration
9ae3a8
Bugzilla: 1139702
9ae3a8
RH-Acked-by: Dr. David Alan Gilbert (git) <dgilbert@redhat.com>
9ae3a8
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
9ae3a8
A drive that backs a pflash device is special:
9ae3a8
- it is very small,
9ae3a8
- its entire contents are kept in a RAMBlock at all times, covering the
9ae3a8
  guest-phys address range that provides the guest's view of the emulated
9ae3a8
  flash chip.
9ae3a8
9ae3a8
The pflash device model keeps the drive (the host-side file) and the
9ae3a8
guest-visible flash contents in sync. When migrating the guest, the
9ae3a8
guest-visible flash contents (the RAMBlock) is migrated by default, but on
9ae3a8
the target host, the drive (the host-side file) remains in full sync with
9ae3a8
the RAMBlock only if:
9ae3a8
- the source and target hosts share the storage underlying the pflash
9ae3a8
  drive,
9ae3a8
- or the migration requests full or incremental block migration too, which
9ae3a8
  then covers all drives.
9ae3a8
9ae3a8
Due to the special nature of pflash drives, the following scenario makes
9ae3a8
sense as well:
9ae3a8
- no full nor incremental block migration, covering all drives, alongside
9ae3a8
  the base migration (justified eg. by shared storage for "normal" (big)
9ae3a8
  drives),
9ae3a8
- non-shared storage for pflash drives.
9ae3a8
9ae3a8
In this case, currently only those portions of the flash drive are updated
9ae3a8
on the target disk that the guest reprograms while running on the target
9ae3a8
host.
9ae3a8
9ae3a8
In order to restore accord, dump the entire flash contents to the bdrv in
9ae3a8
a post_load() callback.
9ae3a8
9ae3a8
- The read-only check follows the other call-sites of pflash_update();
9ae3a8
- both "pfl->ro" and pflash_update() reflect / consider the case when
9ae3a8
  "pfl->bs" is NULL;
9ae3a8
- the total size of the flash device is calculated as in
9ae3a8
  pflash_cfi01_realize().
9ae3a8
9ae3a8
When using shared storage, or requesting full or incremental block
9ae3a8
migration along with the normal migration, the patch should incur a
9ae3a8
harmless rewrite from the target side.
9ae3a8
9ae3a8
It is assumed that, on the target host, RAM is loaded ahead of the call to
9ae3a8
pflash_post_load().
9ae3a8
9ae3a8
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
9ae3a8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
(cherry picked from commit 4c0cfc72b31a79f737a64ebbe0411e4b83e25771)
9ae3a8
---
9ae3a8
 hw/block/pflash_cfi01.c | 14 ++++++++++++++
9ae3a8
 1 file changed, 14 insertions(+)
9ae3a8
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 hw/block/pflash_cfi01.c |   14 ++++++++++++++
9ae3a8
 1 files changed, 14 insertions(+), 0 deletions(-)
9ae3a8
9ae3a8
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
9ae3a8
index 18eb0bc..e8b47fb 100644
9ae3a8
--- a/hw/block/pflash_cfi01.c
9ae3a8
+++ b/hw/block/pflash_cfi01.c
9ae3a8
@@ -85,10 +85,13 @@ struct pflash_t {
9ae3a8
     void *storage;
9ae3a8
 };
9ae3a8
 
9ae3a8
+static int pflash_post_load(void *opaque, int version_id);
9ae3a8
+
9ae3a8
 static const VMStateDescription vmstate_pflash = {
9ae3a8
     .name = "pflash_cfi01",
9ae3a8
     .version_id = 1,
9ae3a8
     .minimum_version_id = 1,
9ae3a8
+    .post_load = pflash_post_load,
9ae3a8
     .fields = (VMStateField[]) {
9ae3a8
         VMSTATE_UINT8(wcycle, pflash_t),
9ae3a8
         VMSTATE_UINT8(cmd, pflash_t),
9ae3a8
@@ -768,3 +771,14 @@ MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl)
9ae3a8
 {
9ae3a8
     return &fl->mem;
9ae3a8
 }
9ae3a8
+
9ae3a8
+static int pflash_post_load(void *opaque, int version_id)
9ae3a8
+{
9ae3a8
+    pflash_t *pfl = opaque;
9ae3a8
+
9ae3a8
+    if (!pfl->ro) {
9ae3a8
+        DPRINTF("%s: updating bdrv for %s\n", __func__, pfl->name);
9ae3a8
+        pflash_update(pfl, 0, pfl->sector_len * pfl->nb_blocs);
9ae3a8
+    }
9ae3a8
+    return 0;
9ae3a8
+}
9ae3a8
-- 
9ae3a8
1.7.1
9ae3a8