All of lore.kernel.org
 help / color / mirror / Atom feed
From: John Levon <levon@movementarian.org>
To: Ian Pratt <m+Ian.Pratt@cl.cam.ac.uk>
Cc: xen-devel@lists.xensource.com
Subject: Re: save/restore race
Date: Wed, 24 Jan 2007 02:10:23 +0000	[thread overview]
Message-ID: <20070124021023.GA30953@totally.trollied.org.uk> (raw)
In-Reply-To: <8A87A9A84C201449A0C56B728ACF491E04F28B@liverpoolst.ad.cl.cam.ac.uk>

On Tue, Jan 23, 2007 at 11:38:29PM -0000, Ian Pratt wrote:

> We should make xc_linux_save cope more gracefully with
> arch.pfn_to_mfn_frame_list_list being NULL, have xc_linux_save zero the
> field in shared_info before writing it out (its an MFN and not valid
> anyhow), and then move the field's re-initialisation a little later in
> the post_suspend function to close the race.

I've done some testing with the below, and it seems to do the trick.

regards
john


# HG changeset patch
# User john.levon@sun.com
# Date 1169600022 28800
# Node ID 3121e0cb7be68fa46c59f61422f05adc03ec5a5e
# Parent  a75413c0072fa5b892bd8b6a05c1f1d3435bb093
Close save-after-restore race. Make xc_linux_save() wait for the
frame_list_list MFN to be updated by the domain before trying to use it.

Signed-off-by: John Levon <john.levon@sun.com>

diff --git a/tools/libxc/xc_linux_save.c b/tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c
+++ b/tools/libxc/xc_linux_save.c
@@ -403,6 +403,33 @@ static int suspend_and_state(int (*suspe
     return -1;
 }
 
+/*
+** Map the top-level page of MFNs from the guest. The guest might not have
+** finished resuming from a previous restore operation, so we wait a while for
+** it to update the MFN to a reasonable value.
+*/
+static void *map_frame_list_list(int xc_handle, uint32_t dom,
+                                 shared_info_t *shinfo)
+{
+    int count = 3000;
+    void *p;
+
+    while (count-- && shinfo->arch.pfn_to_mfn_frame_list_list == 0)
+        usleep(10000);
+
+    if (shinfo->arch.pfn_to_mfn_frame_list_list == 0) {
+        ERROR("Timed out waiting for frame list updated.");
+        return NULL;
+    }
+
+    p = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ,
+                             shinfo->arch.pfn_to_mfn_frame_list_list);
+
+    if (p == NULL)
+        ERROR("Couldn't map p2m_frame_list_list (errno %d)", errno);
+
+    return p;
+}
 
 /*
 ** During transfer (or in the state file), all page-table pages must be
@@ -663,14 +690,11 @@ int xc_linux_save(int xc_handle, int io_
 
     max_pfn = live_shinfo->arch.max_pfn;
 
-    live_p2m_frame_list_list =
-        xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ,
-                             live_shinfo->arch.pfn_to_mfn_frame_list_list);
-
-    if (!live_p2m_frame_list_list) {
-        ERROR("Couldn't map p2m_frame_list_list (errno %d)", errno);
-        goto out;
-    }
+    live_p2m_frame_list_list = map_frame_list_list(xc_handle, dom,
+                                                   live_shinfo);
+
+    if (!live_p2m_frame_list_list)
+        goto out;
 
     live_p2m_frame_list =
         xc_map_foreign_batch(xc_handle, dom, PROT_READ,
@@ -1169,8 +1193,14 @@ int xc_linux_save(int xc_handle, int io_
     ctxt.ctrlreg[3] = 
         xen_pfn_to_cr3(mfn_to_pfn(xen_cr3_to_pfn(ctxt.ctrlreg[3])));
 
+    /*
+     * Reset the MFN to be a known-invalid value. See map_frame_list_list().
+     */
+    memcpy(page, live_shinfo, PAGE_SIZE);
+    ((shared_info_t *)page)->arch.pfn_to_mfn_frame_list_list = 0;
+
     if (!write_exact(io_fd, &ctxt, sizeof(ctxt)) ||
-        !write_exact(io_fd, live_shinfo, PAGE_SIZE)) {
+        !write_exact(io_fd, page, PAGE_SIZE)) {
         ERROR("Error when writing to state file (1) (errno %d)", errno);
         goto out;
     }

  reply	other threads:[~2007-01-24  2:10 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-23 22:01 save/restore race John Levon
2007-01-23 22:15 ` Ian Pratt
2007-01-23 22:48   ` John Levon
2007-01-23 23:38     ` Ian Pratt
2007-01-24  2:10       ` John Levon [this message]
2007-01-24  2:19         ` Ian Pratt
2007-01-24  3:13           ` [PATCH] " John Levon
2007-01-24 10:07             ` Steven Hand
2007-02-06 15:04             ` Srikanth SM
2007-02-06 15:13               ` John Levon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070124021023.GA30953@totally.trollied.org.uk \
    --to=levon@movementarian.org \
    --cc=m+Ian.Pratt@cl.cam.ac.uk \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.