From: Vitaly Kuznetsov <vkuznets@redhat.com>
To: xen-devel@lists.xenproject.org
Cc: Andrew Jones <drjones@redhat.com>,
Julien Grall <julien.grall@linaro.org>,
Keir Fraser <keir@xen.org>,
Ian Campbell <ian.campbell@citrix.com>,
Stefano Stabellini <stefano.stabellini@eu.citrix.com>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Ian Jackson <ian.jackson@eu.citrix.com>,
Olaf Hering <olaf@aepfle.de>, Tim Deegan <tim@xen.org>,
David Vrabel <david.vrabel@citrix.com>,
Jan Beulich <jbeulich@suse.com>, Wei Liu <wei.liu2@citrix.com>,
Daniel De Graaf <dgdegra@tycho.nsa.gov>
Subject: [PATCH v7 07/10] libxc: introduce soft reset for HVM domains
Date: Wed, 27 May 2015 17:25:43 +0200 [thread overview]
Message-ID: <1432740346-7887-8-git-send-email-vkuznets@redhat.com> (raw)
In-Reply-To: <1432740346-7887-1-git-send-email-vkuznets@redhat.com>
Add new xc_soft_reset() function which performs so-called 'soft reset'
for an HVM domain. It is being performed in the following way:
- Save HVM context and all HVM params of the source domain;
- Transfer all the source domain's memory to the destinatio domain with
XEN_DOMCTL_soft_reset;
- Restore HVM context, HVM params, seed grant table for the new domain.
When the operation succeeds the source domain is being destroyed and the
destination domain is ready to proceed from where the source was stopped.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
Changes in v7:
- check that xc_domain_getinfo() return the domain we asked for [Julien Grall]
- xc_domain_soft_reset -> xc_soft_reset
- xc_soft_reset destroys the source domain, no need to do it manually
- nr_transfered was removed from hypercall interface, use
xc_domain_get_pod_target for the source domain instead.
---
tools/libxc/Makefile | 1 +
tools/libxc/include/xenguest.h | 21 ++++
tools/libxc/xc_soft_reset.c | 280 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 302 insertions(+)
create mode 100644 tools/libxc/xc_soft_reset.c
diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
index 63878ec..62bc21b 100644
--- a/tools/libxc/Makefile
+++ b/tools/libxc/Makefile
@@ -69,6 +69,7 @@ $(patsubst %.c,%.opic,$(GUEST_SRCS-y)): CFLAGS += -DXG_LIBXL_HVM_COMPAT
else
GUEST_SRCS-y += xc_nomigrate.c
endif
+GUEST_SRCS-y += xc_soft_reset.c
vpath %.c ../../xen/common/libelf
CFLAGS += -I../../xen/common/libelf
diff --git a/tools/libxc/include/xenguest.h b/tools/libxc/include/xenguest.h
index 7581263..c71b423 100644
--- a/tools/libxc/include/xenguest.h
+++ b/tools/libxc/include/xenguest.h
@@ -147,6 +147,27 @@ int xc_domain_restore2(xc_interface *xch, int io_fd, uint32_t dom,
* of the new domain is automatically appended to the filename,
* separated by a ".".
*/
+
+/**
+ * This function does soft reset for a domain. During soft reset all
+ * source domain's memory is being reassigned to the destination domain,
+ * HVM context and HVM params are being copied, source domain is being
+ * destroyed.
+ *
+ * @parm xch a handle to an open hypervisor interface
+ * @parm source_dom the id of the source domain
+ * @parm dest_dom the id of the destination domain
+ * @parm console_domid the id of the domain handling console
+ * @parm console_mfn returned with the mfn of the console page
+ * @parm store_domid the id of the domain handling store
+ * @parm store_mfn returned with the mfn of the store page
+ * @return 0 on success, -1 on failure
+ */
+int xc_soft_reset(xc_interface *xch, uint32_t source_dom,
+ uint32_t dest_dom, domid_t console_domid,
+ unsigned long *console_mfn, domid_t store_domid,
+ unsigned long *store_mfn);
+
#define XC_DEVICE_MODEL_RESTORE_FILE "/var/lib/xen/qemu-resume"
/**
diff --git a/tools/libxc/xc_soft_reset.c b/tools/libxc/xc_soft_reset.c
new file mode 100644
index 0000000..ea07470
--- /dev/null
+++ b/tools/libxc/xc_soft_reset.c
@@ -0,0 +1,280 @@
+/******************************************************************************
+ * xc_soft_reset.c
+ *
+ * Do soft reset.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <inttypes.h>
+#include <time.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include "xc_private.h"
+#include "xc_core.h"
+#include "xc_bitops.h"
+#include "xc_dom.h"
+#include "xg_private.h"
+#include "xg_save_restore.h"
+
+#include <xen/hvm/params.h>
+
+int xc_soft_reset(xc_interface *xch, uint32_t source_dom,
+ uint32_t dest_dom, domid_t console_domid,
+ unsigned long *console_mfn, domid_t store_domid,
+ unsigned long *store_mfn)
+{
+ xc_dominfo_t old_info, new_info;
+ int rc = 1;
+
+ uint32_t hvm_buf_size = 0;
+ uint8_t *hvm_buf = NULL;
+ unsigned long console_pfn, store_pfn, io_pfn, buffio_pfn;
+ uint64_t hvm_params[HVM_NR_PARAMS];
+ uint64_t pod_info[3];
+ xen_pfn_t sharedinfo_pfn;
+
+ DPRINTF("%s: soft reset domid %u -> %u", __func__, source_dom, dest_dom);
+
+ if ( xc_domain_getinfo(xch, source_dom, 1, &old_info) != 1 ||
+ old_info.domid != source_dom )
+ {
+ PERROR("Could not get old domain's info");
+ return 1;
+ }
+
+ if ( xc_domain_get_pod_target(xch, source_dom, &pod_info[0], &pod_info[1],
+ &pod_info[2]) )
+ {
+ PERROR("Could not get old domain's PoD info");
+ return 1;
+ }
+
+ if ( xc_domain_getinfo(xch, dest_dom, 1, &new_info) != 1 ||
+ new_info.domid != dest_dom )
+ {
+ PERROR("Could not get new domain's info");
+ return 1;
+ }
+
+ if ( !old_info.hvm || !new_info.hvm )
+ {
+ PERROR("Soft reset is supported for HVM only");
+ return 1;
+ }
+
+ sharedinfo_pfn = old_info.shared_info_frame;
+ if ( xc_get_pfn_type_batch(xch, source_dom, 1, &sharedinfo_pfn) )
+ {
+ PERROR("xc_get_pfn_type_batch failed");
+ goto out;
+ }
+
+ hvm_buf_size = xc_domain_hvm_getcontext(xch, source_dom, 0, 0);
+ if ( hvm_buf_size == -1 )
+ {
+ PERROR("Couldn't get HVM context size from Xen");
+ goto out;
+ }
+
+ hvm_buf = malloc(hvm_buf_size);
+ if ( !hvm_buf )
+ {
+ ERROR("Couldn't allocate memory");
+ goto out;
+ }
+
+ if ( xc_domain_hvm_getcontext(xch, source_dom, hvm_buf,
+ hvm_buf_size) == -1 )
+ {
+ PERROR("HVM:Could not get hvm buffer");
+ goto out;
+ }
+
+ xc_hvm_param_get(xch, source_dom, HVM_PARAM_STORE_PFN,
+ &hvm_params[HVM_PARAM_STORE_PFN]);
+ store_pfn = hvm_params[HVM_PARAM_STORE_PFN];
+ *store_mfn = store_pfn;
+
+ xc_hvm_param_get(xch, source_dom,
+ HVM_PARAM_CONSOLE_PFN,
+ &hvm_params[HVM_PARAM_CONSOLE_PFN]);
+ console_pfn = hvm_params[HVM_PARAM_CONSOLE_PFN];
+ *console_mfn = console_pfn;
+
+ xc_hvm_param_get(xch, source_dom, HVM_PARAM_BUFIOREQ_PFN,
+ &hvm_params[HVM_PARAM_BUFIOREQ_PFN]);
+ buffio_pfn = hvm_params[HVM_PARAM_BUFIOREQ_PFN];
+
+ xc_hvm_param_get(xch, source_dom, HVM_PARAM_IOREQ_PFN,
+ &hvm_params[HVM_PARAM_IOREQ_PFN]);
+ io_pfn = hvm_params[HVM_PARAM_IOREQ_PFN];
+
+ xc_hvm_param_get(xch, source_dom, HVM_PARAM_IDENT_PT,
+ &hvm_params[HVM_PARAM_IDENT_PT]);
+
+ xc_hvm_param_get(xch, source_dom, HVM_PARAM_PAGING_RING_PFN,
+ &hvm_params[HVM_PARAM_PAGING_RING_PFN]);
+
+ xc_hvm_param_get(xch, source_dom, HVM_PARAM_VM86_TSS,
+ &hvm_params[HVM_PARAM_VM86_TSS]);
+
+ xc_hvm_param_get(xch, source_dom, HVM_PARAM_ACPI_IOPORTS_LOCATION,
+ &hvm_params[HVM_PARAM_ACPI_IOPORTS_LOCATION]);
+
+ xc_hvm_param_get(xch, source_dom, HVM_PARAM_VIRIDIAN,
+ &hvm_params[HVM_PARAM_VIRIDIAN]);
+
+ xc_hvm_param_get(xch, source_dom, HVM_PARAM_PAE_ENABLED,
+ &hvm_params[HVM_PARAM_PAE_ENABLED]);
+
+ xc_hvm_param_get(xch, source_dom, HVM_PARAM_STORE_EVTCHN,
+ &hvm_params[HVM_PARAM_STORE_EVTCHN]);
+
+ xc_hvm_param_get(xch, source_dom, HVM_PARAM_IOREQ_SERVER_PFN,
+ &hvm_params[HVM_PARAM_IOREQ_SERVER_PFN]);
+
+ xc_hvm_param_get(xch, source_dom, HVM_PARAM_NR_IOREQ_SERVER_PAGES,
+ &hvm_params[HVM_PARAM_NR_IOREQ_SERVER_PAGES]);
+
+ xc_hvm_param_get(xch, source_dom, HVM_PARAM_VM_GENERATION_ID_ADDR,
+ &hvm_params[HVM_PARAM_VM_GENERATION_ID_ADDR]);
+
+ rc = xc_domain_soft_reset(xch, source_dom, dest_dom);
+ if ( rc != 0 )
+ {
+ PERROR("Failed to devour original domain, rc=%d\n", rc);
+ goto out;
+ }
+
+ /*
+ * Shared info frame is being removed when guest maps shared info so this
+ * page is likely XEN_DOMCTL_PFINFO_XTAB but we need to replace it with an
+ * empty page in that case.
+ */
+ if ( sharedinfo_pfn == XEN_DOMCTL_PFINFO_XTAB &&
+ xc_domain_populate_physmap_exact(xch, dest_dom, 1, 0, 0,
+ &old_info.shared_info_frame) )
+ {
+ PERROR("Failed to populate pfn %lx (shared info)",
+ old_info.shared_info_frame);
+ goto out;
+ }
+
+ if ( xc_domain_hvm_setcontext(xch, dest_dom, hvm_buf,
+ hvm_buf_size) == -1 )
+ {
+ PERROR("HVM:Could not set hvm buffer");
+ goto out;
+ }
+
+ if ( store_pfn )
+ xc_clear_domain_page(xch, dest_dom, store_pfn);
+
+ if ( console_pfn )
+ xc_clear_domain_page(xch, dest_dom, console_pfn);
+
+ if ( buffio_pfn )
+ xc_clear_domain_page(xch, dest_dom, buffio_pfn);
+
+ if ( io_pfn )
+ xc_clear_domain_page(xch, dest_dom, io_pfn);
+
+ xc_hvm_param_set(xch, dest_dom, HVM_PARAM_STORE_PFN,
+ hvm_params[HVM_PARAM_STORE_PFN]);
+
+ xc_hvm_param_set(xch, dest_dom,
+ HVM_PARAM_CONSOLE_PFN,
+ hvm_params[HVM_PARAM_CONSOLE_PFN]);
+
+ xc_hvm_param_set(xch, dest_dom, HVM_PARAM_BUFIOREQ_PFN,
+ hvm_params[HVM_PARAM_BUFIOREQ_PFN]);
+
+ xc_hvm_param_set(xch, dest_dom, HVM_PARAM_IOREQ_PFN,
+ hvm_params[HVM_PARAM_IOREQ_PFN]);
+
+ xc_hvm_param_set(xch, dest_dom, HVM_PARAM_IDENT_PT,
+ hvm_params[HVM_PARAM_IDENT_PT]);
+
+ xc_hvm_param_set(xch, dest_dom, HVM_PARAM_PAGING_RING_PFN,
+ hvm_params[HVM_PARAM_PAGING_RING_PFN]);
+
+ xc_hvm_param_set(xch, dest_dom, HVM_PARAM_VM86_TSS,
+ hvm_params[HVM_PARAM_VM86_TSS]);
+
+ xc_hvm_param_set(xch, dest_dom, HVM_PARAM_ACPI_IOPORTS_LOCATION,
+ hvm_params[HVM_PARAM_ACPI_IOPORTS_LOCATION]);
+
+ xc_hvm_param_set(xch, dest_dom, HVM_PARAM_VIRIDIAN,
+ hvm_params[HVM_PARAM_VIRIDIAN]);
+
+ xc_hvm_param_set(xch, dest_dom, HVM_PARAM_PAE_ENABLED,
+ hvm_params[HVM_PARAM_PAE_ENABLED]);
+
+ xc_hvm_param_set(xch, dest_dom, HVM_PARAM_STORE_EVTCHN,
+ hvm_params[HVM_PARAM_STORE_EVTCHN]);
+
+ xc_hvm_param_set(xch, dest_dom, HVM_PARAM_IOREQ_SERVER_PFN,
+ hvm_params[HVM_PARAM_IOREQ_SERVER_PFN]);
+
+ xc_hvm_param_set(xch, dest_dom, HVM_PARAM_NR_IOREQ_SERVER_PAGES,
+ hvm_params[HVM_PARAM_NR_IOREQ_SERVER_PAGES]);
+
+ xc_hvm_param_set(xch, dest_dom, HVM_PARAM_VM_GENERATION_ID_ADDR,
+ hvm_params[HVM_PARAM_VM_GENERATION_ID_ADDR]);
+
+ if ( xc_dom_gnttab_hvm_seed(xch, dest_dom, console_pfn, store_pfn,
+ console_domid, store_domid) )
+ {
+ PERROR("Error seeding hvm grant table");
+ goto out;
+ }
+
+ /* Check if we need to add pages to the PoD cache of the new domain */
+ if ( pod_info[2] &&
+ xc_domain_set_pod_target(xch, dest_dom,
+ old_info.nr_pages +
+ (sharedinfo_pfn == XEN_DOMCTL_PFINFO_XTAB ?
+ 1 : 0), NULL, NULL, NULL) )
+ {
+ PERROR("Failed to set POD target for new domain");
+ goto out;
+ }
+
+ rc = 0;
+ out:
+ if ( hvm_buf )
+ free(hvm_buf);
+
+ if ( (rc != 0) && (dest_dom != 0) ) {
+ PERROR("Failed to perform soft reset, destroying domain %d",
+ dest_dom);
+ xc_domain_destroy(xch, dest_dom);
+ }
+
+ return !!rc;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
--
1.9.3
next prev parent reply other threads:[~2015-05-27 15:26 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-27 15:25 [PATCH v7 00/10] toolstack-based approach to pvhvm guest kexec Vitaly Kuznetsov
2015-05-27 15:25 ` [PATCH v7 01/10] xen: introduce SHUTDOWN_soft_reset shutdown reason Vitaly Kuznetsov
2015-05-27 15:25 ` [PATCH v7 02/10] libxl: support " Vitaly Kuznetsov
2015-06-02 14:58 ` Ian Campbell
2015-05-27 15:25 ` [PATCH v7 03/10] xen: introduce DOMDYING_locked state Vitaly Kuznetsov
2015-05-27 15:25 ` [PATCH v7 04/10] xen: Introduce XEN_DOMCTL_soft_reset Vitaly Kuznetsov
2015-05-28 10:06 ` Tim Deegan
2015-05-28 11:56 ` Vitaly Kuznetsov
2015-05-28 12:52 ` Tim Deegan
2015-05-28 13:11 ` Vitaly Kuznetsov
2015-05-28 13:37 ` Tim Deegan
2015-05-28 13:53 ` Vitaly Kuznetsov
2015-05-28 15:02 ` Jan Beulich
2015-05-27 15:25 ` [PATCH v7 05/10] xsm: add XEN_DOMCTL_soft_reset support Vitaly Kuznetsov
2015-05-27 20:22 ` Daniel De Graaf
2015-05-29 16:16 ` Jan Beulich
2015-05-27 15:25 ` [PATCH v7 06/10] libxc: support XEN_DOMCTL_soft_reset operation Vitaly Kuznetsov
2015-06-02 15:00 ` Ian Campbell
2015-05-27 15:25 ` Vitaly Kuznetsov [this message]
2015-06-02 15:09 ` [PATCH v7 07/10] libxc: introduce soft reset for HVM domains Ian Campbell
2015-05-27 15:25 ` [PATCH v7 08/10] xl: introduce enum domain_restart_type Vitaly Kuznetsov
2015-06-02 15:11 ` Ian Campbell
2015-05-27 15:25 ` [PATCH v7 09/10] libxc: add XC_DEVICE_MODEL_SAVE_FILE Vitaly Kuznetsov
2015-06-02 15:12 ` Ian Campbell
2015-05-27 15:25 ` [PATCH v7 10/10] (lib)xl: soft reset support Vitaly Kuznetsov
2015-06-02 15:25 ` Ian Campbell
2015-05-28 12:20 ` [PATCH v7 00/10] toolstack-based approach to pvhvm guest kexec Jan Beulich
2015-05-28 12:27 ` Vitaly Kuznetsov
2015-05-28 13:05 ` Jan Beulich
2015-05-28 13:41 ` Vitaly Kuznetsov
2015-06-02 14:58 ` Ian Campbell
2015-06-02 16:26 ` Vitaly Kuznetsov
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=1432740346-7887-8-git-send-email-vkuznets@redhat.com \
--to=vkuznets@redhat.com \
--cc=andrew.cooper3@citrix.com \
--cc=david.vrabel@citrix.com \
--cc=dgdegra@tycho.nsa.gov \
--cc=drjones@redhat.com \
--cc=ian.campbell@citrix.com \
--cc=ian.jackson@eu.citrix.com \
--cc=jbeulich@suse.com \
--cc=julien.grall@linaro.org \
--cc=keir@xen.org \
--cc=olaf@aepfle.de \
--cc=stefano.stabellini@eu.citrix.com \
--cc=tim@xen.org \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xenproject.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).