From mboxrd@z Thu Jan 1 00:00:00 1970 From: Wei Liu Subject: [PATCH for 4.6 v2 4/5] libxc: don't populate same pfn more than once in populate_pfns Date: Sat, 5 Sep 2015 00:59:26 +0100 Message-ID: <1441411167-32440-5-git-send-email-wei.liu2@citrix.com> References: <1441411167-32440-1-git-send-email-wei.liu2@citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1ZY0wi-00014l-GR for xen-devel@lists.xenproject.org; Sat, 05 Sep 2015 00:03:04 +0000 In-Reply-To: <1441411167-32440-1-git-send-email-wei.liu2@citrix.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Xen-devel Cc: Andrew Cooper , Ian Jackson , Ian Campbell , Wei Liu List-Id: xen-devel@lists.xenproject.org The original implementation of populate_pfns didn't consider the same pfn can be present multiple times in the array. The mechanism to prevent populating the same pfn multiple times only worked if the recurring pfn appeared in different batches. This bug is discovered by Linux 4.1 32 bit kernel save / restore test, which has several ptes pointing to same pfn, which results in an array containing recurring pfn. When libxc called x86_pv_localise_page, the original implementation would populate the same pfn more than once. The fix is to set bit in populated bitmap as we generate list of pfns to be populated. Signed-off-by: Wei Liu --- tools/libxc/xc_sr_restore.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c index df885b6..924dd55 100644 --- a/tools/libxc/xc_sr_restore.c +++ b/tools/libxc/xc_sr_restore.c @@ -214,6 +214,9 @@ int populate_pfns(struct xc_sr_context *ctx, unsigned count, types[i] != XEN_DOMCTL_PFINFO_BROKEN))) && !pfn_is_populated(ctx, original_pfns[i]) ) { + rc = pfn_set_populated(ctx, original_pfns[i]); + if ( rc ) + goto err; pfns[nr_pfns] = mfns[nr_pfns] = original_pfns[i]; ++nr_pfns; } @@ -238,9 +241,6 @@ int populate_pfns(struct xc_sr_context *ctx, unsigned count, goto err; } - rc = pfn_set_populated(ctx, pfns[i]); - if ( rc ) - goto err; ctx->restore.ops.set_gfn(ctx, pfns[i], mfns[i]); } } -- 2.1.4