From patchwork Tue Dec 24 15:19:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11309509 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 78BAB6C1 for ; Tue, 24 Dec 2019 15:20:46 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 50BE42071E for ; Tue, 24 Dec 2019 15:20:46 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="M/gB5q6j" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 50BE42071E Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlyK-0000Ch-5r; Tue, 24 Dec 2019 15:19:44 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlyJ-0000Ca-2S for xen-devel@lists.xenproject.org; Tue, 24 Dec 2019 15:19:43 +0000 X-Inumbo-ID: cbed5031-2660-11ea-97e5-12813bfff9fa Received: from esa5.hc3370-68.iphmx.com (unknown [216.71.155.168]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id cbed5031-2660-11ea-97e5-12813bfff9fa; Tue, 24 Dec 2019 15:19:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1577200777; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=RX6Blgk0Xk4ef64Q6qEVWGRgYRDhAIECGhmmf5qsoUQ=; b=M/gB5q6jPNTOJF77OwiN9xA+lq/hw4cFXR6QqWpdfl1EMJEjV6VUaOcz ziKyq9U9iGZH0ldJna2AV4LP0ubHQy/utbc5Jy8+/X0N+/XhPzNhE5VII md5vaZIlIgmlzNTZiflVybX8OgO5ccv0baBxEgHEHfeQNEo8wQI7Bsh3Y k=; Authentication-Results: esa5.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa5.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: gYdQIRzRpFKEcwEDoefh1V9O9dVPRkOm1Fo2KiWurvODCjmfnI7J6rsi+6QuY8DzTQL+lddk8B mHufNCvRT3R8NDUo8j9/G0p/Q1yw8kqh5Ngn2W44lK8eXdw+Wihn3QLg6w0pACS3GAjJGDQ8ka DZAE84FqHiBxpjc8wTowdlGCphM1eQBQBNrcP4I/5apIVUu8zO3kJv4nkNx7EvEm11WaSRqY2c /p75Q4DUiuebHvQWqmYIeIDQmj16/k32i0p9zdtYi/rLhHRpq63ktxqOKRHQIk/17Vj4vK8BUq oXo= X-SBRS: 2.7 X-MesageID: 10482745 X-Ironport-Server: esa5.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,351,1571716800"; d="scan'208";a="10482745" From: Andrew Cooper To: Xen-devel Date: Tue, 24 Dec 2019 15:19:21 +0000 Message-ID: <20191224151932.6304-2-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20191224151932.6304-1-andrew.cooper3@citrix.com> References: <20191224151932.6304-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH 01/12] libxc/save: Shrink code volume where possible X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Ian Jackson Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" A property of how the error handling (0 on success, nonzero otherwise) allows these calls to be chained together with the ternary operatior. No functional change, but far less boilerplate code. Signed-off-by: Andrew Cooper --- CC: Ian Jackson CC: Wei Liu --- tools/libxc/xc_sr_save.c | 7 ++--- tools/libxc/xc_sr_save_x86_hvm.c | 21 +++------------ tools/libxc/xc_sr_save_x86_pv.c | 58 ++++++++-------------------------------- 3 files changed, 16 insertions(+), 70 deletions(-) diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c index f89e12c99f..9764aa743f 100644 --- a/tools/libxc/xc_sr_save.c +++ b/tools/libxc/xc_sr_save.c @@ -845,11 +845,8 @@ static int save(struct xc_sr_context *ctx, uint16_t guest_type) xc_report_progress_single(xch, "Start of stream"); - rc = write_headers(ctx, guest_type); - if ( rc ) - goto err; - - rc = ctx->save.ops.start_of_stream(ctx); + rc = (write_headers(ctx, guest_type) ?: + ctx->save.ops.start_of_stream(ctx)); if ( rc ) goto err; diff --git a/tools/libxc/xc_sr_save_x86_hvm.c b/tools/libxc/xc_sr_save_x86_hvm.c index 3d86cb0600..d925a81999 100644 --- a/tools/libxc/xc_sr_save_x86_hvm.c +++ b/tools/libxc/xc_sr_save_x86_hvm.c @@ -187,24 +187,9 @@ static int x86_hvm_check_vm_state(struct xc_sr_context *ctx) static int x86_hvm_end_of_checkpoint(struct xc_sr_context *ctx) { - int rc; - - /* Write the TSC record. */ - rc = write_x86_tsc_info(ctx); - if ( rc ) - return rc; - - /* Write the HVM_CONTEXT record. */ - rc = write_hvm_context(ctx); - if ( rc ) - return rc; - - /* Write HVM_PARAMS record contains applicable HVM params. */ - rc = write_hvm_params(ctx); - if ( rc ) - return rc; - - return 0; + return (write_x86_tsc_info(ctx) ?: + write_hvm_context(ctx) ?: + write_hvm_params(ctx)); } static int x86_hvm_cleanup(struct xc_sr_context *ctx) diff --git a/tools/libxc/xc_sr_save_x86_pv.c b/tools/libxc/xc_sr_save_x86_pv.c index 3ebc5a2bf8..94d0f68911 100644 --- a/tools/libxc/xc_sr_save_x86_pv.c +++ b/tools/libxc/xc_sr_save_x86_pv.c @@ -768,19 +768,10 @@ static int write_all_vcpu_information(struct xc_sr_context *ctx) if ( !vinfo.online ) continue; - rc = write_one_vcpu_basic(ctx, i); - if ( rc ) - return rc; - - rc = write_one_vcpu_extended(ctx, i); - if ( rc ) - return rc; - - rc = write_one_vcpu_xsave(ctx, i); - if ( rc ) - return rc; - - rc = write_one_vcpu_msrs(ctx, i); + rc = (write_one_vcpu_basic(ctx, i) ?: + write_one_vcpu_extended(ctx, i) ?: + write_one_vcpu_xsave(ctx, i) ?: + write_one_vcpu_msrs(ctx, i)); if ( rc ) return rc; } @@ -1031,25 +1022,10 @@ static int x86_pv_normalise_page(struct xc_sr_context *ctx, xen_pfn_t type, */ static int x86_pv_setup(struct xc_sr_context *ctx) { - int rc; - - rc = x86_pv_domain_info(ctx); - if ( rc ) - return rc; - - rc = x86_pv_map_m2p(ctx); - if ( rc ) - return rc; - - rc = map_shinfo(ctx); - if ( rc ) - return rc; - - rc = map_p2m(ctx); - if ( rc ) - return rc; - - return 0; + return (x86_pv_domain_info(ctx) ?: + x86_pv_map_m2p(ctx) ?: + map_shinfo(ctx) ?: + map_p2m(ctx)); } static int x86_pv_start_of_stream(struct xc_sr_context *ctx) @@ -1080,21 +1056,9 @@ static int x86_pv_start_of_checkpoint(struct xc_sr_context *ctx) static int x86_pv_end_of_checkpoint(struct xc_sr_context *ctx) { - int rc; - - rc = write_x86_tsc_info(ctx); - if ( rc ) - return rc; - - rc = write_shared_info(ctx); - if ( rc ) - return rc; - - rc = write_all_vcpu_information(ctx); - if ( rc ) - return rc; - - return 0; + return (write_x86_tsc_info(ctx) ?: + write_shared_info(ctx) ?: + write_all_vcpu_information(ctx)); } static int x86_pv_check_vm_state(struct xc_sr_context *ctx) From patchwork Tue Dec 24 15:19:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11309517 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5C0CB13A4 for ; Tue, 24 Dec 2019 15:20:56 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2DBCB206D3 for ; Tue, 24 Dec 2019 15:20:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="XDCWq1vQ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2DBCB206D3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlyO-0000DW-Eb; Tue, 24 Dec 2019 15:19:48 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlyN-0000DB-7n for xen-devel@lists.xenproject.org; Tue, 24 Dec 2019 15:19:47 +0000 X-Inumbo-ID: cc7907fe-2660-11ea-a914-bc764e2007e4 Received: from esa5.hc3370-68.iphmx.com (unknown [216.71.155.168]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id cc7907fe-2660-11ea-a914-bc764e2007e4; Tue, 24 Dec 2019 15:19:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1577200778; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=HBWvN/EhXh572ocYjiir/jQ4OyA62+y9bdVvZ/ZLnsc=; b=XDCWq1vQyC0f2bSMru07O6LyPQAfQrQWCVgi7XDhwDb679GIjHw+K5G/ MBgTx7BHWrn+hGHbpH6zKnLuCX8XJ3tMb41fCeSl7TJF0QwJP3+ad6BJF oCCym5eYhWL1RnC2ls/QflpEGv0v7/rNMMKxGm4yv6+r2NPWIfWaEdUA2 Y=; Authentication-Results: esa5.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa5.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: jlcK4XYV93j2noYofxyQVYWbymQUK14GnAWhir2QgB251jPXiDpYqYNZhIo2NY3diwakCma+Sp LxVeaqenpIecwSctgRuXASuiLLAqzyqo2/3rh97HEhFlFpTDfFQKXpX2p2yciDtMcjAeETKeTv BnCnNDp8/ZgHxIrNbQZYg9meiuz+zcyNRaZ3faRMf1slW92Vt/lkm83Vt/UAyFXBIbam0eYJ82 BmagAMjct6tOHr4MAVsq3/r0VwfzesEPydI1P34mneal/n3YKi4UVcbNjNVqTO/PCYz8WH+RiI pQ8= X-SBRS: 2.7 X-MesageID: 10482746 X-Ironport-Server: esa5.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,351,1571716800"; d="scan'208";a="10482746" From: Andrew Cooper To: Xen-devel Date: Tue, 24 Dec 2019 15:19:22 +0000 Message-ID: <20191224151932.6304-3-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20191224151932.6304-1-andrew.cooper3@citrix.com> References: <20191224151932.6304-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH 02/12] libxc/restore: Introduce functionality to simplify blob handling X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Ian Jackson Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" During migration, we buffer several blobs of data which ultimately need handing back to Xen at an appropriate time. Currently, this is all handled in an ad-hoc manner, but more blobs are soon going to be added. Introduce xc_sr_blob to encapsulate a ptr/size pair, and update_blob() to handle the memory management aspects. Switch the HVM_CONTEXT and the four PV_VCPU_* blobs over to this new infrastructure. Signed-off-by: Andrew Cooper Acked-by: Ian Jackson --- CC: Ian Jackson CC: Wei Liu --- tools/libxc/xc_sr_common.h | 45 ++++++++++++++++++++----- tools/libxc/xc_sr_restore_x86_hvm.c | 21 ++++-------- tools/libxc/xc_sr_restore_x86_pv.c | 67 ++++++++++++++----------------------- 3 files changed, 68 insertions(+), 65 deletions(-) diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h index b66d785e50..19b053911f 100644 --- a/tools/libxc/xc_sr_common.h +++ b/tools/libxc/xc_sr_common.h @@ -165,13 +165,40 @@ struct xc_sr_restore_ops int (*cleanup)(struct xc_sr_context *ctx); }; -/* x86 PV per-vcpu storage structure for blobs heading Xen-wards. */ -struct xc_sr_x86_pv_restore_vcpu +/* Wrapper for blobs of data heading Xen-wards. */ +struct xc_sr_blob { - void *basic, *extd, *xsave, *msr; - size_t basicsz, extdsz, xsavesz, msrsz; + void *ptr; + size_t size; }; +/* + * Update a blob. Duplicate src/size, freeing the old blob if necessary. May + * fail due to memory allocation. + */ +static inline int update_blob(struct xc_sr_blob *blob, + const void *src, size_t size) +{ + void *ptr; + + if ( !src || !size ) + { + errno = EINVAL; + return -1; + } + + if ( (ptr = malloc(size)) == NULL ) + return -1; + + memcpy(ptr, src, size); + + free(blob->ptr); + blob->ptr = memcpy(ptr, src, size); + blob->size = size; + + return 0; +} + struct xc_sr_context { xc_interface *xch; @@ -306,8 +333,11 @@ struct xc_sr_context /* Types for each page (bounded by max_pfn). */ uint32_t *pfn_types; - /* Vcpu context blobs. */ - struct xc_sr_x86_pv_restore_vcpu *vcpus; + /* x86 PV per-vcpu storage structure for blobs. */ + struct xc_sr_x86_pv_restore_vcpu + { + struct xc_sr_blob basic, extd, xsave, msr; + } *vcpus; unsigned int nr_vcpus; } restore; }; @@ -327,8 +357,7 @@ struct xc_sr_context struct { /* HVM context blob. */ - void *context; - size_t contextsz; + struct xc_sr_blob context; } restore; }; } x86_hvm; diff --git a/tools/libxc/xc_sr_restore_x86_hvm.c b/tools/libxc/xc_sr_restore_x86_hvm.c index 4a24dc0137..fe7be9bde6 100644 --- a/tools/libxc/xc_sr_restore_x86_hvm.c +++ b/tools/libxc/xc_sr_restore_x86_hvm.c @@ -10,21 +10,12 @@ static int handle_hvm_context(struct xc_sr_context *ctx, struct xc_sr_record *rec) { xc_interface *xch = ctx->xch; - void *p; + int rc = update_blob(&ctx->x86_hvm.restore.context, rec->data, rec->length); - p = malloc(rec->length); - if ( !p ) - { + if ( rc ) 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; + return rc; } /* @@ -210,8 +201,8 @@ static int x86_hvm_stream_complete(struct xc_sr_context *ctx) } rc = xc_domain_hvm_setcontext(xch, ctx->domid, - ctx->x86_hvm.restore.context, - ctx->x86_hvm.restore.contextsz); + ctx->x86_hvm.restore.context.ptr, + ctx->x86_hvm.restore.context.size); if ( rc < 0 ) { PERROR("Unable to restore HVM context"); @@ -234,7 +225,7 @@ static int x86_hvm_stream_complete(struct xc_sr_context *ctx) static int x86_hvm_cleanup(struct xc_sr_context *ctx) { - free(ctx->x86_hvm.restore.context); + free(ctx->x86_hvm.restore.context.ptr); return 0; } diff --git a/tools/libxc/xc_sr_restore_x86_pv.c b/tools/libxc/xc_sr_restore_x86_pv.c index c0598af8b7..0ec506632a 100644 --- a/tools/libxc/xc_sr_restore_x86_pv.c +++ b/tools/libxc/xc_sr_restore_x86_pv.c @@ -236,7 +236,7 @@ static int process_vcpu_basic(struct xc_sr_context *ctx, unsigned int vcpuid) { xc_interface *xch = ctx->xch; - vcpu_guest_context_any_t *vcpu = ctx->x86_pv.restore.vcpus[vcpuid].basic; + vcpu_guest_context_any_t *vcpu = ctx->x86_pv.restore.vcpus[vcpuid].basic.ptr; xen_pfn_t pfn, mfn; unsigned int i, gdt_count; int rc = -1; @@ -380,7 +380,7 @@ static int process_vcpu_extended(struct xc_sr_context *ctx, domctl.cmd = XEN_DOMCTL_set_ext_vcpucontext; domctl.domain = ctx->domid; - memcpy(&domctl.u.ext_vcpucontext, vcpu->extd, vcpu->extdsz); + memcpy(&domctl.u.ext_vcpucontext, vcpu->extd.ptr, vcpu->extd.size); if ( xc_domctl(xch, &domctl) != 0 ) { @@ -404,21 +404,21 @@ static int process_vcpu_xsave(struct xc_sr_context *ctx, DECLARE_DOMCTL; DECLARE_HYPERCALL_BUFFER(void, buffer); - buffer = xc_hypercall_buffer_alloc(xch, buffer, vcpu->xsavesz); + buffer = xc_hypercall_buffer_alloc(xch, buffer, vcpu->xsave.size); if ( !buffer ) { ERROR("Unable to allocate %zu bytes for xsave hypercall buffer", - vcpu->xsavesz); + vcpu->xsave.size); return -1; } domctl.cmd = XEN_DOMCTL_setvcpuextstate; domctl.domain = ctx->domid; domctl.u.vcpuextstate.vcpu = vcpuid; - domctl.u.vcpuextstate.size = vcpu->xsavesz; + domctl.u.vcpuextstate.size = vcpu->xsave.size; set_xen_guest_handle(domctl.u.vcpuextstate.buffer, buffer); - memcpy(buffer, vcpu->xsave, vcpu->xsavesz); + memcpy(buffer, vcpu->xsave.ptr, vcpu->xsave.size); rc = xc_domctl(xch, &domctl); if ( rc ) @@ -442,21 +442,21 @@ static int process_vcpu_msrs(struct xc_sr_context *ctx, DECLARE_DOMCTL; DECLARE_HYPERCALL_BUFFER(void, buffer); - buffer = xc_hypercall_buffer_alloc(xch, buffer, vcpu->msrsz); + buffer = xc_hypercall_buffer_alloc(xch, buffer, vcpu->msr.size); if ( !buffer ) { ERROR("Unable to allocate %zu bytes for msr hypercall buffer", - vcpu->msrsz); + vcpu->msr.size); return -1; } domctl.cmd = XEN_DOMCTL_set_vcpu_msrs; domctl.domain = ctx->domid; domctl.u.vcpu_msrs.vcpu = vcpuid; - domctl.u.vcpu_msrs.msr_count = vcpu->msrsz / sizeof(xen_domctl_vcpu_msr_t); + domctl.u.vcpu_msrs.msr_count = vcpu->msr.size / sizeof(xen_domctl_vcpu_msr_t); set_xen_guest_handle(domctl.u.vcpu_msrs.msrs, buffer); - memcpy(buffer, vcpu->msr, vcpu->msrsz); + memcpy(buffer, vcpu->msr.ptr, vcpu->msr.size); rc = xc_domctl(xch, &domctl); if ( rc ) @@ -481,7 +481,7 @@ static int update_vcpu_context(struct xc_sr_context *ctx) { vcpu = &ctx->x86_pv.restore.vcpus[i]; - if ( vcpu->basic ) + if ( vcpu->basic.ptr ) { rc = process_vcpu_basic(ctx, i); if ( rc ) @@ -493,21 +493,21 @@ static int update_vcpu_context(struct xc_sr_context *ctx) return -1; } - if ( vcpu->extd ) + if ( vcpu->extd.ptr ) { rc = process_vcpu_extended(ctx, i); if ( rc ) return rc; } - if ( vcpu->xsave ) + if ( vcpu->xsave.ptr ) { rc = process_vcpu_xsave(ctx, i); if ( rc ) return rc; } - if ( vcpu->msr ) + if ( vcpu->msr.ptr ) { rc = process_vcpu_msrs(ctx, i); if ( rc ) @@ -738,7 +738,7 @@ static int handle_x86_pv_vcpu_blob(struct xc_sr_context *ctx, struct xc_sr_x86_pv_restore_vcpu *vcpu; const char *rec_name; size_t blobsz; - void *blob; + struct xc_sr_blob *blob; int rc = -1; switch ( rec->type ) @@ -812,6 +812,7 @@ static int handle_x86_pv_vcpu_blob(struct xc_sr_context *ctx, rec_name, sizeof(*vhdr) + vcpusz, rec->length); goto out; } + blob = &vcpu->basic; break; } @@ -822,6 +823,7 @@ static int handle_x86_pv_vcpu_blob(struct xc_sr_context *ctx, rec_name, sizeof(*vhdr) + 128, rec->length); goto out; } + blob = &vcpu->extd; break; case REC_TYPE_X86_PV_VCPU_XSAVE: @@ -831,6 +833,7 @@ static int handle_x86_pv_vcpu_blob(struct xc_sr_context *ctx, rec_name, sizeof(*vhdr) + 128, rec->length); goto out; } + blob = &vcpu->xsave; break; case REC_TYPE_X86_PV_VCPU_MSRS: @@ -840,34 +843,14 @@ static int handle_x86_pv_vcpu_blob(struct xc_sr_context *ctx, rec_name, blobsz, sizeof(xen_domctl_vcpu_msr_t)); goto out; } + blob = &vcpu->msr; break; } - /* Allocate memory. */ - blob = malloc(blobsz); - if ( !blob ) - { + rc = update_blob(blob, vhdr->context, blobsz); + if ( rc ) ERROR("Unable to allocate %zu bytes for vcpu%u %s blob", blobsz, vhdr->vcpu_id, rec_name); - goto out; - } - - memcpy(blob, &vhdr->context, blobsz); - - /* Stash sideways for later. */ - switch ( rec->type ) - { -#define RECSTORE(x, y) case REC_TYPE_X86_PV_ ## x: \ - free(y); (y) = blob; (y ## sz) = blobsz; break - - RECSTORE(VCPU_BASIC, vcpu->basic); - RECSTORE(VCPU_EXTENDED, vcpu->extd); - RECSTORE(VCPU_XSAVE, vcpu->xsave); - RECSTORE(VCPU_MSRS, vcpu->msr); -#undef RECSTORE - } - - rc = 0; out: return rc; @@ -1159,10 +1142,10 @@ static int x86_pv_cleanup(struct xc_sr_context *ctx) struct xc_sr_x86_pv_restore_vcpu *vcpu = &ctx->x86_pv.restore.vcpus[i]; - free(vcpu->basic); - free(vcpu->extd); - free(vcpu->xsave); - free(vcpu->msr); + free(vcpu->basic.ptr); + free(vcpu->extd.ptr); + free(vcpu->xsave.ptr); + free(vcpu->msr.ptr); } free(ctx->x86_pv.restore.vcpus); From patchwork Tue Dec 24 15:19:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11309513 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A37166C1 for ; Tue, 24 Dec 2019 15:20:49 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 73B6A206D3 for ; Tue, 24 Dec 2019 15:20:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="H0As9JV8" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 73B6A206D3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlyP-0000Do-Og; Tue, 24 Dec 2019 15:19:49 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlyO-0000DP-2r for xen-devel@lists.xenproject.org; Tue, 24 Dec 2019 15:19:48 +0000 X-Inumbo-ID: ccc7aac7-2660-11ea-97e5-12813bfff9fa Received: from esa5.hc3370-68.iphmx.com (unknown [216.71.155.168]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id ccc7aac7-2660-11ea-97e5-12813bfff9fa; Tue, 24 Dec 2019 15:19:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1577200778; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=DS7TGPbdI6Ja+UTk1N5gZTJcM0lO8dXhUM0YMqhj2aw=; b=H0As9JV8qOTq4FjsavGUIoQfKouz6XaazE5ZneY6USBcH3G+w3p1+8c7 P0BmbJG1dZnYl5hZhDjnrsrTXrwQ88m2Hl4PtOzFgQo6AS3qw7oo64ZWa QRAKAQQ05EUDTOjt12miy1Cbt4dBRTyxLkL+9dzIx+/RROEZY8D3QZ/Z/ c=; Authentication-Results: esa5.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa5.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: qITykmmPSrYxJ1UVeKOFXXQnxV4iBtaACOTvUr4cavWkIWSjGaMjzHSXF50tgdURjxyOcmLXxV ihGnPIheZKLlUI2fgsZuy11yRCR4GsVBTEJiNfQhmAP+wcoV3Qw0U77ciCo4Lij/X6hvHuWtGO VbyvmIywaRZvK+7kwG5Leg/s7Jmj0txfHOr70gfHTIuobHhF9I4nYy+5pMbqLIeNMsF1DIkWd5 VE9gLEBS2G1nxVzHSaMGidGQcDA2cPZ9PzikFh5KhO0H+OvPkGweBpfAH2K2UH+rGsYhjqlT2g j8o= X-SBRS: 2.7 X-MesageID: 10482747 X-Ironport-Server: esa5.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,351,1571716800"; d="scan'208";a="10482747" From: Andrew Cooper To: Xen-devel Date: Tue, 24 Dec 2019 15:19:23 +0000 Message-ID: <20191224151932.6304-4-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20191224151932.6304-1-andrew.cooper3@citrix.com> References: <20191224151932.6304-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH 03/12] libxc/migration: Rationalise the 'checkpointed' field to 'stream_type' X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Ian Jackson Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Originally, 'checkpointed' was a boolean signalling the difference between a plain and a Remus stream. COLO was added later, but several bits of code retained boolean-style logic. While correct, it is confusing to follow. Additionally, XC_MIG_STREAM_NONE means "no checkpoints" but reads as "no stream". Consolidate all the logic on the term 'stream_type', and rename STREAM_NONE to STREAM_PLAIN. Re-position the stream_type variable so it isn't duplicated in both the save and restore unions. No functional change. Signed-off-by: Andrew Cooper Acked-by: Ian Jackson --- CC: Ian Jackson CC: Wei Liu --- tools/libxc/include/xenguest.h | 15 +++++++------- tools/libxc/xc_nomigrate.c | 4 ++-- tools/libxc/xc_sr_common.h | 9 +++------ tools/libxc/xc_sr_restore.c | 33 +++++++++++++++++++------------ tools/libxc/xc_sr_save.c | 44 ++++++++++++++++++++++++----------------- tools/libxl/libxl_save_helper.c | 4 ++-- 6 files changed, 61 insertions(+), 48 deletions(-) diff --git a/tools/libxc/include/xenguest.h b/tools/libxc/include/xenguest.h index b4b2e19619..9ba09af743 100644 --- a/tools/libxc/include/xenguest.h +++ b/tools/libxc/include/xenguest.h @@ -115,11 +115,12 @@ struct save_callbacks { void* data; }; +/* Type of stream. Plain, or using a continuous replication protocol? */ typedef enum { - XC_MIG_STREAM_NONE, /* plain stream */ - XC_MIG_STREAM_REMUS, - XC_MIG_STREAM_COLO, -} xc_migration_stream_t; + XC_STREAM_PLAIN, + XC_STREAM_REMUS, + XC_STREAM_COLO, +} xc_stream_type_t; /** * This function will save a running domain. @@ -127,14 +128,14 @@ typedef enum { * @parm xch a handle to an open hypervisor interface * @parm fd the file descriptor to save a domain to * @parm dom the id of the domain - * @param stream_type XC_MIG_STREAM_NONE if the far end of the stream + * @param stream_type XC_STREAM_PLAIN if the far end of the stream * doesn't use checkpointing * @return 0 on success, -1 on failure */ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t flags /* XCFLAGS_xxx */, struct save_callbacks* callbacks, int hvm, - xc_migration_stream_t stream_type, int recv_fd); + xc_stream_type_t stream_type, int recv_fd); /* callbacks provided by xc_domain_restore */ struct restore_callbacks { @@ -198,7 +199,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, uint32_t store_domid, unsigned int console_evtchn, unsigned long *console_mfn, uint32_t console_domid, unsigned int hvm, unsigned int pae, - xc_migration_stream_t stream_type, + xc_stream_type_t stream_type, struct restore_callbacks *callbacks, int send_back_fd); /** diff --git a/tools/libxc/xc_nomigrate.c b/tools/libxc/xc_nomigrate.c index 6d6169d5ad..3099e3278c 100644 --- a/tools/libxc/xc_nomigrate.c +++ b/tools/libxc/xc_nomigrate.c @@ -22,7 +22,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t flags, struct save_callbacks* callbacks, int hvm, - xc_migration_stream_t stream_type, int recv_fd) + xc_stream_type_t stream_type, int recv_fd) { errno = ENOSYS; return -1; @@ -33,7 +33,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, uint32_t store_domid, unsigned int console_evtchn, unsigned long *console_mfn, uint32_t console_domid, unsigned int hvm, unsigned int pae, - xc_migration_stream_t stream_type, + xc_stream_type_t stream_type, struct restore_callbacks *callbacks, int send_back_fd) { errno = ENOSYS; diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h index 19b053911f..4db63a63b2 100644 --- a/tools/libxc/xc_sr_common.h +++ b/tools/libxc/xc_sr_common.h @@ -205,6 +205,9 @@ struct xc_sr_context uint32_t domid; int fd; + /* Plain VM, or checkpoints over time. */ + xc_stream_type_t stream_type; + xc_dominfo_t dominfo; union /* Common save or restore data. */ @@ -219,9 +222,6 @@ struct xc_sr_context /* Live migrate vs non live suspend. */ bool live; - /* Plain VM, or checkpoints over time. */ - int checkpointed; - /* Further debugging information in the stream. */ bool debug; @@ -252,9 +252,6 @@ struct xc_sr_context uint32_t guest_type; uint32_t guest_page_size; - /* Plain VM, or checkpoints over time. */ - int checkpointed; - /* Currently buffering records between a checkpoint */ bool buffer_all_records; diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c index 98f3fe4098..7872b71ab5 100644 --- a/tools/libxc/xc_sr_restore.c +++ b/tools/libxc/xc_sr_restore.c @@ -511,7 +511,7 @@ static int handle_checkpoint(struct xc_sr_context *ctx) int rc = 0, ret; unsigned int i; - if ( !ctx->restore.checkpointed ) + if ( ctx->stream_type == XC_STREAM_PLAIN ) { ERROR("Found checkpoint in non-checkpointed stream"); rc = -1; @@ -553,7 +553,7 @@ static int handle_checkpoint(struct xc_sr_context *ctx) else ctx->restore.buffer_all_records = true; - if ( ctx->restore.checkpointed == XC_MIG_STREAM_COLO ) + if ( ctx->stream_type == XC_STREAM_COLO ) { #define HANDLE_CALLBACK_RETURN_VALUE(ret) \ do { \ @@ -672,7 +672,7 @@ static int setup(struct xc_sr_context *ctx) DECLARE_HYPERCALL_BUFFER_SHADOW(unsigned long, dirty_bitmap, &ctx->restore.dirty_bitmap_hbuf); - if ( ctx->restore.checkpointed == XC_MIG_STREAM_COLO ) + if ( ctx->stream_type == XC_STREAM_COLO ) { dirty_bitmap = xc_hypercall_buffer_alloc_pages( xch, dirty_bitmap, NRPAGES(bitmap_size(ctx->restore.p2m_size))); @@ -723,7 +723,7 @@ static void cleanup(struct xc_sr_context *ctx) for ( i = 0; i < ctx->restore.buffered_rec_num; i++ ) free(ctx->restore.buffered_records[i].data); - if ( ctx->restore.checkpointed == XC_MIG_STREAM_COLO ) + if ( ctx->stream_type == XC_STREAM_COLO ) xc_hypercall_buffer_free_pages( xch, dirty_bitmap, NRPAGES(bitmap_size(ctx->restore.p2m_size))); @@ -793,7 +793,7 @@ static int restore(struct xc_sr_context *ctx) } while ( rec.type != REC_TYPE_END ); remus_failover: - if ( ctx->restore.checkpointed == XC_MIG_STREAM_COLO ) + if ( ctx->stream_type == XC_STREAM_COLO ) { /* With COLO, we have already called stream_complete */ rc = 0; @@ -834,13 +834,14 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, uint32_t store_domid, unsigned int console_evtchn, unsigned long *console_gfn, uint32_t console_domid, unsigned int hvm, unsigned int pae, - xc_migration_stream_t stream_type, + xc_stream_type_t stream_type, struct restore_callbacks *callbacks, int send_back_fd) { xen_pfn_t nr_pfns; struct xc_sr_context ctx = { .xch = xch, .fd = io_fd, + .stream_type = stream_type, }; /* GCC 4.4 (of CentOS 6.x vintage) can' t initialise anonymous unions. */ @@ -848,21 +849,27 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, ctx.restore.console_domid = console_domid; ctx.restore.xenstore_evtchn = store_evtchn; ctx.restore.xenstore_domid = store_domid; - ctx.restore.checkpointed = stream_type; ctx.restore.callbacks = callbacks; ctx.restore.send_back_fd = send_back_fd; - /* Sanity checks for callbacks. */ - if ( stream_type ) - assert(callbacks->checkpoint); - - if ( ctx.restore.checkpointed == XC_MIG_STREAM_COLO ) + /* Sanity check stream_type-related parameters */ + switch ( stream_type ) { - /* this is COLO restore */ + case XC_STREAM_COLO: assert(callbacks->suspend && callbacks->postcopy && callbacks->wait_checkpoint && callbacks->restore_results); + /* Fallthrough */ + case XC_STREAM_REMUS: + assert(callbacks->checkpoint); + /* Fallthrough */ + case XC_STREAM_PLAIN: + break; + + default: + assert(!"Bad stream_type"); + break; } DPRINTF("fd %d, dom %u, hvm %u, pae %u, stream_type %d", diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c index 9764aa743f..5467965b08 100644 --- a/tools/libxc/xc_sr_save.c +++ b/tools/libxc/xc_sr_save.c @@ -658,7 +658,7 @@ static int suspend_and_send_dirty(struct xc_sr_context *ctx) bitmap_or(dirty_bitmap, ctx->save.deferred_pages, ctx->save.p2m_size); - if ( !ctx->save.live && ctx->save.checkpointed == XC_MIG_STREAM_COLO ) + if ( !ctx->save.live && ctx->stream_type == XC_STREAM_COLO ) { rc = colo_merge_secondary_dirty_bitmap(ctx); if ( rc ) @@ -735,7 +735,7 @@ static int send_domain_memory_live(struct xc_sr_context *ctx) if ( rc ) goto out; - if ( ctx->save.debug && ctx->save.checkpointed != XC_MIG_STREAM_NONE ) + if ( ctx->save.debug && ctx->stream_type != XC_STREAM_PLAIN ) { rc = verify_frames(ctx); if ( rc ) @@ -861,7 +861,7 @@ static int save(struct xc_sr_context *ctx, uint16_t guest_type) if ( ctx->save.live ) rc = send_domain_memory_live(ctx); - else if ( ctx->save.checkpointed != XC_MIG_STREAM_NONE ) + else if ( ctx->stream_type != XC_STREAM_PLAIN ) rc = send_domain_memory_checkpointed(ctx); else rc = send_domain_memory_nonlive(ctx); @@ -881,7 +881,7 @@ static int save(struct xc_sr_context *ctx, uint16_t guest_type) if ( rc ) goto err; - if ( ctx->save.checkpointed != XC_MIG_STREAM_NONE ) + if ( ctx->stream_type != XC_STREAM_PLAIN ) { /* * We have now completed the initial live portion of the checkpoint @@ -894,7 +894,7 @@ static int save(struct xc_sr_context *ctx, uint16_t guest_type) if ( rc ) goto err; - if ( ctx->save.checkpointed == XC_MIG_STREAM_COLO ) + if ( ctx->stream_type == XC_STREAM_COLO ) { rc = ctx->save.callbacks->checkpoint(ctx->save.callbacks->data); if ( !rc ) @@ -908,14 +908,14 @@ static int save(struct xc_sr_context *ctx, uint16_t guest_type) if ( rc <= 0 ) goto err; - if ( ctx->save.checkpointed == XC_MIG_STREAM_COLO ) + if ( ctx->stream_type == XC_STREAM_COLO ) { rc = ctx->save.callbacks->wait_checkpoint( ctx->save.callbacks->data); if ( rc <= 0 ) goto err; } - else if ( ctx->save.checkpointed == XC_MIG_STREAM_REMUS ) + else if ( ctx->stream_type == XC_STREAM_REMUS ) { rc = ctx->save.callbacks->checkpoint(ctx->save.callbacks->data); if ( rc <= 0 ) @@ -928,7 +928,7 @@ static int save(struct xc_sr_context *ctx, uint16_t guest_type) goto err; } } - } while ( ctx->save.checkpointed != XC_MIG_STREAM_NONE ); + } while ( ctx->stream_type != XC_STREAM_PLAIN ); xc_report_progress_single(xch, "End of stream"); @@ -958,32 +958,40 @@ static int save(struct xc_sr_context *ctx, uint16_t guest_type) int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t flags, struct save_callbacks *callbacks, - int hvm, xc_migration_stream_t stream_type, int recv_fd) + int hvm, xc_stream_type_t stream_type, int recv_fd) { struct xc_sr_context ctx = { .xch = xch, .fd = io_fd, + .stream_type = stream_type, }; /* GCC 4.4 (of CentOS 6.x vintage) can' t initialise anonymous unions. */ ctx.save.callbacks = callbacks; ctx.save.live = !!(flags & XCFLAGS_LIVE); ctx.save.debug = !!(flags & XCFLAGS_DEBUG); - ctx.save.checkpointed = stream_type; ctx.save.recv_fd = recv_fd; - /* If altering migration_stream update this assert too. */ - assert(stream_type == XC_MIG_STREAM_NONE || - stream_type == XC_MIG_STREAM_REMUS || - stream_type == XC_MIG_STREAM_COLO); + /* Sanity check stream_type-related parameters */ + switch ( stream_type ) + { + case XC_STREAM_COLO: + assert(callbacks->wait_checkpoint); + /* Fallthrough */ + case XC_STREAM_REMUS: + assert(callbacks->checkpoint && callbacks->postcopy); + /* Fallthrough */ + case XC_STREAM_PLAIN: + break; + + default: + assert(!"Bad stream_type"); + break; + } /* Sanity checks for callbacks. */ if ( hvm ) assert(callbacks->switch_qemu_logdirty); - if ( ctx.save.checkpointed ) - assert(callbacks->checkpoint && callbacks->postcopy); - if ( ctx.save.checkpointed == XC_MIG_STREAM_COLO ) - assert(callbacks->wait_checkpoint); DPRINTF("fd %d, dom %u, flags %u, hvm %d", io_fd, dom, flags, hvm); diff --git a/tools/libxl/libxl_save_helper.c b/tools/libxl/libxl_save_helper.c index 38089a002d..398df00dd6 100644 --- a/tools/libxl/libxl_save_helper.c +++ b/tools/libxl/libxl_save_helper.c @@ -254,7 +254,7 @@ int main(int argc, char **argv) uint32_t flags = strtoul(NEXTARG,0,10); int hvm = atoi(NEXTARG); unsigned cbflags = strtoul(NEXTARG,0,10); - xc_migration_stream_t stream_type = strtoul(NEXTARG,0,10); + xc_stream_type_t stream_type = strtoul(NEXTARG,0,10); assert(!*++argv); helper_setcallbacks_save(&helper_save_callbacks, cbflags); @@ -278,7 +278,7 @@ int main(int argc, char **argv) unsigned int hvm = strtoul(NEXTARG,0,10); unsigned int pae = strtoul(NEXTARG,0,10); unsigned cbflags = strtoul(NEXTARG,0,10); - xc_migration_stream_t stream_type = strtoul(NEXTARG,0,10); + xc_stream_type_t stream_type = strtoul(NEXTARG,0,10); assert(!*++argv); helper_setcallbacks_restore(&helper_restore_callbacks, cbflags); From patchwork Tue Dec 24 15:19:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11309527 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3897313A4 for ; Tue, 24 Dec 2019 15:21:25 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F2B91206D3 for ; Tue, 24 Dec 2019 15:21:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="PfxnLLAj" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F2B91206D3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlyk-00017Z-4l; Tue, 24 Dec 2019 15:20:10 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlyi-000129-3p for xen-devel@lists.xenproject.org; Tue, 24 Dec 2019 15:20:08 +0000 X-Inumbo-ID: cf4d6646-2660-11ea-97e5-12813bfff9fa Received: from esa5.hc3370-68.iphmx.com (unknown [216.71.155.168]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id cf4d6646-2660-11ea-97e5-12813bfff9fa; Tue, 24 Dec 2019 15:19:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1577200782; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=zj0yYgsh25BPJFzuvlT29Uyi2go0KkohGMF7jvuL9iY=; b=PfxnLLAj43FfFRBLYUlfB+jBxa4n77dV0VRksCjW2HCzKHuBig5B3g2a bxPyPd1z82dn1xWSm37dZp4whxXi1Hb+nWWEIb7RFz99Xog35QplGygYR lFGC+eMY6cU9+yzHIpa0vR2TPmP12WVumJvd7Voq2++R2KJeIdv9ECyYL w=; Authentication-Results: esa5.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa5.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: Ru6WlGxjao52/3I9af3UVbf/pzm2/fRD662Kisjlivtqxhrbj97lyzjp0jKK3BR3kLRgeBglam jMWh/dSE99S0B200PwtYg7c/zZR+m+l/tIs3Ec89JnA807x6wuAiVEtmuE+WSJmMjTf8FpEse+ rzCti40z0EMEmFkHASrjVKLEcBAXZ1tpvgsoQrEh5DIVq0vUUYA8hHrr/6nZZIhs/fR678LmCS jUk9PqMHR850E9SymREG6jYg2ty6mTWrusMQ7A2i6DctOyZ9JDd95SEgUtm1lsXktInZTOh0q0 cao= X-SBRS: 2.7 X-MesageID: 10482756 X-Ironport-Server: esa5.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,351,1571716800"; d="scan'208";a="10482756" From: Andrew Cooper To: Xen-devel Date: Tue, 24 Dec 2019 15:19:24 +0000 Message-ID: <20191224151932.6304-5-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20191224151932.6304-1-andrew.cooper3@citrix.com> References: <20191224151932.6304-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH 04/12] libxc/migration: Adjust layout of struct xc_sr_context X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Ian Jackson Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" We are shortly going to want to introduce some common x86 fields, so having x86_pv and x86_hvm as the top level objects is a problem. Insert a surrounding struct x86 and drop the x86 prefix from the pv/hvm objects. No functional change. Signed-off-by: Andrew Cooper Acked-by: Ian Jackson --- CC: Ian Jackson CC: Wei Liu This is much more easily reviewed with git-diff's --ignore-all-space option, which highlights the relevant struct difference. diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h index 4963b30c4b..2d02e80ee3 100644 --- a/tools/libxc/xc_sr_common.h +++ b/tools/libxc/xc_sr_common.h @@ -281,6 +281,8 @@ struct xc_sr_context union /* Guest-arch specific data. */ { + struct /* x86 */ + { struct /* x86 PV guest. */ { /* 4 or 8; 32 or 64 bit domain */ @@ -332,7 +334,7 @@ struct xc_sr_context unsigned int nr_vcpus; } restore; }; - } x86_pv; + } pv; struct /* x86 HVM guest. */ { @@ -351,7 +353,9 @@ struct xc_sr_context struct xc_sr_blob context; } restore; }; - } x86_hvm; + } hvm; + + } x86; }; }; --- tools/libxc/xc_sr_common.h | 132 ++++++++++----------- tools/libxc/xc_sr_common_x86_pv.c | 50 ++++---- tools/libxc/xc_sr_common_x86_pv.h | 4 +- tools/libxc/xc_sr_restore_x86_hvm.c | 12 +- tools/libxc/xc_sr_restore_x86_pv.c | 224 ++++++++++++++++++------------------ tools/libxc/xc_sr_save_x86_hvm.c | 4 +- tools/libxc/xc_sr_save_x86_pv.c | 158 ++++++++++++------------- 7 files changed, 294 insertions(+), 290 deletions(-) diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h index 4db63a63b2..0289c01e13 100644 --- a/tools/libxc/xc_sr_common.h +++ b/tools/libxc/xc_sr_common.h @@ -287,77 +287,81 @@ struct xc_sr_context union /* Guest-arch specific data. */ { - struct /* x86 PV guest. */ + struct /* x86 */ { - /* 4 or 8; 32 or 64 bit domain */ - unsigned int width; - /* 3 or 4 pagetable levels */ - unsigned int levels; - - /* Maximum Xen frame */ - xen_pfn_t max_mfn; - /* Read-only machine to phys map */ - xen_pfn_t *m2p; - /* first mfn of the compat m2p (Only needed for 32bit PV guests) */ - xen_pfn_t compat_m2p_mfn0; - /* Number of m2p frames mapped */ - unsigned long nr_m2p_frames; - - /* Maximum guest frame */ - xen_pfn_t max_pfn; - - /* Number of frames making up the p2m */ - unsigned int p2m_frames; - /* Guest's phys to machine map. Mapped read-only (save) or - * allocated locally (restore). Uses guest unsigned longs. */ - void *p2m; - /* The guest pfns containing the p2m leaves */ - xen_pfn_t *p2m_pfns; - - /* Read-only mapping of guests shared info page */ - shared_info_any_t *shinfo; - - /* p2m generation count for verifying validity of local p2m. */ - uint64_t p2m_generation; - - union + struct /* x86 PV guest. */ { - struct + /* 4 or 8; 32 or 64 bit domain */ + unsigned int width; + /* 3 or 4 pagetable levels */ + unsigned int levels; + + /* Maximum Xen frame */ + xen_pfn_t max_mfn; + /* Read-only machine to phys map */ + xen_pfn_t *m2p; + /* first mfn of the compat m2p (Only needed for 32bit PV guests) */ + xen_pfn_t compat_m2p_mfn0; + /* Number of m2p frames mapped */ + unsigned long nr_m2p_frames; + + /* Maximum guest frame */ + xen_pfn_t max_pfn; + + /* Number of frames making up the p2m */ + unsigned int p2m_frames; + /* Guest's phys to machine map. Mapped read-only (save) or + * allocated locally (restore). Uses guest unsigned longs. */ + void *p2m; + /* The guest pfns containing the p2m leaves */ + xen_pfn_t *p2m_pfns; + + /* Read-only mapping of guests shared info page */ + shared_info_any_t *shinfo; + + /* p2m generation count for verifying validity of local p2m. */ + uint64_t p2m_generation; + + union { - /* State machine for the order of received records. */ - bool seen_pv_info; - - /* Types for each page (bounded by max_pfn). */ - uint32_t *pfn_types; - - /* x86 PV per-vcpu storage structure for blobs. */ - struct xc_sr_x86_pv_restore_vcpu + struct { - struct xc_sr_blob basic, extd, xsave, msr; - } *vcpus; - unsigned int nr_vcpus; - } restore; - }; - } x86_pv; - - struct /* x86 HVM guest. */ - { - union + /* State machine for the order of received records. */ + bool seen_pv_info; + + /* Types for each page (bounded by max_pfn). */ + uint32_t *pfn_types; + + /* x86 PV per-vcpu storage structure for blobs. */ + struct xc_sr_x86_pv_restore_vcpu + { + struct xc_sr_blob basic, extd, xsave, msr; + } *vcpus; + unsigned int nr_vcpus; + } restore; + }; + } pv; + + struct /* x86 HVM guest. */ { - struct + union { - /* Whether qemu enabled logdirty mode, and we should - * disable on cleanup. */ - bool qemu_enabled_logdirty; - } save; + struct + { + /* Whether qemu enabled logdirty mode, and we should + * disable on cleanup. */ + bool qemu_enabled_logdirty; + } save; - struct - { - /* HVM context blob. */ - struct xc_sr_blob context; - } restore; - }; - } x86_hvm; + struct + { + /* HVM context blob. */ + struct xc_sr_blob context; + } restore; + }; + } hvm; + + } x86; }; }; diff --git a/tools/libxc/xc_sr_common_x86_pv.c b/tools/libxc/xc_sr_common_x86_pv.c index ec433fad70..d3d425cb82 100644 --- a/tools/libxc/xc_sr_common_x86_pv.c +++ b/tools/libxc/xc_sr_common_x86_pv.c @@ -4,16 +4,16 @@ xen_pfn_t mfn_to_pfn(struct xc_sr_context *ctx, xen_pfn_t mfn) { - assert(mfn <= ctx->x86_pv.max_mfn); - return ctx->x86_pv.m2p[mfn]; + assert(mfn <= ctx->x86.pv.max_mfn); + return ctx->x86.pv.m2p[mfn]; } bool mfn_in_pseudophysmap(struct xc_sr_context *ctx, xen_pfn_t mfn) { - return ((mfn <= ctx->x86_pv.max_mfn) && - (mfn_to_pfn(ctx, mfn) <= ctx->x86_pv.max_pfn) && - (xc_pfn_to_mfn(mfn_to_pfn(ctx, mfn), ctx->x86_pv.p2m, - ctx->x86_pv.width) == mfn)); + return ((mfn <= ctx->x86.pv.max_mfn) && + (mfn_to_pfn(ctx, mfn) <= ctx->x86.pv.max_pfn) && + (xc_pfn_to_mfn(mfn_to_pfn(ctx, mfn), ctx->x86.pv.p2m, + ctx->x86.pv.width) == mfn)); } void dump_bad_pseudophysmap_entry(struct xc_sr_context *ctx, xen_pfn_t mfn) @@ -21,23 +21,23 @@ void dump_bad_pseudophysmap_entry(struct xc_sr_context *ctx, xen_pfn_t mfn) xc_interface *xch = ctx->xch; xen_pfn_t pfn = ~0UL; - ERROR("mfn %#lx, max %#lx", mfn, ctx->x86_pv.max_mfn); + ERROR("mfn %#lx, max %#lx", mfn, ctx->x86.pv.max_mfn); - if ( (mfn != ~0UL) && (mfn <= ctx->x86_pv.max_mfn) ) + if ( (mfn != ~0UL) && (mfn <= ctx->x86.pv.max_mfn) ) { - pfn = ctx->x86_pv.m2p[mfn]; + pfn = ctx->x86.pv.m2p[mfn]; ERROR(" m2p[%#lx] = %#lx, max_pfn %#lx", - mfn, pfn, ctx->x86_pv.max_pfn); + mfn, pfn, ctx->x86.pv.max_pfn); } - if ( (pfn != ~0UL) && (pfn <= ctx->x86_pv.max_pfn) ) + if ( (pfn != ~0UL) && (pfn <= ctx->x86.pv.max_pfn) ) ERROR(" p2m[%#lx] = %#lx", - pfn, xc_pfn_to_mfn(pfn, ctx->x86_pv.p2m, ctx->x86_pv.width)); + pfn, xc_pfn_to_mfn(pfn, ctx->x86.pv.p2m, ctx->x86.pv.width)); } xen_pfn_t cr3_to_mfn(struct xc_sr_context *ctx, uint64_t cr3) { - if ( ctx->x86_pv.width == 8 ) + if ( ctx->x86.pv.width == 8 ) return cr3 >> 12; else { @@ -53,7 +53,7 @@ uint64_t mfn_to_cr3(struct xc_sr_context *ctx, xen_pfn_t _mfn) { uint64_t mfn = _mfn; - if ( ctx->x86_pv.width == 8 ) + if ( ctx->x86.pv.width == 8 ) return mfn << 12; else { @@ -86,8 +86,8 @@ int x86_pv_domain_info(struct xc_sr_context *ctx) ERROR("Invalid guest width %d. Expected 32 or 64", guest_width * 8); return -1; } - ctx->x86_pv.width = guest_width; - ctx->x86_pv.levels = guest_levels; + ctx->x86.pv.width = guest_width; + ctx->x86.pv.levels = guest_levels; DPRINTF("%d bits, %d levels", guest_width * 8, guest_levels); @@ -108,9 +108,9 @@ int x86_pv_map_m2p(struct xc_sr_context *ctx) goto err; } - ctx->x86_pv.max_mfn = max_page; - m2p_size = M2P_SIZE(ctx->x86_pv.max_mfn); - m2p_chunks = M2P_CHUNKS(ctx->x86_pv.max_mfn); + ctx->x86.pv.max_mfn = max_page; + m2p_size = M2P_SIZE(ctx->x86.pv.max_mfn); + m2p_chunks = M2P_CHUNKS(ctx->x86.pv.max_mfn); extents_start = malloc(m2p_chunks * sizeof(xen_pfn_t)); if ( !extents_start ) @@ -137,27 +137,27 @@ int x86_pv_map_m2p(struct xc_sr_context *ctx) for ( i = 0; i < m2p_chunks; ++i ) entries[i].mfn = extents_start[i]; - ctx->x86_pv.m2p = xc_map_foreign_ranges( + ctx->x86.pv.m2p = xc_map_foreign_ranges( xch, DOMID_XEN, m2p_size, PROT_READ, M2P_CHUNK_SIZE, entries, m2p_chunks); - if ( !ctx->x86_pv.m2p ) + if ( !ctx->x86.pv.m2p ) { PERROR("Failed to mmap() m2p ranges"); goto err; } - ctx->x86_pv.nr_m2p_frames = (M2P_CHUNK_SIZE >> PAGE_SHIFT) * m2p_chunks; + ctx->x86.pv.nr_m2p_frames = (M2P_CHUNK_SIZE >> PAGE_SHIFT) * m2p_chunks; #ifdef __i386__ /* 32 bit toolstacks automatically get the compat m2p */ - ctx->x86_pv.compat_m2p_mfn0 = entries[0].mfn; + ctx->x86.pv.compat_m2p_mfn0 = entries[0].mfn; #else /* 64 bit toolstacks need to ask Xen specially for it */ { struct xen_machphys_mfn_list xmml = { .max_extents = 1, - .extent_start = { &ctx->x86_pv.compat_m2p_mfn0 }, + .extent_start = { &ctx->x86.pv.compat_m2p_mfn0 }, }; rc = do_memory_op(xch, XENMEM_machphys_compat_mfn_list, @@ -173,7 +173,7 @@ int x86_pv_map_m2p(struct xc_sr_context *ctx) /* All Done */ rc = 0; - DPRINTF("max_mfn %#lx", ctx->x86_pv.max_mfn); + DPRINTF("max_mfn %#lx", ctx->x86.pv.max_mfn); err: free(entries); diff --git a/tools/libxc/xc_sr_common_x86_pv.h b/tools/libxc/xc_sr_common_x86_pv.h index f80c75349a..2ed03309af 100644 --- a/tools/libxc/xc_sr_common_x86_pv.h +++ b/tools/libxc/xc_sr_common_x86_pv.h @@ -73,7 +73,7 @@ static inline uint64_t merge_pte(uint64_t pte, xen_pfn_t mfn) /* * Get current domain information. * - * Fills ctx->x86_pv + * Fills ctx->x86.pv * - .width * - .levels * - .fpp @@ -89,7 +89,7 @@ int x86_pv_domain_info(struct xc_sr_context *ctx); /* * Maps the Xen M2P. * - * Fills ctx->x86_pv. + * Fills ctx->x86.pv. * - .max_mfn * - .m2p * diff --git a/tools/libxc/xc_sr_restore_x86_hvm.c b/tools/libxc/xc_sr_restore_x86_hvm.c index fe7be9bde6..3f78248f32 100644 --- a/tools/libxc/xc_sr_restore_x86_hvm.c +++ b/tools/libxc/xc_sr_restore_x86_hvm.c @@ -10,7 +10,7 @@ static int handle_hvm_context(struct xc_sr_context *ctx, struct xc_sr_record *rec) { xc_interface *xch = ctx->xch; - int rc = update_blob(&ctx->x86_hvm.restore.context, rec->data, rec->length); + int rc = update_blob(&ctx->x86.hvm.restore.context, rec->data, rec->length); if ( rc ) ERROR("Unable to allocate %u bytes for hvm context", rec->length); @@ -129,14 +129,14 @@ static int x86_hvm_setup(struct xc_sr_context *ctx) if ( ctx->restore.guest_type != DHDR_TYPE_X86_HVM ) { - ERROR("Unable to restore %s domain into an x86_hvm domain", + ERROR("Unable to restore %s domain into an x86 HVM domain", dhdr_type_to_str(ctx->restore.guest_type)); return -1; } if ( ctx->restore.guest_page_size != PAGE_SIZE ) { - ERROR("Invalid page size %u for x86_hvm domains", + ERROR("Invalid page size %u for x86 HVM domains", ctx->restore.guest_page_size); return -1; } @@ -201,8 +201,8 @@ static int x86_hvm_stream_complete(struct xc_sr_context *ctx) } rc = xc_domain_hvm_setcontext(xch, ctx->domid, - ctx->x86_hvm.restore.context.ptr, - ctx->x86_hvm.restore.context.size); + ctx->x86.hvm.restore.context.ptr, + ctx->x86.hvm.restore.context.size); if ( rc < 0 ) { PERROR("Unable to restore HVM context"); @@ -225,7 +225,7 @@ static int x86_hvm_stream_complete(struct xc_sr_context *ctx) static int x86_hvm_cleanup(struct xc_sr_context *ctx) { - free(ctx->x86_hvm.restore.context.ptr); + free(ctx->x86.hvm.restore.context.ptr); return 0; } diff --git a/tools/libxc/xc_sr_restore_x86_pv.c b/tools/libxc/xc_sr_restore_x86_pv.c index 0ec506632a..8f61a5e8b9 100644 --- a/tools/libxc/xc_sr_restore_x86_pv.c +++ b/tools/libxc/xc_sr_restore_x86_pv.c @@ -4,9 +4,9 @@ static xen_pfn_t pfn_to_mfn(const struct xc_sr_context *ctx, xen_pfn_t pfn) { - assert(pfn <= ctx->x86_pv.max_pfn); + assert(pfn <= ctx->x86.pv.max_pfn); - return xc_pfn_to_mfn(pfn, ctx->x86_pv.p2m, ctx->x86_pv.width); + return xc_pfn_to_mfn(pfn, ctx->x86.pv.p2m, ctx->x86.pv.width); } /* @@ -18,8 +18,8 @@ static xen_pfn_t pfn_to_mfn(const struct xc_sr_context *ctx, xen_pfn_t pfn) static int expand_p2m(struct xc_sr_context *ctx, unsigned long max_pfn) { xc_interface *xch = ctx->xch; - unsigned long old_max = ctx->x86_pv.max_pfn, i; - unsigned int fpp = PAGE_SIZE / ctx->x86_pv.width; + unsigned long old_max = ctx->x86.pv.max_pfn, i; + unsigned int fpp = PAGE_SIZE / ctx->x86.pv.width; unsigned long end_frame = (max_pfn / fpp) + 1; unsigned long old_end_frame = (old_max / fpp) + 1; xen_pfn_t *p2m = NULL, *p2m_pfns = NULL; @@ -28,35 +28,35 @@ static int expand_p2m(struct xc_sr_context *ctx, unsigned long max_pfn) assert(max_pfn > old_max); - p2msz = (max_pfn + 1) * ctx->x86_pv.width; - p2m = realloc(ctx->x86_pv.p2m, p2msz); + p2msz = (max_pfn + 1) * ctx->x86.pv.width; + p2m = realloc(ctx->x86.pv.p2m, p2msz); if ( !p2m ) { ERROR("Failed to (re)alloc %zu bytes for p2m", p2msz); return -1; } - ctx->x86_pv.p2m = p2m; + ctx->x86.pv.p2m = p2m; pfn_typesz = (max_pfn + 1) * sizeof(*pfn_types); - pfn_types = realloc(ctx->x86_pv.restore.pfn_types, pfn_typesz); + pfn_types = realloc(ctx->x86.pv.restore.pfn_types, pfn_typesz); if ( !pfn_types ) { ERROR("Failed to (re)alloc %zu bytes for pfn_types", pfn_typesz); return -1; } - ctx->x86_pv.restore.pfn_types = pfn_types; + ctx->x86.pv.restore.pfn_types = pfn_types; p2m_pfnsz = (end_frame + 1) * sizeof(*p2m_pfns); - p2m_pfns = realloc(ctx->x86_pv.p2m_pfns, p2m_pfnsz); + p2m_pfns = realloc(ctx->x86.pv.p2m_pfns, p2m_pfnsz); if ( !p2m_pfns ) { ERROR("Failed to (re)alloc %zu bytes for p2m frame list", p2m_pfnsz); return -1; } - ctx->x86_pv.p2m_frames = end_frame; - ctx->x86_pv.p2m_pfns = p2m_pfns; + ctx->x86.pv.p2m_frames = end_frame; + ctx->x86.pv.p2m_pfns = p2m_pfns; - ctx->x86_pv.max_pfn = max_pfn; + ctx->x86.pv.max_pfn = max_pfn; for ( i = (old_max ? old_max + 1 : 0); i <= max_pfn; ++i ) { ctx->restore.ops.set_gfn(ctx, i, INVALID_MFN); @@ -64,7 +64,7 @@ static int expand_p2m(struct xc_sr_context *ctx, unsigned long max_pfn) } for ( i = (old_end_frame ? old_end_frame + 1 : 0); i <= end_frame; ++i ) - ctx->x86_pv.p2m_pfns[i] = INVALID_MFN; + ctx->x86.pv.p2m_pfns[i] = INVALID_MFN; DPRINTF("Changed max_pfn from %#lx to %#lx", old_max, max_pfn); return 0; @@ -79,13 +79,13 @@ static int pin_pagetables(struct xc_sr_context *ctx) unsigned long i, nr_pins; struct mmuext_op pin[MAX_PIN_BATCH]; - for ( i = nr_pins = 0; i <= ctx->x86_pv.max_pfn; ++i ) + for ( i = nr_pins = 0; i <= ctx->x86.pv.max_pfn; ++i ) { - if ( (ctx->x86_pv.restore.pfn_types[i] & + if ( (ctx->x86.pv.restore.pfn_types[i] & XEN_DOMCTL_PFINFO_LPINTAB) == 0 ) continue; - switch ( (ctx->x86_pv.restore.pfn_types[i] & + switch ( (ctx->x86.pv.restore.pfn_types[i] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK) ) { case XEN_DOMCTL_PFINFO_L1TAB: @@ -138,18 +138,18 @@ static int process_start_info(struct xc_sr_context *ctx, start_info_any_t *guest_start_info = NULL; int rc = -1; - pfn = GET_FIELD(vcpu, user_regs.edx, ctx->x86_pv.width); + pfn = GET_FIELD(vcpu, user_regs.edx, ctx->x86.pv.width); - if ( pfn > ctx->x86_pv.max_pfn ) + if ( pfn > ctx->x86.pv.max_pfn ) { ERROR("Start Info pfn %#lx out of range", pfn); goto err; } - if ( ctx->x86_pv.restore.pfn_types[pfn] != XEN_DOMCTL_PFINFO_NOTAB ) + if ( ctx->x86.pv.restore.pfn_types[pfn] != XEN_DOMCTL_PFINFO_NOTAB ) { ERROR("Start Info pfn %#lx has bad type %u", pfn, - (ctx->x86_pv.restore.pfn_types[pfn] >> + (ctx->x86.pv.restore.pfn_types[pfn] >> XEN_DOMCTL_PFINFO_LTAB_SHIFT)); goto err; } @@ -162,7 +162,7 @@ static int process_start_info(struct xc_sr_context *ctx, goto err; } - SET_FIELD(vcpu, user_regs.edx, mfn, ctx->x86_pv.width); + SET_FIELD(vcpu, user_regs.edx, mfn, ctx->x86.pv.width); guest_start_info = xc_map_foreign_range( xch, ctx->domid, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn); if ( !guest_start_info ) @@ -172,8 +172,8 @@ static int process_start_info(struct xc_sr_context *ctx, } /* Deal with xenstore stuff */ - pfn = GET_FIELD(guest_start_info, store_mfn, ctx->x86_pv.width); - if ( pfn > ctx->x86_pv.max_pfn ) + pfn = GET_FIELD(guest_start_info, store_mfn, ctx->x86.pv.width); + if ( pfn > ctx->x86.pv.max_pfn ) { ERROR("XenStore pfn %#lx out of range", pfn); goto err; @@ -188,13 +188,13 @@ static int process_start_info(struct xc_sr_context *ctx, } ctx->restore.xenstore_gfn = mfn; - SET_FIELD(guest_start_info, store_mfn, mfn, ctx->x86_pv.width); + SET_FIELD(guest_start_info, store_mfn, mfn, ctx->x86.pv.width); SET_FIELD(guest_start_info, store_evtchn, - ctx->restore.xenstore_evtchn, ctx->x86_pv.width); + ctx->restore.xenstore_evtchn, ctx->x86.pv.width); /* Deal with console stuff */ - pfn = GET_FIELD(guest_start_info, console.domU.mfn, ctx->x86_pv.width); - if ( pfn > ctx->x86_pv.max_pfn ) + pfn = GET_FIELD(guest_start_info, console.domU.mfn, ctx->x86.pv.width); + if ( pfn > ctx->x86.pv.max_pfn ) { ERROR("Console pfn %#lx out of range", pfn); goto err; @@ -209,16 +209,16 @@ static int process_start_info(struct xc_sr_context *ctx, } ctx->restore.console_gfn = mfn; - SET_FIELD(guest_start_info, console.domU.mfn, mfn, ctx->x86_pv.width); + SET_FIELD(guest_start_info, console.domU.mfn, mfn, ctx->x86.pv.width); SET_FIELD(guest_start_info, console.domU.evtchn, - ctx->restore.console_evtchn, ctx->x86_pv.width); + ctx->restore.console_evtchn, ctx->x86.pv.width); /* Set other information */ SET_FIELD(guest_start_info, nr_pages, - ctx->x86_pv.max_pfn + 1, ctx->x86_pv.width); + ctx->x86.pv.max_pfn + 1, ctx->x86.pv.width); SET_FIELD(guest_start_info, shared_info, - ctx->dominfo.shared_info_frame << PAGE_SHIFT, ctx->x86_pv.width); - SET_FIELD(guest_start_info, flags, 0, ctx->x86_pv.width); + ctx->dominfo.shared_info_frame << PAGE_SHIFT, ctx->x86.pv.width); + SET_FIELD(guest_start_info, flags, 0, ctx->x86.pv.width); rc = 0; @@ -236,7 +236,7 @@ static int process_vcpu_basic(struct xc_sr_context *ctx, unsigned int vcpuid) { xc_interface *xch = ctx->xch; - vcpu_guest_context_any_t *vcpu = ctx->x86_pv.restore.vcpus[vcpuid].basic.ptr; + vcpu_guest_context_any_t *vcpu = ctx->x86.pv.restore.vcpus[vcpuid].basic.ptr; xen_pfn_t pfn, mfn; unsigned int i, gdt_count; int rc = -1; @@ -251,10 +251,10 @@ static int process_vcpu_basic(struct xc_sr_context *ctx, } SET_FIELD(vcpu, flags, - GET_FIELD(vcpu, flags, ctx->x86_pv.width) | VGCF_online, - ctx->x86_pv.width); + GET_FIELD(vcpu, flags, ctx->x86.pv.width) | VGCF_online, + ctx->x86.pv.width); - gdt_count = GET_FIELD(vcpu, gdt_ents, ctx->x86_pv.width); + gdt_count = GET_FIELD(vcpu, gdt_ents, ctx->x86.pv.width); if ( gdt_count > FIRST_RESERVED_GDT_ENTRY ) { ERROR("GDT entry count (%u) out of range (max %u)", @@ -267,17 +267,17 @@ static int process_vcpu_basic(struct xc_sr_context *ctx, /* Convert GDT frames to mfns. */ for ( i = 0; i < gdt_count; ++i ) { - pfn = GET_FIELD(vcpu, gdt_frames[i], ctx->x86_pv.width); - if ( pfn > ctx->x86_pv.max_pfn ) + pfn = GET_FIELD(vcpu, gdt_frames[i], ctx->x86.pv.width); + if ( pfn > ctx->x86.pv.max_pfn ) { ERROR("GDT frame %u (pfn %#lx) out of range", i, pfn); goto err; } - if ( (ctx->x86_pv.restore.pfn_types[pfn] != XEN_DOMCTL_PFINFO_NOTAB) ) + if ( (ctx->x86.pv.restore.pfn_types[pfn] != XEN_DOMCTL_PFINFO_NOTAB) ) { ERROR("GDT frame %u (pfn %#lx) has bad type %u", i, pfn, - (ctx->x86_pv.restore.pfn_types[pfn] >> + (ctx->x86.pv.restore.pfn_types[pfn] >> XEN_DOMCTL_PFINFO_LTAB_SHIFT)); goto err; } @@ -290,25 +290,25 @@ static int process_vcpu_basic(struct xc_sr_context *ctx, goto err; } - SET_FIELD(vcpu, gdt_frames[i], mfn, ctx->x86_pv.width); + SET_FIELD(vcpu, gdt_frames[i], mfn, ctx->x86.pv.width); } /* Convert CR3 to an mfn. */ - pfn = cr3_to_mfn(ctx, GET_FIELD(vcpu, ctrlreg[3], ctx->x86_pv.width)); - if ( pfn > ctx->x86_pv.max_pfn ) + pfn = cr3_to_mfn(ctx, GET_FIELD(vcpu, ctrlreg[3], ctx->x86.pv.width)); + if ( pfn > ctx->x86.pv.max_pfn ) { ERROR("cr3 (pfn %#lx) out of range", pfn); goto err; } - if ( (ctx->x86_pv.restore.pfn_types[pfn] & + if ( (ctx->x86.pv.restore.pfn_types[pfn] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK) != - (((xen_pfn_t)ctx->x86_pv.levels) << XEN_DOMCTL_PFINFO_LTAB_SHIFT) ) + (((xen_pfn_t)ctx->x86.pv.levels) << XEN_DOMCTL_PFINFO_LTAB_SHIFT) ) { ERROR("cr3 (pfn %#lx) has bad type %u, expected %u", pfn, - (ctx->x86_pv.restore.pfn_types[pfn] >> + (ctx->x86.pv.restore.pfn_types[pfn] >> XEN_DOMCTL_PFINFO_LTAB_SHIFT), - ctx->x86_pv.levels); + ctx->x86.pv.levels); goto err; } @@ -320,27 +320,27 @@ static int process_vcpu_basic(struct xc_sr_context *ctx, goto err; } - SET_FIELD(vcpu, ctrlreg[3], mfn_to_cr3(ctx, mfn), ctx->x86_pv.width); + SET_FIELD(vcpu, ctrlreg[3], mfn_to_cr3(ctx, mfn), ctx->x86.pv.width); /* 64bit guests: Convert CR1 (guest pagetables) to mfn. */ - if ( ctx->x86_pv.levels == 4 && (vcpu->x64.ctrlreg[1] & 1) ) + if ( ctx->x86.pv.levels == 4 && (vcpu->x64.ctrlreg[1] & 1) ) { pfn = vcpu->x64.ctrlreg[1] >> PAGE_SHIFT; - if ( pfn > ctx->x86_pv.max_pfn ) + if ( pfn > ctx->x86.pv.max_pfn ) { ERROR("cr1 (pfn %#lx) out of range", pfn); goto err; } - if ( (ctx->x86_pv.restore.pfn_types[pfn] & + if ( (ctx->x86.pv.restore.pfn_types[pfn] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK) != - (((xen_pfn_t)ctx->x86_pv.levels) << XEN_DOMCTL_PFINFO_LTAB_SHIFT) ) + (((xen_pfn_t)ctx->x86.pv.levels) << XEN_DOMCTL_PFINFO_LTAB_SHIFT) ) { ERROR("cr1 (pfn %#lx) has bad type %u, expected %u", pfn, - (ctx->x86_pv.restore.pfn_types[pfn] >> + (ctx->x86.pv.restore.pfn_types[pfn] >> XEN_DOMCTL_PFINFO_LTAB_SHIFT), - ctx->x86_pv.levels); + ctx->x86.pv.levels); goto err; } @@ -375,7 +375,7 @@ static int process_vcpu_extended(struct xc_sr_context *ctx, { xc_interface *xch = ctx->xch; struct xc_sr_x86_pv_restore_vcpu *vcpu = - &ctx->x86_pv.restore.vcpus[vcpuid]; + &ctx->x86.pv.restore.vcpus[vcpuid]; DECLARE_DOMCTL; domctl.cmd = XEN_DOMCTL_set_ext_vcpucontext; @@ -399,7 +399,7 @@ static int process_vcpu_xsave(struct xc_sr_context *ctx, { xc_interface *xch = ctx->xch; struct xc_sr_x86_pv_restore_vcpu *vcpu = - &ctx->x86_pv.restore.vcpus[vcpuid]; + &ctx->x86.pv.restore.vcpus[vcpuid]; int rc; DECLARE_DOMCTL; DECLARE_HYPERCALL_BUFFER(void, buffer); @@ -437,7 +437,7 @@ static int process_vcpu_msrs(struct xc_sr_context *ctx, { xc_interface *xch = ctx->xch; struct xc_sr_x86_pv_restore_vcpu *vcpu = - &ctx->x86_pv.restore.vcpus[vcpuid]; + &ctx->x86.pv.restore.vcpus[vcpuid]; int rc; DECLARE_DOMCTL; DECLARE_HYPERCALL_BUFFER(void, buffer); @@ -477,9 +477,9 @@ static int update_vcpu_context(struct xc_sr_context *ctx) unsigned int i; int rc = 0; - for ( i = 0; i < ctx->x86_pv.restore.nr_vcpus; ++i ) + for ( i = 0; i < ctx->x86.pv.restore.nr_vcpus; ++i ) { - vcpu = &ctx->x86_pv.restore.vcpus[i]; + vcpu = &ctx->x86.pv.restore.vcpus[i]; if ( vcpu->basic.ptr ) { @@ -530,21 +530,21 @@ static int update_guest_p2m(struct xc_sr_context *ctx) unsigned int i; int rc = -1; - for ( i = 0; i < ctx->x86_pv.p2m_frames; ++i ) + for ( i = 0; i < ctx->x86.pv.p2m_frames; ++i ) { - pfn = ctx->x86_pv.p2m_pfns[i]; + pfn = ctx->x86.pv.p2m_pfns[i]; - if ( pfn > ctx->x86_pv.max_pfn ) + if ( pfn > ctx->x86.pv.max_pfn ) { ERROR("pfn (%#lx) for p2m_frame_list[%u] out of range", pfn, i); goto err; } - if ( (ctx->x86_pv.restore.pfn_types[pfn] != XEN_DOMCTL_PFINFO_NOTAB) ) + if ( (ctx->x86.pv.restore.pfn_types[pfn] != XEN_DOMCTL_PFINFO_NOTAB) ) { ERROR("pfn (%#lx) for p2m_frame_list[%u] has bad type %u", pfn, i, - (ctx->x86_pv.restore.pfn_types[pfn] >> + (ctx->x86.pv.restore.pfn_types[pfn] >> XEN_DOMCTL_PFINFO_LTAB_SHIFT)); goto err; } @@ -557,25 +557,25 @@ static int update_guest_p2m(struct xc_sr_context *ctx) goto err; } - ctx->x86_pv.p2m_pfns[i] = mfn; + ctx->x86.pv.p2m_pfns[i] = mfn; } guest_p2m = xc_map_foreign_pages(xch, ctx->domid, PROT_WRITE, - ctx->x86_pv.p2m_pfns, - ctx->x86_pv.p2m_frames); + ctx->x86.pv.p2m_pfns, + ctx->x86.pv.p2m_frames); if ( !guest_p2m ) { PERROR("Failed to map p2m frames"); goto err; } - memcpy(guest_p2m, ctx->x86_pv.p2m, - (ctx->x86_pv.max_pfn + 1) * ctx->x86_pv.width); + memcpy(guest_p2m, ctx->x86.pv.p2m, + (ctx->x86.pv.max_pfn + 1) * ctx->x86.pv.width); rc = 0; err: if ( guest_p2m ) - munmap(guest_p2m, ctx->x86_pv.p2m_frames * PAGE_SIZE); + munmap(guest_p2m, ctx->x86.pv.p2m_frames * PAGE_SIZE); return rc; } @@ -604,7 +604,7 @@ static int handle_x86_pv_info(struct xc_sr_context *ctx, xc_interface *xch = ctx->xch; struct xc_sr_rec_x86_pv_info *info = rec->data; - if ( ctx->x86_pv.restore.seen_pv_info ) + if ( ctx->x86.pv.restore.seen_pv_info ) { ERROR("Already received X86_PV_INFO record"); return -1; @@ -628,7 +628,7 @@ static int handle_x86_pv_info(struct xc_sr_context *ctx, * PV domains default to native width. For an incomming compat domain, we * will typically be the first entity to inform Xen. */ - if ( info->guest_width != ctx->x86_pv.width ) + if ( info->guest_width != ctx->x86.pv.width ) { struct xen_domctl domctl = { .domain = ctx->domid, @@ -654,16 +654,16 @@ static int handle_x86_pv_info(struct xc_sr_context *ctx, } /* Sanity check (possibly new) domain settings. */ - if ( (info->guest_width != ctx->x86_pv.width) || - (info->pt_levels != ctx->x86_pv.levels) ) + if ( (info->guest_width != ctx->x86.pv.width) || + (info->pt_levels != ctx->x86.pv.levels) ) { ERROR("X86_PV_INFO width/pt_levels settings %u/%u mismatch with d%d %u/%u", info->guest_width, info->pt_levels, ctx->domid, - ctx->x86_pv.width, ctx->x86_pv.levels); + ctx->x86.pv.width, ctx->x86.pv.levels); return -1; } - ctx->x86_pv.restore.seen_pv_info = true; + ctx->x86.pv.restore.seen_pv_info = true; return 0; } @@ -676,10 +676,10 @@ static int handle_x86_pv_p2m_frames(struct xc_sr_context *ctx, { xc_interface *xch = ctx->xch; struct xc_sr_rec_x86_pv_p2m_frames *data = rec->data; - unsigned int start, end, x, fpp = PAGE_SIZE / ctx->x86_pv.width; + unsigned int start, end, x, fpp = PAGE_SIZE / ctx->x86.pv.width; int rc; - if ( !ctx->x86_pv.restore.seen_pv_info ) + if ( !ctx->x86.pv.restore.seen_pv_info ) { ERROR("Not yet received X86_PV_INFO record"); return -1; @@ -711,7 +711,7 @@ static int handle_x86_pv_p2m_frames(struct xc_sr_context *ctx, return -1; } - if ( data->end_pfn > ctx->x86_pv.max_pfn ) + if ( data->end_pfn > ctx->x86.pv.max_pfn ) { rc = expand_p2m(ctx, data->end_pfn); if ( rc ) @@ -719,7 +719,7 @@ static int handle_x86_pv_p2m_frames(struct xc_sr_context *ctx, } for ( x = 0; x < (end - start); ++x ) - ctx->x86_pv.p2m_pfns[start + x] = data->p2m_pfns[x]; + ctx->x86.pv.p2m_pfns[start + x] = data->p2m_pfns[x]; return 0; } @@ -788,21 +788,21 @@ static int handle_x86_pv_vcpu_blob(struct xc_sr_context *ctx, } /* Check that the vcpu id is within range. */ - if ( vhdr->vcpu_id >= ctx->x86_pv.restore.nr_vcpus ) + if ( vhdr->vcpu_id >= ctx->x86.pv.restore.nr_vcpus ) { ERROR("%s record vcpu_id (%u) exceeds domain max (%u)", - rec_name, vhdr->vcpu_id, ctx->x86_pv.restore.nr_vcpus - 1); + rec_name, vhdr->vcpu_id, ctx->x86.pv.restore.nr_vcpus - 1); goto out; } - vcpu = &ctx->x86_pv.restore.vcpus[vhdr->vcpu_id]; + vcpu = &ctx->x86.pv.restore.vcpus[vhdr->vcpu_id]; /* Further per-record checks, where possible. */ switch ( rec->type ) { case REC_TYPE_X86_PV_VCPU_BASIC: { - size_t vcpusz = ctx->x86_pv.width == 8 ? + size_t vcpusz = ctx->x86.pv.width == 8 ? sizeof(vcpu_guest_context_x86_64_t) : sizeof(vcpu_guest_context_x86_32_t); @@ -868,7 +868,7 @@ static int handle_shared_info(struct xc_sr_context *ctx, shared_info_any_t *guest_shinfo = NULL; const shared_info_any_t *old_shinfo = rec->data; - if ( !ctx->x86_pv.restore.seen_pv_info ) + if ( !ctx->x86.pv.restore.seen_pv_info ) { ERROR("Not yet received X86_PV_INFO record"); return -1; @@ -891,18 +891,18 @@ static int handle_shared_info(struct xc_sr_context *ctx, goto err; } - MEMCPY_FIELD(guest_shinfo, old_shinfo, vcpu_info, ctx->x86_pv.width); - MEMCPY_FIELD(guest_shinfo, old_shinfo, arch, ctx->x86_pv.width); + MEMCPY_FIELD(guest_shinfo, old_shinfo, vcpu_info, ctx->x86.pv.width); + MEMCPY_FIELD(guest_shinfo, old_shinfo, arch, ctx->x86.pv.width); SET_FIELD(guest_shinfo, arch.pfn_to_mfn_frame_list_list, - 0, ctx->x86_pv.width); + 0, ctx->x86.pv.width); - MEMSET_ARRAY_FIELD(guest_shinfo, evtchn_pending, 0, ctx->x86_pv.width); + MEMSET_ARRAY_FIELD(guest_shinfo, evtchn_pending, 0, ctx->x86.pv.width); for ( i = 0; i < XEN_LEGACY_MAX_VCPUS; i++ ) SET_FIELD(guest_shinfo, vcpu_info[i].evtchn_pending_sel, - 0, ctx->x86_pv.width); + 0, ctx->x86.pv.width); - MEMSET_ARRAY_FIELD(guest_shinfo, evtchn_mask, 0xff, ctx->x86_pv.width); + MEMSET_ARRAY_FIELD(guest_shinfo, evtchn_mask, 0xff, ctx->x86.pv.width); rc = 0; @@ -916,30 +916,30 @@ static int handle_shared_info(struct xc_sr_context *ctx, /* restore_ops function. */ static bool x86_pv_pfn_is_valid(const struct xc_sr_context *ctx, xen_pfn_t pfn) { - return pfn <= ctx->x86_pv.max_pfn; + return pfn <= ctx->x86.pv.max_pfn; } /* restore_ops function. */ static void x86_pv_set_page_type(struct xc_sr_context *ctx, xen_pfn_t pfn, unsigned long type) { - assert(pfn <= ctx->x86_pv.max_pfn); + assert(pfn <= ctx->x86.pv.max_pfn); - ctx->x86_pv.restore.pfn_types[pfn] = type; + ctx->x86.pv.restore.pfn_types[pfn] = type; } /* restore_ops function. */ static void x86_pv_set_gfn(struct xc_sr_context *ctx, xen_pfn_t pfn, xen_pfn_t mfn) { - assert(pfn <= ctx->x86_pv.max_pfn); + assert(pfn <= ctx->x86.pv.max_pfn); - if ( ctx->x86_pv.width == sizeof(uint64_t) ) + if ( ctx->x86.pv.width == sizeof(uint64_t) ) /* 64 bit guest. Need to expand INVALID_MFN for 32 bit toolstacks. */ - ((uint64_t *)ctx->x86_pv.p2m)[pfn] = mfn == INVALID_MFN ? ~0ULL : mfn; + ((uint64_t *)ctx->x86.pv.p2m)[pfn] = mfn == INVALID_MFN ? ~0ULL : mfn; else /* 32 bit guest. Can truncate INVALID_MFN for 64 bit toolstacks. */ - ((uint32_t *)ctx->x86_pv.p2m)[pfn] = mfn; + ((uint32_t *)ctx->x86.pv.p2m)[pfn] = mfn; } /* @@ -1043,10 +1043,10 @@ static int x86_pv_setup(struct xc_sr_context *ctx) if ( rc ) return rc; - ctx->x86_pv.restore.nr_vcpus = ctx->dominfo.max_vcpu_id + 1; - ctx->x86_pv.restore.vcpus = calloc(sizeof(struct xc_sr_x86_pv_restore_vcpu), - ctx->x86_pv.restore.nr_vcpus); - if ( !ctx->x86_pv.restore.vcpus ) + ctx->x86.pv.restore.nr_vcpus = ctx->dominfo.max_vcpu_id + 1; + ctx->x86.pv.restore.vcpus = calloc(sizeof(struct xc_sr_x86_pv_restore_vcpu), + ctx->x86.pv.restore.nr_vcpus); + if ( !ctx->x86.pv.restore.vcpus ) { errno = ENOMEM; return -1; @@ -1130,17 +1130,17 @@ static int x86_pv_stream_complete(struct xc_sr_context *ctx) */ static int x86_pv_cleanup(struct xc_sr_context *ctx) { - free(ctx->x86_pv.p2m); - free(ctx->x86_pv.p2m_pfns); + free(ctx->x86.pv.p2m); + free(ctx->x86.pv.p2m_pfns); - if ( ctx->x86_pv.restore.vcpus ) + if ( ctx->x86.pv.restore.vcpus ) { unsigned int i; - for ( i = 0; i < ctx->x86_pv.restore.nr_vcpus; ++i ) + for ( i = 0; i < ctx->x86.pv.restore.nr_vcpus; ++i ) { struct xc_sr_x86_pv_restore_vcpu *vcpu = - &ctx->x86_pv.restore.vcpus[i]; + &ctx->x86.pv.restore.vcpus[i]; free(vcpu->basic.ptr); free(vcpu->extd.ptr); @@ -1148,13 +1148,13 @@ static int x86_pv_cleanup(struct xc_sr_context *ctx) free(vcpu->msr.ptr); } - free(ctx->x86_pv.restore.vcpus); + free(ctx->x86.pv.restore.vcpus); } - free(ctx->x86_pv.restore.pfn_types); + free(ctx->x86.pv.restore.pfn_types); - if ( ctx->x86_pv.m2p ) - munmap(ctx->x86_pv.m2p, ctx->x86_pv.nr_m2p_frames * PAGE_SIZE); + if ( ctx->x86.pv.m2p ) + munmap(ctx->x86.pv.m2p, ctx->x86.pv.nr_m2p_frames * PAGE_SIZE); return 0; } diff --git a/tools/libxc/xc_sr_save_x86_hvm.c b/tools/libxc/xc_sr_save_x86_hvm.c index d925a81999..58722118ae 100644 --- a/tools/libxc/xc_sr_save_x86_hvm.c +++ b/tools/libxc/xc_sr_save_x86_hvm.c @@ -165,7 +165,7 @@ static int x86_hvm_setup(struct xc_sr_context *ctx) return -1; } - ctx->x86_hvm.save.qemu_enabled_logdirty = true; + ctx->x86.hvm.save.qemu_enabled_logdirty = true; return 0; } @@ -197,7 +197,7 @@ static int x86_hvm_cleanup(struct xc_sr_context *ctx) xc_interface *xch = ctx->xch; /* If qemu successfully enabled logdirty mode, attempt to disable. */ - if ( ctx->x86_hvm.save.qemu_enabled_logdirty && + if ( ctx->x86.hvm.save.qemu_enabled_logdirty && ctx->save.callbacks->switch_qemu_logdirty( ctx->domid, 0, ctx->save.callbacks->data) ) { diff --git a/tools/libxc/xc_sr_save_x86_pv.c b/tools/libxc/xc_sr_save_x86_pv.c index 94d0f68911..c1c6892666 100644 --- a/tools/libxc/xc_sr_save_x86_pv.c +++ b/tools/libxc/xc_sr_save_x86_pv.c @@ -16,9 +16,9 @@ static int map_shinfo(struct xc_sr_context *ctx) { xc_interface *xch = ctx->xch; - ctx->x86_pv.shinfo = xc_map_foreign_range( + ctx->x86.pv.shinfo = xc_map_foreign_range( xch, ctx->domid, PAGE_SIZE, PROT_READ, ctx->dominfo.shared_info_frame); - if ( !ctx->x86_pv.shinfo ) + if ( !ctx->x86.pv.shinfo ) { PERROR("Failed to map shared info frame at mfn %#lx", ctx->dominfo.shared_info_frame); @@ -37,7 +37,7 @@ static int copy_mfns_from_guest(const struct xc_sr_context *ctx, { size_t x; - if ( ctx->x86_pv.width == sizeof(unsigned long) ) + if ( ctx->x86.pv.width == sizeof(unsigned long) ) memcpy(dst, src, count * sizeof(*dst)); else { @@ -82,18 +82,18 @@ static int map_p2m_leaves(struct xc_sr_context *ctx, xen_pfn_t *mfns, xc_interface *xch = ctx->xch; unsigned int x; - ctx->x86_pv.p2m = xc_map_foreign_pages(xch, ctx->domid, PROT_READ, + ctx->x86.pv.p2m = xc_map_foreign_pages(xch, ctx->domid, PROT_READ, mfns, n_mfns); - if ( !ctx->x86_pv.p2m ) + if ( !ctx->x86.pv.p2m ) { PERROR("Failed to map p2m frames"); return -1; } - ctx->save.p2m_size = ctx->x86_pv.max_pfn + 1; - ctx->x86_pv.p2m_frames = n_mfns; - ctx->x86_pv.p2m_pfns = malloc(n_mfns * sizeof(*mfns)); - if ( !ctx->x86_pv.p2m_pfns ) + ctx->save.p2m_size = ctx->x86.pv.max_pfn + 1; + ctx->x86.pv.p2m_frames = n_mfns; + ctx->x86.pv.p2m_pfns = malloc(n_mfns * sizeof(*mfns)); + if ( !ctx->x86.pv.p2m_pfns ) { ERROR("Cannot allocate %zu bytes for p2m pfns list", n_mfns * sizeof(*mfns)); @@ -111,7 +111,7 @@ static int map_p2m_leaves(struct xc_sr_context *ctx, xen_pfn_t *mfns, return -1; } - ctx->x86_pv.p2m_pfns[x] = mfn_to_pfn(ctx, mfns[x]); + ctx->x86.pv.p2m_pfns[x] = mfn_to_pfn(ctx, mfns[x]); } return 0; @@ -144,17 +144,17 @@ static int map_p2m_tree(struct xc_sr_context *ctx) void *guest_fl = NULL; size_t local_fl_size; - fpp = PAGE_SIZE / ctx->x86_pv.width; - fll_entries = (ctx->x86_pv.max_pfn / (fpp * fpp)) + 1; + fpp = PAGE_SIZE / ctx->x86.pv.width; + fll_entries = (ctx->x86.pv.max_pfn / (fpp * fpp)) + 1; if ( fll_entries > fpp ) { - ERROR("max_pfn %#lx too large for p2m tree", ctx->x86_pv.max_pfn); + ERROR("max_pfn %#lx too large for p2m tree", ctx->x86.pv.max_pfn); goto err; } - fll_mfn = GET_FIELD(ctx->x86_pv.shinfo, arch.pfn_to_mfn_frame_list_list, - ctx->x86_pv.width); - if ( fll_mfn == 0 || fll_mfn > ctx->x86_pv.max_mfn ) + fll_mfn = GET_FIELD(ctx->x86.pv.shinfo, arch.pfn_to_mfn_frame_list_list, + ctx->x86.pv.width); + if ( fll_mfn == 0 || fll_mfn > ctx->x86.pv.max_mfn ) { ERROR("Bad mfn %#lx for p2m frame list list", fll_mfn); goto err; @@ -189,7 +189,7 @@ static int map_p2m_tree(struct xc_sr_context *ctx) saved_x = 0; for ( x = 0; x < fll_entries; ++x ) { - if ( local_fll[x] == 0 || local_fll[x] > ctx->x86_pv.max_mfn ) + if ( local_fll[x] == 0 || local_fll[x] > ctx->x86.pv.max_mfn ) { ERROR("Bad mfn %#lx at index %u (of %u) in p2m frame list list", local_fll[x], x, fll_entries); @@ -213,15 +213,15 @@ static int map_p2m_tree(struct xc_sr_context *ctx) * needed for p2m and logdirty map. */ max_pfn = (saved_x + 1) * fpp * fpp - 1; - if ( max_pfn < ctx->x86_pv.max_pfn ) + if ( max_pfn < ctx->x86.pv.max_pfn ) { - ctx->x86_pv.max_pfn = max_pfn; - fll_entries = (ctx->x86_pv.max_pfn / (fpp * fpp)) + 1; + ctx->x86.pv.max_pfn = max_pfn; + fll_entries = (ctx->x86.pv.max_pfn / (fpp * fpp)) + 1; } - ctx->x86_pv.p2m_frames = (ctx->x86_pv.max_pfn + fpp) / fpp; - DPRINTF("max_pfn %#lx, p2m_frames %d", ctx->x86_pv.max_pfn, - ctx->x86_pv.p2m_frames); - fl_entries = (ctx->x86_pv.max_pfn / fpp) + 1; + ctx->x86.pv.p2m_frames = (ctx->x86.pv.max_pfn + fpp) / fpp; + DPRINTF("max_pfn %#lx, p2m_frames %d", ctx->x86.pv.max_pfn, + ctx->x86.pv.p2m_frames); + fl_entries = (ctx->x86.pv.max_pfn / fpp) + 1; /* Map the guest mid p2m frames. */ guest_fl = xc_map_foreign_pages(xch, ctx->domid, PROT_READ, @@ -249,7 +249,7 @@ static int map_p2m_tree(struct xc_sr_context *ctx) for ( x = 0; x < fl_entries; ++x ) { - if ( local_fl[x] == 0 || local_fl[x] > ctx->x86_pv.max_mfn ) + if ( local_fl[x] == 0 || local_fl[x] > ctx->x86.pv.max_mfn ) { ERROR("Bad mfn %#lx at index %u (of %u) in p2m frame list", local_fl[x], x, fl_entries); @@ -281,11 +281,11 @@ static int get_p2m_generation(struct xc_sr_context *ctx) uint64_t p2m_generation; int rc; - p2m_generation = GET_FIELD(ctx->x86_pv.shinfo, arch.p2m_generation, - ctx->x86_pv.width); + p2m_generation = GET_FIELD(ctx->x86.pv.shinfo, arch.p2m_generation, + ctx->x86.pv.width); - rc = (p2m_generation == ctx->x86_pv.p2m_generation) ? 0 : -1; - ctx->x86_pv.p2m_generation = p2m_generation; + rc = (p2m_generation == ctx->x86.pv.p2m_generation) ? 0 : -1; + ctx->x86.pv.p2m_generation = p2m_generation; return rc; } @@ -322,7 +322,7 @@ static int map_p2m_list(struct xc_sr_context *ctx, uint64_t p2m_cr3) p2m_mfn = cr3_to_mfn(ctx, p2m_cr3); assert(p2m_mfn != 0); - if ( p2m_mfn > ctx->x86_pv.max_mfn ) + if ( p2m_mfn > ctx->x86.pv.max_mfn ) { ERROR("Bad p2m_cr3 value %#" PRIx64, p2m_cr3); errno = ERANGE; @@ -331,13 +331,13 @@ static int map_p2m_list(struct xc_sr_context *ctx, uint64_t p2m_cr3) get_p2m_generation(ctx); - p2m_vaddr = GET_FIELD(ctx->x86_pv.shinfo, arch.p2m_vaddr, - ctx->x86_pv.width); - fpp = PAGE_SIZE / ctx->x86_pv.width; - ctx->x86_pv.p2m_frames = ctx->x86_pv.max_pfn / fpp + 1; - p2m_end = p2m_vaddr + ctx->x86_pv.p2m_frames * PAGE_SIZE - 1; + p2m_vaddr = GET_FIELD(ctx->x86.pv.shinfo, arch.p2m_vaddr, + ctx->x86.pv.width); + fpp = PAGE_SIZE / ctx->x86.pv.width; + ctx->x86.pv.p2m_frames = ctx->x86.pv.max_pfn / fpp + 1; + p2m_end = p2m_vaddr + ctx->x86.pv.p2m_frames * PAGE_SIZE - 1; - if ( ctx->x86_pv.width == 8 ) + if ( ctx->x86.pv.width == 8 ) { mask = 0x0000ffffffffffffULL; if ( !is_canonical_address(p2m_vaddr) || @@ -368,8 +368,8 @@ static int map_p2m_list(struct xc_sr_context *ctx, uint64_t p2m_cr3) DPRINTF("p2m list from %#" PRIx64 " to %#" PRIx64 ", root at %#lx", p2m_vaddr, p2m_end, p2m_mfn); - DPRINTF("max_pfn %#lx, p2m_frames %d", ctx->x86_pv.max_pfn, - ctx->x86_pv.p2m_frames); + DPRINTF("max_pfn %#lx, p2m_frames %d", ctx->x86.pv.max_pfn, + ctx->x86.pv.p2m_frames); mfns = malloc(sizeof(*mfns)); if ( !mfns ) @@ -382,7 +382,7 @@ static int map_p2m_list(struct xc_sr_context *ctx, uint64_t p2m_cr3) saved_mfn = 0; idx_start = idx_end = saved_idx = 0; - for ( level = ctx->x86_pv.levels; level > 0; level-- ) + for ( level = ctx->x86.pv.levels; level > 0; level-- ) { n_pages = idx_end - idx_start + 1; ptes = xc_map_foreign_pages(xch, ctx->domid, PROT_READ, mfns, n_pages); @@ -407,7 +407,7 @@ static int map_p2m_list(struct xc_sr_context *ctx, uint64_t p2m_cr3) for ( idx = idx_start; idx <= idx_end; idx++ ) { mfn = pte_to_frame(ptes[idx]); - if ( mfn == 0 || mfn > ctx->x86_pv.max_mfn ) + if ( mfn == 0 || mfn > ctx->x86.pv.max_mfn ) { ERROR("Bad mfn %#lx during page table walk for vaddr %#" PRIx64 " at level %d of p2m list", mfn, off + ((xen_vaddr_t)idx << shift), level); @@ -432,11 +432,11 @@ static int map_p2m_list(struct xc_sr_context *ctx, uint64_t p2m_cr3) if ( saved_idx == idx_end ) saved_idx++; max_pfn = ((xen_pfn_t)saved_idx << 9) * fpp - 1; - if ( max_pfn < ctx->x86_pv.max_pfn ) + if ( max_pfn < ctx->x86.pv.max_pfn ) { - ctx->x86_pv.max_pfn = max_pfn; - ctx->x86_pv.p2m_frames = (ctx->x86_pv.max_pfn + fpp) / fpp; - p2m_end = p2m_vaddr + ctx->x86_pv.p2m_frames * PAGE_SIZE - 1; + ctx->x86.pv.max_pfn = max_pfn; + ctx->x86.pv.p2m_frames = (ctx->x86.pv.max_pfn + fpp) / fpp; + p2m_end = p2m_vaddr + ctx->x86.pv.p2m_frames * PAGE_SIZE - 1; idx_end = idx_start + saved_idx; } } @@ -466,10 +466,10 @@ static int map_p2m(struct xc_sr_context *ctx) { uint64_t p2m_cr3; - ctx->x86_pv.p2m_generation = ~0ULL; - ctx->x86_pv.max_pfn = GET_FIELD(ctx->x86_pv.shinfo, arch.max_pfn, - ctx->x86_pv.width) - 1; - p2m_cr3 = GET_FIELD(ctx->x86_pv.shinfo, arch.p2m_cr3, ctx->x86_pv.width); + ctx->x86.pv.p2m_generation = ~0ULL; + ctx->x86.pv.max_pfn = GET_FIELD(ctx->x86.pv.shinfo, arch.max_pfn, + ctx->x86.pv.width) - 1; + p2m_cr3 = GET_FIELD(ctx->x86.pv.shinfo, arch.p2m_cr3, ctx->x86.pv.width); return p2m_cr3 ? map_p2m_list(ctx, p2m_cr3) : map_p2m_tree(ctx); } @@ -503,7 +503,7 @@ static int write_one_vcpu_basic(struct xc_sr_context *ctx, uint32_t id) /* Vcpu0 is special: Convert the suspend record to a pfn. */ if ( id == 0 ) { - mfn = GET_FIELD(&vcpu, user_regs.edx, ctx->x86_pv.width); + mfn = GET_FIELD(&vcpu, user_regs.edx, ctx->x86.pv.width); if ( !mfn_in_pseudophysmap(ctx, mfn) ) { ERROR("Bad mfn for suspend record"); @@ -512,10 +512,10 @@ static int write_one_vcpu_basic(struct xc_sr_context *ctx, uint32_t id) goto err; } SET_FIELD(&vcpu, user_regs.edx, mfn_to_pfn(ctx, mfn), - ctx->x86_pv.width); + ctx->x86.pv.width); } - gdt_count = GET_FIELD(&vcpu, gdt_ents, ctx->x86_pv.width); + gdt_count = GET_FIELD(&vcpu, gdt_ents, ctx->x86.pv.width); if ( gdt_count > FIRST_RESERVED_GDT_ENTRY ) { ERROR("GDT entry count (%u) out of range (max %u)", @@ -528,7 +528,7 @@ static int write_one_vcpu_basic(struct xc_sr_context *ctx, uint32_t id) /* Convert GDT frames to pfns. */ for ( i = 0; i < gdt_count; ++i ) { - mfn = GET_FIELD(&vcpu, gdt_frames[i], ctx->x86_pv.width); + mfn = GET_FIELD(&vcpu, gdt_frames[i], ctx->x86.pv.width); if ( !mfn_in_pseudophysmap(ctx, mfn) ) { ERROR("Bad mfn for frame %u of vcpu%u's GDT", i, id); @@ -537,11 +537,11 @@ static int write_one_vcpu_basic(struct xc_sr_context *ctx, uint32_t id) goto err; } SET_FIELD(&vcpu, gdt_frames[i], mfn_to_pfn(ctx, mfn), - ctx->x86_pv.width); + ctx->x86.pv.width); } /* Convert CR3 to a pfn. */ - mfn = cr3_to_mfn(ctx, GET_FIELD(&vcpu, ctrlreg[3], ctx->x86_pv.width)); + mfn = cr3_to_mfn(ctx, GET_FIELD(&vcpu, ctrlreg[3], ctx->x86.pv.width)); if ( !mfn_in_pseudophysmap(ctx, mfn) ) { ERROR("Bad mfn for vcpu%u's cr3", id); @@ -550,10 +550,10 @@ static int write_one_vcpu_basic(struct xc_sr_context *ctx, uint32_t id) goto err; } pfn = mfn_to_pfn(ctx, mfn); - SET_FIELD(&vcpu, ctrlreg[3], mfn_to_cr3(ctx, pfn), ctx->x86_pv.width); + SET_FIELD(&vcpu, ctrlreg[3], mfn_to_cr3(ctx, pfn), ctx->x86.pv.width); /* 64bit guests: Convert CR1 (guest pagetables) to pfn. */ - if ( ctx->x86_pv.levels == 4 && vcpu.x64.ctrlreg[1] ) + if ( ctx->x86.pv.levels == 4 && vcpu.x64.ctrlreg[1] ) { mfn = vcpu.x64.ctrlreg[1] >> PAGE_SHIFT; if ( !mfn_in_pseudophysmap(ctx, mfn) ) @@ -567,7 +567,7 @@ static int write_one_vcpu_basic(struct xc_sr_context *ctx, uint32_t id) vcpu.x64.ctrlreg[1] = 1 | ((uint64_t)pfn << PAGE_SHIFT); } - if ( ctx->x86_pv.width == 8 ) + if ( ctx->x86.pv.width == 8 ) rc = write_split_record(ctx, &rec, &vcpu, sizeof(vcpu.x64)); else rc = write_split_record(ctx, &rec, &vcpu, sizeof(vcpu.x32)); @@ -785,8 +785,8 @@ static int write_all_vcpu_information(struct xc_sr_context *ctx) static int write_x86_pv_info(struct xc_sr_context *ctx) { struct xc_sr_rec_x86_pv_info info = { - .guest_width = ctx->x86_pv.width, - .pt_levels = ctx->x86_pv.levels, + .guest_width = ctx->x86.pv.width, + .pt_levels = ctx->x86.pv.levels, }; struct xc_sr_record rec = { .type = REC_TYPE_X86_PV_INFO, @@ -805,10 +805,10 @@ static int write_x86_pv_p2m_frames(struct xc_sr_context *ctx) { xc_interface *xch = ctx->xch; int rc; unsigned int i; - size_t datasz = ctx->x86_pv.p2m_frames * sizeof(uint64_t); + size_t datasz = ctx->x86.pv.p2m_frames * sizeof(uint64_t); uint64_t *data = NULL; struct xc_sr_rec_x86_pv_p2m_frames hdr = { - .end_pfn = ctx->x86_pv.max_pfn, + .end_pfn = ctx->x86.pv.max_pfn, }; struct xc_sr_record rec = { .type = REC_TYPE_X86_PV_P2M_FRAMES, @@ -817,7 +817,7 @@ static int write_x86_pv_p2m_frames(struct xc_sr_context *ctx) }; /* No need to translate if sizeof(uint64_t) == sizeof(xen_pfn_t). */ - if ( sizeof(uint64_t) != sizeof(*ctx->x86_pv.p2m_pfns) ) + if ( sizeof(uint64_t) != sizeof(*ctx->x86.pv.p2m_pfns) ) { if ( !(data = malloc(datasz)) ) { @@ -826,15 +826,15 @@ static int write_x86_pv_p2m_frames(struct xc_sr_context *ctx) return -1; } - for ( i = 0; i < ctx->x86_pv.p2m_frames; ++i ) - data[i] = ctx->x86_pv.p2m_pfns[i]; + for ( i = 0; i < ctx->x86.pv.p2m_frames; ++i ) + data[i] = ctx->x86.pv.p2m_pfns[i]; } else - data = (uint64_t *)ctx->x86_pv.p2m_pfns; + data = (uint64_t *)ctx->x86.pv.p2m_pfns; rc = write_split_record(ctx, &rec, data, datasz); - if ( data != (uint64_t *)ctx->x86_pv.p2m_pfns ) + if ( data != (uint64_t *)ctx->x86.pv.p2m_pfns ) free(data); return rc; @@ -848,7 +848,7 @@ static int write_shared_info(struct xc_sr_context *ctx) struct xc_sr_record rec = { .type = REC_TYPE_SHARED_INFO, .length = PAGE_SIZE, - .data = ctx->x86_pv.shinfo, + .data = ctx->x86.pv.shinfo, }; return write_record(ctx, &rec); @@ -867,7 +867,7 @@ static int normalise_pagetable(struct xc_sr_context *ctx, const uint64_t *src, type &= XEN_DOMCTL_PFINFO_LTABTYPE_MASK; - if ( ctx->x86_pv.levels == 4 ) + if ( ctx->x86.pv.levels == 4 ) { /* 64bit guests only have Xen mappings in their L4 tables. */ if ( type == XEN_DOMCTL_PFINFO_L4TAB ) @@ -899,7 +899,7 @@ static int normalise_pagetable(struct xc_sr_context *ctx, const uint64_t *src, * are normal but only a few will have Xen mappings. */ i = (HYPERVISOR_VIRT_START_X86_32 >> L2_PAGETABLE_SHIFT_PAE) & 511; - if ( pte_to_frame(src[i]) == ctx->x86_pv.compat_m2p_mfn0 ) + if ( pte_to_frame(src[i]) == ctx->x86.pv.compat_m2p_mfn0 ) { xen_first = i; xen_last = (HYPERVISOR_VIRT_END_X86_32 >> @@ -980,9 +980,9 @@ static int normalise_pagetable(struct xc_sr_context *ctx, const uint64_t *src, static xen_pfn_t x86_pv_pfn_to_gfn(const struct xc_sr_context *ctx, xen_pfn_t pfn) { - assert(pfn <= ctx->x86_pv.max_pfn); + assert(pfn <= ctx->x86.pv.max_pfn); - return xc_pfn_to_mfn(pfn, ctx->x86_pv.p2m, ctx->x86_pv.width); + return xc_pfn_to_mfn(pfn, ctx->x86.pv.p2m, ctx->x86.pv.width); } @@ -1063,7 +1063,7 @@ static int x86_pv_end_of_checkpoint(struct xc_sr_context *ctx) static int x86_pv_check_vm_state(struct xc_sr_context *ctx) { - if ( ctx->x86_pv.p2m_generation == ~0ULL ) + if ( ctx->x86.pv.p2m_generation == ~0ULL ) return 0; return x86_pv_check_vm_state_p2m_list(ctx); @@ -1071,16 +1071,16 @@ static int x86_pv_check_vm_state(struct xc_sr_context *ctx) static int x86_pv_cleanup(struct xc_sr_context *ctx) { - free(ctx->x86_pv.p2m_pfns); + free(ctx->x86.pv.p2m_pfns); - if ( ctx->x86_pv.p2m ) - munmap(ctx->x86_pv.p2m, ctx->x86_pv.p2m_frames * PAGE_SIZE); + if ( ctx->x86.pv.p2m ) + munmap(ctx->x86.pv.p2m, ctx->x86.pv.p2m_frames * PAGE_SIZE); - if ( ctx->x86_pv.shinfo ) - munmap(ctx->x86_pv.shinfo, PAGE_SIZE); + if ( ctx->x86.pv.shinfo ) + munmap(ctx->x86.pv.shinfo, PAGE_SIZE); - if ( ctx->x86_pv.m2p ) - munmap(ctx->x86_pv.m2p, ctx->x86_pv.nr_m2p_frames * PAGE_SIZE); + if ( ctx->x86.pv.m2p ) + munmap(ctx->x86.pv.m2p, ctx->x86.pv.nr_m2p_frames * PAGE_SIZE); return 0; } From patchwork Tue Dec 24 15:19:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11309523 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 002E06C1 for ; Tue, 24 Dec 2019 15:21:02 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CFE072071A for ; Tue, 24 Dec 2019 15:21:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="YqvRZH5Z" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CFE072071A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlyT-0000FC-7J; Tue, 24 Dec 2019 15:19:53 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlyS-0000Ep-4r for xen-devel@lists.xenproject.org; Tue, 24 Dec 2019 15:19:52 +0000 X-Inumbo-ID: cd47db74-2660-11ea-88e7-bc764e2007e4 Received: from esa5.hc3370-68.iphmx.com (unknown [216.71.155.168]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id cd47db74-2660-11ea-88e7-bc764e2007e4; Tue, 24 Dec 2019 15:19:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1577200779; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Xr9uMqJBCDqqfstRuRIEWyne2KE5Ud58HiPzMMhJMIA=; b=YqvRZH5ZtlgSSaGz5QOu8TZZIwLv+tZwgrr2qRIKYAQWWXaQnCJsNzsm tDmuwFoz2Qa4IPD3u0vG4mWBPeQLiEwrWkGrSmEnqj6Kx2pqwtBvwTz+X DpumjLCUp98G9G3tP7uZCAUElGqusKu+S8K65eYBb/yQBin6ATpaYS1E/ 4=; Authentication-Results: esa5.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa5.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: k6f/c7fgenuQX0JGRvo9n9YCr8uIMO6mCEMPmKczusoYW9LO4kLiHeKaqXJS6x/xgGxi34uMpV QcdyCRsakzOUUY5p2JvefYI7xRY1INqlP2E3RFhhHzLEbSEMDaCBwIeJkuRngEgSXl/LMAvFRh S32tdNV3/nUu+PUYRK3L+cDsLTKmA4hcSyy72N4Xn/WJY07sDQl6jHtal16fyYtKgdzEXej2UY LnWjunTDhm2npBqKQjJOdFtBWhVv0i3sm1J2mS/3MrqOvrubunBFzX86fLZGmXsFZlHmPL9q+k 2jM= X-SBRS: 2.7 X-MesageID: 10482749 X-Ironport-Server: esa5.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,351,1571716800"; d="scan'208";a="10482749" From: Andrew Cooper To: Xen-devel Date: Tue, 24 Dec 2019 15:19:25 +0000 Message-ID: <20191224151932.6304-6-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20191224151932.6304-1-andrew.cooper3@citrix.com> References: <20191224151932.6304-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH 05/12] tools/migration: Drop IHDR_VERSION constant from libxc and python X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , =?utf-8?q?Marek_Marczykowski-?= =?utf-8?q?G=C3=B3recki?= , Wei Liu , Ian Jackson Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Migration v3 is in the process of being introduced, meaning that the code has to cope with both versions. Use an explicit 2 for now. For the verify-stream-v2 and convert-legacy-stream scripts, update text to say "v2 (or later)". What matters is the distinction vs legacy streams. Signed-off-by: Andrew Cooper --- CC: Ian Jackson CC: Wei Liu CC: Marek Marczykowski-Górecki --- tools/libxc/xc_sr_restore.c | 6 +++--- tools/libxc/xc_sr_save.c | 2 +- tools/libxc/xc_sr_stream_format.h | 1 - tools/python/scripts/convert-legacy-stream | 6 +++--- tools/python/scripts/verify-stream-v2 | 2 +- tools/python/xen/migration/libxc.py | 9 ++++----- 6 files changed, 12 insertions(+), 14 deletions(-) diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c index 7872b71ab5..0280e55d4b 100644 --- a/tools/libxc/xc_sr_restore.c +++ b/tools/libxc/xc_sr_restore.c @@ -35,10 +35,10 @@ static int read_headers(struct xc_sr_context *ctx) return -1; } - if ( ihdr.version != IHDR_VERSION ) + if ( ihdr.version != 2 ) { - ERROR("Invalid Version: Expected %d, Got %d", - IHDR_VERSION, ihdr.version); + ERROR("Invalid Version: Expected 2, Got %d", + ihdr.version); return -1; } diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c index 5467965b08..fa1a2e6c2a 100644 --- a/tools/libxc/xc_sr_save.c +++ b/tools/libxc/xc_sr_save.c @@ -13,7 +13,7 @@ static int write_headers(struct xc_sr_context *ctx, uint16_t guest_type) struct xc_sr_ihdr ihdr = { .marker = IHDR_MARKER, .id = htonl(IHDR_ID), - .version = htonl(IHDR_VERSION), + .version = htonl(2), .options = htons(IHDR_OPT_LITTLE_ENDIAN), }; struct xc_sr_dhdr dhdr = { diff --git a/tools/libxc/xc_sr_stream_format.h b/tools/libxc/xc_sr_stream_format.h index 37a7da6eab..ae7c0de393 100644 --- a/tools/libxc/xc_sr_stream_format.h +++ b/tools/libxc/xc_sr_stream_format.h @@ -23,7 +23,6 @@ struct xc_sr_ihdr #define IHDR_MARKER 0xffffffffffffffffULL #define IHDR_ID 0x58454E46U -#define IHDR_VERSION 2 #define _IHDR_OPT_ENDIAN 0 #define IHDR_OPT_LITTLE_ENDIAN (0 << _IHDR_OPT_ENDIAN) diff --git a/tools/python/scripts/convert-legacy-stream b/tools/python/scripts/convert-legacy-stream index 2922fb3185..02a194178f 100755 --- a/tools/python/scripts/convert-legacy-stream +++ b/tools/python/scripts/convert-legacy-stream @@ -79,7 +79,7 @@ def write_libxc_ihdr(): stream_write(pack(libxc.IHDR_FORMAT, libxc.IHDR_MARKER, # Marker libxc.IHDR_IDENT, # Ident - libxc.IHDR_VERSION, # Version + 2, # Version libxc.IHDR_OPT_LE, # Options 0, 0)) # Reserved @@ -632,13 +632,13 @@ def main(): usage = ("%prog [options] -i INPUT -o OUTPUT" " -w WIDTH -g GUEST"), description = - "Convert a legacy stream to a v2 stream") + "Convert a legacy stream to a v2 (or later) stream") # Required options parser.add_option("-i", "--in", dest = "fin", metavar = "", help = "Legacy input to convert") parser.add_option("-o", "--out", dest = "fout", metavar = "", - help = "v2 format output") + help = "v2 (or later) format output") parser.add_option("-w", "--width", dest = "twidth", metavar = "<32/64>", choices = ["32", "64"], help = "Legacy toolstack bitness") diff --git a/tools/python/scripts/verify-stream-v2 b/tools/python/scripts/verify-stream-v2 index 8bac04d566..fe82b86c11 100755 --- a/tools/python/scripts/verify-stream-v2 +++ b/tools/python/scripts/verify-stream-v2 @@ -108,7 +108,7 @@ def main(): parser = OptionParser(usage = "%prog [options]", description = - "Verify a stream according to the v2 spec") + "Verify a stream according to the v2 (or later) spec") # Optional options parser.add_option("-i", "--in", dest = "fin", metavar = "", diff --git a/tools/python/xen/migration/libxc.py b/tools/python/xen/migration/libxc.py index 8a800df980..63b3558029 100644 --- a/tools/python/xen/migration/libxc.py +++ b/tools/python/xen/migration/libxc.py @@ -19,7 +19,6 @@ IHDR_MARKER = 0xffffffffffffffff IHDR_IDENT = 0x58454E46 # "XENF" in ASCII -IHDR_VERSION = 2 IHDR_OPT_BIT_ENDIAN = 0 IHDR_OPT_LE = (0 << IHDR_OPT_BIT_ENDIAN) @@ -113,7 +112,7 @@ HVM_PARAMS_FORMAT = "II" class VerifyLibxc(VerifyBase): - """ Verify a Libxc v2 stream """ + """ Verify a Libxc v2 (or later) stream """ def __init__(self, info, read): VerifyBase.__init__(self, info, read) @@ -144,9 +143,9 @@ def verify_ihdr(self): raise StreamError("Bad image id: Expected 0x%x, got 0x%x" % (IHDR_IDENT, ident)) - if version != IHDR_VERSION: - raise StreamError("Unknown image version: Expected %d, got %d" % - (IHDR_VERSION, version)) + if version != 2: + raise StreamError("Unknown image version: Expected 2, got %d" % + (version, )) if options & IHDR_OPT_RESZ_MASK: raise StreamError("Reserved bits set in image options field: 0x%x" % From patchwork Tue Dec 24 15:19:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11309521 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DD27513A4 for ; Tue, 24 Dec 2019 15:21:01 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B8194206D3 for ; Tue, 24 Dec 2019 15:21:01 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="eODmVEGn" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B8194206D3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlyZ-0000La-6d; Tue, 24 Dec 2019 15:19:59 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlyY-0000Kt-3H for xen-devel@lists.xenproject.org; Tue, 24 Dec 2019 15:19:58 +0000 X-Inumbo-ID: cdd8b881-2660-11ea-97e5-12813bfff9fa Received: from esa5.hc3370-68.iphmx.com (unknown [216.71.155.168]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id cdd8b881-2660-11ea-97e5-12813bfff9fa; Tue, 24 Dec 2019 15:19:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1577200780; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=x3AtcqfE3m4TuZR8xeTxCYK6xltXQe30zR1OuIH6L0s=; b=eODmVEGnLN/7TjjP7dZpFqH6IHYCRkgqOm1+jYBp0MKh2ErI7W8/oF6H 2ISYWD2wcZrRARs/059D4HIt9V0zjwRqtIuNDgffOYckAOt4J2QsMA2mF gRGGyOrMG9nSFYDpRhl4Lsk5zuFkX2EvJZN4ua3At3c96jmNlZcbFsb2b I=; Authentication-Results: esa5.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa5.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: hZuGunqR0J+J7Uy0CxMiBTWIiBBOxeP3OCstwowXe6ug/qnt6lsoRDCKccCSpP6ir1M16W1DzG fxDgqjaezCGCmgj2iRMG3dgZ+XuueZrHRwoom2a//hhZpgoMo1YfQCTBYkT5iwdyiBvBJ/HXrK ZGtFTFrf5Qgnt3R+O+HDCKHsXjbwH3UEXu9PbZBY4mz4DwILPPIzrKZbM3ZpKKhmzl3Iq7GNa4 6OzOSf7EMkEuVvjYPdKwQoo4nn7wY+Irnc+dsGR3BFY1apE1yVRv0owi7f0QMFkm0ZMTH57gQe +mQ= X-SBRS: 2.7 X-MesageID: 10482751 X-Ironport-Server: esa5.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,351,1571716800"; d="scan'208";a="10482751" From: Andrew Cooper To: Xen-devel Date: Tue, 24 Dec 2019 15:19:26 +0000 Message-ID: <20191224151932.6304-7-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20191224151932.6304-1-andrew.cooper3@citrix.com> References: <20191224151932.6304-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH 06/12] docs/migration Specify migration v3 and STATIC_DATA_END X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Stefano Stabellini , Julien Grall , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , =?utf-8?q?Marek_Marczykowski-G?= =?utf-8?q?=C3=B3recki?= , Jan Beulich , Ian Jackson Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Migration data can be split into two parts - that which is invariant of guest execution, and that which is not. Separate these two with the STATIC_DATA_END record. The short term, we want to move the x86 CPU Policy data into the stream. In the longer term, we want to provisionally send the static data only to the destination as a more robust compatibility check. In both cases, we will want a callback into the higher level toolstack. Mandate the presence of the STATIC_DATA_END record, and declare this v3, along with instructions for how to compatibly interpret a v2 stream. Signed-off-by: Andrew Cooper Acked-by: Ian Jackson --- CC: George Dunlap CC: Ian Jackson CC: Jan Beulich CC: Konrad Rzeszutek Wilk CC: Stefano Stabellini CC: Wei Liu CC: Julien Grall CC: Marek Marczykowski-Górecki --- docs/specs/libxc-migration-stream.pandoc | 39 +++++++++++++++++++++++++++++--- tools/libxc/xc_sr_common.c | 1 + tools/libxc/xc_sr_stream_format.h | 1 + tools/python/xen/migration/libxc.py | 2 ++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/docs/specs/libxc-migration-stream.pandoc b/docs/specs/libxc-migration-stream.pandoc index a7a8a08936..22ff306e0b 100644 --- a/docs/specs/libxc-migration-stream.pandoc +++ b/docs/specs/libxc-migration-stream.pandoc @@ -127,7 +127,7 @@ marker 0xFFFFFFFFFFFFFFFF. id 0x58454E46 ("XENF" in ASCII). -version 0x00000002. The version of this specification. +version 0x00000003. The version of this specification. options bit 0: Endianness. 0 = little-endian, 1 = big-endian. @@ -620,6 +620,21 @@ The count of pfns is: record->length/sizeof(uint64_t). \clearpage +STATIC_DATA_END +--------------- + +A static data end record marks the end of the static state. I.e. state which +is invariant of guest execution. + + + 0 1 2 3 4 5 6 7 octet + +-------------------------------------------------+ + +The end record contains no fields; its body_length is 0. + +\clearpage + + Layout ====== @@ -639,7 +654,9 @@ A typical save record for an x86 PV guest image would look like: * Image header * Domain header -* X86_PV_INFO record +* Static data records: + * X86_PV_INFO record + * STATIC_DATA_END * X86_PV_P2M_FRAMES record * Many PAGE_DATA records * X86_TSC_INFO @@ -667,6 +684,8 @@ A typical save record for an x86 HVM guest image would look like: * Image header * Domain header +* Static data records: + * STATIC_DATA_END * Many PAGE_DATA records * X86_TSC_INFO * HVM_PARAMS @@ -675,9 +694,23 @@ A typical save record for an x86 HVM guest image would look like: HVM_PARAMS must precede HVM_CONTEXT, as certain parameters can affect the validity of architectural state in the context. +Compatibility with older versions +================================= + +v3 compat with v2 +----------------- + +A v3 stream is compatible with a v2 stream, but mandates the presense of a +STATIC_DATA_END record ahead of any memory/register content. This is to ease +the introduction of new static configuration records over time. + +A v3-compatible reciever interpreting a v2 stream should infer the position of +STATIC_DATA_END based on finding the first X86_PV_P2M_FRAMES record (for PV +guests), or PAGE_DATA record (for HVM guests) and behave as if STATIC_DATA_END +had been sent. Legacy Images (x86 only) -======================== +------------------------ Restoring legacy images from older tools shall be handled by translating the legacy format image into this new format. diff --git a/tools/libxc/xc_sr_common.c b/tools/libxc/xc_sr_common.c index dd9a11b4b5..7f22cf0365 100644 --- a/tools/libxc/xc_sr_common.c +++ b/tools/libxc/xc_sr_common.c @@ -36,6 +36,7 @@ static const char *const mandatory_rec_types[] = [REC_TYPE_VERIFY] = "Verify", [REC_TYPE_CHECKPOINT] = "Checkpoint", [REC_TYPE_CHECKPOINT_DIRTY_PFN_LIST] = "Checkpoint dirty pfn list", + [REC_TYPE_STATIC_DATA_END] = "Static data end", }; const char *rec_type_to_str(uint32_t type) diff --git a/tools/libxc/xc_sr_stream_format.h b/tools/libxc/xc_sr_stream_format.h index ae7c0de393..81c9765b0a 100644 --- a/tools/libxc/xc_sr_stream_format.h +++ b/tools/libxc/xc_sr_stream_format.h @@ -73,6 +73,7 @@ struct xc_sr_rhdr #define REC_TYPE_VERIFY 0x0000000dU #define REC_TYPE_CHECKPOINT 0x0000000eU #define REC_TYPE_CHECKPOINT_DIRTY_PFN_LIST 0x0000000fU +#define REC_TYPE_STATIC_DATA_END 0x00000010U #define REC_TYPE_OPTIONAL 0x80000000U diff --git a/tools/python/xen/migration/libxc.py b/tools/python/xen/migration/libxc.py index 63b3558029..d0c4f3527d 100644 --- a/tools/python/xen/migration/libxc.py +++ b/tools/python/xen/migration/libxc.py @@ -56,6 +56,7 @@ REC_TYPE_verify = 0x0000000d REC_TYPE_checkpoint = 0x0000000e REC_TYPE_checkpoint_dirty_pfn_list = 0x0000000f +REC_TYPE_static_data_end = 0x00000010 rec_type_to_str = { REC_TYPE_end : "End", @@ -74,6 +75,7 @@ REC_TYPE_verify : "Verify", REC_TYPE_checkpoint : "Checkpoint", REC_TYPE_checkpoint_dirty_pfn_list : "Checkpoint dirty pfn list", + REC_TYPE_static_data_end : "Static data end", } # page_data From patchwork Tue Dec 24 15:19:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11309519 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EDE0017EE for ; Tue, 24 Dec 2019 15:20:56 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CA899206D3 for ; Tue, 24 Dec 2019 15:20:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="dToNGyUU" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CA899206D3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlyY-0000LL-SH; Tue, 24 Dec 2019 15:19:58 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlyX-0000KI-5Z for xen-devel@lists.xenproject.org; Tue, 24 Dec 2019 15:19:57 +0000 X-Inumbo-ID: cee1058c-2660-11ea-b6f1-bc764e2007e4 Received: from esa6.hc3370-68.iphmx.com (unknown [216.71.155.175]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id cee1058c-2660-11ea-b6f1-bc764e2007e4; Tue, 24 Dec 2019 15:19:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1577200782; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=layIOlvyz2mflWYBoajH7snKfP2ZntD7gry0s6iWE38=; b=dToNGyUUmMRAsmThyLSYotPPA/fpKVA3AT1qBFr+jcEbvOiTpdlAdnb1 YAHC+8j2KCsErBCpWL9lgFtw8RTzczblKRl/JZ1U/cxGm8Y1YqAswpLuk flTD+FKVLhXh5At5o+/OOFmKrP2LF3xTukL8NQj3H58nJGnZvsSqg79eG 0=; Authentication-Results: esa6.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa6.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: gVdPLoh5JAPxHWft0PE0GvK98eY8IkTvw8A4+oJ2PIDfQUdYx1NGRyq1XbaM5xoswfF0h95AE1 fdjReqh+D2lMil/HZe3eHWNRuF2LAcDD02UCnrnOYjUVse/2l1TlWusaElg8Jjm+U6KhDzY5iU zYPDxnZDr/EaOZRgfT2Cia1qooE8f5+LcZ2gH9KyhIX/4pWGapiV+s9T0VSMWOM9ZISmejrAlX a62BBMjMx3l8NBMrtDCSEeANmVTXhRiSLEv0lcxpg+GwIx+1wbNQpYK9X5N1TLcqwbN4hpDnQF MH0= X-SBRS: 2.7 X-MesageID: 10540372 X-Ironport-Server: esa6.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,351,1571716800"; d="scan'208";a="10540372" From: Andrew Cooper To: Xen-devel Date: Tue, 24 Dec 2019 15:19:27 +0000 Message-ID: <20191224151932.6304-8-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20191224151932.6304-1-andrew.cooper3@citrix.com> References: <20191224151932.6304-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH 07/12] python/migration: Update validation logic to understand a v3 stream X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , =?utf-8?q?Marek_Marczykowski-?= =?utf-8?q?G=C3=B3recki?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Signed-off-by: Andrew Cooper --- CC: Marek Marczykowski-Górecki --- tools/python/xen/migration/libxc.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/tools/python/xen/migration/libxc.py b/tools/python/xen/migration/libxc.py index d0c4f3527d..5fb51b56ac 100644 --- a/tools/python/xen/migration/libxc.py +++ b/tools/python/xen/migration/libxc.py @@ -119,6 +119,7 @@ class VerifyLibxc(VerifyBase): def __init__(self, info, read): VerifyBase.__init__(self, info, read) + self.version = 0 self.squashed_pagedata_records = 0 @@ -145,9 +146,12 @@ def verify_ihdr(self): raise StreamError("Bad image id: Expected 0x%x, got 0x%x" % (IHDR_IDENT, ident)) - if version != 2: - raise StreamError("Unknown image version: Expected 2, got %d" % - (version, )) + if not (2 <= version <= 3): + raise StreamError( + "Unknown image version: Expected 2 <= ver <= 3, got %d" % + (version, )) + + self.version = version if options & IHDR_OPT_RESZ_MASK: raise StreamError("Reserved bits set in image options field: 0x%x" % @@ -164,7 +168,8 @@ def verify_ihdr(self): "Stream is not native endianess - unable to validate") endian = ["little", "big"][options & IHDR_OPT_LE] - self.info("Libxc Image Header: %s endian" % (endian, )) + self.info("Libxc Image Header: Version %d, %s endian" % + (version, endian)) def verify_dhdr(self): @@ -424,6 +429,16 @@ def verify_record_checkpoint_dirty_pfn_list(self, content): raise RecordError("Found checkpoint dirty pfn list record in stream") + def verify_record_static_data_end(self, content): + """ static data end record """ + + if len(content) != 0: + raise RecordError("End record with non-zero length") + + if self.version < 3: + raise RecordError("Static data end record found in v2 stream") + + record_verifiers = { REC_TYPE_end: VerifyLibxc.verify_record_end, @@ -465,4 +480,7 @@ def verify_record_checkpoint_dirty_pfn_list(self, content): VerifyLibxc.verify_record_checkpoint, REC_TYPE_checkpoint_dirty_pfn_list: VerifyLibxc.verify_record_checkpoint_dirty_pfn_list, + + REC_TYPE_static_data_end: + VerifyLibxc.verify_record_static_data_end, } From patchwork Tue Dec 24 15:19:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11309525 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CD5AD6C1 for ; Tue, 24 Dec 2019 15:21:05 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9E843206D3 for ; Tue, 24 Dec 2019 15:21:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="VH/0fAx8" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9E843206D3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlye-0000ke-Pw; Tue, 24 Dec 2019 15:20:04 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlyd-0000aM-3b for xen-devel@lists.xenproject.org; Tue, 24 Dec 2019 15:20:03 +0000 X-Inumbo-ID: cdd8b883-2660-11ea-97e5-12813bfff9fa Received: from esa5.hc3370-68.iphmx.com (unknown [216.71.155.168]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id cdd8b883-2660-11ea-97e5-12813bfff9fa; Tue, 24 Dec 2019 15:19:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1577200781; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=oG02qkIoQf6BR/eNaATw59qDvYQbyCXkFXPiQUiHJmg=; b=VH/0fAx8R+nFjJLUkE7DDYH0ijq0ca5l8nDGeguyVs6CReIG96mYr8DN 6r50sEYgEZElklyKCx70cCWZHsTmtcXGkpYOi7763nGdRh7g70EfL6iXx SpPbL7+tlEgzZWOk1MO39mRUhVnlYCx7eQdaxt6WEEdf4cTjqR5yUTq58 Q=; Authentication-Results: esa5.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa5.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: 2IqP6V0Fnq+PyVan2TfVu9aD+p+5KyULCuk/9mzMfAo53fPpIIfVvAd3f8F/13fgDvjVp7HxqH dDmDZANrWV0nD55MB8RZ3TH60+QO+k/7FkaOLqlAHuWqJTPpSNnHbHgo03PczcX61pHV37N+x/ 5rgsDe5hDLd/buu9k6/3yu0+IBscAUoDg3pM5XDNfue1+HZrh2fehr/VebGatHiLuzkhFyQLFs /WA7qiBj/hhT1suQSqp5hrnVxriaaMbsvQa95VHV8I4vAy/pkigrKvwHJh6/1aZAmY13foXVg+ LoY= X-SBRS: 2.7 X-MesageID: 10482753 X-Ironport-Server: esa5.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,351,1571716800"; d="scan'208";a="10482753" From: Andrew Cooper To: Xen-devel Date: Tue, 24 Dec 2019 15:19:28 +0000 Message-ID: <20191224151932.6304-9-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20191224151932.6304-1-andrew.cooper3@citrix.com> References: <20191224151932.6304-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH 08/12] libxc/restore: Support v3 streams, and cope with v2 compatibilty X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Ian Jackson Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Introduce a static_data_complete() hook which is called when a STATIC_DATA_END record is found (v3) or inferred (v2). Modify handle_page_data() and handle_x86_pv_p2m_frames() to infer the position in v2 streams. The implementation of x86_static_data_complete() needs to wait until more plumbing is in place, to make a combined libxl/libxc change to maintain (functional) bisectability. No practical change to behaviour - this is all plumbing work. Signed-off-by: Andrew Cooper --- CC: Ian Jackson CC: Wei Liu --- tools/libxc/xc_sr_common.h | 19 +++++++++++++++ tools/libxc/xc_sr_common_x86.c | 7 ++++++ tools/libxc/xc_sr_common_x86.h | 5 ++++ tools/libxc/xc_sr_restore.c | 47 +++++++++++++++++++++++++++++++++++-- tools/libxc/xc_sr_restore_x86_hvm.c | 1 + tools/libxc/xc_sr_restore_x86_pv.c | 18 ++++++++++++++ 6 files changed, 95 insertions(+), 2 deletions(-) diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h index 0289c01e13..2e9a4bc587 100644 --- a/tools/libxc/xc_sr_common.h +++ b/tools/libxc/xc_sr_common.h @@ -153,6 +153,13 @@ struct xc_sr_restore_ops int (*process_record)(struct xc_sr_context *ctx, struct xc_sr_record *rec); /** + * Perform any actions required after the static data has arrived. Called + * when the STATIC_DATA_COMPLETE record has been recieved (or inferred in + * v2-compatibility mode). + */ + int (*static_data_complete)(struct xc_sr_context *ctx); + + /** * Perform any actions required after the stream has been finished. Called * after the END record has been received. */ @@ -255,6 +262,12 @@ struct xc_sr_context /* Currently buffering records between a checkpoint */ bool buffer_all_records; + /* + * Whether a STATIC_DATA_END record has been seen (or implied for + * v2 compatibility). + */ + bool seen_static_data_end; + /* * With Remus/COLO, we buffer the records sent by the primary at checkpoint, * in case the primary will fail, we can recover from the last @@ -427,6 +440,12 @@ int read_record(struct xc_sr_context *ctx, int fd, struct xc_sr_record *rec); int populate_pfns(struct xc_sr_context *ctx, unsigned int count, const xen_pfn_t *original_pfns, const uint32_t *types); +/* + * Handle a STATIC_DATA_END record. For a v2 compat stream, the position of + * this record is inferred from other records. + */ +int handle_static_data_end(struct xc_sr_context *ctx); + #endif /* * Local variables: diff --git a/tools/libxc/xc_sr_common_x86.c b/tools/libxc/xc_sr_common_x86.c index 011684df97..083454d256 100644 --- a/tools/libxc/xc_sr_common_x86.c +++ b/tools/libxc/xc_sr_common_x86.c @@ -42,6 +42,13 @@ int handle_x86_tsc_info(struct xc_sr_context *ctx, struct xc_sr_record *rec) return 0; } +int x86_static_data_complete(struct xc_sr_context *ctx) +{ + /* TODO - something useful. */ + + return 0; +} + /* * Local variables: * mode: C diff --git a/tools/libxc/xc_sr_common_x86.h b/tools/libxc/xc_sr_common_x86.h index ebc4355bd1..7c2d42efe8 100644 --- a/tools/libxc/xc_sr_common_x86.h +++ b/tools/libxc/xc_sr_common_x86.h @@ -14,6 +14,11 @@ int write_x86_tsc_info(struct xc_sr_context *ctx); */ int handle_x86_tsc_info(struct xc_sr_context *ctx, struct xc_sr_record *rec); +/* + * Perform common x86 actions required after the static data has arrived. + */ +int x86_static_data_complete(struct xc_sr_context *ctx); + #endif /* * Local variables: diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c index 0280e55d4b..d4bd60a31e 100644 --- a/tools/libxc/xc_sr_restore.c +++ b/tools/libxc/xc_sr_restore.c @@ -35,9 +35,9 @@ static int read_headers(struct xc_sr_context *ctx) return -1; } - if ( ihdr.version != 2 ) + if ( ihdr.version < 2 || ihdr.version > 3 ) { - ERROR("Invalid Version: Expected 2, Got %d", + ERROR("Invalid Version: Expected 2 <= ver <= 3, Got %d", ihdr.version); return -1; } @@ -342,6 +342,30 @@ static int handle_page_data(struct xc_sr_context *ctx, struct xc_sr_record *rec) xen_pfn_t *pfns = NULL, pfn; uint32_t *types = NULL, type; + /* + * This is a bit of a bodge, but it is less bad than duplicating + * handle_page_data() between different architectures. + */ +#if defined(__i386__) || defined(__x86_64__) + /* v2 compat. Infer the position of STATIC_DATA_END. */ + if ( ctx->restore.format_version < 3 && !ctx->restore.seen_static_data_end ) + { + rc = handle_static_data_end(ctx); + if ( rc ) + { + ERROR("Inferred STATIC_DATA_END record failed"); + goto err; + } + rc = -1; + } + + if ( !ctx->restore.seen_static_data_end ) + { + ERROR("No STATIC_DATA_END seen"); + goto err; + } +#endif + if ( rec->length < sizeof(*pages) ) { ERROR("PAGE_DATA record truncated: length %u, min %zu", @@ -631,6 +655,21 @@ static int buffer_record(struct xc_sr_context *ctx, struct xc_sr_record *rec) return 0; } +int handle_static_data_end(struct xc_sr_context *ctx) +{ + xc_interface *xch = ctx->xch; + + if ( ctx->restore.seen_static_data_end ) + { + ERROR("Multiple STATIC_DATA_END records found"); + return -1; + } + + ctx->restore.seen_static_data_end = true; + + return ctx->restore.ops.static_data_complete(ctx); +} + static int process_record(struct xc_sr_context *ctx, struct xc_sr_record *rec) { xc_interface *xch = ctx->xch; @@ -654,6 +693,10 @@ static int process_record(struct xc_sr_context *ctx, struct xc_sr_record *rec) rc = handle_checkpoint(ctx); break; + case REC_TYPE_STATIC_DATA_END: + rc = handle_static_data_end(ctx); + break; + default: rc = ctx->restore.ops.process_record(ctx, rec); break; diff --git a/tools/libxc/xc_sr_restore_x86_hvm.c b/tools/libxc/xc_sr_restore_x86_hvm.c index 3f78248f32..94f47f2589 100644 --- a/tools/libxc/xc_sr_restore_x86_hvm.c +++ b/tools/libxc/xc_sr_restore_x86_hvm.c @@ -239,6 +239,7 @@ struct xc_sr_restore_ops restore_ops_x86_hvm = .localise_page = x86_hvm_localise_page, .setup = x86_hvm_setup, .process_record = x86_hvm_process_record, + .static_data_complete = x86_static_data_complete, .stream_complete = x86_hvm_stream_complete, .cleanup = x86_hvm_cleanup, }; diff --git a/tools/libxc/xc_sr_restore_x86_pv.c b/tools/libxc/xc_sr_restore_x86_pv.c index 8f61a5e8b9..90b1e5427b 100644 --- a/tools/libxc/xc_sr_restore_x86_pv.c +++ b/tools/libxc/xc_sr_restore_x86_pv.c @@ -679,6 +679,23 @@ static int handle_x86_pv_p2m_frames(struct xc_sr_context *ctx, unsigned int start, end, x, fpp = PAGE_SIZE / ctx->x86.pv.width; int rc; + /* v2 compat. Infer the position of STATIC_DATA_END. */ + if ( ctx->restore.format_version < 3 && !ctx->restore.seen_static_data_end ) + { + rc = handle_static_data_end(ctx); + if ( rc ) + { + ERROR("Inferred STATIC_DATA_END record failed"); + return rc; + } + } + + if ( !ctx->restore.seen_static_data_end ) + { + ERROR("No STATIC_DATA_END seen"); + return -1; + } + if ( !ctx->x86.pv.restore.seen_pv_info ) { ERROR("Not yet received X86_PV_INFO record"); @@ -1168,6 +1185,7 @@ struct xc_sr_restore_ops restore_ops_x86_pv = .localise_page = x86_pv_localise_page, .setup = x86_pv_setup, .process_record = x86_pv_process_record, + .static_data_complete = x86_static_data_complete, .stream_complete = x86_pv_stream_complete, .cleanup = x86_pv_cleanup, }; From patchwork Tue Dec 24 15:19:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11309515 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DDD7D6C1 for ; Tue, 24 Dec 2019 15:20:55 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B7F7B20706 for ; Tue, 24 Dec 2019 15:20:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="HOwULLze" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B7F7B20706 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlyU-0000Fw-Hh; Tue, 24 Dec 2019 15:19:54 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijlyT-0000F5-2p for xen-devel@lists.xenproject.org; Tue, 24 Dec 2019 15:19:53 +0000 X-Inumbo-ID: cdd8b87e-2660-11ea-97e5-12813bfff9fa Received: from esa5.hc3370-68.iphmx.com (unknown [216.71.155.168]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id cdd8b87e-2660-11ea-97e5-12813bfff9fa; Tue, 24 Dec 2019 15:19:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1577200780; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=BgJBwMwc+2ZgDVUftpuJ89tJoR9wAvhwn6Ya11l9r0g=; b=HOwULLzeyoMefa2QUo+sQrKWH39XNWscXdFG6lVM6rfmnvQizVAyu7Tp F82XJo8LXM6e9um9PvwSHb6gy7OhnDvnNGrGEpyDQ+RUGwx4NVT9ceRRf riH6ojrFqBoXrW5ihkO1PYZg6/JpJ0urb26UnFdV/8DgR3DDDP1Ua4vsd k=; Authentication-Results: esa5.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa5.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: pY8uPqMyVJlUYbRUz3s9kmUK13b7iTA07gfVLevMTXxpnWHY9EXb0RvsAZ51I0XiI6uoFsrfL7 s4fdNI5alKpijFBu5vj12lfp69ObEJLVMGLE3wsxyAO1x+0cmPWLbFN404uQLfVrQP24FF64Uc 57AlF9HW2GQFhDCCNu/gGeJMPsj9Qnwf2Pz1Rv1Yj6qHdxBI1bBtj/ZYSrHCzxk6kQ2tSUH3GX BSoPI8tbA92cGP8ci9PQBs9ie/4JUPZ6aaKcNfUteQGTbkMY+vGD8ft96RKNwbyMrqixPQBqgE Bbc= X-SBRS: 2.7 X-MesageID: 10482750 X-Ironport-Server: esa5.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,351,1571716800"; d="scan'208";a="10482750" From: Andrew Cooper To: Xen-devel Date: Tue, 24 Dec 2019 15:19:29 +0000 Message-ID: <20191224151932.6304-10-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20191224151932.6304-1-andrew.cooper3@citrix.com> References: <20191224151932.6304-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH 09/12] libxc/save: Write a v3 stream X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , =?utf-8?q?Marek_Marczykowski-?= =?utf-8?q?G=C3=B3recki?= , Wei Liu , Ian Jackson Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Introduce a new static_data() hook which is responsible for writing out any static data records. The HVM side continues to be a no-op, while the PV side moves write_x86_pv_info() into this earlier hook. The the common code writes out a STATIC_DATA_END record, and the stream version is bumped to 3. Update convert-legacy-stream to write a v3 stream, because this will bypass the compatiblity logic in libxc. Signed-off-by: Andrew Cooper Acked-by: Ian Jackson --- CC: Ian Jackson CC: Wei Liu CC: Marek Marczykowski-Górecki --- tools/libxc/xc_sr_common.h | 10 ++++++++-- tools/libxc/xc_sr_save.c | 14 +++++++++++++- tools/libxc/xc_sr_save_x86_hvm.c | 6 ++++++ tools/libxc/xc_sr_save_x86_pv.c | 10 ++++++---- tools/python/scripts/convert-legacy-stream | 9 ++++++++- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h index 2e9a4bc587..3f52ef7d53 100644 --- a/tools/libxc/xc_sr_common.h +++ b/tools/libxc/xc_sr_common.h @@ -63,8 +63,14 @@ struct xc_sr_save_ops int (*setup)(struct xc_sr_context *ctx); /** - * Send records which need to be at the start of the stream. This is - * called once, after the Image and Domain headers are written. + * Send static records at the head of the stream. This is called once, + * after the Image and Domain headers are written. + */ + int (*static_data)(struct xc_sr_context *ctx); + + /** + * Send dynamic records which need to be at the start of the stream. This + * is called after the STATIC_DATA_END record is written. */ int (*start_of_stream)(struct xc_sr_context *ctx); diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c index fa1a2e6c2a..f24dd0d00b 100644 --- a/tools/libxc/xc_sr_save.c +++ b/tools/libxc/xc_sr_save.c @@ -13,7 +13,7 @@ static int write_headers(struct xc_sr_context *ctx, uint16_t guest_type) struct xc_sr_ihdr ihdr = { .marker = IHDR_MARKER, .id = htonl(IHDR_ID), - .version = htonl(2), + .version = htonl(3), .options = htons(IHDR_OPT_LITTLE_ENDIAN), }; struct xc_sr_dhdr dhdr = { @@ -55,6 +55,16 @@ static int write_end_record(struct xc_sr_context *ctx) } /* + * Writes a STATIC_DATA_END record into the stream. + */ +static int write_static_data_end_record(struct xc_sr_context *ctx) +{ + struct xc_sr_record end = { .type = REC_TYPE_STATIC_DATA_END }; + + return write_record(ctx, &end); +} + +/* * Writes a CHECKPOINT record into the stream. */ static int write_checkpoint_record(struct xc_sr_context *ctx) @@ -846,6 +856,8 @@ static int save(struct xc_sr_context *ctx, uint16_t guest_type) xc_report_progress_single(xch, "Start of stream"); rc = (write_headers(ctx, guest_type) ?: + ctx->save.ops.static_data(ctx) ?: + write_static_data_end_record(ctx) ?: ctx->save.ops.start_of_stream(ctx)); if ( rc ) goto err; diff --git a/tools/libxc/xc_sr_save_x86_hvm.c b/tools/libxc/xc_sr_save_x86_hvm.c index 58722118ae..c146e827bc 100644 --- a/tools/libxc/xc_sr_save_x86_hvm.c +++ b/tools/libxc/xc_sr_save_x86_hvm.c @@ -170,6 +170,11 @@ static int x86_hvm_setup(struct xc_sr_context *ctx) return 0; } +static int x86_hvm_static_data(struct xc_sr_context *ctx) +{ + return 0; +} + static int x86_hvm_start_of_stream(struct xc_sr_context *ctx) { return 0; @@ -213,6 +218,7 @@ struct xc_sr_save_ops save_ops_x86_hvm = .pfn_to_gfn = x86_hvm_pfn_to_gfn, .normalise_page = x86_hvm_normalise_page, .setup = x86_hvm_setup, + .static_data = x86_hvm_static_data, .start_of_stream = x86_hvm_start_of_stream, .start_of_checkpoint = x86_hvm_start_of_checkpoint, .end_of_checkpoint = x86_hvm_end_of_checkpoint, diff --git a/tools/libxc/xc_sr_save_x86_pv.c b/tools/libxc/xc_sr_save_x86_pv.c index c1c6892666..9d1ca6ead7 100644 --- a/tools/libxc/xc_sr_save_x86_pv.c +++ b/tools/libxc/xc_sr_save_x86_pv.c @@ -1028,14 +1028,15 @@ static int x86_pv_setup(struct xc_sr_context *ctx) map_p2m(ctx)); } +static int x86_pv_static_data(struct xc_sr_context *ctx) +{ + return write_x86_pv_info(ctx); +} + static int x86_pv_start_of_stream(struct xc_sr_context *ctx) { int rc; - rc = write_x86_pv_info(ctx); - if ( rc ) - return rc; - /* * Ideally should be able to change during migration. Currently * corruption will occur if the contents or location of the P2M changes @@ -1090,6 +1091,7 @@ struct xc_sr_save_ops save_ops_x86_pv = .pfn_to_gfn = x86_pv_pfn_to_gfn, .normalise_page = x86_pv_normalise_page, .setup = x86_pv_setup, + .static_data = x86_pv_static_data, .start_of_stream = x86_pv_start_of_stream, .start_of_checkpoint = x86_pv_start_of_checkpoint, .end_of_checkpoint = x86_pv_end_of_checkpoint, diff --git a/tools/python/scripts/convert-legacy-stream b/tools/python/scripts/convert-legacy-stream index 02a194178f..ca93a93848 100755 --- a/tools/python/scripts/convert-legacy-stream +++ b/tools/python/scripts/convert-legacy-stream @@ -79,7 +79,7 @@ def write_libxc_ihdr(): stream_write(pack(libxc.IHDR_FORMAT, libxc.IHDR_MARKER, # Marker libxc.IHDR_IDENT, # Ident - 2, # Version + 3, # Version libxc.IHDR_OPT_LE, # Options 0, 0)) # Reserved @@ -166,6 +166,9 @@ def write_libxc_hvm_params(params): pack(libxc.HVM_PARAMS_FORMAT, len(params) / 2, 0), pack("Q" * len(params), *params)) +def write_libxc_static_data_end(): + write_record(libxc.REC_TYPE_static_data_end) + def write_libxl_end(): write_record(libxl.REC_TYPE_end) @@ -590,6 +593,10 @@ def read_legacy_stream(vm): if pv: read_pv_extended_info(vm) + + write_libxc_static_data_end() + + if pv: read_pv_p2m_frames(vm) read_chunks(vm) From patchwork Tue Dec 24 15:19:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11309535 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6A51113A4 for ; Tue, 24 Dec 2019 15:42:05 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3BBE120643 for ; Tue, 24 Dec 2019 15:42:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="GyrKAEF2" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3BBE120643 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijmIi-0003dH-38; Tue, 24 Dec 2019 15:40:48 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijmIg-0003dC-MD for xen-devel@lists.xenproject.org; Tue, 24 Dec 2019 15:40:46 +0000 X-Inumbo-ID: bff69df4-2663-11ea-97ed-12813bfff9fa Received: from esa6.hc3370-68.iphmx.com (unknown [216.71.155.175]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id bff69df4-2663-11ea-97ed-12813bfff9fa; Tue, 24 Dec 2019 15:40:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1577202045; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=bXEprMdLnMAsSlQbR/hJu92Hzj+lCqsYWq7oAUAnzeg=; b=GyrKAEF2cOjfHBmltjjLj19+tKByqmdHZciP+jCWmwzZCjwWKDgwaiz8 cuDJkGsiu7aVohtx86UnNu2ij9KNNmuPONKYFVzF1HaZLlk2JKK5qgjCU qYXOLCQuPuo59nrzq2VaDY2RqHAqy/N0WGbORdy5hX5CKvQgl6EQJ8LPg s=; Authentication-Results: esa6.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa6.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: CpihqIqiA015DtGqXlIOkvsx3U9H9xe397esLnM46fieVEui9AKQgIi23rQIwaQmTniM9Dgh9e tMX0M8A7XM37DS3L0i9zbv0myV71ehWvhbLpKZXnyYfFSj6wyT3qrkANnWjWP1TdrYgV8DnmbT 2yXCyA/e4KKcoOCJ5aXDv0Zx1mcaKMJXp0Fl+msrZkfmt6468rBT9lYHETMW/+hM0j3+A3jepW GmoJvq5EwpoUaWqYH9Hxu1b4IXcHdy0WZEfxh71U6Oc7hQwy7Ej07y+f7sQu/bcYDLKApntVsF 3Po= X-SBRS: 2.7 X-MesageID: 10541027 X-Ironport-Server: esa6.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,351,1571716800"; d="scan'208";a="10541027" From: Andrew Cooper To: Xen-devel Date: Tue, 24 Dec 2019 15:19:30 +0000 Message-ID: <20191224151932.6304-11-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20191224151932.6304-1-andrew.cooper3@citrix.com> References: <20191224151932.6304-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH 10/12] docs/migration: Specify X86_{CPUID, MSR}_POLICY records X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Stefano Stabellini , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Tim Deegan , =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= , Julien Grall , Jan Beulich , Ian Jackson Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" These two records move blobs from the XEN_DOMCTL_{get,set}_cpu_policy hypercall. Signed-off-by: Andrew Cooper --- CC: George Dunlap CC: Ian Jackson CC: Jan Beulich CC: Konrad Rzeszutek Wilk CC: Stefano Stabellini CC: Tim Deegan CC: Wei Liu CC: Julien Grall CC: Marek Marczykowski-Górecki --- docs/specs/libxc-migration-stream.pandoc | 42 +++++++++++++++++++++++++++++++ tools/libxc/xc_sr_common.c | 2 ++ tools/libxc/xc_sr_stream_format.h | 2 ++ tools/python/xen/migration/libxc.py | 43 ++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+) diff --git a/docs/specs/libxc-migration-stream.pandoc b/docs/specs/libxc-migration-stream.pandoc index 22ff306e0b..3a0915b795 100644 --- a/docs/specs/libxc-migration-stream.pandoc +++ b/docs/specs/libxc-migration-stream.pandoc @@ -634,6 +634,46 @@ The end record contains no fields; its body_length is 0. \clearpage +X86_CPUID_POLICY +---------------- + +CPUID policy content, as accessed by the XEN_DOMCTL_{get,set}_cpu_policy +hypercall sub-ops. + + 0 1 2 3 4 5 6 7 octet + +-------------------------------------------------+ + | CPUID_policy | + ... + +-------------------------------------------------+ + +-------------------------------------------------------------------- +Field Description +------------ --------------------------------------------------- +CPUID_policy Array of xen_cpuid_leaf_t[]'s +-------------------------------------------------------------------- + +\clearpage + +X86_MSR_POLICY +-------------- + +MSR policy content, as accessed by the XEN_DOMCTL_{get,set}_cpu_policy +hypercall sub-ops. + + 0 1 2 3 4 5 6 7 octet + +-------------------------------------------------+ + | MSR_policy | + ... + +-------------------------------------------------+ + +-------------------------------------------------------------------- +Field Description +---------- --------------------------------------------------- +MSR_policy Array of xen_msr_entry_t[]'s +-------------------------------------------------------------------- + +\clearpage + Layout ====== @@ -656,6 +696,7 @@ A typical save record for an x86 PV guest image would look like: * Domain header * Static data records: * X86_PV_INFO record + * X86_{CPUID,MSR}_POLICY * STATIC_DATA_END * X86_PV_P2M_FRAMES record * Many PAGE_DATA records @@ -685,6 +726,7 @@ A typical save record for an x86 HVM guest image would look like: * Image header * Domain header * Static data records: + * X86_{CPUID,MSR}_POLICY * STATIC_DATA_END * Many PAGE_DATA records * X86_TSC_INFO diff --git a/tools/libxc/xc_sr_common.c b/tools/libxc/xc_sr_common.c index 7f22cf0365..7c54b03414 100644 --- a/tools/libxc/xc_sr_common.c +++ b/tools/libxc/xc_sr_common.c @@ -37,6 +37,8 @@ static const char *const mandatory_rec_types[] = [REC_TYPE_CHECKPOINT] = "Checkpoint", [REC_TYPE_CHECKPOINT_DIRTY_PFN_LIST] = "Checkpoint dirty pfn list", [REC_TYPE_STATIC_DATA_END] = "Static data end", + [REC_TYPE_X86_CPUID_POLICY] = "x86 CPUID policy", + [REC_TYPE_X86_MSR_POLICY] = "x86 MSR policy", }; const char *rec_type_to_str(uint32_t type) diff --git a/tools/libxc/xc_sr_stream_format.h b/tools/libxc/xc_sr_stream_format.h index 81c9765b0a..8a0da26f75 100644 --- a/tools/libxc/xc_sr_stream_format.h +++ b/tools/libxc/xc_sr_stream_format.h @@ -74,6 +74,8 @@ struct xc_sr_rhdr #define REC_TYPE_CHECKPOINT 0x0000000eU #define REC_TYPE_CHECKPOINT_DIRTY_PFN_LIST 0x0000000fU #define REC_TYPE_STATIC_DATA_END 0x00000010U +#define REC_TYPE_X86_CPUID_POLICY 0x00000011U +#define REC_TYPE_X86_MSR_POLICY 0x00000012U #define REC_TYPE_OPTIONAL 0x80000000U diff --git a/tools/python/xen/migration/libxc.py b/tools/python/xen/migration/libxc.py index 5fb51b56ac..9881f5ced4 100644 --- a/tools/python/xen/migration/libxc.py +++ b/tools/python/xen/migration/libxc.py @@ -57,6 +57,8 @@ REC_TYPE_checkpoint = 0x0000000e REC_TYPE_checkpoint_dirty_pfn_list = 0x0000000f REC_TYPE_static_data_end = 0x00000010 +REC_TYPE_x86_cpuid_policy = 0x00000011 +REC_TYPE_x86_msr_policy = 0x00000012 rec_type_to_str = { REC_TYPE_end : "End", @@ -76,6 +78,8 @@ REC_TYPE_checkpoint : "Checkpoint", REC_TYPE_checkpoint_dirty_pfn_list : "Checkpoint dirty pfn list", REC_TYPE_static_data_end : "Static data end", + REC_TYPE_x86_cpuid_policy : "x86 CPUID policy", + REC_TYPE_x86_msr_policy : "x86 MSR policy", } # page_data @@ -113,6 +117,12 @@ HVM_PARAMS_ENTRY_FORMAT = "QQ" HVM_PARAMS_FORMAT = "II" +# x86_cpuid_policy => xen_cpuid_leaf_t[] +X86_CPUID_POLICY_FORMAT = "IIIIII" + +# x86_msr_policy => xen_msr_entry_t[] +X86_MSR_POLICY_FORMAT = "QII" + class VerifyLibxc(VerifyBase): """ Verify a Libxc v2 (or later) stream """ @@ -439,6 +449,34 @@ def verify_record_static_data_end(self, content): raise RecordError("Static data end record found in v2 stream") + def verify_record_x86_cpuid_policy(self, content): + """ x86 CPUID policy record """ + + if self.version < 3: + raise RecordError("x86 CPUID policy record found in v2 stream") + + sz = calcsize(X86_CPUID_POLICY_FORMAT) + contentsz = len(content) + + if contentsz < sz or (contentsz % sz) != 0: + raise RecordError("Record length %u, expected multiple of %u" % + (contentsz, sz)) + + + def verify_record_x86_msr_policy(self, content): + """ x86 MSR policy record """ + + if self.version < 3: + raise RecordError("x86 MSR policy record found in v2 stream") + + sz = calcsize(X86_MSR_POLICY_FORMAT) + contentsz = len(content) + + if contentsz < sz or (contentsz % sz) != 0: + raise RecordError("Record length %u, expected multiple of %u" % + (contentsz, sz)) + + record_verifiers = { REC_TYPE_end: VerifyLibxc.verify_record_end, @@ -483,4 +521,9 @@ def verify_record_static_data_end(self, content): REC_TYPE_static_data_end: VerifyLibxc.verify_record_static_data_end, + + REC_TYPE_x86_cpuid_policy: + VerifyLibxc.verify_record_x86_cpuid_policy, + REC_TYPE_x86_msr_policy: + VerifyLibxc.verify_record_x86_msr_policy, } From patchwork Tue Dec 24 15:19:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11309531 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4E56313A4 for ; Tue, 24 Dec 2019 15:41:58 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1EEC820643 for ; Tue, 24 Dec 2019 15:41:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="W2qzTils" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1EEC820643 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijmIn-0003dW-Ct; Tue, 24 Dec 2019 15:40:53 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijmIm-0003dQ-3S for xen-devel@lists.xenproject.org; Tue, 24 Dec 2019 15:40:52 +0000 X-Inumbo-ID: be703bca-2663-11ea-88e7-bc764e2007e4 Received: from esa2.hc3370-68.iphmx.com (unknown [216.71.145.153]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id be703bca-2663-11ea-88e7-bc764e2007e4; Tue, 24 Dec 2019 15:40:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1577202044; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=4fBapI9z/Ms+ixWeUrkyCN8fJrLRsHqVO9a2fRn+69o=; b=W2qzTilsVB3tY4QCsI4OANP2Env+btfBLp7ZVKONQMEiYdS7U7cnBf7R XwVV+qafhEsjof6EXeH0K2Q8z5QNwOEIm96oNeVuZbHyLYP0aycB9x3Ap IFtWqckuvyS+dRg+w1TLPgVi03ha7hWytq+fdXSW8GIt+Nrkm9fPXxpbG w=; Authentication-Results: esa2.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa2.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa2.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa2.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: lhpDStWcvWfCljV8jH97FFhZwk42l0YOizboElBhUSSaoulaJ60VPQrSnVxal9gm6CQfc1W4t3 HhRieveMpjpiXGxGY7WuBg6FawKspkW9ZMyCFqn4YnOCEczEr23cLjCmHvrNyAggFGqhSROJsG HymPF4LHIiL8GVS2qA6xnO4XfSijGmGCELrv3EmUHmWxx1hc+cedzSJkSJxb2XcRl8lBiPWsWZ DHlwgoSWlysEwpubJwzEjVyROICMsF7805byyADjRYLB65f2OH0O0lO2is85IBVOHttBxYO17B OiY= X-SBRS: 2.7 X-MesageID: 10129278 X-Ironport-Server: esa2.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,351,1571716800"; d="scan'208";a="10129278" From: Andrew Cooper To: Xen-devel Date: Tue, 24 Dec 2019 15:19:31 +0000 Message-ID: <20191224151932.6304-12-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20191224151932.6304-1-andrew.cooper3@citrix.com> References: <20191224151932.6304-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH 11/12] libxc/restore: Handle X86_{CPUID, MSR}_DATA records X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Ian Jackson Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" For now, the data are just stashed, and discarded at the end. This will be addressed when the TODO in x86_static_data_complete() is addressed. No practical change to behaviour - this is all plumbing work. Signed-off-by: Andrew Cooper Acked-by: Ian Jackson --- CC: Ian Jackson CC: Wei Liu --- tools/libxc/xc_sr_common.h | 10 ++++++++++ tools/libxc/xc_sr_common_x86.c | 40 +++++++++++++++++++++++++++++++++++++ tools/libxc/xc_sr_common_x86.h | 14 +++++++++++++ tools/libxc/xc_sr_restore_x86_hvm.c | 9 +++++++++ tools/libxc/xc_sr_restore_x86_pv.c | 9 +++++++++ 5 files changed, 82 insertions(+) diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h index 3f52ef7d53..337c746e17 100644 --- a/tools/libxc/xc_sr_common.h +++ b/tools/libxc/xc_sr_common.h @@ -308,6 +308,16 @@ struct xc_sr_context { struct /* x86 */ { + /* Common save/restore data. */ + union + { + struct + { + /* X86_{CPUID,MSR}_DATA blobs for CPU Policy. */ + struct xc_sr_blob cpuid, msr; + } restore; + }; + struct /* x86 PV guest. */ { /* 4 or 8; 32 or 64 bit domain */ diff --git a/tools/libxc/xc_sr_common_x86.c b/tools/libxc/xc_sr_common_x86.c index 083454d256..d4d86bb12f 100644 --- a/tools/libxc/xc_sr_common_x86.c +++ b/tools/libxc/xc_sr_common_x86.c @@ -49,6 +49,46 @@ int x86_static_data_complete(struct xc_sr_context *ctx) return 0; } +int handle_x86_cpuid_policy(struct xc_sr_context *ctx, struct xc_sr_record *rec) +{ + xc_interface *xch = ctx->xch; + int rc; + + if ( rec->length == 0 || + rec->length % sizeof(xen_cpuid_leaf_t) != 0 ) + { + ERROR("X86_CPUID_POLICY size %u should be multiple of %zu", + rec->length, sizeof(xen_cpuid_leaf_t)); + return -1; + } + + rc = update_blob(&ctx->x86.restore.cpuid, rec->data, rec->length); + if ( rc ) + ERROR("Unable to allocate %u bytes for X86_CPUID_POLICY", rec->length); + + return rc; +} + +int handle_x86_msr_policy(struct xc_sr_context *ctx, struct xc_sr_record *rec) +{ + xc_interface *xch = ctx->xch; + int rc; + + if ( rec->length == 0 || + rec->length % sizeof(xen_msr_entry_t) != 0 ) + { + ERROR("X86_MSR_POLICY size %u should be multiple of %zu", + rec->length, sizeof(xen_cpuid_leaf_t)); + return -1; + } + + rc = update_blob(&ctx->x86.restore.msr, rec->data, rec->length); + if ( rc ) + ERROR("Unable to allocate %u bytes for X86_MSR_POLICY", rec->length); + + return rc; +} + /* * Local variables: * mode: C diff --git a/tools/libxc/xc_sr_common_x86.h b/tools/libxc/xc_sr_common_x86.h index 7c2d42efe8..f7fa4fe62b 100644 --- a/tools/libxc/xc_sr_common_x86.h +++ b/tools/libxc/xc_sr_common_x86.h @@ -19,6 +19,20 @@ int handle_x86_tsc_info(struct xc_sr_context *ctx, struct xc_sr_record *rec); */ int x86_static_data_complete(struct xc_sr_context *ctx); +/* + * Parses an X86_CPUID_POLICY record and stashes the content for application + * when a STATIC_DATA_END record is encountered. + */ +int handle_x86_cpuid_policy(struct xc_sr_context *ctx, + struct xc_sr_record *rec); + +/* + * Parses an X86_MSR_POLICY record and stashes the content for application + * when a STATIC_DATA_END record is encountered. + */ +int handle_x86_msr_policy(struct xc_sr_context *ctx, + struct xc_sr_record *rec); + #endif /* * Local variables: diff --git a/tools/libxc/xc_sr_restore_x86_hvm.c b/tools/libxc/xc_sr_restore_x86_hvm.c index 94f47f2589..9190edaee7 100644 --- a/tools/libxc/xc_sr_restore_x86_hvm.c +++ b/tools/libxc/xc_sr_restore_x86_hvm.c @@ -171,6 +171,12 @@ static int x86_hvm_process_record(struct xc_sr_context *ctx, case REC_TYPE_HVM_PARAMS: return handle_hvm_params(ctx, rec); + case REC_TYPE_X86_CPUID_POLICY: + return handle_x86_cpuid_policy(ctx, rec); + + case REC_TYPE_X86_MSR_POLICY: + return handle_x86_msr_policy(ctx, rec); + default: return RECORD_NOT_PROCESSED; } @@ -227,6 +233,9 @@ static int x86_hvm_cleanup(struct xc_sr_context *ctx) { free(ctx->x86.hvm.restore.context.ptr); + free(ctx->x86.restore.cpuid.ptr); + free(ctx->x86.restore.msr.ptr); + return 0; } diff --git a/tools/libxc/xc_sr_restore_x86_pv.c b/tools/libxc/xc_sr_restore_x86_pv.c index 90b1e5427b..3d593753ab 100644 --- a/tools/libxc/xc_sr_restore_x86_pv.c +++ b/tools/libxc/xc_sr_restore_x86_pv.c @@ -1102,6 +1102,12 @@ static int x86_pv_process_record(struct xc_sr_context *ctx, case REC_TYPE_X86_TSC_INFO: return handle_x86_tsc_info(ctx, rec); + case REC_TYPE_X86_CPUID_POLICY: + return handle_x86_cpuid_policy(ctx, rec); + + case REC_TYPE_X86_MSR_POLICY: + return handle_x86_msr_policy(ctx, rec); + default: return RECORD_NOT_PROCESSED; } @@ -1173,6 +1179,9 @@ static int x86_pv_cleanup(struct xc_sr_context *ctx) if ( ctx->x86.pv.m2p ) munmap(ctx->x86.pv.m2p, ctx->x86.pv.nr_m2p_frames * PAGE_SIZE); + free(ctx->x86.restore.cpuid.ptr); + free(ctx->x86.restore.msr.ptr); + return 0; } From patchwork Tue Dec 24 15:19:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11309533 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DF2FB13A4 for ; Tue, 24 Dec 2019 15:42:03 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BAB1820643 for ; Tue, 24 Dec 2019 15:42:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="dtn4pP8o" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BAB1820643 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijmIs-0003ei-RV; Tue, 24 Dec 2019 15:40:58 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1ijmIq-0003eE-VH for xen-devel@lists.xenproject.org; Tue, 24 Dec 2019 15:40:56 +0000 X-Inumbo-ID: bef87422-2663-11ea-b6f1-bc764e2007e4 Received: from esa6.hc3370-68.iphmx.com (unknown [216.71.155.175]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id bef87422-2663-11ea-b6f1-bc764e2007e4; Tue, 24 Dec 2019 15:40:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1577202043; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=KQhkIOgzt49L0i00k4ynvFA0A6jR7i5a5ab8esd54EA=; b=dtn4pP8oOPr+8e7XczNMAyQJNII5loDzGqT9dbOZ0a6Bz0/VyqHxHj9p F2IA1PEdSLRDsVT9z2c4hc0BJjgQFwYUJC5hkwh7P2idBTiMK/RNDpcae to4TJGoe/wNspRJGtxPbO9QrAYAOYFDK+zr7dGixqRQc1JtXe6WRlSNUd c=; Authentication-Results: esa6.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa6.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: bJ1LtwAbfu2lBrqKcluGb8rv8TXteGtmbtGpQnwT2y6Bowu6Rogs4svlXZDUQ1HQfn8BH1pyiB s8Oq1xo6OcJ8yK553UigNokKcGdfxrSkG9MyMTGBck1HnW0Aa4r5yoZB+AwnCtKEvdTrS6vF/F KrbuECntSrTyQcrTnfrTb3hZMX60T5I9k40Vk4OqnVQSzPI5Nwl0gL7qDgpGXvmH5ALZg8CtEC TMYNLGnONO2JsT4nUkk3+jQJLVsQwxBWlozRCRfNgA7T5zNBvvioynt0Pi9JGG8JiqDHwaxvn1 aXU= X-SBRS: 2.7 X-MesageID: 10541026 X-Ironport-Server: esa6.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.69,351,1571716800"; d="scan'208";a="10541026" From: Andrew Cooper To: Xen-devel Date: Tue, 24 Dec 2019 15:19:32 +0000 Message-ID: <20191224151932.6304-13-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20191224151932.6304-1-andrew.cooper3@citrix.com> References: <20191224151932.6304-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH 12/12] libxc/save: Write X86_{CPUID, MSR}_DATA records X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Ian Jackson Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" With all other plumbing in place, obtain the CPU Policy from Xen and write it into the migration stream. Signed-off-by: Andrew Cooper --- CC: Ian Jackson CC: Wei Liu --- tools/libxc/xc_sr_common_x86.c | 50 ++++++++++++++++++++++++++++++++++++++++ tools/libxc/xc_sr_common_x86.h | 6 +++++ tools/libxc/xc_sr_save_x86_hvm.c | 2 +- tools/libxc/xc_sr_save_x86_pv.c | 3 ++- 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/tools/libxc/xc_sr_common_x86.c b/tools/libxc/xc_sr_common_x86.c index d4d86bb12f..09fb1d93d6 100644 --- a/tools/libxc/xc_sr_common_x86.c +++ b/tools/libxc/xc_sr_common_x86.c @@ -49,6 +49,56 @@ int x86_static_data_complete(struct xc_sr_context *ctx) return 0; } +int write_x86_cpu_policy_records(struct xc_sr_context *ctx) +{ + xc_interface *xch = ctx->xch; + struct xc_sr_record cpuid = { .type = REC_TYPE_X86_CPUID_POLICY, }; + struct xc_sr_record msrs = { .type = REC_TYPE_X86_MSR_POLICY, }; + uint32_t nr_leaves = 0, nr_msrs = 0; + int rc; + + if ( xc_get_cpu_policy_size(xch, &nr_leaves, &nr_msrs) < 0 ) + { + PERROR("Unable to get CPU Policy size"); + return -1; + } + + cpuid.data = malloc(nr_leaves * sizeof(xen_cpuid_leaf_t)); + msrs.data = malloc(nr_msrs * sizeof(xen_msr_entry_t)); + if ( !cpuid.data || !msrs.data ) + { + ERROR("Cannot allocate memory for CPU Policy"); + rc = -1; + goto out; + } + + if ( xc_get_domain_cpu_policy(xch, ctx->domid, &nr_leaves, cpuid.data, + &nr_msrs, msrs.data) ) + { + PERROR("Unable to get d%d CPU Policy", ctx->domid); + rc = -1; + goto out; + } + + cpuid.length = nr_leaves * sizeof(xen_cpuid_leaf_t); + if ( cpuid.length ) + { + rc = write_record(ctx, &cpuid); + if ( rc ) + goto out; + } + + msrs.length = nr_msrs * sizeof(xen_msr_entry_t); + if ( msrs.length ) + rc = write_record(ctx, &msrs); + + out: + free(cpuid.data); + free(msrs.data); + + return rc; +} + int handle_x86_cpuid_policy(struct xc_sr_context *ctx, struct xc_sr_record *rec) { xc_interface *xch = ctx->xch; diff --git a/tools/libxc/xc_sr_common_x86.h b/tools/libxc/xc_sr_common_x86.h index f7fa4fe62b..7b1823eca9 100644 --- a/tools/libxc/xc_sr_common_x86.h +++ b/tools/libxc/xc_sr_common_x86.h @@ -20,6 +20,12 @@ int handle_x86_tsc_info(struct xc_sr_context *ctx, struct xc_sr_record *rec); int x86_static_data_complete(struct xc_sr_context *ctx); /* + * Obtains a domains CPU Policy from Xen, and writes X86_{CPUID,MSR}_POLICY + * records into the stream. + */ +int write_x86_cpu_policy_records(struct xc_sr_context *ctx); + +/* * Parses an X86_CPUID_POLICY record and stashes the content for application * when a STATIC_DATA_END record is encountered. */ diff --git a/tools/libxc/xc_sr_save_x86_hvm.c b/tools/libxc/xc_sr_save_x86_hvm.c index c146e827bc..5b95d20b19 100644 --- a/tools/libxc/xc_sr_save_x86_hvm.c +++ b/tools/libxc/xc_sr_save_x86_hvm.c @@ -172,7 +172,7 @@ static int x86_hvm_setup(struct xc_sr_context *ctx) static int x86_hvm_static_data(struct xc_sr_context *ctx) { - return 0; + return write_x86_cpu_policy_records(ctx); } static int x86_hvm_start_of_stream(struct xc_sr_context *ctx) diff --git a/tools/libxc/xc_sr_save_x86_pv.c b/tools/libxc/xc_sr_save_x86_pv.c index 9d1ca6ead7..2e9aa9ea16 100644 --- a/tools/libxc/xc_sr_save_x86_pv.c +++ b/tools/libxc/xc_sr_save_x86_pv.c @@ -1030,7 +1030,8 @@ static int x86_pv_setup(struct xc_sr_context *ctx) static int x86_pv_static_data(struct xc_sr_context *ctx) { - return write_x86_pv_info(ctx); + return (write_x86_pv_info(ctx) ?: + write_x86_cpu_policy_records(ctx)); } static int x86_pv_start_of_stream(struct xc_sr_context *ctx)