[Xen-devel] [PATCH v2 05/16] Save/Restore Support: Add kernel shutdown logic to shutdown.c

2018-02-13 Thread Bruno Alvisio
Created shutdown.c for the shutdown thread and all the shutdown related
functions.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
Changesd since v1:
   * Updated license to a BSD 3-clause. This license was taken
from the updated original file. (Repo: sysml/mini-os)
---
 Makefile   |   1 +
 include/shutdown.h |  11 
 shutdown.c | 188 +
 3 files changed, 200 insertions(+)
 create mode 100644 include/shutdown.h
 create mode 100644 shutdown.c

diff --git a/Makefile b/Makefile
index 88315c4..6a05de6 100644
--- a/Makefile
+++ b/Makefile
@@ -53,6 +53,7 @@ src-y += mm.c
 src-$(CONFIG_NETFRONT) += netfront.c
 src-$(CONFIG_PCIFRONT) += pcifront.c
 src-y += sched.c
+src-y += shutdown.c
 src-$(CONFIG_TEST) += test.c
 src-$(CONFIG_BALLOON) += balloon.c
 
diff --git a/include/shutdown.h b/include/shutdown.h
new file mode 100644
index 000..a5ec019
--- /dev/null
+++ b/include/shutdown.h
@@ -0,0 +1,11 @@
+#ifndef _SHUTDOWN_H_
+#define _SHUTDOWN_H_
+
+#include 
+
+void init_shutdown(start_info_t *si);
+
+void kernel_shutdown(int reason) __attribute__((noreturn));
+void kernel_suspend(void);
+
+#endif
diff --git a/shutdown.c b/shutdown.c
new file mode 100644
index 000..aba146e
--- /dev/null
+++ b/shutdown.c
@@ -0,0 +1,188 @@
+/*
+ *  MiniOS
+ *
+ *   file: fromdevice.cc
+ *
+ * Authors: Joao Martins <joao.mart...@neclab.eu>
+ *
+ *
+ * Copyright (c) 2014, NEC Europe Ltd., NEC Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in the
+ *documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ *contributors may be used to endorse or promote products derived from
+ *this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+
+static start_info_t *start_info_ptr;
+
+static const char *path = "control/shutdown";
+static const char *token = "control/shutdown";
+static xenbus_event_queue events = NULL;
+static int end_shutdown_thread = 0;
+
+#ifdef CONFIG_XENBUS
+/* This should be overridden by the application we are linked against. */
+__attribute__((weak)) void app_shutdown(unsigned reason)
+{
+printk("Shutdown requested: %d\n", reason);
+if (reason == SHUTDOWN_suspend) {
+kernel_suspend();
+} else {
+struct sched_shutdown sched_shutdown = { .reason = reason };
+HYPERVISOR_sched_op(SCHEDOP_shutdown, _shutdown);
+}
+}
+
+static void shutdown_thread(void *p)
+{
+char *shutdown, *err;
+unsigned int shutdown_reason;
+
+xenbus_watch_path_token(XBT_NIL, path, token, );
+
+for ( ;; ) {
+xenbus_wait_for_watch();
+if ((err = xenbus_read(XBT_NIL, path, ))) {
+free(err);
+do_exit();
+}
+
+if (end_shutdown_thread)
+break;
+
+if (!strcmp(shutdown, "")) {
+/* Avoid spurious event on xenbus */
+/* FIXME: investigate the reason of the spurious event */
+free(shutdown);
+continue;
+} else if (!strcmp(shutdown, "poweroff")) {
+shutdown_reason = SHUTDOWN_poweroff;
+} else if (!strcmp(shutdown, "reboot")) {
+shutdown_reason = SHUTDOWN_reboot;
+} else if (!strcmp(shutdown, "suspend")) {
+shutdown_reason = SHUTDOWN_suspend;
+} else {
+shutdown_reason = SHUTDOWN_crash;
+}
+free(shutdown);
+
+/* Acknowledge shutd

[Xen-devel] [PATCH v2 03/16] Save/Restore Support: Declare kernel and arch pre/post suspend functions

2018-02-13 Thread Bruno Alvisio
For mini-OS to support suspend and restore, the kernel will have to suspend
different modules such as xenbus, console, irq, etc. During save/restore the
kernel and arch pre_suspend and post_suspend functions will be invoked to
suspend/resume each of the modules.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
 arch/x86/setup.c | 10 ++
 include/kernel.h |  2 ++
 include/x86/os.h |  4 ++--
 kernel.c | 10 ++
 4 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/arch/x86/setup.c b/arch/x86/setup.c
index 5278227..3dd86f9 100644
--- a/arch/x86/setup.c
+++ b/arch/x86/setup.c
@@ -204,6 +204,16 @@ arch_init(void *par)
start_kernel();
 }
 
+void arch_pre_suspend(void)
+{
+
+}
+
+void arch_post_suspend(int canceled)
+{
+
+}
+
 void
 arch_fini(void)
 {
diff --git a/include/kernel.h b/include/kernel.h
index d37ddda..161d757 100644
--- a/include/kernel.h
+++ b/include/kernel.h
@@ -5,6 +5,8 @@
 extern char cmdline[MAX_CMDLINE_SIZE];
 
 void start_kernel(void);
+void pre_suspend(void);
+void post_suspend(int canceled);
 void do_exit(void) __attribute__((noreturn));
 void arch_do_exit(void);
 void stop_kernel(void);
diff --git a/include/x86/os.h b/include/x86/os.h
index d155914..a73b63e 100644
--- a/include/x86/os.h
+++ b/include/x86/os.h
@@ -71,10 +71,10 @@ void trap_fini(void);
 void xen_callback_vector(void);
 #endif
 
+void arch_pre_suspend(void);
+void arch_post_suspend(int canceled);
 void arch_fini(void);
 
-
-
 #ifdef CONFIG_PARAVIRT
 
 /* 
diff --git a/kernel.c b/kernel.c
index 0d84a9b..90c865a 100644
--- a/kernel.c
+++ b/kernel.c
@@ -155,6 +155,16 @@ void start_kernel(void)
 run_idle_thread();
 }
 
+void pre_suspend(void)
+{
+
+}
+
+void post_suspend(int canceled)
+{
+
+}
+
 void stop_kernel(void)
 {
 /* TODO: fs import */
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 15/16] Save/Restore Support: Add suspend/restore support for netfront

2018-02-13 Thread Bruno Alvisio
Performed an additional cleanup to make the file more syntactically consistent.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
 include/netfront.h |   8 +-
 kernel.c   |   8 ++
 netfront.c | 309 ++---
 3 files changed, 236 insertions(+), 89 deletions(-)

diff --git a/include/netfront.h b/include/netfront.h
index 2b95da9..1164d50 100644
--- a/include/netfront.h
+++ b/include/netfront.h
@@ -3,9 +3,15 @@
 #include 
 #endif
 struct netfront_dev;
-struct netfront_dev *init_netfront(char *nodename, void (*netif_rx)(unsigned 
char *data, int len), unsigned char rawmac[6], char **ip);
+struct netfront_dev *init_netfront(char *nodename,
+   void (*netif_rx)(unsigned char *data,
+int len, void* arg),
+   unsigned char rawmac[6],
+   char **ip);
 void netfront_xmit(struct netfront_dev *dev, unsigned char* data,int len);
 void shutdown_netfront(struct netfront_dev *dev);
+void suspend_netfront(void);
+void resume_netfront(void);
 #ifdef HAVE_LIBC
 int netfront_tap_open(char *nodename);
 ssize_t netfront_receive(struct netfront_dev *dev, unsigned char *data, size_t 
len);
diff --git a/kernel.c b/kernel.c
index 1393d15..301273d 100644
--- a/kernel.c
+++ b/kernel.c
@@ -119,6 +119,10 @@ void start_kernel(void* par)
 
 void pre_suspend(void)
 {
+#ifdef CONFIG_NETFRONT
+suspend_netfront();
+#endif
+
 #ifdef CONFIG_XENBUS
 suspend_xenbus();
 #endif
@@ -147,6 +151,10 @@ void post_suspend(int canceled)
 #ifdef CONFIG_XENBUS
 resume_xenbus(canceled);
 #endif
+
+#ifdef CONFIG_NETFRONT
+resume_netfront();
+#endif
 }
 
 void stop_kernel(void)
diff --git a/netfront.c b/netfront.c
index b8fac62..50b3a57 100644
--- a/netfront.c
+++ b/netfront.c
@@ -63,10 +63,30 @@ struct netfront_dev {
 size_t rlen;
 #endif
 
-void (*netif_rx)(unsigned char* data, int len);
+void (*netif_rx)(unsigned char* data, int len, void* arg);
+void *netif_rx_arg;
 };
 
+struct netfront_dev_list {
+struct netfront_dev *dev;
+unsigned char rawmac[6];
+char *ip;
+
+int refcount;
+
+struct netfront_dev_list *next;
+};
+
+static struct netfront_dev_list *dev_list = NULL;
+
 void init_rx_buffers(struct netfront_dev *dev);
+static struct netfront_dev *_init_netfront(struct netfront_dev *dev,
+   unsigned char rawmac[6], char **ip);
+static void _shutdown_netfront(struct netfront_dev *dev);
+void netfront_set_rx_handler(struct netfront_dev *dev,
+ void (*thenetif_rx)(unsigned char *data, int len,
+ void *arg),
+ void *arg);
 
 static inline void add_id_to_freelist(unsigned int id,unsigned short* freelist)
 {
@@ -81,7 +101,7 @@ static inline unsigned short get_id_from_freelist(unsigned 
short* freelist)
 return id;
 }
 
-__attribute__((weak)) void netif_rx(unsigned char* data,int len)
+__attribute__((weak)) void netif_rx(unsigned char* data, int len, void *arg)
 {
 printk("%d bytes incoming at %p\n",len,data);
 }
@@ -120,21 +140,20 @@ moretodo:
 page = (unsigned char*)buf->page;
 gnttab_end_access(buf->gref);
 
-if (rx->status > NETIF_RSP_NULL)
-{
+if (rx->status > NETIF_RSP_NULL) {
 #ifdef HAVE_LIBC
-   if (dev->netif_rx == NETIF_SELECT_RX) {
-   int len = rx->status;
-   ASSERT(current == main_thread);
-   if (len > dev->len)
-   len = dev->len;
-   memcpy(dev->data, page+rx->offset, len);
-   dev->rlen = len;
-   /* No need to receive the rest for now */
-   dobreak = 1;
-   } else
+if (dev->netif_rx == NETIF_SELECT_RX) {
+int len = rx->status;
+ASSERT(current == main_thread);
+if (len > dev->len)
+len = dev->len;
+memcpy(dev->data, page+rx->offset, len);
+dev->rlen = len;
+/* No need to receive the rest for now */
+dobreak = 1;
+} else
 #endif
-   dev->netif_rx(page+rx->offset,rx->status);
+   dev->netif_rx(page+rx->offset, rx->status, 
dev->netif_rx_arg);
 }
 }
 dev->rx.rsp_cons=cons;
@@ -144,17 +163,16 @@ moretodo:
 
 req_prod = dev->rx.req_prod_pvt;
 
-for(i=0; i<nr_consumed; i++)
-{
+for (i = 0; i < nr_consumed; i++) {
 int id = xennet_rxidx(req_prod + i);
 netif_rx_request_t *req = RING_GET_REQUEST(>rx, req_prod + i);
 struct net_buffer* buf = >rx_buf

[Xen-devel] [PATCH v2 13/16] Save/Restore Support: Add suspend/restore support for Grant Tables.

2018-02-13 Thread Bruno Alvisio
Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
Changed since v1:
- Moved suspend/resume _gnttab to arch specific files
---
 arch/x86/mm.c| 34 ++
 gnttab.c | 10 ++
 include/gnttab.h |  4 
 kernel.c |  4 
 4 files changed, 52 insertions(+)

diff --git a/arch/x86/mm.c b/arch/x86/mm.c
index 1b163ac..2597c5b 100644
--- a/arch/x86/mm.c
+++ b/arch/x86/mm.c
@@ -917,6 +917,40 @@ grant_entry_v1_t *arch_init_gnttab(int nr_grant_frames)
 return map_frames(frames, nr_grant_frames);
 }
 
+void arch_suspend_gnttab(grant_entry_v1_t *gnttab_table, int nr_grant_frames)
+{
+#ifdef CONFIG_PARAVIRT
+int i;
+
+for (i = 0; i < nr_grant_frames; i++) {
+HYPERVISOR_update_va_mapping((unsigned long)(((char *)gnttab_table) + 
PAGE_SIZE*i),
+(pte_t){0x0<<PAGE_SHIFT}, UVMF_INVLPG);
+}
+#endif
+return;
+}
+
+void arch_resume_gnttab(grant_entry_v1_t *gnttab_table, int nr_grant_frames)
+{
+struct gnttab_setup_table setup;
+unsigned long frames[nr_grant_frames];
+#ifdef CONFIG_PARAVIRT
+int i;
+#endif
+setup.dom = DOMID_SELF;
+setup.nr_frames = nr_grant_frames;
+set_xen_guest_handle(setup.frame_list, frames);
+
+HYPERVISOR_grant_table_op(GNTTABOP_setup_table, , 1);
+
+#ifdef CONFIG_PARAVIRT
+for (i = 0; i < nr_grant_frames; i++) {
+HYPERVISOR_update_va_mapping((unsigned long)(((char *)gnttab_table) + 
PAGE_SIZE*i),
+(pte_t){(frames[i] << PAGE_SHIFT) | L1_PROT}, UVMF_INVLPG);
+}
+#endif
+}
+
 unsigned long alloc_virt_kernel(unsigned n_pages)
 {
 unsigned long addr;
diff --git a/gnttab.c b/gnttab.c
index 3f0e35f..6978a9b 100644
--- a/gnttab.c
+++ b/gnttab.c
@@ -194,3 +194,13 @@ fini_gnttab(void)
 
 HYPERVISOR_grant_table_op(GNTTABOP_setup_table, , 1);
 }
+
+void suspend_gnttab(void)
+{
+arch_suspend_gnttab(gnttab_table, NR_GRANT_FRAMES);
+}
+
+void resume_gnttab(void)
+{
+arch_resume_gnttab(gnttab_table, NR_GRANT_FRAMES);
+}
diff --git a/include/gnttab.h b/include/gnttab.h
index a9d8e09..974cb89 100644
--- a/include/gnttab.h
+++ b/include/gnttab.h
@@ -12,6 +12,10 @@ unsigned long gnttab_end_transfer(grant_ref_t gref);
 int gnttab_end_access(grant_ref_t ref);
 const char *gnttabop_error(int16_t status);
 void fini_gnttab(void);
+void suspend_gnttab(void);
+void resume_gnttab(void);
 grant_entry_v1_t *arch_init_gnttab(int nr_grant_frames);
+void arch_suspend_gnttab(grant_entry_v1_t *gnttab_table, int nr_grant_frames);
+void arch_resume_gnttab(grant_entry_v1_t *gnttab_table, int nr_grant_frames);
 
 #endif /* !__GNTTAB_H__ */
diff --git a/kernel.c b/kernel.c
index d078e0a..933cbcd 100644
--- a/kernel.c
+++ b/kernel.c
@@ -121,6 +121,8 @@ void pre_suspend(void)
 {
 local_irq_disable();
 
+suspend_gnttab();
+
 fini_time();
 
 suspend_console();
@@ -134,6 +136,8 @@ void post_suspend(int canceled)
 
 init_time();
 
+resume_gnttab();
+
 local_irq_enable();
 }
 
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 14/16] Save/Restore Support: Add suspend/restore support for xenbus

2018-02-13 Thread Bruno Alvisio
Currently the watch path is not saved in the watch struct when it is registered.
During xenbus resume the path is needed so that the watches can be registered 
again.
Thus, 'path' field is added to struct watch so that watches can be re-registered
during xenbus resume.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
 include/xenbus.h |   2 ++
 kernel.c |   8 +
 xenbus/xenbus.c  | 106 +++
 3 files changed, 85 insertions(+), 31 deletions(-)

diff --git a/include/xenbus.h b/include/xenbus.h
index b2d5072..3871f35 100644
--- a/include/xenbus.h
+++ b/include/xenbus.h
@@ -120,6 +120,8 @@ domid_t xenbus_get_self_id(void);
 #ifdef CONFIG_XENBUS
 /* Reset the XenBus system. */
 void fini_xenbus(void);
+void suspend_xenbus(void);
+void resume_xenbus(int canceled);
 #else
 static inline void fini_xenbus(void)
 {
diff --git a/kernel.c b/kernel.c
index 933cbcd..1393d15 100644
--- a/kernel.c
+++ b/kernel.c
@@ -119,6 +119,10 @@ void start_kernel(void* par)
 
 void pre_suspend(void)
 {
+#ifdef CONFIG_XENBUS
+suspend_xenbus();
+#endif
+
 local_irq_disable();
 
 suspend_gnttab();
@@ -139,6 +143,10 @@ void post_suspend(int canceled)
 resume_gnttab();
 
 local_irq_enable();
+
+#ifdef CONFIG_XENBUS
+resume_xenbus(canceled);
+#endif
 }
 
 void stop_kernel(void)
diff --git a/xenbus/xenbus.c b/xenbus/xenbus.c
index c2d2bd1..d72dc3a 100644
--- a/xenbus/xenbus.c
+++ b/xenbus/xenbus.c
@@ -50,6 +50,7 @@ DECLARE_WAIT_QUEUE_HEAD(xenbus_watch_queue);
 xenbus_event_queue xenbus_events;
 static struct watch {
 char *token;
+char *path;
 xenbus_event_queue *events;
 struct watch *next;
 } *watches;
@@ -63,6 +64,8 @@ struct xenbus_req_info
 #define NR_REQS 32
 static struct xenbus_req_info req_info[NR_REQS];
 
+static char *errmsg(struct xsd_sockmsg *rep);
+
 uint32_t xenbus_evtchn;
 
 #ifdef CONFIG_PARAVIRT
@@ -231,45 +234,39 @@ static void xenbus_thread_func(void *ign)
 struct xsd_sockmsg msg;
 unsigned prod = xenstore_buf->rsp_prod;
 
-for (;;) 
-{
+for (;;) {
 wait_event(xb_waitq, prod != xenstore_buf->rsp_prod);
-while (1) 
-{
+while (1) {
 prod = xenstore_buf->rsp_prod;
 DEBUG("Rsp_cons %d, rsp_prod %d.\n", xenstore_buf->rsp_cons,
-xenstore_buf->rsp_prod);
+  xenstore_buf->rsp_prod);
 if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons < sizeof(msg))
 break;
 rmb();
-memcpy_from_ring(xenstore_buf->rsp,
-,
-MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
-sizeof(msg));
-DEBUG("Msg len %d, %d avail, id %d.\n",
-msg.len + sizeof(msg),
-xenstore_buf->rsp_prod - xenstore_buf->rsp_cons,
-msg.req_id);
+memcpy_from_ring(xenstore_buf->rsp, ,
+ MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
+ sizeof(msg));
+DEBUG("Msg len %d, %d avail, id %d.\n", msg.len + sizeof(msg),
+  xenstore_buf->rsp_prod - xenstore_buf->rsp_cons, msg.req_id);
+
 if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons <
-sizeof(msg) + msg.len)
+sizeof(msg) + msg.len)
 break;
 
 DEBUG("Message is good.\n");
 
-if(msg.type == XS_WATCH_EVENT)
-{
-   struct xenbus_event *event = malloc(sizeof(*event) + msg.len);
+if (msg.type == XS_WATCH_EVENT) {
+struct xenbus_event *event = malloc(sizeof(*event) + msg.len);
 xenbus_event_queue *events = NULL;
-   char *data = (char*)event + sizeof(*event);
+char *data = (char*)event + sizeof(*event);
 struct watch *watch;
 
-memcpy_from_ring(xenstore_buf->rsp,
-   data,
+memcpy_from_ring(xenstore_buf->rsp, data,
 MASK_XENSTORE_IDX(xenstore_buf->rsp_cons + sizeof(msg)),
 msg.len);
 
-   event->path = data;
-   event->token = event->path + strlen(event->path) + 1;
+event->path = data;
+event->token = event->path + strlen(event->path) + 1;
 
 mb();
 xenstore_buf->rsp_cons += msg.len + sizeof(msg);
@@ -288,15 +285,11 @@ static void xenbus_thread_func(void *ign)
 printk("unexpected watch token %s\n", event->token);
 free(event);
 }
-}
-
-else
-{
+} else {

[Xen-devel] [PATCH v2 09/16] Save/Restore Support: Disable/enable IRQs during suspend/restore

2018-02-13 Thread Bruno Alvisio
Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
 kernel.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel.c b/kernel.c
index 1cd40e8..782eb79 100644
--- a/kernel.c
+++ b/kernel.c
@@ -119,12 +119,12 @@ void start_kernel(void* par)
 
 void pre_suspend(void)
 {
-
+local_irq_disable();
 }
 
 void post_suspend(int canceled)
 {
-
+local_irq_enable();
 }
 
 void stop_kernel(void)
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 16/16] Save/Restore Support: Implement code for arch suspend/resume

2018-02-13 Thread Bruno Alvisio
Before suspending the domain the shared_info_page is unmapped and for PVs the
pagetables should be canonicalized. After resume the shared_info_page should be
mapped again.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
Changed since v1:
  * Fixed comment
---
 arch/x86/setup.c | 51 +++
 1 file changed, 51 insertions(+)

diff --git a/arch/x86/setup.c b/arch/x86/setup.c
index b6e0541..b5ed1c8 100644
--- a/arch/x86/setup.c
+++ b/arch/x86/setup.c
@@ -32,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #ifdef CONFIG_PARAVIRT
 /*
@@ -42,6 +43,11 @@ union start_info_union start_info_union;
 #endif
 
 /*
+ * This pointer holds a reference to the copy of the start_info struct.
+ */
+static start_info_t *start_info_ptr;
+
+/*
  * Shared page for communicating with the hypervisor.
  * Events flags go here, for example.
  */
@@ -212,18 +218,63 @@ arch_init(void *par)
 #ifdef CONFIG_PARAVIRT
memcpy(_info, par, sizeof(start_info));
 #endif
+   start_info_ptr = (start_info_t *)par;
 
start_kernel((start_info_t *)par);
 }
 
 void arch_pre_suspend(void)
 {
+#ifdef CONFIG_PARAVIRT
+   /* Replace xenstore and console mfns with the correspondent pfns */
+start_info_ptr->store_mfn =
+virt_to_pfn(mfn_to_virt(start_info_ptr->store_mfn));
+start_info_ptr->console.domU.mfn =
+virt_to_pfn(mfn_to_virt(start_info_ptr->console.domU.mfn));
+#else
+uint64_t store_v;
+uint64_t console_v;
+
+if( hvm_get_parameter(HVM_PARAM_STORE_PFN, _v) )
+BUG();
+start_info_ptr->store_mfn = store_v;
+
+if( hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, _v) )
+BUG();
+start_info_ptr->console.domU.mfn = console_v;
+#endif
+unmap_shared_info();
 
+arch_mm_pre_suspend();
 }
 
 void arch_post_suspend(int canceled)
 {
+#if CONFIG_PARAVIRT
+if (canceled) {
+start_info_ptr->store_mfn = pfn_to_mfn(start_info_ptr->store_mfn);
+start_info_ptr->console.domU.mfn = 
pfn_to_mfn(start_info_ptr->console.domU.mfn);
+} else {
+memcpy(_info, start_info_ptr, sizeof(start_info_t));
+}
+#else
+uint64_t store_v;
+uint64_t console_v;
+
+if (hvm_get_parameter(HVM_PARAM_STORE_PFN, _v))
+BUG();
+start_info_ptr->store_mfn = pfn_to_mfn(store_v);
 
+if (hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, _v))
+BUG();
+start_info_ptr->console.domU.mfn = pfn_to_mfn(console_v);
+#endif
+
+HYPERVISOR_shared_info = map_shared_info((void*) 
start_info_ptr->shared_info);
+#ifndef CONFIG_PARAVIRT
+xen_callback_vector();
+#endif
+arch_mm_post_suspend(canceled);
 }
 
 void
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 12/16] Save/Restore Support: Add support for suspend/restore events.

2018-02-13 Thread Bruno Alvisio
Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
 events.c | 5 +
 include/events.h | 1 +
 kernel.c | 2 ++
 3 files changed, 8 insertions(+)

diff --git a/events.c b/events.c
index e8ef8aa..342aead 100644
--- a/events.c
+++ b/events.c
@@ -183,6 +183,11 @@ void fini_events(void)
 arch_fini_events();
 }
 
+void suspend_events(void)
+{
+unbind_all_ports();
+}
+
 void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore)
 {
 printk("[Port %d] - event received\n", port);
diff --git a/include/events.h b/include/events.h
index 89b5997..705ad93 100644
--- a/include/events.h
+++ b/include/events.h
@@ -55,5 +55,6 @@ static inline int notify_remote_via_evtchn(evtchn_port_t port)
 }
 
 void fini_events(void);
+void suspend_events(void);
 
 #endif /* _EVENTS_H_ */
diff --git a/kernel.c b/kernel.c
index 2fb69bf..d078e0a 100644
--- a/kernel.c
+++ b/kernel.c
@@ -124,6 +124,8 @@ void pre_suspend(void)
 fini_time();
 
 suspend_console();
+
+suspend_events();
 }
 
 void post_suspend(int canceled)
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 00/16] Save/Restore Support for mini-OS PVH

2018-02-13 Thread Bruno Alvisio
Hi all,

I am sending the second revision for supporting save/restore in Mini-OS PVH. 
The 
branch can be found at: 

https://github.com/balvisio/mini-os/tree/feature/mini-os-suspend-support-submission-2

Feedback would be greatly appreciated.

Cheers,

Bruno

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 06/16] Save/Restore Support: Moved shutdown thread to shutdown.c

2018-02-13 Thread Bruno Alvisio
The shutdown thread present in kernel.c was removed and now the thread in
shutdown.c is created instead.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
 arch/x86/setup.c |  2 +-
 include/kernel.h |  2 +-
 kernel.c | 50 ++
 3 files changed, 8 insertions(+), 46 deletions(-)

diff --git a/arch/x86/setup.c b/arch/x86/setup.c
index 3dd86f9..31fa2c6 100644
--- a/arch/x86/setup.c
+++ b/arch/x86/setup.c
@@ -201,7 +201,7 @@ arch_init(void *par)
memcpy(_info, par, sizeof(start_info));
 #endif
 
-   start_kernel();
+   start_kernel((start_info_t *)par);
 }
 
 void arch_pre_suspend(void)
diff --git a/include/kernel.h b/include/kernel.h
index 161d757..742abf5 100644
--- a/include/kernel.h
+++ b/include/kernel.h
@@ -4,7 +4,7 @@
 #define MAX_CMDLINE_SIZE 1024
 extern char cmdline[MAX_CMDLINE_SIZE];
 
-void start_kernel(void);
+void start_kernel(void* par);
 void pre_suspend(void);
 void post_suspend(int canceled);
 void do_exit(void) __attribute__((noreturn));
diff --git a/kernel.c b/kernel.c
index 90c865a..1cd40e8 100644
--- a/kernel.c
+++ b/kernel.c
@@ -42,6 +42,9 @@
 #include 
 #include 
 #include 
+#ifdef CONFIG_XENBUS
+#include 
+#endif
 #include 
 #include 
 #include 
@@ -66,48 +69,6 @@ void setup_xen_features(void)
 }
 }
 
-#ifdef CONFIG_XENBUS
-/* This should be overridden by the application we are linked against. */
-__attribute__((weak)) void app_shutdown(unsigned reason)
-{
-struct sched_shutdown sched_shutdown = { .reason = reason };
-printk("Shutdown requested: %d\n", reason);
-HYPERVISOR_sched_op(SCHEDOP_shutdown, _shutdown);
-}
-
-static void shutdown_thread(void *p)
-{
-const char *path = "control/shutdown";
-const char *token = path;
-xenbus_event_queue events = NULL;
-char *shutdown = NULL, *err;
-unsigned int shutdown_reason;
-xenbus_watch_path_token(XBT_NIL, path, token, );
-while ((err = xenbus_read(XBT_NIL, path, )) != NULL || 
!strcmp(shutdown, ""))
-{
-free(err);
-free(shutdown);
-shutdown = NULL;
-xenbus_wait_for_watch();
-}
-err = xenbus_unwatch_path_token(XBT_NIL, path, token);
-free(err);
-err = xenbus_write(XBT_NIL, path, "");
-free(err);
-printk("Shutting down (%s)\n", shutdown);
-
-if (!strcmp(shutdown, "poweroff"))
-shutdown_reason = SHUTDOWN_poweroff;
-else if (!strcmp(shutdown, "reboot"))
-shutdown_reason = SHUTDOWN_reboot;
-else
-/* Unknown */
-shutdown_reason = SHUTDOWN_crash;
-app_shutdown(shutdown_reason);
-free(shutdown);
-}
-#endif
-
 
 /* This should be overridden by the application we are linked against. */
 __attribute__((weak)) int app_main(void *p)
@@ -116,7 +77,7 @@ __attribute__((weak)) int app_main(void *p)
 return 0;
 }
 
-void start_kernel(void)
+void start_kernel(void* par)
 {
 /* Set up events. */
 init_events();
@@ -145,7 +106,8 @@ void start_kernel(void)
 init_xenbus();
 
 #ifdef CONFIG_XENBUS
-create_thread("shutdown", shutdown_thread, NULL);
+/* Init shutdown thread */
+init_shutdown((start_info_t *)par);
 #endif
 
 /* Call (possibly overridden) app_main() */
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 02/16] Save/Restore Support: Refactor trap_init() and setup vector callbacks

2018-02-13 Thread Bruno Alvisio
Currently the setup of the IDT and the request to set the HVM vector callbacks
are performed both in the trap_init function.

As part of the post-suspend operation, the HVM vector callback needs to be setup
again while the IDT does not. Thus, the trap_init function is split into two
separate functions: trap_init (sets up IDT) and xen_callback_vector (sets the
HVM vector callback). During the post-suspend operations the xen_callback_vector
function will be invoked.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
 arch/x86/traps.c | 17 +++--
 include/x86/os.h |  3 +++
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/arch/x86/traps.c b/arch/x86/traps.c
index aa17da3..a7388a5 100644
--- a/arch/x86/traps.c
+++ b/arch/x86/traps.c
@@ -389,6 +389,16 @@ static void setup_gate(unsigned int entry, void *addr, 
unsigned int dpl)
 #endif
 }
 
+void xen_callback_vector(void)
+{
+if (hvm_set_parameter(HVM_PARAM_CALLBACK_IRQ,
+ (2ULL << 56) | TRAP_xen_callback))
+{
+xprintk("Request for Xen HVM callback vector failed\n");
+do_exit();
+}
+}
+
 void trap_init(void)
 {
 setup_gate(TRAP_divide_error, _error, 0);
@@ -415,12 +425,7 @@ void trap_init(void)
 gdt[GDTE_TSS] = (typeof(*gdt))INIT_GDTE((unsigned long), 0x67, 0x89);
 asm volatile ("ltr %w0" :: "rm" (GDTE_TSS * 8));
 
-if ( hvm_set_parameter(HVM_PARAM_CALLBACK_IRQ,
-   (2ULL << 56) | TRAP_xen_callback) )
-{
-xprintk("Request for Xen HVM callback vector failed\n");
-do_exit();
-}
+xen_callback_vector();
 }
 
 void trap_fini(void)
diff --git a/include/x86/os.h b/include/x86/os.h
index fbc2eeb..d155914 100644
--- a/include/x86/os.h
+++ b/include/x86/os.h
@@ -67,6 +67,9 @@ extern shared_info_t *HYPERVISOR_shared_info;
 
 void trap_init(void);
 void trap_fini(void);
+#ifndef CONFIG_PARAVIRT
+void xen_callback_vector(void);
+#endif
 
 void arch_fini(void);
 
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 11/16] Save/Restore Support: Add suspend/restore support for console

2018-02-13 Thread Bruno Alvisio
Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
 console/console.c  | 15 -
 console/xenbus.c   |  3 +-
 console/xencons_ring.c | 83 +++---
 include/console.h  |  6 +++-
 kernel.c   |  4 +++
 lib/sys.c  |  2 +-
 6 files changed, 77 insertions(+), 36 deletions(-)

diff --git a/console/console.c b/console/console.c
index 2e04552..9814506 100644
--- a/console/console.c
+++ b/console/console.c
@@ -52,6 +52,7 @@
 
 /* If console not initialised the printk will be sent to xen serial line 
NOTE: you need to enable verbose in xen/Rules.mk for it to work. */
+static struct consfront_dev* xen_console = NULL;
 static int console_initialised = 0;
 
 __attribute__((weak)) void console_input(char * buf, unsigned len)
@@ -162,8 +163,20 @@ void xprintk(const char *fmt, ...)
 void init_console(void)
 {   
 printk("Initialising console ... ");
-xencons_ring_init();
+xen_console = xencons_ring_init();
 console_initialised = 1;
 /* This is also required to notify the daemon */
 printk("done.\n");
 }
+
+void suspend_console(void)
+{
+console_initialised = 0;
+xencons_ring_fini(xen_console);
+}
+
+void resume_console(void)
+{
+xencons_ring_resume(xen_console);
+console_initialised = 1;
+}
\ No newline at end of file
diff --git a/console/xenbus.c b/console/xenbus.c
index 1c9a590..654b469 100644
--- a/console/xenbus.c
+++ b/console/xenbus.c
@@ -188,8 +188,7 @@ error:
 return NULL;
 }
 
-void fini_console(struct consfront_dev *dev)
+void fini_consfront(struct consfront_dev *dev)
 {
 if (dev) free_consfront(dev);
 }
-
diff --git a/console/xencons_ring.c b/console/xencons_ring.c
index dd64a41..b6db74e 100644
--- a/console/xencons_ring.c
+++ b/console/xencons_ring.c
@@ -19,6 +19,8 @@ DECLARE_WAIT_QUEUE_HEAD(console_queue);
 static struct xencons_interface *console_ring;
 uint32_t console_evtchn;
 
+static struct consfront_dev* resume_xen_console(struct consfront_dev* dev);
+
 #ifdef CONFIG_PARAVIRT
 void get_console(void *p)
 {
@@ -32,10 +34,12 @@ void get_console(void *p)
 {
 uint64_t v = -1;
 
-hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, );
+if (hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, ))
+BUG();
 console_evtchn = v;
 
-hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, );
+if (hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, ))
+BUG();
 console_ring = (struct xencons_interface *)map_frame_virt(v);
 }
 #endif
@@ -89,9 +93,7 @@ int xencons_ring_send(struct consfront_dev *dev, const char 
*data, unsigned len)
 notify_daemon(dev);
 
 return sent;
-}  
-
-
+}
 
 void console_handle_input(evtchn_port_t port, struct pt_regs *regs, void *data)
 {
@@ -177,41 +179,60 @@ int xencons_ring_recv(struct consfront_dev *dev, char 
*data, unsigned len)
 
 struct consfront_dev *xencons_ring_init(void)
 {
-   int err;
-   struct consfront_dev *dev;
+struct consfront_dev *dev;
 
-   if (!console_evtchn)
-   return 0;
+if (!console_evtchn)
+return 0;
 
-   dev = malloc(sizeof(struct consfront_dev));
-   memset(dev, 0, sizeof(struct consfront_dev));
-   dev->nodename = "device/console";
-   dev->dom = 0;
-   dev->backend = 0;
-   dev->ring_ref = 0;
+dev = malloc(sizeof(struct consfront_dev));
+memset(dev, 0, sizeof(struct consfront_dev));
+dev->nodename = "device/console";
+dev->dom = 0;
+dev->backend = 0;
+dev->ring_ref = 0;
 
 #ifdef HAVE_LIBC
-   dev->fd = -1;
+dev->fd = -1;
 #endif
-   dev->evtchn = console_evtchn;
-   dev->ring = xencons_interface();
-
-   err = bind_evtchn(dev->evtchn, console_handle_input, dev);
-   if (err <= 0) {
-   printk("XEN console request chn bind failed %i\n", err);
-free(dev);
-   return NULL;
-   }
-unmask_evtchn(dev->evtchn);
 
-   /* In case we have in-flight data after save/restore... */
-   notify_daemon(dev);
+return resume_xen_console(dev);
+}
+
+static struct consfront_dev* resume_xen_console(struct consfront_dev* dev)
+{
+int err;
 
-   return dev;
+dev->evtchn = console_evtchn;
+dev->ring = xencons_interface();
+
+err = bind_evtchn(dev->evtchn, console_handle_input, dev);
+if (err <= 0) {
+printk("XEN console request chn bind failed %i\n", err);
+free(dev);
+return NULL;
+}
+unmask_evtchn(dev->evtchn);
+
+/* In case we have in-flight data after save/restore... */
+notify_daemon(dev);
+
+return dev;
 }
 
-void xencons_resume(void)
+void xencons_ring_fini(struct consfront_dev* dev)
 {
-   (void)xencons_ring_init();
+if (dev)
+mask_evtchn(dev->evtchn);
 }
 
+void xencons_ri

[Xen-devel] [PATCH v2 07/16] Save/Restore Support: Add unmap_shared_info

2018-02-13 Thread Bruno Alvisio
This function is necessary as part of the pre-suspend operation.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
Changed since v1:
 * Changed HYPERVISOR_shared_info for shared_info
---
 arch/x86/setup.c | 12 
 hypervisor.c | 12 
 include/hypervisor.h |  1 +
 3 files changed, 25 insertions(+)

diff --git a/arch/x86/setup.c b/arch/x86/setup.c
index 31fa2c6..b6e0541 100644
--- a/arch/x86/setup.c
+++ b/arch/x86/setup.c
@@ -93,6 +93,18 @@ shared_info_t *map_shared_info(void *p)
 return (shared_info_t *)shared_info;
 }
 
+void unmap_shared_info(void)
+{
+int rc;
+
+if ( (rc = HYPERVISOR_update_va_mapping((unsigned long)shared_info,
+__pte((virt_to_mfn(shared_info)<<L1_PAGETABLE_SHIFT)| L1_PROT), 
UVMF_INVLPG)) )
+{
+printk("Failed to unmap shared_info page!! rc=%d\n", rc);
+do_exit();
+}
+}
+
 static void get_cmdline(void *p)
 {
 start_info_t *si = p;
diff --git a/hypervisor.c b/hypervisor.c
index 1647121..d3857e7 100644
--- a/hypervisor.c
+++ b/hypervisor.c
@@ -78,6 +78,18 @@ shared_info_t *map_shared_info(void *p)
 
 return _info;
 }
+
+void unmap_shared_info(void)
+{
+struct xen_remove_from_physmap xrtp;
+
+xrtp.domid = DOMID_SELF;
+xrtp.gpfn = virt_to_pfn(_info);
+if ( HYPERVISOR_memory_op(XENMEM_remove_from_physmap, ) != 0 )
+BUG();
+
+return;
+}
 #endif
 
 void do_hypervisor_callback(struct pt_regs *regs)
diff --git a/include/hypervisor.h b/include/hypervisor.h
index f3b1f3c..1d09271 100644
--- a/include/hypervisor.h
+++ b/include/hypervisor.h
@@ -43,6 +43,7 @@ int hvm_get_parameter(int idx, uint64_t *value);
 int hvm_set_parameter(int idx, uint64_t value);
 #endif
 shared_info_t *map_shared_info(void *p);
+void unmap_shared_info(void);
 void force_evtchn_callback(void);
 void do_hypervisor_callback(struct pt_regs *regs);
 void mask_evtchn(uint32_t port);
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 08/16] Save/Restore Support: Add arch_mm_pre|post_suspend

2018-02-13 Thread Bruno Alvisio
For PV guests the pagetables reference the real MFNs rather than PFNs, so when
the guest is resumed into a different area of a hosts memory, these will need to
be rewritten. Thus for PV guests the MFNs need to be replaced with PFNs:
canonicalization.

PVH guests are auto-translated so no memory operation is needed.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
 arch/x86/mm.c | 14 ++
 include/x86/arch_mm.h |  3 +++
 2 files changed, 17 insertions(+)

diff --git a/arch/x86/mm.c b/arch/x86/mm.c
index 05ad029..1b163ac 100644
--- a/arch/x86/mm.c
+++ b/arch/x86/mm.c
@@ -848,6 +848,20 @@ void arch_init_p2m(unsigned long max_pfn)
 
 arch_remap_p2m(max_pfn);
 }
+
+void arch_mm_pre_suspend(void)
+{
+//TODO: Canonicalize pagetables
+}
+
+void arch_mm_post_suspend(int canceled)
+{
+//TODO: Locate pagetables and 'uncanonicalize' them
+}
+#else
+void arch_mm_pre_suspend(void){ }
+
+void arch_mm_post_suspend(int canceled){ }
 #endif
 
 void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p)
diff --git a/include/x86/arch_mm.h b/include/x86/arch_mm.h
index ab8a53e..cbbeb21 100644
--- a/include/x86/arch_mm.h
+++ b/include/x86/arch_mm.h
@@ -279,6 +279,9 @@ pgentry_t *need_pgt(unsigned long addr);
 void arch_mm_preinit(void *p);
 unsigned long alloc_virt_kernel(unsigned n_pages);
 
+void arch_mm_pre_suspend(void);
+void arch_mm_post_suspend(int canceled);
+
 #ifndef CONFIG_PARAVIRT
 void arch_print_memmap(void);
 #endif
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 07/17] Save/Restore Support: Add unmap_shared_info

2018-02-13 Thread Bruno Alvisio
This function is necessary as part of the pre-suspend operation.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
Changed since v1:
 * Changed HYPERVISOR_shared_info for shared_info
---
 arch/x86/setup.c | 12 
 hypervisor.c | 12 
 include/hypervisor.h |  1 +
 3 files changed, 25 insertions(+)

diff --git a/arch/x86/setup.c b/arch/x86/setup.c
index 31fa2c6..b6e0541 100644
--- a/arch/x86/setup.c
+++ b/arch/x86/setup.c
@@ -93,6 +93,18 @@ shared_info_t *map_shared_info(void *p)
 return (shared_info_t *)shared_info;
 }
 
+void unmap_shared_info(void)
+{
+int rc;
+
+if ( (rc = HYPERVISOR_update_va_mapping((unsigned long)shared_info,
+__pte((virt_to_mfn(shared_info)<<L1_PAGETABLE_SHIFT)| L1_PROT), 
UVMF_INVLPG)) )
+{
+printk("Failed to unmap shared_info page!! rc=%d\n", rc);
+do_exit();
+}
+}
+
 static void get_cmdline(void *p)
 {
 start_info_t *si = p;
diff --git a/hypervisor.c b/hypervisor.c
index 1647121..d3857e7 100644
--- a/hypervisor.c
+++ b/hypervisor.c
@@ -78,6 +78,18 @@ shared_info_t *map_shared_info(void *p)
 
 return _info;
 }
+
+void unmap_shared_info(void)
+{
+struct xen_remove_from_physmap xrtp;
+
+xrtp.domid = DOMID_SELF;
+xrtp.gpfn = virt_to_pfn(_info);
+if ( HYPERVISOR_memory_op(XENMEM_remove_from_physmap, ) != 0 )
+BUG();
+
+return;
+}
 #endif
 
 void do_hypervisor_callback(struct pt_regs *regs)
diff --git a/include/hypervisor.h b/include/hypervisor.h
index f3b1f3c..1d09271 100644
--- a/include/hypervisor.h
+++ b/include/hypervisor.h
@@ -43,6 +43,7 @@ int hvm_get_parameter(int idx, uint64_t *value);
 int hvm_set_parameter(int idx, uint64_t value);
 #endif
 shared_info_t *map_shared_info(void *p);
+void unmap_shared_info(void);
 void force_evtchn_callback(void);
 void do_hypervisor_callback(struct pt_regs *regs);
 void mask_evtchn(uint32_t port);
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 04/16] Save/Restore Support: Add xenbus_release_wait_for_watch

2018-02-13 Thread Bruno Alvisio
xenbus_release_wait_for_watch generates a fake event to trigger make
xenbus_wait_for_watch return. This is necessary to wake up waiting threads.

release_xenbus_id additionally checks if the number of requests == 0 to wake
up the 'waiting' suspend xenbus thread.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
Changed since v1:
  * Added doc for change in release_xenbus_id
---
 include/xenbus.h |  1 +
 xenbus/xenbus.c  | 10 +-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/include/xenbus.h b/include/xenbus.h
index 12391b9..b2d5072 100644
--- a/include/xenbus.h
+++ b/include/xenbus.h
@@ -42,6 +42,7 @@ char *xenbus_unwatch_path_token(xenbus_transaction_t xbt, 
const char *path, cons
 extern struct wait_queue_head xenbus_watch_queue;
 void xenbus_wait_for_watch(xenbus_event_queue *queue);
 char **xenbus_wait_for_watch_return(xenbus_event_queue *queue);
+void xenbus_release_wait_for_watch(xenbus_event_queue *queue);
 char* xenbus_wait_for_value(const char *path, const char *value, 
xenbus_event_queue *queue);
 char *xenbus_wait_for_state_change(const char* path, XenbusState *state, 
xenbus_event_queue *queue);
 char *xenbus_switch_state(xenbus_transaction_t xbt, const char* path, 
XenbusState state);
diff --git a/xenbus/xenbus.c b/xenbus/xenbus.c
index 636786c..c2d2bd1 100644
--- a/xenbus/xenbus.c
+++ b/xenbus/xenbus.c
@@ -129,6 +129,14 @@ void xenbus_wait_for_watch(xenbus_event_queue *queue)
 printk("unexpected path returned by watch\n");
 }
 
+void xenbus_release_wait_for_watch(xenbus_event_queue *queue)
+{
+struct xenbus_event *event = malloc(sizeof(*event));
+event->next = *queue;
+*queue = event;
+wake_up(_watch_queue);
+}
+
 char* xenbus_wait_for_value(const char* path, const char* value, 
xenbus_event_queue *queue)
 {
 if (!queue)
@@ -318,7 +326,7 @@ static void release_xenbus_id(int id)
 req_info[id].in_use = 0;
 nr_live_reqs--;
 req_info[id].in_use = 0;
-if (nr_live_reqs == NR_REQS - 1)
+if (nr_live_reqs == 0 || nr_live_reqs == NR_REQS - 1)
 wake_up(_wq);
 spin_unlock(_lock);
 }
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 11/17] Save/Restore Support: Add suspend/restore support for console

2018-02-13 Thread Bruno Alvisio
Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
 console/console.c  | 15 -
 console/xenbus.c   |  3 +-
 console/xencons_ring.c | 83 +++---
 include/console.h  |  6 +++-
 kernel.c   |  4 +++
 lib/sys.c  |  2 +-
 6 files changed, 77 insertions(+), 36 deletions(-)

diff --git a/console/console.c b/console/console.c
index 2e04552..9814506 100644
--- a/console/console.c
+++ b/console/console.c
@@ -52,6 +52,7 @@
 
 /* If console not initialised the printk will be sent to xen serial line 
NOTE: you need to enable verbose in xen/Rules.mk for it to work. */
+static struct consfront_dev* xen_console = NULL;
 static int console_initialised = 0;
 
 __attribute__((weak)) void console_input(char * buf, unsigned len)
@@ -162,8 +163,20 @@ void xprintk(const char *fmt, ...)
 void init_console(void)
 {   
 printk("Initialising console ... ");
-xencons_ring_init();
+xen_console = xencons_ring_init();
 console_initialised = 1;
 /* This is also required to notify the daemon */
 printk("done.\n");
 }
+
+void suspend_console(void)
+{
+console_initialised = 0;
+xencons_ring_fini(xen_console);
+}
+
+void resume_console(void)
+{
+xencons_ring_resume(xen_console);
+console_initialised = 1;
+}
\ No newline at end of file
diff --git a/console/xenbus.c b/console/xenbus.c
index 1c9a590..654b469 100644
--- a/console/xenbus.c
+++ b/console/xenbus.c
@@ -188,8 +188,7 @@ error:
 return NULL;
 }
 
-void fini_console(struct consfront_dev *dev)
+void fini_consfront(struct consfront_dev *dev)
 {
 if (dev) free_consfront(dev);
 }
-
diff --git a/console/xencons_ring.c b/console/xencons_ring.c
index dd64a41..b6db74e 100644
--- a/console/xencons_ring.c
+++ b/console/xencons_ring.c
@@ -19,6 +19,8 @@ DECLARE_WAIT_QUEUE_HEAD(console_queue);
 static struct xencons_interface *console_ring;
 uint32_t console_evtchn;
 
+static struct consfront_dev* resume_xen_console(struct consfront_dev* dev);
+
 #ifdef CONFIG_PARAVIRT
 void get_console(void *p)
 {
@@ -32,10 +34,12 @@ void get_console(void *p)
 {
 uint64_t v = -1;
 
-hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, );
+if (hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, ))
+BUG();
 console_evtchn = v;
 
-hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, );
+if (hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, ))
+BUG();
 console_ring = (struct xencons_interface *)map_frame_virt(v);
 }
 #endif
@@ -89,9 +93,7 @@ int xencons_ring_send(struct consfront_dev *dev, const char 
*data, unsigned len)
 notify_daemon(dev);
 
 return sent;
-}  
-
-
+}
 
 void console_handle_input(evtchn_port_t port, struct pt_regs *regs, void *data)
 {
@@ -177,41 +179,60 @@ int xencons_ring_recv(struct consfront_dev *dev, char 
*data, unsigned len)
 
 struct consfront_dev *xencons_ring_init(void)
 {
-   int err;
-   struct consfront_dev *dev;
+struct consfront_dev *dev;
 
-   if (!console_evtchn)
-   return 0;
+if (!console_evtchn)
+return 0;
 
-   dev = malloc(sizeof(struct consfront_dev));
-   memset(dev, 0, sizeof(struct consfront_dev));
-   dev->nodename = "device/console";
-   dev->dom = 0;
-   dev->backend = 0;
-   dev->ring_ref = 0;
+dev = malloc(sizeof(struct consfront_dev));
+memset(dev, 0, sizeof(struct consfront_dev));
+dev->nodename = "device/console";
+dev->dom = 0;
+dev->backend = 0;
+dev->ring_ref = 0;
 
 #ifdef HAVE_LIBC
-   dev->fd = -1;
+dev->fd = -1;
 #endif
-   dev->evtchn = console_evtchn;
-   dev->ring = xencons_interface();
-
-   err = bind_evtchn(dev->evtchn, console_handle_input, dev);
-   if (err <= 0) {
-   printk("XEN console request chn bind failed %i\n", err);
-free(dev);
-   return NULL;
-   }
-unmask_evtchn(dev->evtchn);
 
-   /* In case we have in-flight data after save/restore... */
-   notify_daemon(dev);
+return resume_xen_console(dev);
+}
+
+static struct consfront_dev* resume_xen_console(struct consfront_dev* dev)
+{
+int err;
 
-   return dev;
+dev->evtchn = console_evtchn;
+dev->ring = xencons_interface();
+
+err = bind_evtchn(dev->evtchn, console_handle_input, dev);
+if (err <= 0) {
+printk("XEN console request chn bind failed %i\n", err);
+free(dev);
+return NULL;
+}
+unmask_evtchn(dev->evtchn);
+
+/* In case we have in-flight data after save/restore... */
+notify_daemon(dev);
+
+return dev;
 }
 
-void xencons_resume(void)
+void xencons_ring_fini(struct consfront_dev* dev)
 {
-   (void)xencons_ring_init();
+if (dev)
+mask_evtchn(dev->evtchn);
 }
 
+void xencons_ri

[Xen-devel] [PATCH v2 08/17] Save/Restore Support: Add arch_mm_pre|post_suspend

2018-02-13 Thread Bruno Alvisio
For PV guests the pagetables reference the real MFNs rather than PFNs, so when
the guest is resumed into a different area of a hosts memory, these will need to
be rewritten. Thus for PV guests the MFNs need to be replaced with PFNs:
canonicalization.

PVH guests are auto-translated so no memory operation is needed.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
 arch/x86/mm.c | 14 ++
 include/x86/arch_mm.h |  3 +++
 2 files changed, 17 insertions(+)

diff --git a/arch/x86/mm.c b/arch/x86/mm.c
index 05ad029..1b163ac 100644
--- a/arch/x86/mm.c
+++ b/arch/x86/mm.c
@@ -848,6 +848,20 @@ void arch_init_p2m(unsigned long max_pfn)
 
 arch_remap_p2m(max_pfn);
 }
+
+void arch_mm_pre_suspend(void)
+{
+//TODO: Canonicalize pagetables
+}
+
+void arch_mm_post_suspend(int canceled)
+{
+//TODO: Locate pagetables and 'uncanonicalize' them
+}
+#else
+void arch_mm_pre_suspend(void){ }
+
+void arch_mm_post_suspend(int canceled){ }
 #endif
 
 void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p)
diff --git a/include/x86/arch_mm.h b/include/x86/arch_mm.h
index ab8a53e..cbbeb21 100644
--- a/include/x86/arch_mm.h
+++ b/include/x86/arch_mm.h
@@ -279,6 +279,9 @@ pgentry_t *need_pgt(unsigned long addr);
 void arch_mm_preinit(void *p);
 unsigned long alloc_virt_kernel(unsigned n_pages);
 
+void arch_mm_pre_suspend(void);
+void arch_mm_post_suspend(int canceled);
+
 #ifndef CONFIG_PARAVIRT
 void arch_print_memmap(void);
 #endif
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 04/17] Save/Restore Support: Add xenbus_release_wait_for_watch

2018-02-13 Thread Bruno Alvisio
xenbus_release_wait_for_watch generates a fake event to trigger make
xenbus_wait_for_watch return. This is necessary to wake up waiting threads.

release_xenbus_id additionally checks if the number of requests == 0 to wake
up the 'waiting' suspend xenbus thread.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
Changed since v1:
  * Added doc for change in release_xenbus_id
---
 include/xenbus.h |  1 +
 xenbus/xenbus.c  | 10 +-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/include/xenbus.h b/include/xenbus.h
index 12391b9..b2d5072 100644
--- a/include/xenbus.h
+++ b/include/xenbus.h
@@ -42,6 +42,7 @@ char *xenbus_unwatch_path_token(xenbus_transaction_t xbt, 
const char *path, cons
 extern struct wait_queue_head xenbus_watch_queue;
 void xenbus_wait_for_watch(xenbus_event_queue *queue);
 char **xenbus_wait_for_watch_return(xenbus_event_queue *queue);
+void xenbus_release_wait_for_watch(xenbus_event_queue *queue);
 char* xenbus_wait_for_value(const char *path, const char *value, 
xenbus_event_queue *queue);
 char *xenbus_wait_for_state_change(const char* path, XenbusState *state, 
xenbus_event_queue *queue);
 char *xenbus_switch_state(xenbus_transaction_t xbt, const char* path, 
XenbusState state);
diff --git a/xenbus/xenbus.c b/xenbus/xenbus.c
index 636786c..c2d2bd1 100644
--- a/xenbus/xenbus.c
+++ b/xenbus/xenbus.c
@@ -129,6 +129,14 @@ void xenbus_wait_for_watch(xenbus_event_queue *queue)
 printk("unexpected path returned by watch\n");
 }
 
+void xenbus_release_wait_for_watch(xenbus_event_queue *queue)
+{
+struct xenbus_event *event = malloc(sizeof(*event));
+event->next = *queue;
+*queue = event;
+wake_up(_watch_queue);
+}
+
 char* xenbus_wait_for_value(const char* path, const char* value, 
xenbus_event_queue *queue)
 {
 if (!queue)
@@ -318,7 +326,7 @@ static void release_xenbus_id(int id)
 req_info[id].in_use = 0;
 nr_live_reqs--;
 req_info[id].in_use = 0;
-if (nr_live_reqs == NR_REQS - 1)
+if (nr_live_reqs == 0 || nr_live_reqs == NR_REQS - 1)
 wake_up(_wq);
 spin_unlock(_lock);
 }
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 00/16] Save/Restore Support for mini-OS PVH

2018-02-13 Thread Bruno Alvisio
Hi all,

I am sending the second revision for supporting save/restore in Mini-OS PVH. 
The 
branch can be found at: 

https://github.com/balvisio/mini-os/tree/feature/mini-os-suspend-support-submission-2

Feedback would be greatly appreciated.

Cheers,

Bruno

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 10/17] Save/Restore Support: Add suspend/resume support for timers

2018-02-13 Thread Bruno Alvisio
Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
Changed since v1:
   * Removed resume/suspend_time() and used init/fini_time() instead
---
 arch/x86/time.c | 1 -
 kernel.c| 4 
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/x86/time.c b/arch/x86/time.c
index 3658142..8077c80 100644
--- a/arch/x86/time.c
+++ b/arch/x86/time.c
@@ -233,7 +233,6 @@ static void timer_handler(evtchn_port_t ev, struct pt_regs 
*regs, void *ign)
 static evtchn_port_t port;
 void init_time(void)
 {
-printk("Initialising timer interface\n");
 port = bind_virq(VIRQ_TIMER, _handler, NULL);
 unmask_evtchn(port);
 }
diff --git a/kernel.c b/kernel.c
index 782eb79..3564af3 100644
--- a/kernel.c
+++ b/kernel.c
@@ -120,10 +120,14 @@ void start_kernel(void* par)
 void pre_suspend(void)
 {
 local_irq_disable();
+
+fini_time();
 }
 
 void post_suspend(int canceled)
 {
+init_time();
+
 local_irq_enable();
 }
 
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 06/17] Save/Restore Support: Moved shutdown thread to shutdown.c

2018-02-13 Thread Bruno Alvisio
The shutdown thread present in kernel.c was removed and now the thread in
shutdown.c is created instead.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
 arch/x86/setup.c |  2 +-
 include/kernel.h |  2 +-
 kernel.c | 50 ++
 3 files changed, 8 insertions(+), 46 deletions(-)

diff --git a/arch/x86/setup.c b/arch/x86/setup.c
index 3dd86f9..31fa2c6 100644
--- a/arch/x86/setup.c
+++ b/arch/x86/setup.c
@@ -201,7 +201,7 @@ arch_init(void *par)
memcpy(_info, par, sizeof(start_info));
 #endif
 
-   start_kernel();
+   start_kernel((start_info_t *)par);
 }
 
 void arch_pre_suspend(void)
diff --git a/include/kernel.h b/include/kernel.h
index 161d757..742abf5 100644
--- a/include/kernel.h
+++ b/include/kernel.h
@@ -4,7 +4,7 @@
 #define MAX_CMDLINE_SIZE 1024
 extern char cmdline[MAX_CMDLINE_SIZE];
 
-void start_kernel(void);
+void start_kernel(void* par);
 void pre_suspend(void);
 void post_suspend(int canceled);
 void do_exit(void) __attribute__((noreturn));
diff --git a/kernel.c b/kernel.c
index 90c865a..1cd40e8 100644
--- a/kernel.c
+++ b/kernel.c
@@ -42,6 +42,9 @@
 #include 
 #include 
 #include 
+#ifdef CONFIG_XENBUS
+#include 
+#endif
 #include 
 #include 
 #include 
@@ -66,48 +69,6 @@ void setup_xen_features(void)
 }
 }
 
-#ifdef CONFIG_XENBUS
-/* This should be overridden by the application we are linked against. */
-__attribute__((weak)) void app_shutdown(unsigned reason)
-{
-struct sched_shutdown sched_shutdown = { .reason = reason };
-printk("Shutdown requested: %d\n", reason);
-HYPERVISOR_sched_op(SCHEDOP_shutdown, _shutdown);
-}
-
-static void shutdown_thread(void *p)
-{
-const char *path = "control/shutdown";
-const char *token = path;
-xenbus_event_queue events = NULL;
-char *shutdown = NULL, *err;
-unsigned int shutdown_reason;
-xenbus_watch_path_token(XBT_NIL, path, token, );
-while ((err = xenbus_read(XBT_NIL, path, )) != NULL || 
!strcmp(shutdown, ""))
-{
-free(err);
-free(shutdown);
-shutdown = NULL;
-xenbus_wait_for_watch();
-}
-err = xenbus_unwatch_path_token(XBT_NIL, path, token);
-free(err);
-err = xenbus_write(XBT_NIL, path, "");
-free(err);
-printk("Shutting down (%s)\n", shutdown);
-
-if (!strcmp(shutdown, "poweroff"))
-shutdown_reason = SHUTDOWN_poweroff;
-else if (!strcmp(shutdown, "reboot"))
-shutdown_reason = SHUTDOWN_reboot;
-else
-/* Unknown */
-shutdown_reason = SHUTDOWN_crash;
-app_shutdown(shutdown_reason);
-free(shutdown);
-}
-#endif
-
 
 /* This should be overridden by the application we are linked against. */
 __attribute__((weak)) int app_main(void *p)
@@ -116,7 +77,7 @@ __attribute__((weak)) int app_main(void *p)
 return 0;
 }
 
-void start_kernel(void)
+void start_kernel(void* par)
 {
 /* Set up events. */
 init_events();
@@ -145,7 +106,8 @@ void start_kernel(void)
 init_xenbus();
 
 #ifdef CONFIG_XENBUS
-create_thread("shutdown", shutdown_thread, NULL);
+/* Init shutdown thread */
+init_shutdown((start_info_t *)par);
 #endif
 
 /* Call (possibly overridden) app_main() */
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 05/17] Save/Restore Support: Add kernel shutdown logic to shutdown.c

2018-02-13 Thread Bruno Alvisio
Created shutdown.c for the shutdown thread and all the shutdown related
functions.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
Changesd since v1:
   * Updated license to a BSD 3-clause. This license was taken
from the updated original file. (Repo: sysml/mini-os)
---
 Makefile   |   1 +
 include/shutdown.h |  11 
 shutdown.c | 188 +
 3 files changed, 200 insertions(+)
 create mode 100644 include/shutdown.h
 create mode 100644 shutdown.c

diff --git a/Makefile b/Makefile
index 88315c4..6a05de6 100644
--- a/Makefile
+++ b/Makefile
@@ -53,6 +53,7 @@ src-y += mm.c
 src-$(CONFIG_NETFRONT) += netfront.c
 src-$(CONFIG_PCIFRONT) += pcifront.c
 src-y += sched.c
+src-y += shutdown.c
 src-$(CONFIG_TEST) += test.c
 src-$(CONFIG_BALLOON) += balloon.c
 
diff --git a/include/shutdown.h b/include/shutdown.h
new file mode 100644
index 000..a5ec019
--- /dev/null
+++ b/include/shutdown.h
@@ -0,0 +1,11 @@
+#ifndef _SHUTDOWN_H_
+#define _SHUTDOWN_H_
+
+#include 
+
+void init_shutdown(start_info_t *si);
+
+void kernel_shutdown(int reason) __attribute__((noreturn));
+void kernel_suspend(void);
+
+#endif
diff --git a/shutdown.c b/shutdown.c
new file mode 100644
index 000..aba146e
--- /dev/null
+++ b/shutdown.c
@@ -0,0 +1,188 @@
+/*
+ *  MiniOS
+ *
+ *   file: fromdevice.cc
+ *
+ * Authors: Joao Martins <joao.mart...@neclab.eu>
+ *
+ *
+ * Copyright (c) 2014, NEC Europe Ltd., NEC Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *notice, this list of conditions and the following disclaimer in the
+ *documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ *contributors may be used to endorse or promote products derived from
+ *this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+
+static start_info_t *start_info_ptr;
+
+static const char *path = "control/shutdown";
+static const char *token = "control/shutdown";
+static xenbus_event_queue events = NULL;
+static int end_shutdown_thread = 0;
+
+#ifdef CONFIG_XENBUS
+/* This should be overridden by the application we are linked against. */
+__attribute__((weak)) void app_shutdown(unsigned reason)
+{
+printk("Shutdown requested: %d\n", reason);
+if (reason == SHUTDOWN_suspend) {
+kernel_suspend();
+} else {
+struct sched_shutdown sched_shutdown = { .reason = reason };
+HYPERVISOR_sched_op(SCHEDOP_shutdown, _shutdown);
+}
+}
+
+static void shutdown_thread(void *p)
+{
+char *shutdown, *err;
+unsigned int shutdown_reason;
+
+xenbus_watch_path_token(XBT_NIL, path, token, );
+
+for ( ;; ) {
+xenbus_wait_for_watch();
+if ((err = xenbus_read(XBT_NIL, path, ))) {
+free(err);
+do_exit();
+}
+
+if (end_shutdown_thread)
+break;
+
+if (!strcmp(shutdown, "")) {
+/* Avoid spurious event on xenbus */
+/* FIXME: investigate the reason of the spurious event */
+free(shutdown);
+continue;
+} else if (!strcmp(shutdown, "poweroff")) {
+shutdown_reason = SHUTDOWN_poweroff;
+} else if (!strcmp(shutdown, "reboot")) {
+shutdown_reason = SHUTDOWN_reboot;
+} else if (!strcmp(shutdown, "suspend")) {
+shutdown_reason = SHUTDOWN_suspend;
+} else {
+shutdown_reason = SHUTDOWN_crash;
+}
+free(shutdown);
+
+/* Acknowledge shutd

[Xen-devel] [PATCH v2 03/17] Save/Restore Support: Declare kernel and arch pre/post suspend functions

2018-02-13 Thread Bruno Alvisio
For mini-OS to support suspend and restore, the kernel will have to suspend
different modules such as xenbus, console, irq, etc. During save/restore the
kernel and arch pre_suspend and post_suspend functions will be invoked to
suspend/resume each of the modules.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
 arch/x86/setup.c | 10 ++
 include/kernel.h |  2 ++
 include/x86/os.h |  4 ++--
 kernel.c | 10 ++
 4 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/arch/x86/setup.c b/arch/x86/setup.c
index 5278227..3dd86f9 100644
--- a/arch/x86/setup.c
+++ b/arch/x86/setup.c
@@ -204,6 +204,16 @@ arch_init(void *par)
start_kernel();
 }
 
+void arch_pre_suspend(void)
+{
+
+}
+
+void arch_post_suspend(int canceled)
+{
+
+}
+
 void
 arch_fini(void)
 {
diff --git a/include/kernel.h b/include/kernel.h
index d37ddda..161d757 100644
--- a/include/kernel.h
+++ b/include/kernel.h
@@ -5,6 +5,8 @@
 extern char cmdline[MAX_CMDLINE_SIZE];
 
 void start_kernel(void);
+void pre_suspend(void);
+void post_suspend(int canceled);
 void do_exit(void) __attribute__((noreturn));
 void arch_do_exit(void);
 void stop_kernel(void);
diff --git a/include/x86/os.h b/include/x86/os.h
index d155914..a73b63e 100644
--- a/include/x86/os.h
+++ b/include/x86/os.h
@@ -71,10 +71,10 @@ void trap_fini(void);
 void xen_callback_vector(void);
 #endif
 
+void arch_pre_suspend(void);
+void arch_post_suspend(int canceled);
 void arch_fini(void);
 
-
-
 #ifdef CONFIG_PARAVIRT
 
 /* 
diff --git a/kernel.c b/kernel.c
index 0d84a9b..90c865a 100644
--- a/kernel.c
+++ b/kernel.c
@@ -155,6 +155,16 @@ void start_kernel(void)
 run_idle_thread();
 }
 
+void pre_suspend(void)
+{
+
+}
+
+void post_suspend(int canceled)
+{
+
+}
+
 void stop_kernel(void)
 {
 /* TODO: fs import */
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 09/17] Save/Restore Support: Disable/enable IRQs during suspend/restore

2018-02-13 Thread Bruno Alvisio
Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
 kernel.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel.c b/kernel.c
index 1cd40e8..782eb79 100644
--- a/kernel.c
+++ b/kernel.c
@@ -119,12 +119,12 @@ void start_kernel(void* par)
 
 void pre_suspend(void)
 {
-
+local_irq_disable();
 }
 
 void post_suspend(int canceled)
 {
-
+local_irq_enable();
 }
 
 void stop_kernel(void)
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2 02/17] Save/Restore Support: Refactor trap_init() and setup vector callbacks

2018-02-13 Thread Bruno Alvisio
Currently the setup of the IDT and the request to set the HVM vector callbacks
are performed both in the trap_init function.

As part of the post-suspend operation, the HVM vector callback needs to be setup
again while the IDT does not. Thus, the trap_init function is split into two
separate functions: trap_init (sets up IDT) and xen_callback_vector (sets the
HVM vector callback). During the post-suspend operations the xen_callback_vector
function will be invoked.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
Reviewed-by: Samuel Thibault <samuel.thiba...@ens-lyon.org>
---
 arch/x86/traps.c | 17 +++--
 include/x86/os.h |  3 +++
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/arch/x86/traps.c b/arch/x86/traps.c
index aa17da3..a7388a5 100644
--- a/arch/x86/traps.c
+++ b/arch/x86/traps.c
@@ -389,6 +389,16 @@ static void setup_gate(unsigned int entry, void *addr, 
unsigned int dpl)
 #endif
 }
 
+void xen_callback_vector(void)
+{
+if (hvm_set_parameter(HVM_PARAM_CALLBACK_IRQ,
+ (2ULL << 56) | TRAP_xen_callback))
+{
+xprintk("Request for Xen HVM callback vector failed\n");
+do_exit();
+}
+}
+
 void trap_init(void)
 {
 setup_gate(TRAP_divide_error, _error, 0);
@@ -415,12 +425,7 @@ void trap_init(void)
 gdt[GDTE_TSS] = (typeof(*gdt))INIT_GDTE((unsigned long), 0x67, 0x89);
 asm volatile ("ltr %w0" :: "rm" (GDTE_TSS * 8));
 
-if ( hvm_set_parameter(HVM_PARAM_CALLBACK_IRQ,
-   (2ULL << 56) | TRAP_xen_callback) )
-{
-xprintk("Request for Xen HVM callback vector failed\n");
-do_exit();
-}
+xen_callback_vector();
 }
 
 void trap_fini(void)
diff --git a/include/x86/os.h b/include/x86/os.h
index fbc2eeb..d155914 100644
--- a/include/x86/os.h
+++ b/include/x86/os.h
@@ -67,6 +67,9 @@ extern shared_info_t *HYPERVISOR_shared_info;
 
 void trap_init(void);
 void trap_fini(void);
+#ifndef CONFIG_PARAVIRT
+void xen_callback_vector(void);
+#endif
 
 void arch_fini(void);
 
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] Unexpected behavior: Xen creating domains on startup

2018-01-15 Thread Bruno Alvisio
Hello all,

I am doing some testing with Xen. After some of the guest domains I am
testing crashed, I decided to add some logging to Xen and the tools. After
rebuilding, reinstalling and rebooting the system, Xen seems to create
guest domains (the ones created before reboot) on startup (with no 'xl
create' command issued by me). The domains are deleted a few seconds after
startup and when I create the first domain, the domain number is not 1 but
3 or 4. Below is an example of dmesg logs right after startup: (int this
case a domain 2 was launched, xl list shows no domain few seconds later):

(XEN) Dom0 has maximum 8 VCPUs

(XEN) ELF: phdr 0 at 0x8100 -> 0x81aca000

(XEN) ELF: phdr 1 at 0x81c0 -> 0x81d1e000

(XEN) ELF: phdr 2 at 0x81d1e000 -> 0x81d37418

(XEN) ELF: phdr 3 at 0x81d38000 -> 0x81e82000

(XEN) Initial low memory virq threshold set at 0x4000 pages.

(XEN) Scrubbing Free RAM on 1 nodes using 4 CPUs

(XEN) ..done.

(XEN) Std. Loglevel: All

(XEN) Guest Loglevel: All

(XEN) Xen is relinquishing VGA console.

(XEN) *** Serial input -> DOM0 (type 'CTRL-a' three times to switch input
to Xen)

(XEN) Freed 456kB init memory

(XEN) PCI add device :00:00.0

(XEN) PCI add device :00:01.0

(XEN) PCI add device :00:16.0

(XEN) PCI add device :00:16.1

(XEN) PCI add device :00:1a.0

(XEN) PCI add device :00:1d.0

(XEN) PCI add device :00:1e.0

(XEN) PCI add device :00:1f.0

(XEN) PCI add device :00:1f.2

(XEN) PCI add device :00:1f.3

(XEN) PCI add device :01:00.0

(XEN) PCI add device :01:00.1

(XEN) PCI add device :02:03.0

(XEN) PCI: Using MCFG for segment  bus 00-ff

(XEN) d0: Forcing read-only access to MFN fed00

(XEN) traps.c:1540: GPF (): 82d080363383
[emul-priv-op.c#read_msr+0x370/0x45c] -> 82d08036d9b2

(XEN) traps.c:1540: GPF (): 82d080363383
[emul-priv-op.c#read_msr+0x370/0x45c] -> 82d08036d9b2

(XEN) traps.c:1540: GPF (): 82d080363383
[emul-priv-op.c#read_msr+0x370/0x45c] -> 82d08036d9b2

(XEN) grant_table.c:1688:d0v1 Expanding d1 grant table from 0 to 1 frames

(XEN) HVM1 restore: CPU 0

(XEN) HVM1 restore: CPU 1

(XEN) HVM1 restore: PIC 0

(XEN) HVM1 restore: PIC 1

(XEN) HVM1 restore: IOAPIC 0

(XEN) HVM1 restore: LAPIC 0

(XEN) HVM1 restore: LAPIC 1

(XEN) HVM1 restore: LAPIC_REGS 0

(XEN) HVM1 restore: LAPIC_REGS 1

(XEN) HVM1 restore: PCI_IRQ 0

(XEN) HVM1 restore: ISA_IRQ 0

(XEN) HVM1 restore: PCI_LINK 0

(XEN) HVM1 restore: PIT 0

(XEN) HVM1 restore: RTC 0

(XEN) HVM1 restore: HPET 0

(XEN) HVM1 restore: PMTIMER 0

(XEN) HVM1 restore: MTRR 0

(XEN) HVM1 restore: MTRR 1

(XEN) HVM1 restore: CPU_XSAVE 0

(XEN) HVM1 restore: CPU_XSAVE 1

(XEN) HVM1 restore: VMCE_VCPU 0

(XEN) HVM1 restore: VMCE_VCPU 1

(XEN) HVM1 restore: TSC_ADJUST 0

(XEN) HVM1 restore: TSC_ADJUST 1

(XEN) grant_table.c:1688:d0v6 Expanding d2 grant table from 0 to 1 frames

(d2) Bootstrapping...

(d2) Xen Minimal OS (pv)!

(d2)   start_info: 0x574000(VA)

(d2) nr_pages: 0x2000
(d2)   shared_inf: 0x06182000(MA)


Any explanation/idea on what could be occurring would be appreciated.

Cheers,

Bruno
___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] Problem creating x86_64 PVH mini-os domain

2018-01-02 Thread Bruno Alvisio
On Sun, Dec 31, 2017 at 5:12 PM, Andrew Cooper <andrew.coop...@citrix.com>
wrote:

> On 31/12/2017 15:19, Bruno Alvisio wrote:
>
> Hi all,
>
>
>
> I was trying to create mini-os PVH instances both x86_32 and x86_64. I
> have no issue with x86_32 but when trying to ‘xl create’ x86_64 type I get
> the following error:
>
>
> 
>
> xc: error: panic: xc_dom_hvmloader.c:113: xc_dom_parse_hvm_kernel: ELF
> image is not 32bit: Invalid kernel
>
>
> The domain loader only ever accepts elf32 images, because the starting
> state is 32bit flat mode.
>
> This is how XTF deals with the problem:
>
> http://xenbits.xen.org/gitweb/?p=xtf.git;a=blob;f=build/gen.mk;h=
> 8d7a6bf89725fedc8343d2e4d3c8e2c93c16811f;hb=HEAD#l47
>
> There is a lot of template meta-programming in there, but basically after
> doing the final link, do a further objcopy to convert the image to
> elf32-x86-64 (if available), or elf32-i386.  The former is only available
> if you have an x32 toolchain, and allows the binary to load properly and
> disassemble correctly.
>

Thank you. Doing:

$objcopy  -O elf32-x86-64 

 worked perfectly!

>
>  Happy New Year!
>
>
> Happy new year.
>
> ~Andrew
>
___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] Problem creating x86_64 PVH mini-os domain

2017-12-31 Thread Bruno Alvisio
Hi all,



I was trying to create mini-os PVH instances both x86_32 and x86_64. I have
no issue with x86_32 but when trying to ‘xl create’ x86_64 type I get the
following error:


root@debianxen:/home/balvisio# xl -vvv create minios_pvh.cfg

Parsing config from minios_pvh.cfg

libxl: debug: libxl_create.c:1646:do_domain_create: Domain 0:ao
0x558d17c32c70: create: how=(nil) callback=(nil) poller=0x558d17c32b30

libxl: debug: libxl_create.c:987:initiate_domain_create: Domain 24:running
bootloader

libxl: debug: libxl_bootloader.c:335:libxl__bootloader_run: Domain 24:no
bootloader configured, using user supplied kernel

libxl: debug: libxl_event.c:686:libxl__ev_xswatch_deregister: watch
w=0x558d17c33d20: deregister unregistered

domainbuilder: detail: xc_dom_allocate: cmdline="", features=""

domainbuilder: detail: xc_dom_kernel_file:
filename="/home/balvisio/mini-os/mini-os"

domainbuilder: detail: xc_dom_malloc_filemap: 2367 kB

domainbuilder: detail: xc_dom_boot_xen_init: ver 4.10, caps xen-3.0-x86_64
xen-3.0-x86_32p hvm-3.0-x86_32 hvm-3.0-x86_32p hvm-3.0-x86_64

domainbuilder: detail: xc_dom_parse_image: called

domainbuilder: detail: xc_dom_find_loader: trying multiboot-binary loader
...

domainbuilder: detail: loader probe failed

domainbuilder: detail: xc_dom_find_loader: trying HVM-generic loader ...

domainbuilder: detail: loader probe OK

xc: error: panic: xc_dom_hvmloader.c:113: xc_dom_parse_hvm_kernel: ELF
image is not 32bit: Invalid kernel

libxl: error: libxl_dom.c:718:libxl__build_dom: xc_dom_parse_image failed:
No such file or directory

domainbuilder: detail: xc_dom_release: called

libxl: error: libxl_create.c:1246:domcreate_rebuild_done: Domain 24:cannot
(re-)build domain: -3

libxl: debug: libxl_domain.c:1138:devices_destroy_cb: Domain 24:Forked pid
23698 for destroy of domain

libxl: debug: libxl_create.c:1683:do_domain_create: Domain 0:ao
0x558d17c32c70: inprogress: poller=0x558d17c32b30, flags=i

libxl: debug: libxl_event.c:1869:libxl__ao_complete: ao 0x558d17c32c70:
complete, rc=-3

libxl: debug: libxl_event.c:1838:libxl__ao__destroy: ao 0x558d17c32c70:
destroy

libxl: debug: libxl_domain.c:868:libxl_domain_destroy: Domain 24:ao
0x558d17c32c70: create: how=(nil) callback=(nil) poller=0x558d17c32b30

libxl: error: libxl_domain.c:1000:libxl__destroy_domid: Domain
24:Non-existant domain

libxl: error: libxl_domain.c:959:domain_destroy_callback: Domain 24:Unable
to destroy guest

libxl: error: libxl_domain.c:886:domain_destroy_cb: Domain 24:Destruction
of domain failed

libxl: debug: libxl_event.c:1869:libxl__ao_complete: ao 0x558d17c32c70:
complete, rc=-21

libxl: debug: libxl_domain.c:877:libxl_domain_destroy: Domain 24:ao
0x558d17c32c70: inprogress: poller=0x558d17c32b30, flags=ic

libxl: debug: libxl_event.c:1838:libxl__ao__destroy: ao 0x558d17c32c70:
destroy

xencall:buffer: debug: total allocations:78 total releases:78

xencall:buffer: debug: current allocations:0 maximum allocations:3

xencall:buffer: debug: cache current size:3

xencall:buffer: debug: cache hits:64 misses:3 toobig:11

xencall:buffer: debug: total allocations:0 total releases:0

xencall:buffer: debug: current allocations:0 maximum allocations:0

xencall:buffer: debug: cache current size:0

xencall:buffer: debug: cache hits:0 misses:0 toobig:0



The config file used is:



type="pvh"

memory=1024

vcpu=2

name="minios"

kernel="/home/balvisio/mini-os/mini-os"



The minios elf file header is:



root@debianxen:/home/balvisio/mini-os# readelf -a mini-os

ELF Header:

  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00

  Class: ELF64

  Data:  2's complement, little endian

  Version:   1 (current)

  OS/ABI:UNIX - System V

  ABI Version:   0

  Type:  EXEC (Executable file)

  Machine:   Advanced Micro Devices X86-64

  Version:   0x1

  Entry point address:   0x0

  Start of program headers:  64 (bytes into file)

  Start of section headers:  2422464 (bytes into file)

  Flags: 0x0

  Size of this header:   64 (bytes)

  Size of program headers:   56 (bytes)

  Number of program headers: 2

  Size of section headers:   64 (bytes)

  Number of section headers: 22

  Section header string table index: 21



Is there any extra setup needed to launch this type of domain?

Just in case, my host system is an x86_64 system.



Happy New Year!



Cheers,



Bruno
___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] Building PVH mini-os with libc support

2017-12-28 Thread Bruno Alvisio
e to TARGET_LDFLAGS and recompile the kernel. Now, the kernel carshed
at instruction 0x673bb in the run_idle_thread function:



000673ac :

   673ac:   55  push   %rbp

   673ad:   48 89 e5mov%rsp,%rbp

   673b0:   48 8b 05 00 00 00 00mov0x0(%rip),%rax# 673b7
<run_idle_thread+0xb>

   673b7:   48 8b 60 10 mov0x10(%rax),%rsp

   673bb:   ff 70 18pushq  0x18(%rax)

   673be:   c3  retq

   673bf:   5d  pop%rbp

   673c0:   c3  retq





Finally, just to try I commented out the run_idle_thread function and the
kernel crashed at the very beginning at 0x63. The kern dump in this case
points to the stack:



  5e:   e8 00 00 00 00  callq  63 



0063 :

...

  6b:   90  nop

  6c:   90  nop

  6d:   90  nop





I am not familiar with the XTF relocalability code. Any pointer or
suggestion at this point would be again appreciated.



Thanks,

Bruno

On Thu, Dec 28, 2017 at 7:18 PM, Andrew Cooper <andrew.coop...@citrix.com>
wrote:

> On 28/12/17 18:33, Bruno Alvisio wrote:
>
> (d360) Bootstrapping...
>
> (XEN) Dom360 callback via changed to Direct Vector 0x20
>
> (d360) Xen Minimal OS (hvm)!
>
> (XEN) d360v0 Triple fault - invoking HVM shutdown action 1
>
> (XEN) *** Dumping Dom360 vcpu#0 state: ***
>
> (XEN) [ Xen-4.10.0-rc  x86_64  debug=y   Not tainted ]
>
> (XEN) CPU:7
>
> (XEN) RIP:0008:[<00056fc8>]
>
> (XEN) RFLAGS: 00010006   CONTEXT: hvm guest (d360v0)
>
> (XEN) rax: 000bfe75   rbx: 000bfe75   rcx:
> 
>
> (XEN) rdx: 0017   rsi: 000bfe60   rdi:
> 
>
> (XEN) rbp: 000bfec0   rsp: 000bfe60   r8:
> 
>
> (XEN) r9:  00089982   r10: 0016   r11:
> 
>
> (XEN) r12: 0017   r13: 0016   r14:
> 
>
> (XEN) r15: 0d8b4c1575ff8548   cr0: 8011   cr4:
> 0220
>
> (XEN) cr3: 00099000   cr2: 
>
> (XEN) fsb:    gsb:    gss:
> 
>
> (XEN) ds: 0033   es: 0033   fs: 0033   gs: 0033   ss:    cs: 0008
>
>
>
>
>
> Any help on this would be greatly appreciated.
>
>
> You will need to disassemble your minios kernel and see which instruction
> is at 0x56fc8.  (Chances are, it will be `jmp %r15`).
>
> The content of %r15 looks like x86 opcode, which is reminiscent of the XTF
> relocatability bugs.  Make doubly sure you are compiling with -fno-pic and
> link with -no-pie.
>
> ~Andrew
>
___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] Building PVH mini-os with libc support

2017-12-28 Thread Bruno Alvisio
Hello all,

I am trying to build PVH mini-os with libc support. These are the steps I
have followed so far:

1. Xen repo (master: commit id: d2f86bf604698806d311cc251c1b66fbb752673c)

2. mini-os repo (master: commit id:
0b4b7897e08b967a09bed2028a79fabff82342dd)
3. Made the following modifications in the xen repo to build c-stubdom:



diff --git a/stubdom/Makefile b/stubdom/Makefile

index f45eeabd8b..aa21904019 100644

--- a/stubdom/Makefile

+++ b/stubdom/Makefile

@@ -61,7 +61,7 @@ TARGET_CPPFLAGS += -I$(XEN_ROOT)/xen/include



 TARGET_LDFLAGS += -nostdlib
-L$(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/lib



-TARGETS=$(STUBDOM_TARGETS)

+TARGETS=$(STUBDOM_TARGETS) c



 STUBDOMPATH="stubdompath.sh"

 genpath-target = $(call buildmakevars2file,$(STUBDOMPATH))

diff --git a/stubdom/c/minios.cfg b/stubdom/c/minios.cfg

index e69de29bb2..cacde0cbca 100644

--- a/stubdom/c/minios.cfg

+++ b/stubdom/c/minios.cfg

@@ -0,0 +1,18 @@

+CONFIG_PARAVIRT=n

+CONFIG_START_NETWORK ?= y

+CONFIG_SPARSE_BSS ?= y

+CONFIG_QEMU_XS_ARGS ?= n

+CONFIG_PCIFRONT ?= n

+CONFIG_BLKFRONT ?= y

+CONFIG_TPMFRONT ?= n

+CONFIG_TPM_TIS ?= n

+CONFIG_TPMBACK ?= n

+CONFIG_NETFRONT ?= y

+CONFIG_FBFRONT ?= y

+CONFIG_KBDFRONT ?= y

+CONFIG_CONSFRONT ?= y

+CONFIG_XENBUS ?= y

+CONFIG_XC ?=y

+CONFIG_BALLOON ?= n



4. $ cd $(XEN_ROOT)
5. $ make; sudo make instal
6. Reboot host
7. $ cd $(XEN_ROOT)/stubdom
8. $ make c-stubdom
9. Used the following configuration file to create the domain:



type="pvh"

memory=512

vcpu=1

name="minios"

kernel="/home/balvisio/xen/stubdom/mini-os-x86_64-c/mini-os.gz"




When I create the domain it crashes during the bootstrap process with a
triple fault. The following are the dmesg logs (note that "Xen Minimal OS
(hvm)!" is printed and the domain crashes after that line in setup.c):




(XEN) grant_table.c:1688:d0v3 Expanding d360 grant table from 0 to 1 frames

(XEN) HVM360 save: CPU

(XEN) HVM360 save: PIC

(XEN) HVM360 save: IOAPIC

(XEN) HVM360 save: LAPIC

(XEN) HVM360 save: LAPIC_REGS

(XEN) HVM360 save: PCI_IRQ

(XEN) HVM360 save: ISA_IRQ

(XEN) HVM360 save: PCI_LINK

(XEN) HVM360 save: PIT

(XEN) HVM360 save: RTC

(XEN) HVM360 save: HPET

(XEN) HVM360 save: PMTIMER

(XEN) HVM360 save: MTRR

(XEN) HVM360 save: VIRIDIAN_DOMAIN

(XEN) HVM360 save: CPU_XSAVE

(XEN) HVM360 save: VIRIDIAN_VCPU

(XEN) HVM360 save: VMCE_VCPU

(XEN) HVM360 save: TSC_ADJUST

(XEN) HVM360 restore: CPU 0

(d360) Bootstrapping...

(XEN) Dom360 callback via changed to Direct Vector 0x20

(d360) Xen Minimal OS (hvm)!

(XEN) d360v0 Triple fault - invoking HVM shutdown action 1

(XEN) *** Dumping Dom360 vcpu#0 state: ***

(XEN) [ Xen-4.10.0-rc  x86_64  debug=y   Not tainted ]

(XEN) CPU:7

(XEN) RIP:0008:[<00056fc8>]

(XEN) RFLAGS: 00010006   CONTEXT: hvm guest (d360v0)

(XEN) rax: 000bfe75   rbx: 000bfe75   rcx: 

(XEN) rdx: 0017   rsi: 000bfe60   rdi: 

(XEN) rbp: 000bfec0   rsp: 000bfe60   r8:  

(XEN) r9:  00089982   r10: 0016   r11: 

(XEN) r12: 0017   r13: 0016   r14: 

(XEN) r15: 0d8b4c1575ff8548   cr0: 8011   cr4: 0220

(XEN) cr3: 00099000   cr2: 

(XEN) fsb:    gsb:    gss: 

(XEN) ds: 0033   es: 0033   fs: 0033   gs: 0033   ss:    cs: 0008





Any help on this would be greatly appreciated. In addition to this I have
noticed that even fter installing Xen and rebooting the host, the initial
‘xl dmesg’ logs show that Xen tries to launch unsuccessfully domains
created before the system was rebooted. I am not sure if these two issues
are related but I pasting a trace of the logs (these dmesg logs are seen
just after rebooting the host before attempting anything else):



root@debianxen:/home/balvisio# xl dmesg

(XEN) parameter "placeholder" unknown!

 Xen 4.10.0-rc

(XEN) Xen version 4.10.0-rc (balvi...@us.oracle.com) (gcc (Debian 6.3.0-18)
6.3.0 20170516) debug=y  Thu Dec 28 09:53:12 PST 2017

(XEN) Latest ChangeSet: Thu Nov 16 21:34:02 2017 + git:d2f86bf604-dirty

(XEN) Bootloader: GRUB 2.02~beta3-5

(XEN) Command line: placeholder

(XEN) Xen image load base address: 0

(XEN) Video information:

(XEN)  VGA is text mode 80x25, font 8x16

(XEN)  VBE/DDC methods: none; EDID transfer time: 0 seconds

(XEN)  EDID info not retrieved because no DDC retrieval method detected

(XEN) Disc information:

(XEN)  Found 2 MBR signatures

(XEN)  Found 2 EDD information structures

(XEN) Xen-e820 RAM map:

(XEN)   - 0009a400 (usable)

(XEN)  0009a400 - 000a (reserved)

(XEN)  000e - 0010 (reserved)

(XEN)  0010 - bf406000 (usable)

(XEN)  bf406000 - bf452000 (ACPI NVS)

(XEN)  bf452000 - bf45a000 (ACPI data)


[Xen-devel] [PATCH RFC v3 RESEND 09/12] Migration with Local Disks Mirroring: New stream phase type for libxc streams

2017-12-23 Thread Bruno Alvisio
Adapted libxc restore stream. Defined libxc stream phase types:

0. XC_STREAM_PHASE_DEFAULT: This is the stream phase when no local disks are
being mirrored as part of the domain save or restore (=0)

1. XC_STREAM_PHASE_POST_MIRROR_DISKS: This stream phase transfers the virtual
RAM from source to destination. It happens after disks mirroring is completed.

2. XC_STREAM_PHASE_PRE_MIRROR_DISKS: This stream transfers pfns and parameters
necessary to start the QEMU process in the destination. It happens before the
disks mirroring.

The PRE_MIRROR_DISKS phase stream type skips the stream_complete ops to restore
the domain. The restore is performed by the POST_MIRROR_DISKS phase stream that
is executed later in the restore flow. If no local disks are mirrored the
restore is executed by the DEFAULT phase stream type.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 tools/libxc/xc_sr_common.h|  1 +
 tools/libxc/xc_sr_restore.c   | 51 ++-
 tools/libxc/xc_sr_stream_format.h |  5 
 3 files changed, 35 insertions(+), 22 deletions(-)

diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
index a145a15..8cf393f 100644
--- a/tools/libxc/xc_sr_common.h
+++ b/tools/libxc/xc_sr_common.h
@@ -177,6 +177,7 @@ struct xc_sr_context
 xc_interface *xch;
 uint32_t domid;
 int fd;
+int stream_phase;
 
 xc_dominfo_t dominfo;
 
diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
index 7f74d28..924386c 100644
--- a/tools/libxc/xc_sr_restore.c
+++ b/tools/libxc/xc_sr_restore.c
@@ -736,7 +736,10 @@ static int restore(struct xc_sr_context *ctx)
 struct xc_sr_record rec;
 int rc, saved_rc = 0, saved_errno = 0;
 
-IPRINTF("Restoring domain");
+if ( ctx->stream_phase != XC_STREAM_PHASE_PRE_MIRROR_DISKS )
+IPRINTF("Restoring domain");
+else
+IPRINTF("Mirroring disks restoring phase");
 
 rc = setup(ctx);
 if ( rc )
@@ -799,11 +802,16 @@ static int restore(struct xc_sr_context *ctx)
  * With Remus, if we reach here, there must be some error on primary,
  * failover from the last checkpoint state.
  */
-rc = ctx->restore.ops.stream_complete(ctx);
-if ( rc )
-goto err;
+if ( ctx->stream_phase != XC_STREAM_PHASE_PRE_MIRROR_DISKS )
+{
+rc = ctx->restore.ops.stream_complete(ctx);
+if ( rc )
+goto err;
 
-IPRINTF("Restore successful");
+IPRINTF("Restore successful");
+} else {
+IPRINTF("Mirroring disks restore phase successful");
+}
 goto done;
 
  err:
@@ -837,6 +845,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
 {
 .xch = xch,
 .fd = io_fd,
+.stream_phase = stream_phase
 };
 
 /* GCC 4.4 (of CentOS 6.x vintage) can' t initialise anonymous unions. */
@@ -890,29 +899,27 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
 ctx.restore.p2m_size = nr_pfns;
 
 if ( ctx.dominfo.hvm )
-{
 ctx.restore.ops = restore_ops_x86_hvm;
-if ( restore() )
-return -1;
-}
 else
-{
 ctx.restore.ops = restore_ops_x86_pv;
-if ( restore() )
-return -1;
-}
 
-IPRINTF("XenStore: mfn %#"PRIpfn", dom %d, evt %u",
-ctx.restore.xenstore_gfn,
-ctx.restore.xenstore_domid,
-ctx.restore.xenstore_evtchn);
+if ( restore() )
+return -1;
+
+if ( stream_phase != XC_STREAM_PHASE_PRE_MIRROR_DISKS )
+{
+IPRINTF("XenStore: mfn %#"PRIpfn", dom %d, evt %u",
+ctx.restore.xenstore_gfn,
+ctx.restore.xenstore_domid,
+ctx.restore.xenstore_evtchn);
 
-IPRINTF("Console: mfn %#"PRIpfn", dom %d, evt %u",
-ctx.restore.console_gfn,
-ctx.restore.console_domid,
-ctx.restore.console_evtchn);
+IPRINTF("Console: mfn %#"PRIpfn", dom %d, evt %u",
+ctx.restore.console_gfn,
+ctx.restore.console_domid,
+ctx.restore.console_evtchn);
 
-*console_gfn = ctx.restore.console_gfn;
+*console_gfn = ctx.restore.console_gfn;
+}
 *store_mfn = ctx.restore.xenstore_gfn;
 
 return 0;
diff --git a/tools/libxc/xc_sr_stream_format.h 
b/tools/libxc/xc_sr_stream_format.h
index 15ff1c7..c705da4 100644
--- a/tools/libxc/xc_sr_stream_format.h
+++ b/tools/libxc/xc_sr_stream_format.h
@@ -138,6 +138,11 @@ struct xc_sr_rec_hvm_params
 struct xc_sr_rec_hvm_params_entry param[0];
 };
 
+/* LIBXC stream phase types */
+#define XC_STREAM_PHASE_DEFAULT 0
+#define XC_STREAM_PHASE_POST_MIRROR_DISKS 1
+#define XC_STREAM_PHASE_PRE_MIRROR_DISKS 2
+
 #endif
 /*
  * Local variables:
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH RFC v3 RESEND 06/12] Migration with Local Disks Mirroring: Added 'mirror_disks' field to domain_create_state

2017-12-23 Thread Bruno Alvisio
A new field 'mirror_disks' is added to the libxl struct
libxl__domain_create_state to record if QEMU drives should be mirrored during
migration. This variable is used to setup the sequence of calls and streams in
libxl and libxc.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 tools/libxl/libxl.h  | 4 ++--
 tools/libxl/libxl_create.c   | 8 +---
 tools/libxl/libxl_internal.h | 1 +
 tools/ocaml/libs/xl/xenlight_stubs.c | 2 +-
 tools/xl/xl_vmcontrol.c  | 5 +++--
 5 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 7828ba8..25245cc 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1371,7 +1371,7 @@ int libxl_domain_create_new(libxl_ctx *ctx, 
libxl_domain_config *d_config,
 LIBXL_EXTERNAL_CALLERS_ONLY;
 int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config,
 uint32_t *domid, int restore_fd,
-int send_back_fd,
+int send_back_fd, int mirror_disks,
 const libxl_domain_restore_params *params,
 const libxl_asyncop_how *ao_how,
 const libxl_asyncprogress_how *aop_console_how)
@@ -1412,7 +1412,7 @@ static inline int libxl_domain_create_restore_0x040400(
 LIBXL_EXTERNAL_CALLERS_ONLY
 {
 return libxl_domain_create_restore(ctx, d_config, domid, restore_fd,
-   -1, params, ao_how, aop_console_how);
+   -1, 0, params, ao_how, aop_console_how);
 }
 
 #define libxl_domain_create_restore libxl_domain_create_restore_0x040400
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index f15fb21..95978a8 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -1639,6 +1639,7 @@ static void domain_create_cb(libxl__egc *egc,
 
 static int do_domain_create(libxl_ctx *ctx, libxl_domain_config *d_config,
 uint32_t *domid, int restore_fd, int send_back_fd,
+int mirror_disks,
 const libxl_domain_restore_params *params,
 const libxl_asyncop_how *ao_how,
 const libxl_asyncprogress_how *aop_console_how)
@@ -1654,6 +1655,7 @@ static int do_domain_create(libxl_ctx *ctx, 
libxl_domain_config *d_config,
 libxl_domain_config_copy(ctx, >dcs.guest_config_saved, d_config);
 cdcs->dcs.restore_fd = cdcs->dcs.libxc_fd = restore_fd;
 cdcs->dcs.send_back_fd = send_back_fd;
+cdcs->dcs.mirror_disks = mirror_disks;
 if (restore_fd > -1) {
 cdcs->dcs.restore_params = *params;
 rc = libxl__fd_flags_modify_save(gc, cdcs->dcs.restore_fd,
@@ -1881,13 +1883,13 @@ int libxl_domain_create_new(libxl_ctx *ctx, 
libxl_domain_config *d_config,
 const libxl_asyncprogress_how *aop_console_how)
 {
 unset_disk_colo_restore(d_config);
-return do_domain_create(ctx, d_config, domid, -1, -1, NULL,
+return do_domain_create(ctx, d_config, domid, -1, -1, 0, NULL,
 ao_how, aop_console_how);
 }
 
 int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config,
 uint32_t *domid, int restore_fd,
-int send_back_fd,
+int send_back_fd, int mirror_disks,
 const libxl_domain_restore_params *params,
 const libxl_asyncop_how *ao_how,
 const libxl_asyncprogress_how *aop_console_how)
@@ -1899,7 +1901,7 @@ int libxl_domain_create_restore(libxl_ctx *ctx, 
libxl_domain_config *d_config,
 }
 
 return do_domain_create(ctx, d_config, domid, restore_fd, send_back_fd,
-params, ao_how, aop_console_how);
+mirror_disks, params, ao_how, aop_console_how);
 }
 
 int libxl_domain_soft_reset(libxl_ctx *ctx,
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index e8a4dc2..ee62bfb 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3757,6 +3757,7 @@ struct libxl__domain_create_state {
 int restore_fd, libxc_fd;
 int restore_fdfl; /* original flags of restore_fd */
 int send_back_fd;
+int mirror_disks;
 libxl_domain_restore_params restore_params;
 uint32_t domid_soft_reset;
 libxl__domain_create_cb *callback;
diff --git a/tools/ocaml/libs/xl/xenlight_stubs.c 
b/tools/ocaml/libs/xl/xenlight_stubs.c
index a757782..900d7f1 100644
--- a/tools/ocaml/libs/xl/xenlight_stubs.c
+++ b/tools/ocaml/libs/xl/xenlight_stubs.c
@@ -538,7 +538,7 @@ value stub_libxl_domain_create_restore(value ctx, v

[Xen-devel] [PATCH RFC v3 RESEND 02/12] Migration with Local Disks Mirroring: Added QMP commands used for mirroring disks

2017-12-23 Thread Bruno Alvisio
Migration with local disks mirroring uses the embedded NBD server in QEMU. A NBD
server is added in libxl during instance creation time in the destination (QMP
command: nbd_server_add). The drive mirror command (QMP: driver_mirror) is
executed on the source during 'instance save' to replicate the disk in the
destination. When the local disk migration option is used, the QEMU process in
the destination will be started with the "-incoming defer" option instead of
"-incoming fd". Once the disk and memory have been transferred to the
destination the QEMU process will be resumed using the migrate incoming command
(QMP command: migrate_incoming).

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 tools/libxl/libxl_internal.h |  11 
 tools/libxl/libxl_qmp.c  | 139 +++
 2 files changed, 150 insertions(+)

diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index bfa95d8..4d7679e 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1830,6 +1830,17 @@ _hidden int libxl__qmp_nbd_server_add(libxl__gc *gc, int 
domid,
 /* Start replication */
 _hidden int libxl__qmp_start_replication(libxl__gc *gc, int domid,
  bool primary);
+/* Mirror drive */
+_hidden int libxl__qmp_drive_mirror(libxl__gc *gc, int domid,
+const char* device, const char* target,
+const char* format);
+/* Query block devices */
+_hidden int libxl__qmp_query_block(libxl__gc *gc, int domid,
+   char *device_names);
+/* Resume QEMU process started with -incoming defer option */
+_hidden int libxl__qmp_migrate_incoming(libxl__gc *gc, int domid,
+const char* uri);
+
 /* Get replication error that occurs when the vm is running */
 _hidden int libxl__qmp_query_xen_replication_status(libxl__gc *gc, int domid);
 /* Do checkpoint */
diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 0e993af..1a1a318 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -1159,6 +1159,145 @@ int libxl__qmp_stop_replication(libxl__gc *gc, int 
domid, bool primary)
 return qmp_run_command(gc, domid, "xen-set-replication", args, NULL, NULL);
 }
 
+static int block_job_ready_handler(libxl__qmp_handler *qmp,
+   const libxl__json_object *data,
+   void *opaque)
+{
+GC_INIT(qmp->ctx);
+int rc = -1;
+
+const char *type;
+const char *device;
+unsigned int len;
+unsigned int offset;
+unsigned int speed;
+
+const libxl__json_object *obj = NULL;
+
+obj = libxl__json_map_get("type", data, JSON_STRING);
+if (!obj) {
+LOGD(ERROR, qmp->domid, "Failed to retrieve job type.");
+rc = ERROR_FAIL;
+goto out;
+}
+type = libxl__json_object_get_string(obj);
+
+obj = libxl__json_map_get("device", data, JSON_STRING);
+if (!obj) {
+LOGD(ERROR, qmp->domid, "Failed to retrieve device.");
+rc = ERROR_FAIL;
+goto out;
+}
+device = libxl__json_object_get_string(obj);
+
+obj = libxl__json_map_get("len", data, JSON_INTEGER);
+if (!obj) {
+LOGD(ERROR, qmp->domid, "Failed to retrieve length.");
+rc = ERROR_FAIL;
+goto out;
+}
+len = libxl__json_object_get_integer(obj);
+
+obj = libxl__json_map_get("offset", data, JSON_INTEGER);
+if (!obj) {
+LOGD(ERROR, qmp->domid, "Failed to retrieve offset.");
+rc = ERROR_FAIL;
+goto out;
+}
+offset = libxl__json_object_get_integer(obj);
+
+obj = libxl__json_map_get("speed", data, JSON_INTEGER);
+if (!obj) {
+LOGD(ERROR, qmp->domid, "Failed to retrieve speed.");
+rc = ERROR_FAIL;
+goto out;
+}
+speed = libxl__json_object_get_integer(obj);
+
+LOGD(INFO, qmp->domid, "Block Job Ready: Details: Device: %s, Type: %s, "
+   "Len: %u, Offset: %u, Speed %u.", device, type,
+   len, offset, speed);
+
+rc = 0;
+out:
+GC_FREE;
+return rc;
+}
+
+int libxl__qmp_drive_mirror(libxl__gc *gc, int domid, const char* device,
+const char* target, const char* format)
+{
+libxl__qmp_handler *qmp = NULL;
+libxl__json_object *args = NULL;
+int block_job_timeout = 3600;
+int rc = 0;
+
+qmp = libxl__qmp_initialize(gc, domid);
+if (!qmp)
+return -1;
+
+qmp_parameters_add_string(gc, , "device", device);
+qmp_parameters_add_string(gc, , "target", target);
+qmp_parameters_add_string(gc, , "sync", "full");
+qmp_parameters_add_string(gc, , &qu

[Xen-devel] [PATCH RFC v3 RESEND 10/12] Migration with Local Disks Mirroring: libxl save flow support

2017-12-23 Thread Bruno Alvisio
The domain save state contains a new 'mirror_disks' field. It determines the
flow of the domain save. If false, the save flow will invoke the DEFAULT phase
libxl/libxc stream type. If true, the save flow invokes the PRE_MIRROR_DISKS
phase stream type first. Upon reception of the signal from the source that the
NBD server has been started it triggers the disks mirroring job. Once it
receives an event from QEMU that the mirroring job is complete, the
POST_MIRROR_DISKS phase stream type is invoked.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 tools/libxl/libxl_dom_save.c | 53 ++--
 tools/libxl/libxl_domain.c   |  2 ++
 tools/libxl/libxl_internal.h |  4 
 3 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/tools/libxl/libxl_dom_save.c b/tools/libxl/libxl_dom_save.c
index 6487672..78c4e86 100644
--- a/tools/libxl/libxl_dom_save.c
+++ b/tools/libxl/libxl_dom_save.c
@@ -25,6 +25,9 @@ static void stream_done(libxl__egc *egc,
 libxl__stream_write_state *sws, int rc);
 static void domain_save_done(libxl__egc *egc,
  libxl__domain_save_state *dss, int rc);
+static void domain_pre_mirror_disks_done(libxl__egc *egc,
+ libxl__stream_write_state *sws,
+ int rc);
 
 /*- complicated callback, called by xc_domain_save -*/
 
@@ -411,14 +414,60 @@ void libxl__domain_save(libxl__egc *egc, 
libxl__domain_save_state *dss)
 dss->sws.fd  = dss->fd;
 dss->sws.back_channel = false;
 dss->sws.completion_callback = stream_done;
-
-libxl__stream_write_start(egc, >sws);
+dss->sws.mirror_disks = 0;
+
+if (!dss->mirror_disks) {
+libxl__stream_write_start(egc, >sws);
+} else {
+dss->sws_mirror_disks.ao  = dss->ao;
+dss->sws_mirror_disks.dss = dss;
+dss->sws_mirror_disks.fd  = dss->fd;
+dss->sws_mirror_disks.back_channel = false;
+dss->sws_mirror_disks.mirror_disks = 1;
+dss->sws_mirror_disks.completion_callback = 
domain_pre_mirror_disks_done;
+
+libxl__stream_write_start(egc, >sws_mirror_disks);
+}
 return;
 
  out:
 domain_save_done(egc, dss, rc);
 }
 
+static void domain_pre_mirror_disks_done(libxl__egc *egc,
+ libxl__stream_write_state *sws,
+ int rc)
+{
+libxl__domain_save_state *dss = sws->dss;
+STATE_AO_GC(dss->ao);
+const uint32_t domid = dss->domid;
+char* target;
+
+if (rc)
+goto err;
+
+rc = libxl_read_fixedmessage(CTX, dss->recv_fd, nbd_server_started_banner,
+ sizeof(nbd_server_started_banner)-1,
+ "migration stream", 0);
+if (rc)
+goto err;
+
+target = GCSPRINTF("nbd:%s:%s:exportname=%s", dss->hostname,
+   DRIVE_MIRROR_PORT, DRIVE_MIRROR_DEVICE);
+rc = libxl__qmp_drive_mirror(gc, dss->domid, DRIVE_MIRROR_DEVICE, target,
+ "raw");
+if (rc) {
+LOGD(ERROR, domid, "Sending QMP drive mirror command failed");
+goto err;
+}
+
+libxl__stream_write_start(egc, >dss->sws);
+return;
+
+ err:
+   dss->callback(egc, dss, rc);
+}
+
 static void stream_done(libxl__egc *egc,
 libxl__stream_write_state *sws, int rc)
 {
diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index d1209cd..341ed52 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -511,6 +511,8 @@ int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, 
int fd, int recv_fd,
 dss->type = type;
 dss->live = flags & LIBXL_SUSPEND_LIVE;
 dss->debug = flags & LIBXL_SUSPEND_DEBUG;
+dss->mirror_disks = (flags & LIBXL_SUSPEND_MIRROR_DISKS) ? 1 : 0;
+dss->hostname = hostname;
 dss->checkpointed_stream = LIBXL_CHECKPOINTED_STREAM_NONE;
 
 rc = libxl__fd_flags_modify_save(gc, dss->fd,
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 76bbe48..0a3215f 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3197,6 +3197,7 @@ struct libxl__stream_write_state {
 libxl__domain_save_state *dss;
 int fd;
 bool back_channel;
+int mirror_disks;
 void (*completion_callback)(libxl__egc *egc,
 libxl__stream_write_state *sws,
 int rc);
@@ -3296,6 +3297,8 @@ struct libxl__domain_save_state {
 libxl_domain_type type;
 int live;
 int debug;
+int mirror_disks;
+const char* hostname;
 int checkpointed_stream;
 const libxl_domain_remus_info *remus;
 /* private */
@@ -3311,6 +3314,7 @@ struct lib

[Xen-devel] [PATCH RFC v3 RESEND 03/12] Migration with Local Disks Mirroring: Refactored migrate_read_fixedmessage

2017-12-23 Thread Bruno Alvisio
The function migrate_fixed_message is going to be used in the libxl create and
save flow for event synchronization during migration. It needs to be accessible
from libxl_create and libxl_dom_save and thus it is moved to libxl_utils.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 tools/libxl/libxl_utils.c | 21 +++
 tools/libxl/libxl_utils.h |  3 +++
 tools/xl/xl_migrate.c | 52 +++
 3 files changed, 40 insertions(+), 36 deletions(-)

diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c
index 507ee56..5139320 100644
--- a/tools/libxl/libxl_utils.c
+++ b/tools/libxl/libxl_utils.c
@@ -510,6 +510,27 @@ int libxl__read_sysfs_file_contents(libxl__gc *gc, const 
char *filename,
 READ_WRITE_EXACTLY(read, 1, /* */)
 READ_WRITE_EXACTLY(write, 0, const)
 
+int libxl_read_fixedmessage(libxl_ctx *ctx, int fd, const void *msg, int msgsz,
+const char *what, const char *rune)
+{
+char buf[msgsz];
+const char *stream;
+int rc;
+
+stream = rune ? "migration receiver stream" : "migration stream";
+rc = libxl_read_exactly(ctx, fd, buf, msgsz, stream, what);
+if (rc) return 1;
+
+if (memcmp(buf, msg, msgsz)) {
+fprintf(stderr, "%s contained unexpected data instead of %s\n",
+stream, what);
+if (rune)
+fprintf(stderr, "(command run was: %s )\n", rune);
+return 1;
+}
+return 0;
+}
+
 int libxl__remove_file(libxl__gc *gc, const char *path)
 {
 for (;;) {
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
index 9e743dc..d1e80ef 100644
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -56,6 +56,9 @@ int libxl_write_exactly(libxl_ctx *ctx, int fd, const void 
*data,
* logged using filename (which is only used for logging) and what
* (which may be 0). */
 
+int libxl_read_fixedmessage(libxl_ctx *ctx, int fd, const void *msg, int msgsz,
+const char *what, const char *rune);
+
 int libxl_pipe(libxl_ctx *ctx, int pipes[2]);
   /* Just like pipe(2), but log errors. */
 
diff --git a/tools/xl/xl_migrate.c b/tools/xl/xl_migrate.c
index 1f0e87d..33d39e8 100644
--- a/tools/xl/xl_migrate.c
+++ b/tools/xl/xl_migrate.c
@@ -68,26 +68,6 @@ static pid_t create_migration_child(const char *rune, int 
*send_fd,
 return child;
 }
 
-static int migrate_read_fixedmessage(int fd, const void *msg, int msgsz,
- const char *what, const char *rune) {
-char buf[msgsz];
-const char *stream;
-int rc;
-
-stream = rune ? "migration receiver stream" : "migration stream";
-rc = libxl_read_exactly(ctx, fd, buf, msgsz, stream, what);
-if (rc) return 1;
-
-if (memcmp(buf, msg, msgsz)) {
-fprintf(stderr, "%s contained unexpected data instead of %s\n",
-stream, what);
-if (rune)
-fprintf(stderr, "(command run was: %s )\n", rune);
-return 1;
-}
-return 0;
-}
-
 static void migration_child_report(int recv_fd) {
 pid_t child;
 int status, sr;
@@ -162,9 +142,9 @@ static void migrate_do_preamble(int send_fd, int recv_fd, 
pid_t child,
 exit(EXIT_FAILURE);
 }
 
-rc = migrate_read_fixedmessage(recv_fd, migrate_receiver_banner,
-   sizeof(migrate_receiver_banner)-1,
-   "banner", rune);
+rc = libxl_read_fixedmessage(ctx, recv_fd, migrate_receiver_banner,
+ sizeof(migrate_receiver_banner)-1,
+ "banner", rune);
 if (rc) {
 close(send_fd);
 migration_child_report(recv_fd);
@@ -219,9 +199,9 @@ static void migrate_domain(uint32_t domid, const char 
*rune, int debug,
 // Should only be printed when debugging as it's a bit messy with
 // progress indication.
 
-rc = migrate_read_fixedmessage(recv_fd, migrate_receiver_ready,
-   sizeof(migrate_receiver_ready),
-   "ready message", rune);
+rc = libxl_read_fixedmessage(ctx, recv_fd, migrate_receiver_ready,
+ sizeof(migrate_receiver_ready),
+ "ready message", rune);
 if (rc) goto failed_resume;
 
 xtl_stdiostream_adjust_flags(logger, 0, XTL_STDIOSTREAM_HIDE_PROGRESS);
@@ -251,9 +231,9 @@ static void migrate_domain(uint32_t domid, const char 
*rune, int debug,
  "migration stream", "GO message");
 if (rc) goto failed_badly;
 
-rc = migrate_read_fixedmessage(recv_fd, migrate_report,
-   sizeof(migrate_report),
-   "success/failure report message", rune);
+rc 

[Xen-devel] [PATCH RFC v3 RESEND 05/12] Migration with Local Disks Mirroring: QEMU process is started with '-incoming defer' option

2017-12-23 Thread Bruno Alvisio
For the migration with local disks mirroring scenario, the QEMU process is
started before the virtual RAM is transferred to the destination node so that
the QEMU embedded NBD server and disks mirroring jobs can be started. After the
virtual RAM and QEMU state are transferred, the QEMU process will be resumed
using the QMP 'migrate-incoming' command.

When qemu-xen is started with '-incoming defer' option the initial state of the
instance will be 'inmigrate'. Thus, when either 'running' or 'inmigrate' are
read from xenstore the spawn detach is carried out.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 tools/libxl/libxl_dm.c   | 20 ++--
 tools/libxl/libxl_internal.h |  1 +
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index a2ea95a..e12e015 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -940,7 +940,7 @@ static int libxl__build_device_model_args_new(libxl__gc *gc,
 const libxl_domain_config 
*guest_config,
 char ***args, char ***envs,
 const libxl__domain_build_state *state,
-int *dm_state_fd)
+int *dm_state_fd, int mirror_disks)
 {
 const libxl_domain_create_info *c_info = _config->c_info;
 const libxl_domain_build_info *b_info = _config->b_info;
@@ -1431,6 +1431,12 @@ static int libxl__build_device_model_args_new(libxl__gc 
*gc,
 flexarray_append(dm_args, "-incoming");
 flexarray_append(dm_args, GCSPRINTF("fd:%d",*dm_state_fd));
 }
+
+if (mirror_disks) {
+flexarray_append(dm_args, "-incoming");
+flexarray_append(dm_args, "defer");
+}
+
 for (i = 0; b_info->extra && b_info->extra[i] != NULL; i++)
 flexarray_append(dm_args, b_info->extra[i]);
 
@@ -1728,7 +1734,7 @@ static int libxl__build_device_model_args(libxl__gc *gc,
 const libxl_domain_config 
*guest_config,
 char ***args, char ***envs,
 const libxl__domain_build_state *state,
-int *dm_state_fd)
+int *dm_state_fd, int mirror_disks)
 /* dm_state_fd may be NULL iff caller knows we are using old stubdom
  * and therefore will be passing a filename rather than a fd. */
 {
@@ -1744,7 +1750,8 @@ static int libxl__build_device_model_args(libxl__gc *gc,
 return libxl__build_device_model_args_new(gc, dm,
   guest_domid, guest_config,
   args, envs,
-  state, dm_state_fd);
+  state, dm_state_fd,
+  mirror_disks);
 default:
 LOGED(ERROR, guest_domid, "unknown device model version %d",
   guest_config->b_info.device_model_version);
@@ -1964,7 +1971,7 @@ void libxl__spawn_stub_dm(libxl__egc *egc, 
libxl__stub_dm_spawn_state *sdss)
 
 ret = libxl__build_device_model_args(gc, "stubdom-dm", guest_domid,
  guest_config, , NULL,
- d_state, NULL);
+ d_state, NULL, 0);
 if (ret) {
 ret = ERROR_FAIL;
 goto out;
@@ -2267,7 +2274,8 @@ void libxl__spawn_local_dm(libxl__egc *egc, 
libxl__dm_spawn_state *dmss)
 }
 rc = libxl__build_device_model_args(gc, dm, domid, guest_config,
   , , state,
-  _state_fd);
+  _state_fd,
+  dmss->mirror_disks);
 if (rc)
 goto out;
 
@@ -2397,7 +2405,7 @@ static void device_model_confirm(libxl__egc *egc, 
libxl__spawn_state *spawn,
 if (!xsdata)
 return;
 
-if (strcmp(xsdata, "running"))
+if (strcmp(xsdata, "running") && strcmp(xsdata, "inmigrate"))
 return;
 
 libxl__spawn_initiate_detach(gc, spawn);
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 4d7679e..e8a4dc2 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3711,6 +3711,7 @@ struct libxl__dm_spawn_state {
 libxl__spawn_state spawn;
 /* filled in by user, must remain valid: */
 uint32_t guest_domid; /* domain being served */
+int mirror_disks;
 libxl_domain_config *guest_config;
 libxl__domain_build_state *build_state; /* relates to guest_domid */
 libxl__dm_spawn_cb *callback;
-

[Xen-devel] [PATCH RFC v3 RESEND 04/12] Migration with Local Disks Mirroring: Added a new '-q' flag to xl migrate for disk mirorring

2017-12-23 Thread Bruno Alvisio
When the '-q' flag is provided to the 'xl migrate' command all the block devices
that are local should be mirrored to the destination node. If the flag is not
present migration flow will be equivalent to current migration flow. A new
'mirror_disks' field is added to the xl domain_create struct to indicate that
disks will be mirrored during instance startup. A new LIBXL_SUSPEND_MIRROR_DISK
flag is added to indicate that the block mirror jobs should be performed during
the suspension of the instance. libxl_domain_suspend takes a new 'hostname'
param with the name of the host where the QEMU drives will be mirrored to.
libxl_domain_suspend takes a 'recv_fd' param that is used for receving messages
from destination during migration.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 tools/libxl/libxl.h  |  4 +-
 tools/libxl/libxl_domain.c   |  4 +-
 tools/ocaml/libs/xl/xenlight_stubs.c |  2 +-
 tools/xl/xl.h|  1 +
 tools/xl/xl_cmdtable.c   |  3 +-
 tools/xl/xl_migrate.c| 74 +++-
 tools/xl/xl_saverestore.c|  2 +-
 7 files changed, 75 insertions(+), 15 deletions(-)

diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 5e9aed7..7828ba8 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1444,12 +1444,14 @@ int libxl_retrieve_domain_configuration(libxl_ctx *ctx, 
uint32_t domid,
 libxl_domain_config *d_config)
 LIBXL_EXTERNAL_CALLERS_ONLY;
 
-int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
+int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int recv_fd,
  int flags, /* LIBXL_SUSPEND_* */
+ const char* hostname,
  const libxl_asyncop_how *ao_how)
  LIBXL_EXTERNAL_CALLERS_ONLY;
 #define LIBXL_SUSPEND_DEBUG 1
 #define LIBXL_SUSPEND_LIVE 2
+#define LIBXL_SUSPEND_MIRROR_DISKS 4
 
 /* @param suspend_cancel [from xenctrl.h:xc_domain_resume( @param fast )]
  *   If this parameter is true, use co-operative resume. The guest
diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index 814f812..d1209cd 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -486,7 +486,8 @@ static void domain_suspend_cb(libxl__egc *egc,
 
 }
 
-int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int flags,
+int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int recv_fd,
+ int flags, const char* hostname,
  const libxl_asyncop_how *ao_how)
 {
 AO_CREATE(ctx, domid, ao_how);
@@ -506,6 +507,7 @@ int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, 
int fd, int flags,
 
 dss->domid = domid;
 dss->fd = fd;
+dss->recv_fd = recv_fd;
 dss->type = type;
 dss->live = flags & LIBXL_SUSPEND_LIVE;
 dss->debug = flags & LIBXL_SUSPEND_DEBUG;
diff --git a/tools/ocaml/libs/xl/xenlight_stubs.c 
b/tools/ocaml/libs/xl/xenlight_stubs.c
index 0140780..a757782 100644
--- a/tools/ocaml/libs/xl/xenlight_stubs.c
+++ b/tools/ocaml/libs/xl/xenlight_stubs.c
@@ -611,7 +611,7 @@ value stub_libxl_domain_suspend(value ctx, value domid, 
value fd, value async, v
libxl_asyncop_how *ao_how = aohow_val(async);
 
caml_enter_blocking_section();
-   ret = libxl_domain_suspend(CTX, c_domid, c_fd, 0, ao_how);
+   ret = libxl_domain_suspend(CTX, c_domid, c_fd, 0, 0, NULL, ao_how);
caml_leave_blocking_section();
 
free(ao_how);
diff --git a/tools/xl/xl.h b/tools/xl/xl.h
index 6b60d1d..fd8e8e6 100644
--- a/tools/xl/xl.h
+++ b/tools/xl/xl.h
@@ -35,6 +35,7 @@ struct domain_create {
 int daemonize;
 int monitor; /* handle guest reboots etc */
 int paused;
+int mirror_disks;
 int dryrun;
 int quiet;
 int vnc;
diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c
index 5546cf6..45a0b1a 100644
--- a/tools/xl/xl_cmdtable.c
+++ b/tools/xl/xl_cmdtable.c
@@ -165,7 +165,8 @@ struct cmd_spec cmd_table[] = {
   "-e  Do not wait in the background (on ) for the 
death\n"
   "of the domain.\n"
   "--debug Print huge (!) amount of debug during the migration 
process.\n"
-  "-p  Do not unpause domain after migrating it."
+  "-p  Do not unpause domain after migrating it.\n"
+  "-q  Mirror local disks to destination - Copy all local 
storage devices."
 },
 { "restore",
   _restore, 0, 1,
diff --git a/tools/xl/xl_migrate.c b/tools/xl/xl_migrate.c
index 33d39e8..48b0179 100644
--- a/tools/xl/xl_migrate.c
+++ b/tools/xl/xl_migrate.c
@@ -157,7 +157,8 @@ static void migrate_do_preamble(int send_fd, int recv_fd, 
pid_t child,
 }
 
 static v

[Xen-devel] [PATCH RFC v3 RESEND 11/12] Migration with Local Disks Mirroring: libxl write stream support for stream phase type

2017-12-23 Thread Bruno Alvisio
The libxl stream write receives stream phase type (DEFAULT, PRE_MIRROR_DISKS or
POST_MIRROR_DISKS) and registers the appropiate callback to the
libxl_save_helper. If the stream phase == PRE_MIRROR_DISKS the stream skips
writing the context record since it is written at a later time by the
POST_MIRROR_DISKS libxl stream.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 tools/libxc/include/xenguest.h   |  3 +-
 tools/libxc/xc_nomigrate.c   |  3 +-
 tools/libxc/xc_sr_save.c |  3 +-
 tools/libxl/libxl_internal.h | 12 +--
 tools/libxl/libxl_save_callout.c | 10 --
 tools/libxl/libxl_save_helper.c  |  3 +-
 tools/libxl/libxl_stream_write.c | 67 +---
 7 files changed, 73 insertions(+), 28 deletions(-)

diff --git a/tools/libxc/include/xenguest.h b/tools/libxc/include/xenguest.h
index 014dee0..743294b 100644
--- a/tools/libxc/include/xenguest.h
+++ b/tools/libxc/include/xenguest.h
@@ -134,7 +134,8 @@ typedef enum {
 int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom,
uint32_t flags /* XCFLAGS_xxx */,
struct save_callbacks* callbacks, int hvm,
-   xc_migration_stream_t stream_type, int recv_fd);
+   xc_migration_stream_t stream_type, int recv_fd,
+   int stream_phase);
 
 /* callbacks provided by xc_domain_restore */
 struct restore_callbacks {
diff --git a/tools/libxc/xc_nomigrate.c b/tools/libxc/xc_nomigrate.c
index 75fe560..ab2d744 100644
--- a/tools/libxc/xc_nomigrate.c
+++ b/tools/libxc/xc_nomigrate.c
@@ -22,7 +22,8 @@
 
 int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t flags,
struct save_callbacks* callbacks, int hvm,
-   xc_migration_stream_t stream_type, int recv_fd)
+   xc_migration_stream_t stream_type, int recv_fd,
+   int stream_phase)
 {
 errno = ENOSYS;
 return -1;
diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c
index 5a40e58..b7498e3 100644
--- a/tools/libxc/xc_sr_save.c
+++ b/tools/libxc/xc_sr_save.c
@@ -967,7 +967,8 @@ static int save(struct xc_sr_context *ctx, uint16_t 
guest_type)
 
 int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom,
uint32_t flags, struct save_callbacks* callbacks,
-   int hvm, xc_migration_stream_t stream_type, int recv_fd)
+   int hvm, xc_migration_stream_t stream_type, int recv_fd,
+   int stream_phase)
 {
 struct xc_sr_context ctx =
 {
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 0a3215f..320c97d 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3799,12 +3799,18 @@ _hidden void libxl__domain_save(libxl__egc *egc,
 /* calls libxl__xc_domain_suspend_done when done */
 _hidden void libxl__xc_domain_save(libxl__egc *egc,
libxl__domain_save_state *dss,
-   libxl__save_helper_state *shs);
+   libxl__save_helper_state *shs,
+   int stream_phase);
 /* If rc==0 then retval is the return value from xc_domain_save
  * and errnoval is the errno value it provided.
  * If rc!=0, retval and errnoval are undefined. */
-_hidden void libxl__xc_domain_save_done(libxl__egc*, void *dss_void,
-int rc, int retval, int errnoval);
+_hidden void libxl__xc_domain_save_returned(libxl__egc*, void *dss_void,
+int rc, int retval, int errnoval);
+
+_hidden void libxl__xc_mirror_disks_save_returned(libxl__egc *egc,
+  void *dss_void,
+  int rc, int retval,
+  int errnoval);
 
 /* Used by asynchronous callbacks: ie ones which xc regards as
  * returning a value, but which we want to handle asynchronously.
diff --git a/tools/libxl/libxl_save_callout.c b/tools/libxl/libxl_save_callout.c
index 0ff9a01..090d50b 100644
--- a/tools/libxl/libxl_save_callout.c
+++ b/tools/libxl/libxl_save_callout.c
@@ -86,7 +86,7 @@ void libxl__xc_domain_restore(libxl__egc *egc, 
libxl__domain_create_state *dcs,
 }
 
 void libxl__xc_domain_save(libxl__egc *egc, libxl__domain_save_state *dss,
-   libxl__save_helper_state *shs)
+   libxl__save_helper_state *shs, int stream_phase)
 {
 STATE_AO_GC(dss->ao);
 
@@ -95,13 +95,17 @@ void libxl__xc_domain_save(libxl__egc *egc, 
libxl__domain_save_state *dss,
 
 const unsigned long argnums[] = {
 dss->domid, dss->xcflags, dss->hvm, cbflags,
-dss->checkpointed_stream,
+dss->checkpointed_stream, stream_phase,
 };
 
 shs->ao = ao;
 shs->domid = dss->domid;
 shs->recv_callbac

[Xen-devel] [PATCH RFC v3 RESEND 00/12] Migration with Local Disks Mirroring

2017-12-23 Thread Bruno Alvisio
I have worked on a solution to be able to migrate domains that use QEMU as the
backend disk driver. I have adapted the migration flow and piggybacked on the
"drive-mirroring" capability already provided by QEMU.

Overview

1. The "xl migrate" command has an additional "-q" flag. When provided the local
storage of the domain is mirrored to the destination during the migration
process.

2. Internally, the modification consists on adding a new
libxl__stream_read_state struct to the libxl__domain_create_state structure and
libxl__stream_write_state struct to the libxl__domain_save_state struct.

3. Migration flow can now be divided into three phases:
   a. Phase One: Copies the necessary PFNs/params to start a QEMU process on the
  destination. QEMU is started with the "-incoming defer" option.
   b. Phase Two: Disk is mirrored using the QEMU embedded NBD server.
   c. Phase Three: Once the disk is completely mirrored, virtual RAM of the
  domain is live migrated to the destination. This phase most closely 
  resembles to the current migration flow.

4. If the “-q” option is not provided the migration is equivalent to the current
migration flow.

The new migration flow has follows the following major sequence of steps:
1. 1st stream copies the necessary PFNs and params from source to destination
to start the QEMU process in destination.
2. QEMU process is started on the destination with the option "-incoming defer".
(This creates the QEMU process but it doesn’t start running the main loop until
"migrate incoming" command is executed)
3. "drive mirror" QMP command is executed so that the disk is mirrored to the
destination node.
4. An event listener waits for the QMP BLOCK_JOB_READY event sent by QEMU which
signals that the "disk mirror job" is complete.
5. 2nd stream copies the virtual RAM from source to destination. At this point, 
the domain is suspended on source.
6. "migrate incoming" QMP command is executed in the destination node.
7. Domain is restored in destination.

Notes

1. Note that as of now "xen_platform_pci=0" for this feature to work. 
This is necessary so that the block devices are seen by QEMU. Further 
modification should be made for the case "xen_platform_pci=1" if we still 
want to use NBD mirroring capability provided by QEMU.
2. The current branch has still some hardcoded values but they can be easily
removed (I wanted initial feedback first):
a. Port used for disks mirroring ("11000"): Changed by opening a socket and
   sending the port number to the source node.
b. Name of the block devices ("ide0-hd0"): Currently the branch only 
   supports domains with one IDE drive. This constraint can easily be 
   removed by querying QEMU for the block-devices and checking their 
   backends on Xenstore. The name of the block devices to be mirrored 
   would be then sent to the destination node for starting the NBD server.
3.This feature needs a small patch to QEMU-XEN.

Here is a link to the Xen branch in Github:
https://github.com/balvisio/xen/tree/feature/migration_with_local_disks_mirroring

Here is a link to the QEMU-Xen branch in Github:
https://github.com/balvisio/qemu-xen/tree/feature/migration_with_local_disks_mirroring

Any feedback/suggestion is appreciated.

Cheers,

Bruno

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH RFC v3 RESEND 07/12] Migration with Local Disks Mirroring: Added new libxl_read_stream and callbacks in restore flow

2017-12-23 Thread Bruno Alvisio
For migration with local disks mirroring a QEMU NBD server is started while
restoring the domain. This server will be responsible for receiving the disks
sent from the source node: The disks transfer will be triggered during the
domain save on the source using the QMP drive-mirror command.

A second libxl_read_stream is created (srs_mirror_disks): During domain restore
the first libxc stream transfers the necessary PFNs and params only so that the
QEMU process and NBD server can be started. After the disk mirroring jobs are
completed the second libxl_read_stream is started and the virtual RAM is
transferred.

In the migration with disks mirroring case:
1. domcreate_devmodel_deferred_started is the callback function for launch_dm

2. domcreate_stream_done is the callback function for the end of 1st
libxl_read_stream

3. domcreate_post_mirror_disks_stream_done is the callback function for the 2nd
libxl_read_stream

The original libxl_create calling sequence:
1. domcreate_bootloader_done
2. libxl/libxc stream
3. domcreate_stream_done
4. domcreate_pre_build
5. domcreate_rebuild_done
6. domcreate_multidev_begin
7. domcreate_launch_dm
8. domcreate_devmodel_started

In the case of migration with local disk mirroring the sequence becomes:

1. domcreate_bootloader_done
2. pre mirror disk libxl/libxc stream: Transfers PFNs/params necessary for
QEMU initilization
3. domcreate_stream_done
4. domcreate_pre_build
5. domcreate_rebuild_done
6. domcreate_multidev_begin
7. domcreate_launch_dm: Starts QEMU with "-incoming defer option"
8. domcreate_devmodel_deferred_started: Starts NBD server for disks mirroring
9. post mirror disks libxl/libxc stream: Transfers all virtual RAM: Similar to
original stream
10. domcreate_post_mirror_disks_steam_done: Resumes QEMU process by
executing QMP "migrate-incoming" command
11. domcreate_devmodel_started

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 tools/libxl/libxl.h  |   6 +++
 tools/libxl/libxl_create.c   | 117 +--
 tools/libxl/libxl_internal.h |   2 +
 3 files changed, 120 insertions(+), 5 deletions(-)

diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 25245cc..af2aa9a 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -1453,6 +1453,12 @@ int libxl_domain_suspend(libxl_ctx *ctx, uint32_t domid, 
int fd, int recv_fd,
 #define LIBXL_SUSPEND_LIVE 2
 #define LIBXL_SUSPEND_MIRROR_DISKS 4
 
+#define DRIVE_MIRROR_PORT "11000"
+#define DRIVE_MIRROR_DEVICE "ide0-hd0"
+
+static const char nbd_server_started_banner[]=
+"nbd server started on source, start mirror job.\n";
+
 /* @param suspend_cancel [from xenctrl.h:xc_domain_resume( @param fast )]
  *   If this parameter is true, use co-operative resume. The guest
  *   must support this.
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 95978a8..f834282 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -761,6 +761,9 @@ static int store_libxl_entry(libxl__gc *gc, uint32_t domid,
 static void domcreate_devmodel_started(libxl__egc *egc,
libxl__dm_spawn_state *dmss,
int rc);
+static void domcreate_devmodel_deferred_started(libxl__egc *egc,
+libxl__dm_spawn_state *dmss,
+int ret);
 static void domcreate_bootloader_console_available(libxl__egc *egc,
libxl__bootloader_state 
*bl);
 static void domcreate_bootloader_done(libxl__egc *egc,
@@ -777,6 +780,10 @@ static void domcreate_stream_done(libxl__egc *egc,
   libxl__stream_read_state *srs,
   int ret);
 
+static void domcreate_post_mirror_disks_stream_done(libxl__egc *egc,
+libxl__stream_read_state 
*srs,
+int ret);
+
 static void domcreate_rebuild_done(libxl__egc *egc,
libxl__domain_create_state *dcs,
int ret);
@@ -1036,6 +1043,48 @@ static void libxl__colo_restore_setup_done(libxl__egc 
*egc,
 libxl__stream_read_start(egc, >srs);
 }
 
+static void domcreate_devmodel_deferred_started(libxl__egc *egc,
+libxl__dm_spawn_state *dmss,
+int ret)
+{
+libxl__domain_create_state *dcs = CONTAINER_OF(dmss, *dcs, sdss.dm);
+STATE_AO_GC(dmss->spawn.ao);
+const uint32_t domid = dcs->guest_domid;
+dcs->sdss.dm.guest_domid = domid;
+
+if (ret) {
+LOGD(ERROR, domid, "device model did not start: %d", ret);
+goto error_out;
+}
+
+ret = libxl__qmp_nbd_server_start(gc, domid, "::", DRI

[Xen-devel] [PATCH RFC v3 RESEND 08/12] Migration with Local Disks Mirroring: New stream phase type for libxl streams

2017-12-23 Thread Bruno Alvisio
The libxl streams are classified by a stream phase parameter (stream_phase):

0. DEFAULT: This is the stream phase when no local disks are being mirrored as
part of the domain save or restore flow. (=0)

1. POST_MIRROR_DISKS: This stream phase happens during the migration flow after
the disks have been completely mirrored. In time order, this is the second libxl
stream of the migration flow. (=1)

2. PRE_MIRROR_DISKS: This stream happens before the disks start to be mirrored
to the destination. In time order, this is the first libxl stream of the
migration flow. (=2)

libxl__xc_mirror_disks_restore_returned is the callback function in the
libxl_read_stream that is registered for the return of libxc_mirror_disks
stream.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 tools/libxc/include/xenguest.h   |  3 ++-
 tools/libxc/xc_nomigrate.c   |  3 ++-
 tools/libxc/xc_sr_restore.c  |  3 ++-
 tools/libxl/libxl_colo_restore.c |  4 ++--
 tools/libxl/libxl_internal.h | 12 +++-
 tools/libxl/libxl_save_callout.c | 13 +
 tools/libxl/libxl_save_helper.c  |  5 -
 tools/libxl/libxl_stream_read.c  | 24 ++--
 tools/libxl/libxl_types.idl  |  6 ++
 9 files changed, 60 insertions(+), 13 deletions(-)

diff --git a/tools/libxc/include/xenguest.h b/tools/libxc/include/xenguest.h
index b4b2e19..014dee0 100644
--- a/tools/libxc/include/xenguest.h
+++ b/tools/libxc/include/xenguest.h
@@ -199,7 +199,8 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
   unsigned long *console_mfn, uint32_t console_domid,
   unsigned int hvm, unsigned int pae,
   xc_migration_stream_t stream_type,
-  struct restore_callbacks *callbacks, int send_back_fd);
+  struct restore_callbacks *callbacks, int send_back_fd,
+  int stream_phase);
 
 /**
  * This function will create a domain for a paravirtualized Linux
diff --git a/tools/libxc/xc_nomigrate.c b/tools/libxc/xc_nomigrate.c
index 6d6169d..75fe560 100644
--- a/tools/libxc/xc_nomigrate.c
+++ b/tools/libxc/xc_nomigrate.c
@@ -34,7 +34,8 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t 
dom,
   unsigned long *console_mfn, uint32_t console_domid,
   unsigned int hvm, unsigned int pae,
   xc_migration_stream_t stream_type,
-  struct restore_callbacks *callbacks, int send_back_fd)
+  struct restore_callbacks *callbacks, int send_back_fd,
+  int stream_phase)
 {
 errno = ENOSYS;
 return -1;
diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
index ea7b033..7f74d28 100644
--- a/tools/libxc/xc_sr_restore.c
+++ b/tools/libxc/xc_sr_restore.c
@@ -829,7 +829,8 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
   unsigned long *console_gfn, uint32_t console_domid,
   unsigned int hvm, unsigned int pae,
   xc_migration_stream_t stream_type,
-  struct restore_callbacks *callbacks, int send_back_fd)
+  struct restore_callbacks *callbacks, int send_back_fd,
+  int stream_phase)
 {
 xen_pfn_t nr_pfns;
 struct xc_sr_context ctx =
diff --git a/tools/libxl/libxl_colo_restore.c b/tools/libxl/libxl_colo_restore.c
index 0c535bd..a45bf51 100644
--- a/tools/libxl/libxl_colo_restore.c
+++ b/tools/libxl/libxl_colo_restore.c
@@ -132,7 +132,7 @@ static void colo_resume_vm(libxl__egc *egc,
 return;
 }
 
-libxl__xc_domain_restore_done(egc, dcs, 0, 0, 0);
+libxl__xc_domain_restore_done(egc, dcs, dcs->srs, 0, 0, 0);
 
 return;
 }
@@ -325,7 +325,7 @@ void libxl__colo_restore_teardown(libxl__egc *egc, void 
*dcs_void,
 /* crcs->status is LIBXL_COLO_SETUPED */
 dcs->srs.completion_callback = NULL;
 }
-libxl__xc_domain_restore_done(egc, dcs, ret, retval, errnoval);
+libxl__xc_domain_restore_done(egc, dcs, dcs->srs, ret, retval, errnoval);
 
 if (crs->qdisk_setuped) {
 libxl__qmp_stop_replication(gc, crs->domid, false);
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index feb9370..76bbe48 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3825,13 +3825,23 @@ _hidden int libxl__restore_emulator_xenstore_data
 _hidden void libxl__xc_domain_restore(libxl__egc *egc,
   libxl__domain_create_state *dcs,
   libxl__save_helper_state *shs,
-  int hvm, int pae);
+  int hvm, int pae, int stream_phase);
 /* If rc==0 then retval is the return value from xc_domain_save
  * and errnoval is the errno value it provided.
  * If rc!=0, retval and errnoval ar

[Xen-devel] [PATCH RFC v3 RESEND 12/12] Migration with Local Disks Mirroring: Introduce pre_mirror_disks_stream_phase op to xc_sr_save_ops

2017-12-23 Thread Bruno Alvisio
A new op pre_mirror_stream_phase is introduced as part of the xc_sr_save_ops.
This op sends all pfns and params that need to be transferred before the disks
mirroring jobs can be started. Note that no new libxc record type is created.

The save flow is modified such that: if the stream_phase ==
XC_PRE_MIRROR_DISKS_STREAM_PHASE only the pre_mirror_disks op is executed as
part of the save(). In all other libxc phase types, the original flow is
executed.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 tools/libxc/xc_sr_common.h   |  11 
 tools/libxc/xc_sr_save.c |  24 +++--
 tools/libxc/xc_sr_save_x86_hvm.c | 109 +++
 3 files changed, 105 insertions(+), 39 deletions(-)

diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
index 8cf393f..44f4103 100644
--- a/tools/libxc/xc_sr_common.h
+++ b/tools/libxc/xc_sr_common.h
@@ -96,6 +96,13 @@ struct xc_sr_save_ops
  * after a successful save, or upon encountering an error.
  */
 int (*cleanup)(struct xc_sr_context *ctx);
+
+/**
+ * Send the necessary records/params to allow the start of the local
+ * disks mirroring job in the destination node. It will be called exactly
+ * once only if the stream phase type == XC_STREAM_PHASE_PRE_MIRROR_DISKS
+ */
+int (*pre_mirror_disks_stream_phase)(struct xc_sr_context *ctx);
 };
 
 
@@ -398,6 +405,10 @@ int read_record(struct xc_sr_context *ctx, int fd, struct 
xc_sr_record *rec);
 int populate_pfns(struct xc_sr_context *ctx, unsigned count,
   const xen_pfn_t *original_pfns, const uint32_t *types);
 
+int add_to_batch(struct xc_sr_context *ctx, xen_pfn_t pfn);
+
+int flush_batch(struct xc_sr_context *ctx);
+
 #endif
 /*
  * Local variables:
diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c
index b7498e3..557dafe 100644
--- a/tools/libxc/xc_sr_save.c
+++ b/tools/libxc/xc_sr_save.c
@@ -279,7 +279,7 @@ static int write_batch(struct xc_sr_context *ctx)
 /*
  * Flush a batch of pfns into the stream.
  */
-static int flush_batch(struct xc_sr_context *ctx)
+int flush_batch(struct xc_sr_context *ctx)
 {
 int rc = 0;
 
@@ -301,7 +301,7 @@ static int flush_batch(struct xc_sr_context *ctx)
 /*
  * Add a single pfn to the batch, flushing the batch if full.
  */
-static int add_to_batch(struct xc_sr_context *ctx, xen_pfn_t pfn)
+int add_to_batch(struct xc_sr_context *ctx, xen_pfn_t pfn)
 {
 int rc = 0;
 
@@ -842,8 +842,12 @@ static int save(struct xc_sr_context *ctx, uint16_t 
guest_type)
 xc_interface *xch = ctx->xch;
 int rc, saved_rc = 0, saved_errno = 0;
 
-IPRINTF("Saving domain %d, type %s",
-ctx->domid, dhdr_type_to_str(guest_type));
+if ( ctx->stream_phase == XC_STREAM_PHASE_PRE_MIRROR_DISKS )
+IPRINTF("Pre-mirroring disks save phase for domain %d, type %s",
+ctx->domid, dhdr_type_to_str(guest_type));
+else
+IPRINTF("Saving domain %d, type %s",
+ctx->domid, dhdr_type_to_str(guest_type));
 
 rc = setup(ctx);
 if ( rc )
@@ -855,6 +859,13 @@ static int save(struct xc_sr_context *ctx, uint16_t 
guest_type)
 if ( rc )
 goto err;
 
+if ( ctx->stream_phase == XC_STREAM_PHASE_PRE_MIRROR_DISKS ) {
+rc = ctx->save.ops.pre_mirror_disks_stream_phase(ctx);
+if ( rc )
+goto err;
+goto end;
+}
+
 rc = ctx->save.ops.start_of_stream(ctx);
 if ( rc )
 goto err;
@@ -939,6 +950,7 @@ static int save(struct xc_sr_context *ctx, uint16_t 
guest_type)
 }
 } while ( ctx->save.checkpointed != XC_MIG_STREAM_NONE );
 
+ end:
 xc_report_progress_single(xch, "End of stream");
 
 rc = write_end_record(ctx);
@@ -974,6 +986,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom,
 {
 .xch = xch,
 .fd = io_fd,
+.stream_phase = stream_phase
 };
 
 /* GCC 4.4 (of CentOS 6.x vintage) can' t initialise anonymous unions. */
@@ -989,7 +1002,8 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom,
stream_type == XC_MIG_STREAM_COLO);
 
 /* Sanity checks for callbacks. */
-if ( hvm )
+/* The pre mirror disks phase stream doesn't enable/disable qemu log */
+if ( hvm && ctx.stream_phase != XC_STREAM_PHASE_PRE_MIRROR_DISKS )
 assert(callbacks->switch_qemu_logdirty);
 if ( ctx.save.checkpointed )
 assert(callbacks->checkpoint && callbacks->postcopy);
diff --git a/tools/libxc/xc_sr_save_x86_hvm.c b/tools/libxc/xc_sr_save_x86_hvm.c
index 97a8c49..423edd7 100644
--- a/tools/libxc/xc_sr_save_x86_hvm.c
+++ b/tools/libxc/xc_sr_save_x86_hvm.c
@@ -4,6 +4,32 @@
 
 #include 
 
+static const unsigned int params[] = {
+HVM_PARAM_STORE_PFN,
+HVM_PARAM_IOREQ_PFN,
+HVM_PARAM_BUFIOREQ_PFN,
+HVM_PARAM_PAGING_RING_PF

[Xen-devel] [PATCH RFC v3 RESEND 01/12] Migration with Local Disks Mirroring: Added support in libxl to handle QMP events

2017-12-23 Thread Bruno Alvisio
Migration with Local Disk Mirroring uses the QEMU embedded NBD server. To
migrate the disk, a 'disk mirror job' is started from the source so that the
block devices emulated by QEMU are mirrored to the destination node. Once the
mirroring job is ready, QEMU sends an asynchronous QMP event. This code adds
support to register handlers when QMP events are received.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 tools/libxl/libxl_qmp.c | 58 +
 1 file changed, 58 insertions(+)

diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index eab993a..0e993af 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -59,6 +59,13 @@ typedef struct callback_id_pair {
 LIBXL_STAILQ_ENTRY(struct callback_id_pair) next;
 } callback_id_pair;
 
+typedef struct event_handler_pair {
+const char* event_type;
+void *opaque;
+qmp_request_context *context;
+qmp_callback_t event_handler;
+} event_handler_pair;
+
 struct libxl__qmp_handler {
 struct sockaddr_un addr;
 int qmp_fd;
@@ -66,6 +73,9 @@ struct libxl__qmp_handler {
 time_t timeout;
 /* wait_for_id will be used by the synchronous send function */
 int wait_for_id;
+/* wait_for_event_type is used to wait on QMP events */
+const char* wait_for_event_type;
+event_handler_pair *ehp;
 
 char buffer[QMP_RECEIVE_BUFFER_SIZE + 1];
 libxl__yajl_ctx *yajl_ctx;
@@ -287,6 +297,27 @@ static void qmp_handle_error_response(libxl__gc *gc, 
libxl__qmp_handler *qmp,
  libxl__json_object_get_string(resp));
 }
 
+static void qmp_handle_event(libxl__gc *gc, libxl__qmp_handler *qmp,
+ const libxl__json_object *event)
+{
+const char* event_type = NULL;
+const libxl__json_object *event_o = NULL;
+event_o = libxl__json_map_get("event", event, JSON_ANY);
+event_type = libxl__json_object_get_string(event_o);
+int rc;
+
+if(qmp->wait_for_event_type &&
+!strcmp(event_type, qmp->wait_for_event_type)) {
+if(qmp->ehp->event_handler) {
+rc = qmp->ehp->event_handler(qmp,
+   libxl__json_map_get("data", event, JSON_ANY),
+   qmp->ehp->opaque);
+}
+qmp->ehp->context->rc = rc;
+qmp->wait_for_event_type = NULL;
+}
+}
+
 static int qmp_handle_response(libxl__gc *gc, libxl__qmp_handler *qmp,
const libxl__json_object *resp)
 {
@@ -325,6 +356,7 @@ static int qmp_handle_response(libxl__gc *gc, 
libxl__qmp_handler *qmp,
 qmp_handle_error_response(gc, qmp, resp);
 return -1;
 case LIBXL__QMP_MESSAGE_TYPE_EVENT:
+qmp_handle_event(gc, qmp, resp);
 return 0;
 case LIBXL__QMP_MESSAGE_TYPE_INVALID:
 return -1;
@@ -624,6 +656,32 @@ static void qmp_free_handler(libxl__qmp_handler *qmp)
 free(qmp);
 }
 
+static int __attribute__((unused)) wait_for_event(libxl__qmp_handler *qmp,
+  event_handler_pair *ehp,
+  int timeout)
+{
+int ret = 0;
+GC_INIT(qmp->ctx);
+qmp->timeout = timeout;
+qmp_request_context context = { .rc = 0 };
+qmp->ehp = ehp;
+qmp->wait_for_event_type = ehp->event_type;
+ehp->context = 
+
+while (qmp->wait_for_event_type) {
+if ((ret = qmp_next(gc, qmp)) < 0) {
+break;
+}
+}
+
+if (!qmp->wait_for_event_type && ret == 0)
+ret = context.rc;
+
+GC_FREE;
+
+return ret;
+}
+
 /*
  * QMP Parameters Helpers
  */
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] Question about PV normalise_pagetable

2017-12-23 Thread Bruno Alvisio
Hi all,

I was understanding the code in tools/libxc/xc_sr_save_x86_pv.c and found
this comment to the normalise_pagetable:

/*
 * Normalise a pagetable for the migration stream.  Performs pfn->mfn
 * conversions on the ptes.
 */
static int normalise_pagetable(struct xc_sr_context *ctx, const uint64_t *src,
   uint64_t *dst, unsigned long type)


Looks like the function (as it should) is doing the reverse conversion mfn->pfn.

Wanted to confirm this typo or if I am missing something?

Thanks,

Bruno
___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH RFC 07/16] Save/Restore Support: Add unmap_shared_info

2017-12-19 Thread Bruno Alvisio
This function is necessary as part of the pre-suspend operation.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 arch/x86/setup.c | 12 
 hypervisor.c | 12 
 include/hypervisor.h |  1 +
 3 files changed, 25 insertions(+)

diff --git a/arch/x86/setup.c b/arch/x86/setup.c
index 31fa2c6..3eabce4 100644
--- a/arch/x86/setup.c
+++ b/arch/x86/setup.c
@@ -93,6 +93,18 @@ shared_info_t *map_shared_info(void *p)
 return (shared_info_t *)shared_info;
 }
 
+void unmap_shared_info(void)
+{
+int rc;
+
+if ( (rc = HYPERVISOR_update_va_mapping((unsigned 
long)HYPERVISOR_shared_info,
+__pte((virt_to_mfn(shared_info)<<L1_PAGETABLE_SHIFT)| L1_PROT), 
UVMF_INVLPG)) )
+{
+printk("Failed to unmap shared_info page!! rc=%d\n", rc);
+do_exit();
+}
+}
+
 static void get_cmdline(void *p)
 {
 start_info_t *si = p;
diff --git a/hypervisor.c b/hypervisor.c
index 1647121..d3857e7 100644
--- a/hypervisor.c
+++ b/hypervisor.c
@@ -78,6 +78,18 @@ shared_info_t *map_shared_info(void *p)
 
 return _info;
 }
+
+void unmap_shared_info(void)
+{
+struct xen_remove_from_physmap xrtp;
+
+xrtp.domid = DOMID_SELF;
+xrtp.gpfn = virt_to_pfn(_info);
+if ( HYPERVISOR_memory_op(XENMEM_remove_from_physmap, ) != 0 )
+BUG();
+
+return;
+}
 #endif
 
 void do_hypervisor_callback(struct pt_regs *regs)
diff --git a/include/hypervisor.h b/include/hypervisor.h
index f3b1f3c..1d09271 100644
--- a/include/hypervisor.h
+++ b/include/hypervisor.h
@@ -43,6 +43,7 @@ int hvm_get_parameter(int idx, uint64_t *value);
 int hvm_set_parameter(int idx, uint64_t value);
 #endif
 shared_info_t *map_shared_info(void *p);
+void unmap_shared_info(void);
 void force_evtchn_callback(void);
 void do_hypervisor_callback(struct pt_regs *regs);
 void mask_evtchn(uint32_t port);
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH RFC 14/16] Save/Restore Support: Add suspend/restore support for xenbus

2017-12-19 Thread Bruno Alvisio
Currently the watch path is not saved in the watch struct when it is registered.
During xenbus resume the path is needed so that the watches can be registered 
again.
Thus, 'path' field is added to struct watch so that watches can be re-registered
during xenbus resume.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 include/xenbus.h |   2 ++
 kernel.c |   8 +
 xenbus/xenbus.c  | 106 +++
 3 files changed, 85 insertions(+), 31 deletions(-)

diff --git a/include/xenbus.h b/include/xenbus.h
index b2d5072..3871f35 100644
--- a/include/xenbus.h
+++ b/include/xenbus.h
@@ -120,6 +120,8 @@ domid_t xenbus_get_self_id(void);
 #ifdef CONFIG_XENBUS
 /* Reset the XenBus system. */
 void fini_xenbus(void);
+void suspend_xenbus(void);
+void resume_xenbus(int canceled);
 #else
 static inline void fini_xenbus(void)
 {
diff --git a/kernel.c b/kernel.c
index a563f60..bc2394f 100644
--- a/kernel.c
+++ b/kernel.c
@@ -119,6 +119,10 @@ void start_kernel(void* par)
 
 void pre_suspend(void)
 {
+#ifdef CONFIG_XENBUS
+suspend_xenbus();
+#endif
+
 local_irq_disable();
 
 suspend_gnttab();
@@ -139,6 +143,10 @@ void post_suspend(int canceled)
 resume_gnttab();
 
 local_irq_enable();
+
+#ifdef CONFIG_XENBUS
+resume_xenbus(canceled);
+#endif
 }
 
 void stop_kernel(void)
diff --git a/xenbus/xenbus.c b/xenbus/xenbus.c
index c2d2bd1..4c626fb 100644
--- a/xenbus/xenbus.c
+++ b/xenbus/xenbus.c
@@ -50,6 +50,7 @@ DECLARE_WAIT_QUEUE_HEAD(xenbus_watch_queue);
 xenbus_event_queue xenbus_events;
 static struct watch {
 char *token;
+char *path;
 xenbus_event_queue *events;
 struct watch *next;
 } *watches;
@@ -63,6 +64,8 @@ struct xenbus_req_info
 #define NR_REQS 32
 static struct xenbus_req_info req_info[NR_REQS];
 
+static char *errmsg(struct xsd_sockmsg *rep);
+
 uint32_t xenbus_evtchn;
 
 #ifdef CONFIG_PARAVIRT
@@ -231,45 +234,39 @@ static void xenbus_thread_func(void *ign)
 struct xsd_sockmsg msg;
 unsigned prod = xenstore_buf->rsp_prod;
 
-for (;;) 
-{
+for (;;) {
 wait_event(xb_waitq, prod != xenstore_buf->rsp_prod);
-while (1) 
-{
+while (1) {
 prod = xenstore_buf->rsp_prod;
 DEBUG("Rsp_cons %d, rsp_prod %d.\n", xenstore_buf->rsp_cons,
-xenstore_buf->rsp_prod);
+  xenstore_buf->rsp_prod);
 if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons < sizeof(msg))
 break;
 rmb();
-memcpy_from_ring(xenstore_buf->rsp,
-,
-MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
-sizeof(msg));
-DEBUG("Msg len %d, %d avail, id %d.\n",
-msg.len + sizeof(msg),
-xenstore_buf->rsp_prod - xenstore_buf->rsp_cons,
-msg.req_id);
+memcpy_from_ring(xenstore_buf->rsp, ,
+ MASK_XENSTORE_IDX(xenstore_buf->rsp_cons),
+ sizeof(msg));
+DEBUG("Msg len %d, %d avail, id %d.\n", msg.len + sizeof(msg),
+  xenstore_buf->rsp_prod - xenstore_buf->rsp_cons, msg.req_id);
+
 if (xenstore_buf->rsp_prod - xenstore_buf->rsp_cons <
-sizeof(msg) + msg.len)
+sizeof(msg) + msg.len)
 break;
 
 DEBUG("Message is good.\n");
 
-if(msg.type == XS_WATCH_EVENT)
-{
-   struct xenbus_event *event = malloc(sizeof(*event) + msg.len);
+if (msg.type == XS_WATCH_EVENT) {
+   struct xenbus_event *event = malloc(sizeof(*event) + 
msg.len);
 xenbus_event_queue *events = NULL;
-   char *data = (char*)event + sizeof(*event);
+   char *data = (char*)event + sizeof(*event);
 struct watch *watch;
 
-memcpy_from_ring(xenstore_buf->rsp,
-   data,
+memcpy_from_ring(xenstore_buf->rsp, data,
 MASK_XENSTORE_IDX(xenstore_buf->rsp_cons + sizeof(msg)),
 msg.len);
 
-   event->path = data;
-   event->token = event->path + strlen(event->path) + 1;
+   event->path = data;
+   event->token = event->path + strlen(event->path) + 1;
 
 mb();
 xenstore_buf->rsp_cons += msg.len + sizeof(msg);
@@ -288,15 +285,11 @@ static void xenbus_thread_func(void *ign)
 printk("unexpected watch token %s\n", event->token);
 free(event);
 }
-}
-
-else
-{
+} else {
 req_i

[Xen-devel] [PATCH RFC 04/16] Save/Restore Support: Add xenbus_release_wait_for_watch

2017-12-19 Thread Bruno Alvisio
xenbus_release_wait_for_watch generates a fake event to trigger make
xenbus_wait_for_watch return. This is necessary to wake up waiting threads.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 include/xenbus.h |  1 +
 xenbus/xenbus.c  | 10 +-
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/include/xenbus.h b/include/xenbus.h
index 12391b9..b2d5072 100644
--- a/include/xenbus.h
+++ b/include/xenbus.h
@@ -42,6 +42,7 @@ char *xenbus_unwatch_path_token(xenbus_transaction_t xbt, 
const char *path, cons
 extern struct wait_queue_head xenbus_watch_queue;
 void xenbus_wait_for_watch(xenbus_event_queue *queue);
 char **xenbus_wait_for_watch_return(xenbus_event_queue *queue);
+void xenbus_release_wait_for_watch(xenbus_event_queue *queue);
 char* xenbus_wait_for_value(const char *path, const char *value, 
xenbus_event_queue *queue);
 char *xenbus_wait_for_state_change(const char* path, XenbusState *state, 
xenbus_event_queue *queue);
 char *xenbus_switch_state(xenbus_transaction_t xbt, const char* path, 
XenbusState state);
diff --git a/xenbus/xenbus.c b/xenbus/xenbus.c
index 636786c..c2d2bd1 100644
--- a/xenbus/xenbus.c
+++ b/xenbus/xenbus.c
@@ -129,6 +129,14 @@ void xenbus_wait_for_watch(xenbus_event_queue *queue)
 printk("unexpected path returned by watch\n");
 }
 
+void xenbus_release_wait_for_watch(xenbus_event_queue *queue)
+{
+struct xenbus_event *event = malloc(sizeof(*event));
+event->next = *queue;
+*queue = event;
+wake_up(_watch_queue);
+}
+
 char* xenbus_wait_for_value(const char* path, const char* value, 
xenbus_event_queue *queue)
 {
 if (!queue)
@@ -318,7 +326,7 @@ static void release_xenbus_id(int id)
 req_info[id].in_use = 0;
 nr_live_reqs--;
 req_info[id].in_use = 0;
-if (nr_live_reqs == NR_REQS - 1)
+if (nr_live_reqs == 0 || nr_live_reqs == NR_REQS - 1)
 wake_up(_wq);
 spin_unlock(_lock);
 }
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH RFC 15/16] Save/Restore Support: Add suspend/restore support for netfront

2017-12-19 Thread Bruno Alvisio
Performed an additional cleanup to make the file more syntactically consistent.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 include/netfront.h |   8 +-
 kernel.c   |   8 ++
 netfront.c | 242 +
 3 files changed, 204 insertions(+), 54 deletions(-)

diff --git a/include/netfront.h b/include/netfront.h
index 2b95da9..1164d50 100644
--- a/include/netfront.h
+++ b/include/netfront.h
@@ -3,9 +3,15 @@
 #include 
 #endif
 struct netfront_dev;
-struct netfront_dev *init_netfront(char *nodename, void (*netif_rx)(unsigned 
char *data, int len), unsigned char rawmac[6], char **ip);
+struct netfront_dev *init_netfront(char *nodename,
+   void (*netif_rx)(unsigned char *data,
+int len, void* arg),
+   unsigned char rawmac[6],
+   char **ip);
 void netfront_xmit(struct netfront_dev *dev, unsigned char* data,int len);
 void shutdown_netfront(struct netfront_dev *dev);
+void suspend_netfront(void);
+void resume_netfront(void);
 #ifdef HAVE_LIBC
 int netfront_tap_open(char *nodename);
 ssize_t netfront_receive(struct netfront_dev *dev, unsigned char *data, size_t 
len);
diff --git a/kernel.c b/kernel.c
index bc2394f..805539e 100644
--- a/kernel.c
+++ b/kernel.c
@@ -119,6 +119,10 @@ void start_kernel(void* par)
 
 void pre_suspend(void)
 {
+#ifdef CONFIG_NETFRONT
+suspend_netfront();
+#endif
+
 #ifdef CONFIG_XENBUS
 suspend_xenbus();
 #endif
@@ -147,6 +151,10 @@ void post_suspend(int canceled)
 #ifdef CONFIG_XENBUS
 resume_xenbus(canceled);
 #endif
+
+#ifdef CONFIG_NETFRONT
+resume_netfront();
+#endif
 }
 
 void stop_kernel(void)
diff --git a/netfront.c b/netfront.c
index b8fac62..9aef42b 100644
--- a/netfront.c
+++ b/netfront.c
@@ -63,10 +63,29 @@ struct netfront_dev {
 size_t rlen;
 #endif
 
-void (*netif_rx)(unsigned char* data, int len);
+void (*netif_rx)(unsigned char* data, int len, void* arg);
+void *netif_rx_arg;
 };
 
+struct netfront_dev_list {
+   struct netfront_dev *dev;
+   unsigned char rawmac[6];
+   char *ip;
+
+   int refcount;
+
+   struct netfront_dev_list *next;
+};
+
+static struct netfront_dev_list *dev_list = NULL;
+
 void init_rx_buffers(struct netfront_dev *dev);
+static struct netfront_dev *_init_netfront(struct netfront_dev *dev,
+  unsigned char rawmac[6], char **ip);
+static void _shutdown_netfront(struct netfront_dev *dev);
+void netfront_set_rx_handler(struct netfront_dev *dev,
+void (*thenetif_rx)(unsigned char 
*data, int len,
+void *arg), void *arg);
 
 static inline void add_id_to_freelist(unsigned int id,unsigned short* freelist)
 {
@@ -81,7 +100,7 @@ static inline unsigned short get_id_from_freelist(unsigned 
short* freelist)
 return id;
 }
 
-__attribute__((weak)) void netif_rx(unsigned char* data,int len)
+__attribute__((weak)) void netif_rx(unsigned char* data, int len, void *arg)
 {
 printk("%d bytes incoming at %p\n",len,data);
 }
@@ -134,7 +153,7 @@ moretodo:
dobreak = 1;
} else
 #endif
-   dev->netif_rx(page+rx->offset,rx->status);
+   dev->netif_rx(page+rx->offset, rx->status, dev->netif_rx_arg);
 }
 }
 dev->rx.rsp_cons=cons;
@@ -282,19 +301,16 @@ static void free_netfront(struct netfront_dev *dev)
 free(dev);
 }
 
-struct netfront_dev *init_netfront(char *_nodename, void 
(*thenetif_rx)(unsigned char* data, int len), unsigned char rawmac[6], char 
**ip)
+struct netfront_dev *init_netfront(char *_nodename,
+   void (*thenetif_rx)(unsigned char* data,
+   int len, void* arg),
+   unsigned char rawmac[6],
+   char **ip)
 {
-xenbus_transaction_t xbt;
-char* err;
-char* message=NULL;
-struct netif_tx_sring *txs;
-struct netif_rx_sring *rxs;
-int retry=0;
-int i;
-char* msg = NULL;
 char nodename[256];
-char path[256];
 struct netfront_dev *dev;
+struct netfront_dev_list *ldev = NULL;
+struct netfront_dev_list *list = NULL;
 static int netfrontends = 0;
 
 if (!_nodename)
@@ -303,10 +319,20 @@ struct netfront_dev *init_netfront(char *_nodename, void 
(*thenetif_rx)(unsigned
 strncpy(nodename, _nodename, sizeof(nodename) - 1);
 nodename[sizeof(nodename) - 1] = 0;
 }
-netfrontends++;
+
+/* Check if the device is already initialized */
+for (list = dev_list; list != NULL; list = list->next) {
+if (strcmp(nodename, list->dev->nodename) == 0) {
+list->refcount++;
+ 

[Xen-devel] [PATCH RFC 09/16] Save/Restore Support: Disable/enable IRQs during suspend/restore

2017-12-19 Thread Bruno Alvisio
Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 kernel.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel.c b/kernel.c
index 1cd40e8..782eb79 100644
--- a/kernel.c
+++ b/kernel.c
@@ -119,12 +119,12 @@ void start_kernel(void* par)
 
 void pre_suspend(void)
 {
-
+local_irq_disable();
 }
 
 void post_suspend(int canceled)
 {
-
+local_irq_enable();
 }
 
 void stop_kernel(void)
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH RFC 03/16] Save/Restore Support: Declare kernel and arch pre/post suspend functions

2017-12-19 Thread Bruno Alvisio
For mini-OS to support suspend and restore, the kernel will have to suspend
different modules such as xenbus, console, irq, etc. During save/restore the
kernel and arch pre_suspend and post_suspend functions will be invoked to
suspend/resume each of the modules.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 arch/x86/setup.c | 10 ++
 include/kernel.h |  2 ++
 include/x86/os.h |  4 ++--
 kernel.c | 10 ++
 4 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/arch/x86/setup.c b/arch/x86/setup.c
index 5278227..3dd86f9 100644
--- a/arch/x86/setup.c
+++ b/arch/x86/setup.c
@@ -204,6 +204,16 @@ arch_init(void *par)
start_kernel();
 }
 
+void arch_pre_suspend(void)
+{
+
+}
+
+void arch_post_suspend(int canceled)
+{
+
+}
+
 void
 arch_fini(void)
 {
diff --git a/include/kernel.h b/include/kernel.h
index d37ddda..161d757 100644
--- a/include/kernel.h
+++ b/include/kernel.h
@@ -5,6 +5,8 @@
 extern char cmdline[MAX_CMDLINE_SIZE];
 
 void start_kernel(void);
+void pre_suspend(void);
+void post_suspend(int canceled);
 void do_exit(void) __attribute__((noreturn));
 void arch_do_exit(void);
 void stop_kernel(void);
diff --git a/include/x86/os.h b/include/x86/os.h
index d155914..a73b63e 100644
--- a/include/x86/os.h
+++ b/include/x86/os.h
@@ -71,10 +71,10 @@ void trap_fini(void);
 void xen_callback_vector(void);
 #endif
 
+void arch_pre_suspend(void);
+void arch_post_suspend(int canceled);
 void arch_fini(void);
 
-
-
 #ifdef CONFIG_PARAVIRT
 
 /* 
diff --git a/kernel.c b/kernel.c
index 0d84a9b..90c865a 100644
--- a/kernel.c
+++ b/kernel.c
@@ -155,6 +155,16 @@ void start_kernel(void)
 run_idle_thread();
 }
 
+void pre_suspend(void)
+{
+
+}
+
+void post_suspend(int canceled)
+{
+
+}
+
 void stop_kernel(void)
 {
 /* TODO: fs import */
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH RFC 02/16] Save/Restore Support: Refactor trap_init() and setup vector callbacks

2017-12-19 Thread Bruno Alvisio
Currently the setup of the IDT and the request to set the HVM vector callbacks
are performed both in the trap_init function.

As part of the post-suspend operation, the HVM vector callback needs to be setup
again while the IDT does not. Thus, the trap_init function is split into two
separate functions: trap_init (sets up IDT) and xen_callback_vector (sets the
HVM vector callback). During the post-suspend operations the xen_callback_vector
function will be invoked.

Signed-off-by: Bruno Alvisio <bruno.alvi...@oracle.com>
---
 arch/x86/traps.c | 17 +++--
 include/x86/os.h |  3 +++
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/arch/x86/traps.c b/arch/x86/traps.c
index aa17da3..a7388a5 100644
--- a/arch/x86/traps.c
+++ b/arch/x86/traps.c
@@ -389,6 +389,16 @@ static void setup_gate(unsigned int entry, void *addr, 
unsigned int dpl)
 #endif
 }
 
+void xen_callback_vector(void)
+{
+if (hvm_set_parameter(HVM_PARAM_CALLBACK_IRQ,
+ (2ULL << 56) | TRAP_xen_callback))
+{
+xprintk("Request for Xen HVM callback vector failed\n");
+do_exit();
+}
+}
+
 void trap_init(void)
 {
 setup_gate(TRAP_divide_error, _error, 0);
@@ -415,12 +425,7 @@ void trap_init(void)
 gdt[GDTE_TSS] = (typeof(*gdt))INIT_GDTE((unsigned long), 0x67, 0x89);
 asm volatile ("ltr %w0" :: "rm" (GDTE_TSS * 8));
 
-if ( hvm_set_parameter(HVM_PARAM_CALLBACK_IRQ,
-   (2ULL << 56) | TRAP_xen_callback) )
-{
-xprintk("Request for Xen HVM callback vector failed\n");
-do_exit();
-}
+xen_callback_vector();
 }
 
 void trap_fini(void)
diff --git a/include/x86/os.h b/include/x86/os.h
index fbc2eeb..d155914 100644
--- a/include/x86/os.h
+++ b/include/x86/os.h
@@ -67,6 +67,9 @@ extern shared_info_t *HYPERVISOR_shared_info;
 
 void trap_init(void);
 void trap_fini(void);
+#ifndef CONFIG_PARAVIRT
+void xen_callback_vector(void);
+#endif
 
 void arch_fini(void);
 
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH RFC 06/16] Save/Restore Support: Moved shutdown thread to shutdown.c

2017-12-19 Thread Bruno Alvisio
The shutdown thread present in kernel.c was removed and now the thread in
shutdown.c is created instead.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 arch/x86/setup.c |  2 +-
 include/kernel.h |  2 +-
 kernel.c | 50 ++
 3 files changed, 8 insertions(+), 46 deletions(-)

diff --git a/arch/x86/setup.c b/arch/x86/setup.c
index 3dd86f9..31fa2c6 100644
--- a/arch/x86/setup.c
+++ b/arch/x86/setup.c
@@ -201,7 +201,7 @@ arch_init(void *par)
memcpy(_info, par, sizeof(start_info));
 #endif
 
-   start_kernel();
+   start_kernel((start_info_t *)par);
 }
 
 void arch_pre_suspend(void)
diff --git a/include/kernel.h b/include/kernel.h
index 161d757..742abf5 100644
--- a/include/kernel.h
+++ b/include/kernel.h
@@ -4,7 +4,7 @@
 #define MAX_CMDLINE_SIZE 1024
 extern char cmdline[MAX_CMDLINE_SIZE];
 
-void start_kernel(void);
+void start_kernel(void* par);
 void pre_suspend(void);
 void post_suspend(int canceled);
 void do_exit(void) __attribute__((noreturn));
diff --git a/kernel.c b/kernel.c
index 90c865a..1cd40e8 100644
--- a/kernel.c
+++ b/kernel.c
@@ -42,6 +42,9 @@
 #include 
 #include 
 #include 
+#ifdef CONFIG_XENBUS
+#include 
+#endif
 #include 
 #include 
 #include 
@@ -66,48 +69,6 @@ void setup_xen_features(void)
 }
 }
 
-#ifdef CONFIG_XENBUS
-/* This should be overridden by the application we are linked against. */
-__attribute__((weak)) void app_shutdown(unsigned reason)
-{
-struct sched_shutdown sched_shutdown = { .reason = reason };
-printk("Shutdown requested: %d\n", reason);
-HYPERVISOR_sched_op(SCHEDOP_shutdown, _shutdown);
-}
-
-static void shutdown_thread(void *p)
-{
-const char *path = "control/shutdown";
-const char *token = path;
-xenbus_event_queue events = NULL;
-char *shutdown = NULL, *err;
-unsigned int shutdown_reason;
-xenbus_watch_path_token(XBT_NIL, path, token, );
-while ((err = xenbus_read(XBT_NIL, path, )) != NULL || 
!strcmp(shutdown, ""))
-{
-free(err);
-free(shutdown);
-shutdown = NULL;
-xenbus_wait_for_watch();
-}
-err = xenbus_unwatch_path_token(XBT_NIL, path, token);
-free(err);
-err = xenbus_write(XBT_NIL, path, "");
-free(err);
-printk("Shutting down (%s)\n", shutdown);
-
-if (!strcmp(shutdown, "poweroff"))
-shutdown_reason = SHUTDOWN_poweroff;
-else if (!strcmp(shutdown, "reboot"))
-shutdown_reason = SHUTDOWN_reboot;
-else
-/* Unknown */
-shutdown_reason = SHUTDOWN_crash;
-app_shutdown(shutdown_reason);
-free(shutdown);
-}
-#endif
-
 
 /* This should be overridden by the application we are linked against. */
 __attribute__((weak)) int app_main(void *p)
@@ -116,7 +77,7 @@ __attribute__((weak)) int app_main(void *p)
 return 0;
 }
 
-void start_kernel(void)
+void start_kernel(void* par)
 {
 /* Set up events. */
 init_events();
@@ -145,7 +106,8 @@ void start_kernel(void)
 init_xenbus();
 
 #ifdef CONFIG_XENBUS
-create_thread("shutdown", shutdown_thread, NULL);
+/* Init shutdown thread */
+init_shutdown((start_info_t *)par);
 #endif
 
 /* Call (possibly overridden) app_main() */
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH RFC 08/16] Save/Restore Support: Add arch_mm_pre|post_suspend

2017-12-19 Thread Bruno Alvisio
For PV guests the pagetables reference the real MFNs rather than PFNs, so when
the guest is resumed into a different area of a hosts memory, these will need to
be rewritten. Thus for PV guests the MFNs need to be replaced with PFNs:
canonicalization.

PVH guests are auto-translated so no memory operation is needed.

Signed-off-by: Bruno Alvisio <bruno.alvi...@oracle.com>
---
 arch/x86/mm.c | 14 ++
 include/x86/arch_mm.h |  3 +++
 2 files changed, 17 insertions(+)

diff --git a/arch/x86/mm.c b/arch/x86/mm.c
index 05ad029..1b163ac 100644
--- a/arch/x86/mm.c
+++ b/arch/x86/mm.c
@@ -848,6 +848,20 @@ void arch_init_p2m(unsigned long max_pfn)
 
 arch_remap_p2m(max_pfn);
 }
+
+void arch_mm_pre_suspend(void)
+{
+//TODO: Canonicalize pagetables
+}
+
+void arch_mm_post_suspend(int canceled)
+{
+//TODO: Locate pagetables and 'uncanonicalize' them
+}
+#else
+void arch_mm_pre_suspend(void){ }
+
+void arch_mm_post_suspend(int canceled){ }
 #endif
 
 void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p)
diff --git a/include/x86/arch_mm.h b/include/x86/arch_mm.h
index ab8a53e..cbbeb21 100644
--- a/include/x86/arch_mm.h
+++ b/include/x86/arch_mm.h
@@ -279,6 +279,9 @@ pgentry_t *need_pgt(unsigned long addr);
 void arch_mm_preinit(void *p);
 unsigned long alloc_virt_kernel(unsigned n_pages);
 
+void arch_mm_pre_suspend(void);
+void arch_mm_post_suspend(int canceled);
+
 #ifndef CONFIG_PARAVIRT
 void arch_print_memmap(void);
 #endif
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH RFC 13/16] Save/Restore Support: Add suspend/restore support for Grant Tables.

2017-12-19 Thread Bruno Alvisio
Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 gnttab.c | 33 +
 include/gnttab.h |  2 ++
 kernel.c |  4 
 3 files changed, 39 insertions(+)

diff --git a/gnttab.c b/gnttab.c
index 3f0e35f..a91c2e1 100644
--- a/gnttab.c
+++ b/gnttab.c
@@ -194,3 +194,36 @@ fini_gnttab(void)
 
 HYPERVISOR_grant_table_op(GNTTABOP_setup_table, , 1);
 }
+
+void suspend_gnttab(void)
+{
+#ifdef CONFIG_PARAVIRT
+int i;
+
+for (i = 0; i < NR_GRANT_FRAMES; i++) {
+HYPERVISOR_update_va_mapping((unsigned long)(((char *)gnttab_table) + 
PAGE_SIZE*i),
+(pte_t){0x0<<PAGE_SHIFT}, UVMF_INVLPG);
+}
+#endif
+return;
+}
+
+void resume_gnttab(void)
+{
+struct gnttab_setup_table setup;
+unsigned long frames[NR_GRANT_FRAMES];
+
+setup.dom = DOMID_SELF;
+setup.nr_frames = NR_GRANT_FRAMES;
+set_xen_guest_handle(setup.frame_list, frames);
+
+HYPERVISOR_grant_table_op(GNTTABOP_setup_table, , 1);
+
+#ifdef CONFIG_PARAVIRT
+int i;
+for (i = 0; i < NR_GRANT_FRAMES; i++) {
+HYPERVISOR_update_va_mapping((unsigned long)(((char *)gnttab_table) + 
PAGE_SIZE*i),
+(pte_t){(frames[i] << PAGE_SHIFT) | L1_PROT}, UVMF_INVLPG);
+}
+#endif
+}
\ No newline at end of file
diff --git a/include/gnttab.h b/include/gnttab.h
index a9d8e09..56f5159 100644
--- a/include/gnttab.h
+++ b/include/gnttab.h
@@ -12,6 +12,8 @@ unsigned long gnttab_end_transfer(grant_ref_t gref);
 int gnttab_end_access(grant_ref_t ref);
 const char *gnttabop_error(int16_t status);
 void fini_gnttab(void);
+void suspend_gnttab(void);
+void resume_gnttab(void);
 grant_entry_v1_t *arch_init_gnttab(int nr_grant_frames);
 
 #endif /* !__GNTTAB_H__ */
diff --git a/kernel.c b/kernel.c
index c6ff9f3..a563f60 100644
--- a/kernel.c
+++ b/kernel.c
@@ -121,6 +121,8 @@ void pre_suspend(void)
 {
 local_irq_disable();
 
+suspend_gnttab();
+
 suspend_time();
 
 suspend_console();
@@ -134,6 +136,8 @@ void post_suspend(int canceled)
 
 resume_time();
 
+resume_gnttab();
+
 local_irq_enable();
 }
 
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH RFC 10/16] Save/Restore Support: Add suspend/resume support for timers

2017-12-19 Thread Bruno Alvisio
Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 arch/x86/time.c | 13 +
 include/time.h  |  2 ++
 kernel.c|  4 
 3 files changed, 19 insertions(+)

diff --git a/arch/x86/time.c b/arch/x86/time.c
index 3658142..8f79d69 100644
--- a/arch/x86/time.c
+++ b/arch/x86/time.c
@@ -244,3 +244,16 @@ void fini_time(void)
 HYPERVISOR_set_timer_op(0);
 unbind_evtchn(port);
 }
+
+void suspend_time(void)
+{
+/* Clear any pending timer */
+HYPERVISOR_set_timer_op(0);
+unbind_evtchn(port);
+}
+
+void resume_time(void)
+{
+port = bind_virq(VIRQ_TIMER, _handler, NULL);
+unmask_evtchn(port);
+}
diff --git a/include/time.h b/include/time.h
index 5d6ed67..2e06d58 100644
--- a/include/time.h
+++ b/include/time.h
@@ -55,6 +55,8 @@ typedef long suseconds_t;
 /* prototypes */
 void init_time(void);
 void fini_time(void);
+void suspend_time(void);
+void resume_time(void);
 s_time_t get_s_time(void);
 s_time_t get_v_time(void);
 uint64_t monotonic_clock(void);
diff --git a/kernel.c b/kernel.c
index 782eb79..a16b1ba 100644
--- a/kernel.c
+++ b/kernel.c
@@ -120,10 +120,14 @@ void start_kernel(void* par)
 void pre_suspend(void)
 {
 local_irq_disable();
+
+suspend_time();
 }
 
 void post_suspend(int canceled)
 {
+resume_time();
+
 local_irq_enable();
 }
 
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH RFC 12/16] Save/Restore Support: Add support for suspend/restore events.

2017-12-19 Thread Bruno Alvisio
Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 events.c | 5 +
 include/events.h | 1 +
 kernel.c | 2 ++
 3 files changed, 8 insertions(+)

diff --git a/events.c b/events.c
index e8ef8aa..342aead 100644
--- a/events.c
+++ b/events.c
@@ -183,6 +183,11 @@ void fini_events(void)
 arch_fini_events();
 }
 
+void suspend_events(void)
+{
+unbind_all_ports();
+}
+
 void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore)
 {
 printk("[Port %d] - event received\n", port);
diff --git a/include/events.h b/include/events.h
index 89b5997..705ad93 100644
--- a/include/events.h
+++ b/include/events.h
@@ -55,5 +55,6 @@ static inline int notify_remote_via_evtchn(evtchn_port_t port)
 }
 
 void fini_events(void);
+void suspend_events(void);
 
 #endif /* _EVENTS_H_ */
diff --git a/kernel.c b/kernel.c
index fd1c4c5..c6ff9f3 100644
--- a/kernel.c
+++ b/kernel.c
@@ -124,6 +124,8 @@ void pre_suspend(void)
 suspend_time();
 
 suspend_console();
+
+suspend_events();
 }
 
 void post_suspend(int canceled)
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH RFC 00/16] Save/Restore Support for mini-OS PVH

2017-12-19 Thread Bruno Alvisio
Hi all,

I have been working on supporting save/restore for mini-os PVH. Some parts of
the implementation were taken from the sysml/mini-os repository. The branch can
be found at:

https://github.com/balvisio/mini-os/tree/feature/mini-os-suspend-support

Any feedback would be greatly appreciated.

Cheers,

Bruno

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH RFC v3 09/12] Migration with Local Disks Mirroring: New stream phase type for libxc streams

2017-12-04 Thread Bruno Alvisio
Adapted libxc restore stream. Defined libxc stream phase types:

0. XC_STREAM_PHASE_DEFAULT: This is the stream phase when no local disks are
being mirrored as part of the domain save or restore (=0)

1. XC_STREAM_PHASE_POST_MIRROR_DISKS: This stream phase transfers the virtual
RAM from source to destination. It happens after disks mirroring is completed.

2. XC_STREAM_PHASE_PRE_MIRROR_DISKS: This stream transfers pfns and parameters
necessary to start the QEMU process in the destination. It happens before the
disks mirroring.

The PRE_MIRROR_DISKS phase stream type skips the stream_complete ops to restore
the domain. The restore is performed by the POST_MIRROR_DISKS phase stream that
is executed later in the restore flow. If no local disks are mirrored the
restore is executed by the DEFAULT phase stream type.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 tools/libxc/xc_sr_common.h|  1 +
 tools/libxc/xc_sr_restore.c   | 51 ++-
 tools/libxc/xc_sr_stream_format.h |  5 
 3 files changed, 35 insertions(+), 22 deletions(-)

diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
index a145a15..8cf393f 100644
--- a/tools/libxc/xc_sr_common.h
+++ b/tools/libxc/xc_sr_common.h
@@ -177,6 +177,7 @@ struct xc_sr_context
 xc_interface *xch;
 uint32_t domid;
 int fd;
+int stream_phase;
 
 xc_dominfo_t dominfo;
 
diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
index 7f74d28..924386c 100644
--- a/tools/libxc/xc_sr_restore.c
+++ b/tools/libxc/xc_sr_restore.c
@@ -736,7 +736,10 @@ static int restore(struct xc_sr_context *ctx)
 struct xc_sr_record rec;
 int rc, saved_rc = 0, saved_errno = 0;
 
-IPRINTF("Restoring domain");
+if ( ctx->stream_phase != XC_STREAM_PHASE_PRE_MIRROR_DISKS )
+IPRINTF("Restoring domain");
+else
+IPRINTF("Mirroring disks restoring phase");
 
 rc = setup(ctx);
 if ( rc )
@@ -799,11 +802,16 @@ static int restore(struct xc_sr_context *ctx)
  * With Remus, if we reach here, there must be some error on primary,
  * failover from the last checkpoint state.
  */
-rc = ctx->restore.ops.stream_complete(ctx);
-if ( rc )
-goto err;
+if ( ctx->stream_phase != XC_STREAM_PHASE_PRE_MIRROR_DISKS )
+{
+rc = ctx->restore.ops.stream_complete(ctx);
+if ( rc )
+goto err;
 
-IPRINTF("Restore successful");
+IPRINTF("Restore successful");
+} else {
+IPRINTF("Mirroring disks restore phase successful");
+}
 goto done;
 
  err:
@@ -837,6 +845,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
 {
 .xch = xch,
 .fd = io_fd,
+.stream_phase = stream_phase
 };
 
 /* GCC 4.4 (of CentOS 6.x vintage) can' t initialise anonymous unions. */
@@ -890,29 +899,27 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
 ctx.restore.p2m_size = nr_pfns;
 
 if ( ctx.dominfo.hvm )
-{
 ctx.restore.ops = restore_ops_x86_hvm;
-if ( restore() )
-return -1;
-}
 else
-{
 ctx.restore.ops = restore_ops_x86_pv;
-if ( restore() )
-return -1;
-}
 
-IPRINTF("XenStore: mfn %#"PRIpfn", dom %d, evt %u",
-ctx.restore.xenstore_gfn,
-ctx.restore.xenstore_domid,
-ctx.restore.xenstore_evtchn);
+if ( restore() )
+return -1;
+
+if ( stream_phase != XC_STREAM_PHASE_PRE_MIRROR_DISKS )
+{
+IPRINTF("XenStore: mfn %#"PRIpfn", dom %d, evt %u",
+ctx.restore.xenstore_gfn,
+ctx.restore.xenstore_domid,
+ctx.restore.xenstore_evtchn);
 
-IPRINTF("Console: mfn %#"PRIpfn", dom %d, evt %u",
-ctx.restore.console_gfn,
-ctx.restore.console_domid,
-ctx.restore.console_evtchn);
+IPRINTF("Console: mfn %#"PRIpfn", dom %d, evt %u",
+ctx.restore.console_gfn,
+ctx.restore.console_domid,
+ctx.restore.console_evtchn);
 
-*console_gfn = ctx.restore.console_gfn;
+*console_gfn = ctx.restore.console_gfn;
+}
 *store_mfn = ctx.restore.xenstore_gfn;
 
 return 0;
diff --git a/tools/libxc/xc_sr_stream_format.h 
b/tools/libxc/xc_sr_stream_format.h
index 15ff1c7..c705da4 100644
--- a/tools/libxc/xc_sr_stream_format.h
+++ b/tools/libxc/xc_sr_stream_format.h
@@ -138,6 +138,11 @@ struct xc_sr_rec_hvm_params
 struct xc_sr_rec_hvm_params_entry param[0];
 };
 
+/* LIBXC stream phase types */
+#define XC_STREAM_PHASE_DEFAULT 0
+#define XC_STREAM_PHASE_POST_MIRROR_DISKS 1
+#define XC_STREAM_PHASE_PRE_MIRROR_DISKS 2
+
 #endif
 /*
  * Local variables:
-- 
2.3.2 (Apple Git-55)


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH RFC v3 12/12] Migration with Local Disks Mirroring: Introduce pre_mirror_disks_stream_phase op to xc_sr_save_ops

2017-12-04 Thread Bruno Alvisio
A new op pre_mirror_stream_phase is introduced as part of the xc_sr_save_ops.
This op sends all pfns and params that need to be transferred before the disks
mirroring jobs can be started. Note that no new libxc record type is created.

The save flow is modified such that: if the stream_phase ==
XC_PRE_MIRROR_DISKS_STREAM_PHASE only the pre_mirror_disks op is executed as
part of the save(). In all other libxc phase types, the original flow is
executed.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 tools/libxc/xc_sr_common.h   |  11 
 tools/libxc/xc_sr_save.c |  24 +++--
 tools/libxc/xc_sr_save_x86_hvm.c | 109 +++
 3 files changed, 105 insertions(+), 39 deletions(-)

diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
index 8cf393f..44f4103 100644
--- a/tools/libxc/xc_sr_common.h
+++ b/tools/libxc/xc_sr_common.h
@@ -96,6 +96,13 @@ struct xc_sr_save_ops
  * after a successful save, or upon encountering an error.
  */
 int (*cleanup)(struct xc_sr_context *ctx);
+
+/**
+ * Send the necessary records/params to allow the start of the local
+ * disks mirroring job in the destination node. It will be called exactly
+ * once only if the stream phase type == XC_STREAM_PHASE_PRE_MIRROR_DISKS
+ */
+int (*pre_mirror_disks_stream_phase)(struct xc_sr_context *ctx);
 };
 
 
@@ -398,6 +405,10 @@ int read_record(struct xc_sr_context *ctx, int fd, struct 
xc_sr_record *rec);
 int populate_pfns(struct xc_sr_context *ctx, unsigned count,
   const xen_pfn_t *original_pfns, const uint32_t *types);
 
+int add_to_batch(struct xc_sr_context *ctx, xen_pfn_t pfn);
+
+int flush_batch(struct xc_sr_context *ctx);
+
 #endif
 /*
  * Local variables:
diff --git a/tools/libxc/xc_sr_save.c b/tools/libxc/xc_sr_save.c
index b7498e3..557dafe 100644
--- a/tools/libxc/xc_sr_save.c
+++ b/tools/libxc/xc_sr_save.c
@@ -279,7 +279,7 @@ static int write_batch(struct xc_sr_context *ctx)
 /*
  * Flush a batch of pfns into the stream.
  */
-static int flush_batch(struct xc_sr_context *ctx)
+int flush_batch(struct xc_sr_context *ctx)
 {
 int rc = 0;
 
@@ -301,7 +301,7 @@ static int flush_batch(struct xc_sr_context *ctx)
 /*
  * Add a single pfn to the batch, flushing the batch if full.
  */
-static int add_to_batch(struct xc_sr_context *ctx, xen_pfn_t pfn)
+int add_to_batch(struct xc_sr_context *ctx, xen_pfn_t pfn)
 {
 int rc = 0;
 
@@ -842,8 +842,12 @@ static int save(struct xc_sr_context *ctx, uint16_t 
guest_type)
 xc_interface *xch = ctx->xch;
 int rc, saved_rc = 0, saved_errno = 0;
 
-IPRINTF("Saving domain %d, type %s",
-ctx->domid, dhdr_type_to_str(guest_type));
+if ( ctx->stream_phase == XC_STREAM_PHASE_PRE_MIRROR_DISKS )
+IPRINTF("Pre-mirroring disks save phase for domain %d, type %s",
+ctx->domid, dhdr_type_to_str(guest_type));
+else
+IPRINTF("Saving domain %d, type %s",
+ctx->domid, dhdr_type_to_str(guest_type));
 
 rc = setup(ctx);
 if ( rc )
@@ -855,6 +859,13 @@ static int save(struct xc_sr_context *ctx, uint16_t 
guest_type)
 if ( rc )
 goto err;
 
+if ( ctx->stream_phase == XC_STREAM_PHASE_PRE_MIRROR_DISKS ) {
+rc = ctx->save.ops.pre_mirror_disks_stream_phase(ctx);
+if ( rc )
+goto err;
+goto end;
+}
+
 rc = ctx->save.ops.start_of_stream(ctx);
 if ( rc )
 goto err;
@@ -939,6 +950,7 @@ static int save(struct xc_sr_context *ctx, uint16_t 
guest_type)
 }
 } while ( ctx->save.checkpointed != XC_MIG_STREAM_NONE );
 
+ end:
 xc_report_progress_single(xch, "End of stream");
 
 rc = write_end_record(ctx);
@@ -974,6 +986,7 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom,
 {
 .xch = xch,
 .fd = io_fd,
+.stream_phase = stream_phase
 };
 
 /* GCC 4.4 (of CentOS 6.x vintage) can' t initialise anonymous unions. */
@@ -989,7 +1002,8 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom,
stream_type == XC_MIG_STREAM_COLO);
 
 /* Sanity checks for callbacks. */
-if ( hvm )
+/* The pre mirror disks phase stream doesn't enable/disable qemu log */
+if ( hvm && ctx.stream_phase != XC_STREAM_PHASE_PRE_MIRROR_DISKS )
 assert(callbacks->switch_qemu_logdirty);
 if ( ctx.save.checkpointed )
 assert(callbacks->checkpoint && callbacks->postcopy);
diff --git a/tools/libxc/xc_sr_save_x86_hvm.c b/tools/libxc/xc_sr_save_x86_hvm.c
index 97a8c49..423edd7 100644
--- a/tools/libxc/xc_sr_save_x86_hvm.c
+++ b/tools/libxc/xc_sr_save_x86_hvm.c
@@ -4,6 +4,32 @@
 
 #include 
 
+static const unsigned int params[] = {
+HVM_PARAM_STORE_PFN,
+HVM_PARAM_IOREQ_PFN,
+HVM_PARAM_BUFIOREQ_PFN,
+HVM_PARAM_PAGING_RING_PF

[Xen-devel] [PATCH RFC v3 08/12] Migration with Local Disks Mirroring: New stream phase type for libxl streams

2017-12-04 Thread Bruno Alvisio
The libxl streams are classified by a stream phase parameter (stream_phase):

0. DEFAULT: This is the stream phase when no local disks are being mirrored as
part of the domain save or restore flow. (=0)

1. POST_MIRROR_DISKS: This stream phase happens during the migration flow after
the disks have been completely mirrored. In time order, this is the second libxl
stream of the migration flow. (=1)

2. PRE_MIRROR_DISKS: This stream happens before the disks start to be mirrored
to the destination. In time order, this is the first libxl stream of the
migration flow. (=2)

libxl__xc_mirror_disks_restore_returned is the callback function in the
libxl_read_stream that is registered for the return of libxc_mirror_disks
stream.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 tools/libxc/include/xenguest.h   |  3 ++-
 tools/libxc/xc_nomigrate.c   |  3 ++-
 tools/libxc/xc_sr_restore.c  |  3 ++-
 tools/libxl/libxl_colo_restore.c |  4 ++--
 tools/libxl/libxl_internal.h | 12 +++-
 tools/libxl/libxl_save_callout.c | 13 +
 tools/libxl/libxl_save_helper.c  |  5 -
 tools/libxl/libxl_stream_read.c  | 24 ++--
 tools/libxl/libxl_types.idl  |  6 ++
 9 files changed, 60 insertions(+), 13 deletions(-)

diff --git a/tools/libxc/include/xenguest.h b/tools/libxc/include/xenguest.h
index b4b2e19..014dee0 100644
--- a/tools/libxc/include/xenguest.h
+++ b/tools/libxc/include/xenguest.h
@@ -199,7 +199,8 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
   unsigned long *console_mfn, uint32_t console_domid,
   unsigned int hvm, unsigned int pae,
   xc_migration_stream_t stream_type,
-  struct restore_callbacks *callbacks, int send_back_fd);
+  struct restore_callbacks *callbacks, int send_back_fd,
+  int stream_phase);
 
 /**
  * This function will create a domain for a paravirtualized Linux
diff --git a/tools/libxc/xc_nomigrate.c b/tools/libxc/xc_nomigrate.c
index 6d6169d..75fe560 100644
--- a/tools/libxc/xc_nomigrate.c
+++ b/tools/libxc/xc_nomigrate.c
@@ -34,7 +34,8 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t 
dom,
   unsigned long *console_mfn, uint32_t console_domid,
   unsigned int hvm, unsigned int pae,
   xc_migration_stream_t stream_type,
-  struct restore_callbacks *callbacks, int send_back_fd)
+  struct restore_callbacks *callbacks, int send_back_fd,
+  int stream_phase)
 {
 errno = ENOSYS;
 return -1;
diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
index ea7b033..7f74d28 100644
--- a/tools/libxc/xc_sr_restore.c
+++ b/tools/libxc/xc_sr_restore.c
@@ -829,7 +829,8 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
   unsigned long *console_gfn, uint32_t console_domid,
   unsigned int hvm, unsigned int pae,
   xc_migration_stream_t stream_type,
-  struct restore_callbacks *callbacks, int send_back_fd)
+  struct restore_callbacks *callbacks, int send_back_fd,
+  int stream_phase)
 {
 xen_pfn_t nr_pfns;
 struct xc_sr_context ctx =
diff --git a/tools/libxl/libxl_colo_restore.c b/tools/libxl/libxl_colo_restore.c
index 0c535bd..a45bf51 100644
--- a/tools/libxl/libxl_colo_restore.c
+++ b/tools/libxl/libxl_colo_restore.c
@@ -132,7 +132,7 @@ static void colo_resume_vm(libxl__egc *egc,
 return;
 }
 
-libxl__xc_domain_restore_done(egc, dcs, 0, 0, 0);
+libxl__xc_domain_restore_done(egc, dcs, dcs->srs, 0, 0, 0);
 
 return;
 }
@@ -325,7 +325,7 @@ void libxl__colo_restore_teardown(libxl__egc *egc, void 
*dcs_void,
 /* crcs->status is LIBXL_COLO_SETUPED */
 dcs->srs.completion_callback = NULL;
 }
-libxl__xc_domain_restore_done(egc, dcs, ret, retval, errnoval);
+libxl__xc_domain_restore_done(egc, dcs, dcs->srs, ret, retval, errnoval);
 
 if (crs->qdisk_setuped) {
 libxl__qmp_stop_replication(gc, crs->domid, false);
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index feb9370..76bbe48 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3825,13 +3825,23 @@ _hidden int libxl__restore_emulator_xenstore_data
 _hidden void libxl__xc_domain_restore(libxl__egc *egc,
   libxl__domain_create_state *dcs,
   libxl__save_helper_state *shs,
-  int hvm, int pae);
+  int hvm, int pae, int stream_phase);
 /* If rc==0 then retval is the return value from xc_domain_save
  * and errnoval is the errno value it provided.
  * If rc!=0, retval and errnoval ar

[Xen-devel] [PATCH RFC v3 03/12] Migration with Local Disks Mirroring: Refactored migrate_read_fixedmessage

2017-12-04 Thread Bruno Alvisio
The function migrate_fixed_message is going to be used in the libxl create and
save flow for event synchronization during migration. It needs to be accessible
from libxl_create and libxl_dom_save and thus it is moved to libxl_utils.

Signed-off-by: Bruno Alvisio <bruno.alvi...@gmail.com>
---
 tools/libxl/libxl_utils.c | 21 +++
 tools/libxl/libxl_utils.h |  3 +++
 tools/xl/xl_migrate.c | 52 +++
 3 files changed, 40 insertions(+), 36 deletions(-)

diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c
index 507ee56..5139320 100644
--- a/tools/libxl/libxl_utils.c
+++ b/tools/libxl/libxl_utils.c
@@ -510,6 +510,27 @@ int libxl__read_sysfs_file_contents(libxl__gc *gc, const 
char *filename,
 READ_WRITE_EXACTLY(read, 1, /* */)
 READ_WRITE_EXACTLY(write, 0, const)
 
+int libxl_read_fixedmessage(libxl_ctx *ctx, int fd, const void *msg, int msgsz,
+const char *what, const char *rune)
+{
+char buf[msgsz];
+const char *stream;
+int rc;
+
+stream = rune ? "migration receiver stream" : "migration stream";
+rc = libxl_read_exactly(ctx, fd, buf, msgsz, stream, what);
+if (rc) return 1;
+
+if (memcmp(buf, msg, msgsz)) {
+fprintf(stderr, "%s contained unexpected data instead of %s\n",
+stream, what);
+if (rune)
+fprintf(stderr, "(command run was: %s )\n", rune);
+return 1;
+}
+return 0;
+}
+
 int libxl__remove_file(libxl__gc *gc, const char *path)
 {
 for (;;) {
diff --git a/tools/libxl/libxl_utils.h b/tools/libxl/libxl_utils.h
index 9e743dc..d1e80ef 100644
--- a/tools/libxl/libxl_utils.h
+++ b/tools/libxl/libxl_utils.h
@@ -56,6 +56,9 @@ int libxl_write_exactly(libxl_ctx *ctx, int fd, const void 
*data,
* logged using filename (which is only used for logging) and what
* (which may be 0). */
 
+int libxl_read_fixedmessage(libxl_ctx *ctx, int fd, const void *msg, int msgsz,
+const char *what, const char *rune);
+
 int libxl_pipe(libxl_ctx *ctx, int pipes[2]);
   /* Just like pipe(2), but log errors. */
 
diff --git a/tools/xl/xl_migrate.c b/tools/xl/xl_migrate.c
index 1f0e87d..33d39e8 100644
--- a/tools/xl/xl_migrate.c
+++ b/tools/xl/xl_migrate.c
@@ -68,26 +68,6 @@ static pid_t create_migration_child(const char *rune, int 
*send_fd,
 return child;
 }
 
-static int migrate_read_fixedmessage(int fd, const void *msg, int msgsz,
- const char *what, const char *rune) {
-char buf[msgsz];
-const char *stream;
-int rc;
-
-stream = rune ? "migration receiver stream" : "migration stream";
-rc = libxl_read_exactly(ctx, fd, buf, msgsz, stream, what);
-if (rc) return 1;
-
-if (memcmp(buf, msg, msgsz)) {
-fprintf(stderr, "%s contained unexpected data instead of %s\n",
-stream, what);
-if (rune)
-fprintf(stderr, "(command run was: %s )\n", rune);
-return 1;
-}
-return 0;
-}
-
 static void migration_child_report(int recv_fd) {
 pid_t child;
 int status, sr;
@@ -162,9 +142,9 @@ static void migrate_do_preamble(int send_fd, int recv_fd, 
pid_t child,
 exit(EXIT_FAILURE);
 }
 
-rc = migrate_read_fixedmessage(recv_fd, migrate_receiver_banner,
-   sizeof(migrate_receiver_banner)-1,
-   "banner", rune);
+rc = libxl_read_fixedmessage(ctx, recv_fd, migrate_receiver_banner,
+ sizeof(migrate_receiver_banner)-1,
+ "banner", rune);
 if (rc) {
 close(send_fd);
 migration_child_report(recv_fd);
@@ -219,9 +199,9 @@ static void migrate_domain(uint32_t domid, const char 
*rune, int debug,
 // Should only be printed when debugging as it's a bit messy with
 // progress indication.
 
-rc = migrate_read_fixedmessage(recv_fd, migrate_receiver_ready,
-   sizeof(migrate_receiver_ready),
-   "ready message", rune);
+rc = libxl_read_fixedmessage(ctx, recv_fd, migrate_receiver_ready,
+ sizeof(migrate_receiver_ready),
+ "ready message", rune);
 if (rc) goto failed_resume;
 
 xtl_stdiostream_adjust_flags(logger, 0, XTL_STDIOSTREAM_HIDE_PROGRESS);
@@ -251,9 +231,9 @@ static void migrate_domain(uint32_t domid, const char 
*rune, int debug,
  "migration stream", "GO message");
 if (rc) goto failed_badly;
 
-rc = migrate_read_fixedmessage(recv_fd, migrate_report,
-   sizeof(migrate_report),
-   "success/failure report message", rune);
+rc