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, };