Skip to content

Commit

Permalink
migration/savevm.c: migrate non-default page size
Browse files Browse the repository at this point in the history
Add a subsection to vmstate_configuration which is present
only if the guest is using a target page size which is
different from the default. This allows us to helpfully
diagnose attempts to migrate between machines which
are using different target page sizes.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <rth@twiddle.net>
  • Loading branch information
pm215 committed Oct 24, 2016
1 parent 20bccb8 commit 59811a3
Showing 1 changed file with 49 additions and 0 deletions.
49 changes: 49 additions & 0 deletions migration/savevm.c
Expand Up @@ -265,6 +265,7 @@ typedef struct SaveState {
bool skip_configuration;
uint32_t len;
const char *name;
uint32_t target_page_bits;
} SaveState;

static SaveState savevm_state = {
Expand All @@ -286,6 +287,19 @@ static void configuration_pre_save(void *opaque)

state->len = strlen(current_name);
state->name = current_name;
state->target_page_bits = TARGET_PAGE_BITS;
}

static int configuration_pre_load(void *opaque)
{
SaveState *state = opaque;

/* If there is no target-page-bits subsection it means the source
* predates the variable-target-page-bits support and is using the
* minimum possible value for this CPU.
*/
state->target_page_bits = TARGET_PAGE_BITS_MIN;
return 0;
}

static int configuration_post_load(void *opaque, int version_id)
Expand All @@ -298,19 +312,54 @@ static int configuration_post_load(void *opaque, int version_id)
(int) state->len, state->name, current_name);
return -EINVAL;
}

if (state->target_page_bits != TARGET_PAGE_BITS) {
error_report("Received TARGET_PAGE_BITS is %d but local is %d",
state->target_page_bits, TARGET_PAGE_BITS);
return -EINVAL;
}

return 0;
}

/* The target-page-bits subsection is present only if the
* target page size is not the same as the default (ie the
* minimum page size for a variable-page-size guest CPU).
* If it is present then it contains the actual target page
* bits for the machine, and migration will fail if the
* two ends don't agree about it.
*/
static bool vmstate_target_page_bits_needed(void *opaque)
{
return TARGET_PAGE_BITS > TARGET_PAGE_BITS_MIN;
}

static const VMStateDescription vmstate_target_page_bits = {
.name = "configuration/target-page-bits",
.version_id = 1,
.minimum_version_id = 1,
.needed = vmstate_target_page_bits_needed,
.fields = (VMStateField[]) {
VMSTATE_UINT32(target_page_bits, SaveState),
VMSTATE_END_OF_LIST()
}
};

static const VMStateDescription vmstate_configuration = {
.name = "configuration",
.version_id = 1,
.pre_load = configuration_pre_load,
.post_load = configuration_post_load,
.pre_save = configuration_pre_save,
.fields = (VMStateField[]) {
VMSTATE_UINT32(len, SaveState),
VMSTATE_VBUFFER_ALLOC_UINT32(name, SaveState, 0, NULL, 0, len),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription*[]) {
&vmstate_target_page_bits,
NULL
}
};

static void dump_vmstate_vmsd(FILE *out_file,
Expand Down

0 comments on commit 59811a3

Please sign in to comment.