[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v9 11/15] tools/libxc: x86 HVM restore code
Restore the x86 HVM specific parts of a domain. This is the HVM_CONTEXT and HVM_PARAMS records. There is no need for any page localisation. This also includes writing the trailing qemu save record to a file because this is what libxc currently does. This is intended to be moved into libxl proper in the future. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CC: Ian Campbell <Ian.Campbell@xxxxxxxxxx> CC: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> CC: Wei Liu <wei.liu2@xxxxxxxxxx> --- tools/libxc/Makefile | 1 + tools/libxc/xc_sr_common.h | 1 + tools/libxc/xc_sr_restore_x86_hvm.c | 225 +++++++++++++++++++++++++++++++++++ 3 files changed, 227 insertions(+) create mode 100644 tools/libxc/xc_sr_restore_x86_hvm.c diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index ba124f4..9b965f2 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -57,6 +57,7 @@ GUEST_SRCS-y += xc_sr_common.c GUEST_SRCS-$(CONFIG_X86) += xc_sr_common_x86.c GUEST_SRCS-$(CONFIG_X86) += xc_sr_common_x86_pv.c GUEST_SRCS-$(CONFIG_X86) += xc_sr_restore_x86_pv.c +GUEST_SRCS-$(CONFIG_X86) += xc_sr_restore_x86_hvm.c GUEST_SRCS-$(CONFIG_X86) += xc_sr_save_x86_pv.c GUEST_SRCS-$(CONFIG_X86) += xc_sr_save_x86_hvm.c GUEST_SRCS-y += xc_sr_restore.c diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h index ec14d59..ab36ec0 100644 --- a/tools/libxc/xc_sr_common.h +++ b/tools/libxc/xc_sr_common.h @@ -289,6 +289,7 @@ struct xc_sr_context extern struct xc_sr_save_ops save_ops_x86_hvm; extern struct xc_sr_restore_ops restore_ops_x86_pv; +extern struct xc_sr_restore_ops restore_ops_x86_hvm; struct xc_sr_record { diff --git a/tools/libxc/xc_sr_restore_x86_hvm.c b/tools/libxc/xc_sr_restore_x86_hvm.c new file mode 100644 index 0000000..3b16139 --- /dev/null +++ b/tools/libxc/xc_sr_restore_x86_hvm.c @@ -0,0 +1,225 @@ +#include <assert.h> +#include <arpa/inet.h> + +#include "xc_sr_common_x86.h" + +/* + * Process an HVM_CONTEXT record from the stream. + */ +static int handle_hvm_context(struct xc_sr_context *ctx, + struct xc_sr_record *rec) +{ + xc_interface *xch = ctx->xch; + void *p; + + p = malloc(rec->length); + if ( !p ) + { + ERROR("Unable to allocate %u bytes for hvm context", rec->length); + return -1; + } + + free(ctx->x86_hvm.restore.context); + + ctx->x86_hvm.restore.context = memcpy(p, rec->data, rec->length); + ctx->x86_hvm.restore.contextsz = rec->length; + + return 0; +} + +/* + * Process an HVM_PARAMS record from the stream. + */ +static int handle_hvm_params(struct xc_sr_context *ctx, + struct xc_sr_record *rec) +{ + xc_interface *xch = ctx->xch; + struct xc_sr_rec_hvm_params *hdr = rec->data; + struct xc_sr_rec_hvm_params_entry *entry = hdr->param; + unsigned int i; + int rc; + + if ( rec->length < sizeof(*hdr) + || rec->length < sizeof(*hdr) + hdr->count * sizeof(*entry) ) + { + ERROR("hvm_params record is too short"); + return -1; + } + + for ( i = 0; i < hdr->count; i++, entry++ ) + { + switch ( entry->index ) + { + case HVM_PARAM_CONSOLE_PFN: + ctx->restore.console_gfn = entry->value; + xc_clear_domain_page(xch, ctx->domid, entry->value); + break; + case HVM_PARAM_STORE_PFN: + ctx->restore.xenstore_gfn = entry->value; + xc_clear_domain_page(xch, ctx->domid, entry->value); + break; + case HVM_PARAM_IOREQ_PFN: + case HVM_PARAM_BUFIOREQ_PFN: + xc_clear_domain_page(xch, ctx->domid, entry->value); + break; + } + + rc = xc_hvm_param_set(xch, ctx->domid, entry->index, entry->value); + if ( rc < 0 ) + { + PERROR("set HVM param %"PRId64" = 0x%016"PRIx64, + entry->index, entry->value); + return rc; + } + } + return 0; +} + +/* restore_ops function. */ +static bool x86_hvm_pfn_is_valid(const struct xc_sr_context *ctx, xen_pfn_t pfn) +{ + return true; +} + +/* restore_ops function. */ +static xen_pfn_t x86_hvm_pfn_to_gfn(const struct xc_sr_context *ctx, + xen_pfn_t pfn) +{ + return pfn; +} + +/* restore_ops function. */ +static void x86_hvm_set_gfn(struct xc_sr_context *ctx, xen_pfn_t pfn, + xen_pfn_t gfn) +{ + /* no op */ +} + +/* restore_ops function. */ +static void x86_hvm_set_page_type(struct xc_sr_context *ctx, + xen_pfn_t pfn, xen_pfn_t type) +{ + /* no-op */ +} + +/* restore_ops function. */ +static int x86_hvm_localise_page(struct xc_sr_context *ctx, + uint32_t type, void *page) +{ + /* no-op */ + return 0; +} + +/* + * restore_ops function. Confirms the stream matches the domain. + */ +static int x86_hvm_setup(struct xc_sr_context *ctx) +{ + xc_interface *xch = ctx->xch; + + if ( ctx->restore.guest_type != DHDR_TYPE_X86_HVM ) + { + ERROR("Unable to restore %s domain into an x86_hvm domain", + dhdr_type_to_str(ctx->restore.guest_type)); + return -1; + } + else if ( ctx->restore.guest_page_size != PAGE_SIZE ) + { + ERROR("Invalid page size %u for x86_hvm domains", + ctx->restore.guest_page_size); + return -1; + } + + return 0; +} + +/* + * restore_ops function. + */ +static int x86_hvm_process_record(struct xc_sr_context *ctx, + struct xc_sr_record *rec) +{ + switch ( rec->type ) + { + case REC_TYPE_TSC_INFO: + return handle_tsc_info(ctx, rec); + + case REC_TYPE_HVM_CONTEXT: + return handle_hvm_context(ctx, rec); + + case REC_TYPE_HVM_PARAMS: + return handle_hvm_params(ctx, rec); + + default: + return RECORD_NOT_PROCESSED; + } +} + +/* + * restore_ops function. Sets extra hvm parameters and seeds the grant table. + */ +static int x86_hvm_stream_complete(struct xc_sr_context *ctx) +{ + xc_interface *xch = ctx->xch; + int rc; + + rc = xc_hvm_param_set(xch, ctx->domid, HVM_PARAM_STORE_EVTCHN, + ctx->restore.xenstore_evtchn); + if ( rc ) + { + PERROR("Failed to set HVM_PARAM_STORE_EVTCHN"); + return rc; + } + + rc = xc_domain_hvm_setcontext(xch, ctx->domid, + ctx->x86_hvm.restore.context, + ctx->x86_hvm.restore.contextsz); + if ( rc < 0 ) + { + PERROR("Unable to restore HVM context"); + return rc; + } + + rc = xc_dom_gnttab_hvm_seed(xch, ctx->domid, + ctx->restore.console_gfn, + ctx->restore.xenstore_gfn, + ctx->restore.console_domid, + ctx->restore.xenstore_domid); + if ( rc ) + { + PERROR("Failed to seed grant table"); + return rc; + } + + return rc; +} + +static int x86_hvm_cleanup(struct xc_sr_context *ctx) +{ + free(ctx->x86_hvm.restore.context); + + return 0; +} + +struct xc_sr_restore_ops restore_ops_x86_hvm = +{ + .pfn_is_valid = x86_hvm_pfn_is_valid, + .pfn_to_gfn = x86_hvm_pfn_to_gfn, + .set_gfn = x86_hvm_set_gfn, + .set_page_type = x86_hvm_set_page_type, + .localise_page = x86_hvm_localise_page, + .setup = x86_hvm_setup, + .process_record = x86_hvm_process_record, + .stream_complete = x86_hvm_stream_complete, + .cleanup = x86_hvm_cleanup, +}; + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |