diff options
author | Samuel Mendoza-Jonas <sam.mj@au1.ibm.com> | 2014-11-17 15:12:28 +1100 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2015-01-07 16:16:26 +0100 |
commit | 01a579729b2e614bd02b25c8504976eeecb64eff (patch) | |
tree | f5ce4284c32e0460ece5346ce914598e65f0ea3c /hw | |
parent | e094c4c12f33a1c965f5af02f33968a337348739 (diff) |
spapr: Fix stale HTAB during live migration (KVM)
If a guest reboots during a running migration, changes to the
hash page table are not necessarily updated on the destination.
Opening a new file descriptor to the HTAB forces the migration
handler to resend the entire table.
Signed-off-by: Samuel Mendoza-Jonas <sam.mj@au1.ibm.com>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/ppc/spapr.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 08401e0fde..869b72125a 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -833,6 +833,11 @@ static void spapr_reset_htab(sPAPREnvironment *spapr) /* Kernel handles htab, we don't need to allocate one */ spapr->htab_shift = shift; kvmppc_kern_htab = true; + + /* Tell readers to update their file descriptor */ + if (spapr->htab_fd >= 0) { + spapr->htab_fd_stale = true; + } } else { if (!spapr->htab) { /* Allocate an htab if we don't yet have one */ @@ -867,6 +872,28 @@ static int find_unknown_sysbus_device(SysBusDevice *sbdev, void *opaque) return 0; } +/* + * A guest reset will cause spapr->htab_fd to become stale if being used. + * Reopen the file descriptor to make sure the whole HTAB is properly read. + */ +static int spapr_check_htab_fd(sPAPREnvironment *spapr) +{ + int rc = 0; + + if (spapr->htab_fd_stale) { + close(spapr->htab_fd); + spapr->htab_fd = kvmppc_get_htab_fd(false); + if (spapr->htab_fd < 0) { + error_report("Unable to open fd for reading hash table from KVM: " + "%s", strerror(errno)); + rc = -1; + } + spapr->htab_fd_stale = false; + } + + return rc; +} + static void ppc_spapr_reset(void) { PowerPCCPU *first_ppc_cpu; @@ -1005,6 +1032,7 @@ static int htab_save_setup(QEMUFile *f, void *opaque) assert(kvm_enabled()); spapr->htab_fd = kvmppc_get_htab_fd(false); + spapr->htab_fd_stale = false; if (spapr->htab_fd < 0) { fprintf(stderr, "Unable to open fd for reading hash table from KVM: %s\n", strerror(errno)); @@ -1157,6 +1185,11 @@ static int htab_save_iterate(QEMUFile *f, void *opaque) if (!spapr->htab) { assert(kvm_enabled()); + rc = spapr_check_htab_fd(spapr); + if (rc < 0) { + return rc; + } + rc = kvmppc_save_htab(f, spapr->htab_fd, MAX_KVM_BUF_SIZE, MAX_ITERATION_NS); if (rc < 0) { @@ -1188,6 +1221,11 @@ static int htab_save_complete(QEMUFile *f, void *opaque) assert(kvm_enabled()); + rc = spapr_check_htab_fd(spapr); + if (rc < 0) { + return rc; + } + rc = kvmppc_save_htab(f, spapr->htab_fd, MAX_KVM_BUF_SIZE, -1); if (rc < 0) { return rc; |