From d379534a8f15dc05dbb6ed76eeff144dcad024e3 Mon Sep 17 00:00:00 2001
From: Eduardo Habkost <ehabkost@redhat.com>
Date: Mon, 14 Oct 2013 19:42:52 +0200
Subject: [PATCH 1/4] vmstate: Add max_version_id field to VMStateDescription

RH-Author: Eduardo Habkost <ehabkost@redhat.com>
Message-id: <1381779774-3554-2-git-send-email-ehabkost@redhat.com>
Patchwork-id: 54901
O-Subject: [qemu-kvm RHEL-6 PATCH v2 1/3] vmstate: Add max_version_id field to VMStateDescription
Bugzilla: 1016736
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Orit Wasserman <owasserm@redhat.com>

Bugzilla: 1016736
Scratch build: https://brewweb.devel.redhat.com/taskinfo?taskID=6415966
Upstream status: submitted, but not likely to be accepted

This will allow us to load data that has a high version_id, while using
a lower version_id when saving.

This doesn't include vmstate_save_state() changes to skip fields with
field->version_id > vmsd->version_id. But this is enough for our case
where the xsave data is not present on "cpu" section v12 (so both
v11 and v12 sections will have the same format).

Patch is not included upstream yet, but if the patch is not accepted, we
have no other choice to fix version_id on RHEL-6.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/hw.h  | 6 ++++++
 savevm.c | 2 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 hw/hw.h  |    6 ++++++
 savevm.c |    2 +-
 2 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/hw/hw.h b/hw/hw.h
index 479a9f2..d896da2 100644
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -326,6 +326,12 @@ struct VMStateDescription {
     const char *name;
     int unmigratable;
     int version_id;
+    /* Maximum version_id we accept. Note that the existing code
+     * won't skip fields on vmstate_save_state() based on version_id,
+     * so no fields with field->version_id > vmsd->version_id are
+     * allowed.
+     */
+    int max_version_id;
     int minimum_version_id;
     int minimum_version_id_old;
     LoadStateHandler *load_state_old;
diff --git a/savevm.c b/savevm.c
index 22cfffd..fda52dd 100644
--- a/savevm.c
+++ b/savevm.c
@@ -1325,7 +1325,7 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
     VMStateField *field = vmsd->fields;
     int ret;
 
-    if (version_id > vmsd->version_id) {
+    if (version_id > MAX(vmsd->version_id, vmsd->max_version_id)) {
         return -EINVAL;
     }
     if (version_id < vmsd->minimum_version_id_old) {
-- 
1.7.1

