From patchwork Wed Oct 11 14:21:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Olaf Hering X-Patchwork-Id: 9999773 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 2C02760244 for ; Wed, 11 Oct 2017 14:24:07 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1A36028A0A for ; Wed, 11 Oct 2017 14:24:07 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0F09A28A52; Wed, 11 Oct 2017 14:24:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id F220C28A0A for ; Wed, 11 Oct 2017 14:24:05 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e2HtO-0005RK-U5; Wed, 11 Oct 2017 14:21:50 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e2HtO-0005Qn-AB for xen-devel@lists.xen.org; Wed, 11 Oct 2017 14:21:50 +0000 Received: from [85.158.143.35] by server-2.bemta-6.messagelabs.com id 7C/E0-02373-DF82ED95; Wed, 11 Oct 2017 14:21:49 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrHLMWRWlGSWpSXmKPExsUSuHLSQt0/Gvc iDRY9lLZY8nExiwOjx9Hdv5kCGKNYM/OS8isSWDMeTJ7MXvDAuuLB8fQGxpe6XYxcHCwCn5gk jqw7y9bFyMkhIVAosW/nFOYuRg4gW0Tiyf80kBohgZNMEqf3/mEHqWETUJLYe/A4I0hCRGAio 8TB0/cYQRLMAgoSL55vZQKxhQW8JV43bwKzWQRUJQ71z2QFsXkFjCUe75nMDLFMXuL9gvuMIM s4BUwkFnzyAQkLAZV0TfzKOoGRdwEjwypG9eLUorLUIl1jvaSizPSMktzEzBxdQwMzvdzU4uL E9NScxKRiveT83E2MwFBgAIIdjB3/nA4xSnIwKYnyXn9+N1KILyk/pTIjsTgjvqg0J7X4EKMM B4eSBC8LMLSEBItS01Mr0jJzgEEJk5bg4FES4T2sDpTmLS5IzC3OTIdInWI05ji26fIfJo6Om 3f/MAmx5OXnpUqJ87qBTBIAKc0ozYMbBIuWS4yyUsK8jECnCfEUpBblZpagyr9iFOdgVBLmvQ eykCczrwRu3yugU5iAThFNuwNySkkiQkqqgXGd/jTpM6LX6ypK5hj/MztwUE7myNtLwTeTYo6 /XfrS9KHNG9erLDuPTD942n+PoPqkPyt5b+92mnZz6f3NUf8kNXXnLJbItjscKNL1ebXKlIOO G+xbxBo3Mn04s7G7Z19PhLedCIuOrO11lZ0R4qXCL2Q4p8SJqq4py907fZLCo7d16qoGp34os RRnJBpqMRcVJwIAPamygZECAAA= X-Env-Sender: olaf@aepfle.de X-Msg-Ref: server-16.tower-21.messagelabs.com!1507731708!64730497!1 X-Originating-IP: [81.169.146.161] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: QmFkIElQOiA4MS4xNjkuMTQ2LjE2MSA9PiA1ODk3MjY=\n,sa_preprocessor: QmFkIElQOiA4MS4xNjkuMTQ2LjE2MSA9PiA1ODk3MjY=\n X-StarScan-Received: X-StarScan-Version: 9.4.45; banners=-,-,- X-VirusChecked: Checked Received: (qmail 48471 invoked from network); 11 Oct 2017 14:21:48 -0000 Received: from mo4-p00-ob.smtp.rzone.de (HELO mo4-p00-ob.smtp.rzone.de) (81.169.146.161) by server-16.tower-21.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 11 Oct 2017 14:21:48 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1507731708; s=domk; d=aepfle.de; h=References:In-Reply-To:Date:Subject:Cc:To:From; bh=dRikyl3VAvD1Dr0ci9mZ8fS4qF3DK0gcGsbYDl1GnI0=; b=SCoxFQF0Xj3rudgy7WKX3issWx4bioErVchkqmG1mMFvQWsxMU6t9fdjua56aUS/NY JCG1NHSEY4cWea05lcynYQnjidIAkZsp5xRKcuLjkVvM6uvhdU81Vv+yZY1i1gSz1ku9 fBc7q7Cpfjry34l3VP5qEdxUjyW3DSCf7PrLU= X-RZG-AUTH: :P2EQZWCpfu+qG7CngxMFH1J+3q8wa/QDiZbDmui9LcK/RdXt7GAQpV1nK0XLk0Fbzd1FwkwtpDETnMYPl+awhe1GfLaCoLDva5dK X-RZG-CLASS-ID: mo00 Received: from sender ([2001:a61:3425:72ff:16fc:b7d5:a2e5:4df1]) by smtp.strato.de (RZmta 42.5 AUTH) with ESMTPSA id g0af76t9BELX1mW (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA)) (Client did not present a certificate); Wed, 11 Oct 2017 16:21:33 +0200 (CEST) From: Olaf Hering To: xen-devel@lists.xen.org, Andrew Cooper , Ian Jackson , Wei Liu Date: Wed, 11 Oct 2017 16:21:23 +0200 Message-Id: <20171011142124.22052-3-olaf@aepfle.de> X-Mailer: git-send-email 2.14.2 In-Reply-To: <20171011142124.22052-1-olaf@aepfle.de> References: <20171011142124.22052-1-olaf@aepfle.de> Cc: Olaf Hering Subject: [Xen-devel] [PATCH v10 2/3] tools/libxc: add API for bitmap access for restore X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP Extend API for managing bitmaps. Each bitmap is now represented by a generic struct xc_sr_bitmap. Switch the existing populated_pfns to this API. Signed-off-by: Olaf Hering Acked-by: Wei Liu --- tools/libxc/xc_sr_common.c | 41 +++++++++++++++++++++++++ tools/libxc/xc_sr_common.h | 73 +++++++++++++++++++++++++++++++++++++++++++-- tools/libxc/xc_sr_restore.c | 66 ++-------------------------------------- 3 files changed, 115 insertions(+), 65 deletions(-) diff --git a/tools/libxc/xc_sr_common.c b/tools/libxc/xc_sr_common.c index 79b9c3e940..28c7be2b15 100644 --- a/tools/libxc/xc_sr_common.c +++ b/tools/libxc/xc_sr_common.c @@ -155,6 +155,47 @@ static void __attribute__((unused)) build_assertions(void) BUILD_BUG_ON(sizeof(struct xc_sr_rec_hvm_params) != 8); } +/* + * Expand the tracking structures as needed. + * To avoid realloc()ing too excessively, the size increased to the nearest power + * of two large enough to contain the required number of bits. + */ +bool _xc_sr_bitmap_resize(struct xc_sr_bitmap *bm, unsigned long bits) +{ + if ( bits > bm->bits ) + { + size_t new_max; + size_t old_sz, new_sz; + void *p; + + /* Round up to the nearest power of two larger than bit, less 1. */ + new_max = bits; + new_max |= new_max >> 1; + new_max |= new_max >> 2; + new_max |= new_max >> 4; + new_max |= new_max >> 8; + new_max |= new_max >> 16; +#ifdef __x86_64__ + new_max |= new_max >> 32; +#endif + + old_sz = bitmap_size(bm->bits + 1); + new_sz = bitmap_size(new_max + 1); + p = realloc(bm->p, new_sz); + if ( !p ) + return false; + + if (bm->p) + memset(p + old_sz, 0, new_sz - old_sz); + else + memset(p, 0, new_sz); + + bm->p = p; + bm->bits = new_max; + } + return true; +} + /* * Local variables: * mode: C diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h index a83f22af4e..a728c93e53 100644 --- a/tools/libxc/xc_sr_common.h +++ b/tools/libxc/xc_sr_common.h @@ -172,6 +172,12 @@ struct xc_sr_x86_pv_restore_vcpu size_t basicsz, extdsz, xsavesz, msrsz; }; +struct xc_sr_bitmap +{ + void *p; + unsigned long bits; +}; + struct xc_sr_context { xc_interface *xch; @@ -255,8 +261,7 @@ struct xc_sr_context domid_t xenstore_domid, console_domid; /* Bitmap of currently populated PFNs during restore. */ - unsigned long *populated_pfns; - xen_pfn_t max_populated_pfn; + struct xc_sr_bitmap populated_pfns; /* Sender has invoked verify mode on the stream. */ bool verify; @@ -343,6 +348,70 @@ extern struct xc_sr_save_ops save_ops_x86_hvm; extern struct xc_sr_restore_ops restore_ops_x86_pv; extern struct xc_sr_restore_ops restore_ops_x86_hvm; +bool _xc_sr_bitmap_resize(struct xc_sr_bitmap *bm, unsigned long bits); + +static inline bool xc_sr_bitmap_resize(struct xc_sr_bitmap *bm, unsigned long bits) +{ + if ( bits > bm->bits ) + return _xc_sr_bitmap_resize(bm, bits); + return true; +} + +static inline void xc_sr_bitmap_free(struct xc_sr_bitmap *bm) +{ + free( bm->p ); + bm->bits = 0; + bm->p = NULL; +} + +static inline bool xc_sr_set_bit(unsigned long bit, struct xc_sr_bitmap *bm) +{ + if ( !xc_sr_bitmap_resize(bm, bit) ) + return false; + + set_bit(bit, bm->p); + return true; +} + +static inline bool xc_sr_test_bit(unsigned long bit, struct xc_sr_bitmap *bm) +{ + if ( bit > bm->bits || !bm->bits ) + return false; + return !!test_bit(bit, bm->p); +} + +static inline bool xc_sr_test_and_clear_bit(unsigned long bit, struct xc_sr_bitmap *bm) +{ + if ( bit > bm->bits || !bm->bits ) + return false; + return !!test_and_clear_bit(bit, bm->p); +} + +static inline bool xc_sr_test_and_set_bit(unsigned long bit, struct xc_sr_bitmap *bm) +{ + if ( bit > bm->bits || !bm->bits ) + return false; + return !!test_and_set_bit(bit, bm->p); +} + +static inline bool pfn_is_populated(struct xc_sr_context *ctx, xen_pfn_t pfn) +{ + return xc_sr_test_bit(pfn, &ctx->restore.populated_pfns); +} + +static inline int pfn_set_populated(struct xc_sr_context *ctx, xen_pfn_t pfn) +{ + xc_interface *xch = ctx->xch; + + if ( !xc_sr_set_bit(pfn, &ctx->restore.populated_pfns) ) + { + ERROR("Failed to realloc populated_pfns bitmap"); + errno = ENOMEM; + return -1; + } + return 0; +} + struct xc_sr_record { uint32_t type; diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c index a016678332..d53948e1a6 100644 --- a/tools/libxc/xc_sr_restore.c +++ b/tools/libxc/xc_sr_restore.c @@ -68,64 +68,6 @@ static int read_headers(struct xc_sr_context *ctx) return 0; } -/* - * Is a pfn populated? - */ -static bool pfn_is_populated(const struct xc_sr_context *ctx, xen_pfn_t pfn) -{ - if ( pfn > ctx->restore.max_populated_pfn ) - return false; - return test_bit(pfn, ctx->restore.populated_pfns); -} - -/* - * Set a pfn as populated, expanding the tracking structures if needed. To - * avoid realloc()ing too excessively, the size increased to the nearest power - * of two large enough to contain the required pfn. - */ -static int pfn_set_populated(struct xc_sr_context *ctx, xen_pfn_t pfn) -{ - xc_interface *xch = ctx->xch; - - if ( pfn > ctx->restore.max_populated_pfn ) - { - xen_pfn_t new_max; - size_t old_sz, new_sz; - unsigned long *p; - - /* Round up to the nearest power of two larger than pfn, less 1. */ - new_max = pfn; - new_max |= new_max >> 1; - new_max |= new_max >> 2; - new_max |= new_max >> 4; - new_max |= new_max >> 8; - new_max |= new_max >> 16; -#ifdef __x86_64__ - new_max |= new_max >> 32; -#endif - - old_sz = bitmap_size(ctx->restore.max_populated_pfn + 1); - new_sz = bitmap_size(new_max + 1); - p = realloc(ctx->restore.populated_pfns, new_sz); - if ( !p ) - { - ERROR("Failed to realloc populated bitmap"); - errno = ENOMEM; - return -1; - } - - memset((uint8_t *)p + old_sz, 0x00, new_sz - old_sz); - - ctx->restore.populated_pfns = p; - ctx->restore.max_populated_pfn = new_max; - } - - assert(!test_bit(pfn, ctx->restore.populated_pfns)); - set_bit(pfn, ctx->restore.populated_pfns); - - return 0; -} - /* * Given a set of pfns, obtain memory from Xen to fill the physmap for the * unpopulated subset. If types is NULL, no page type checking is performed @@ -684,10 +626,8 @@ static int setup(struct xc_sr_context *ctx) if ( rc ) goto err; - ctx->restore.max_populated_pfn = (32 * 1024 / 4) - 1; - ctx->restore.populated_pfns = bitmap_alloc( - ctx->restore.max_populated_pfn + 1); - if ( !ctx->restore.populated_pfns ) + rc = !xc_sr_bitmap_resize(&ctx->restore.populated_pfns, 32 * 1024 / 4); + if ( rc ) { ERROR("Unable to allocate memory for populated_pfns bitmap"); rc = -1; @@ -722,7 +662,7 @@ static void cleanup(struct xc_sr_context *ctx) xc_hypercall_buffer_free_pages(xch, dirty_bitmap, NRPAGES(bitmap_size(ctx->restore.p2m_size))); free(ctx->restore.buffered_records); - free(ctx->restore.populated_pfns); + xc_sr_bitmap_free(&ctx->restore.populated_pfns); if ( ctx->restore.ops.cleanup(ctx) ) PERROR("Failed to clean up"); }