[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 06/18] lib{xc, xl}: Seed grant tables with xenstore and console grants



From: Alex Zeffertt <alex.zeffertt@xxxxxxxxxxxxx>

This patch claims one reserved grant entry for the console and another
for the xenstore. It modifies the builder to fill in the grant table
entries for the console and the xenstore.

This has not been tested with any kind of migration.

Previous versions of this patch have been sent to xen-devel. See
http://lists.xensource.com/archives/html/xen-devel/2008-07/msg00610.html
http://lists.xensource.com/archives/html/xen-devel/2009-03/msg01491.html

Signed-off-by: Diego Ongaro <diego.ongaro@xxxxxxxxxx>
Signed-off-by: Alex Zeffertt <alex.zeffertt@xxxxxxxxxxxxx>
Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
---
 tools/libxc/xc_dom.h              |   13 +++
 tools/libxc/xc_dom_boot.c         |  164 +++++++++++++++++++++++++++++++++++++
 tools/libxc/xc_dom_compat_linux.c |    2 +
 tools/libxc/xc_domain_restore.c   |   17 ++++
 tools/libxc/xc_hvm_build.c        |    1 +
 tools/libxl/libxl_dom.c           |   17 ++++-
 tools/libxl/libxl_internal.h      |    2 +
 xen/include/public/grant_table.h  |    6 ++
 8 files changed, 220 insertions(+), 2 deletions(-)

diff --git a/tools/libxc/xc_dom.h b/tools/libxc/xc_dom.h
index e72f066..6c36403 100644
--- a/tools/libxc/xc_dom.h
+++ b/tools/libxc/xc_dom.h
@@ -106,7 +106,9 @@ struct xc_dom_image {
     /* misc xen domain config stuff */
     unsigned long flags;
     unsigned int console_evtchn;
+    unsigned int console_domid;
     unsigned int xenstore_evtchn;
+    unsigned int xenstore_domid;
     xen_pfn_t shared_info_mfn;
 
     xc_interface *xch;
@@ -200,6 +202,17 @@ void *xc_dom_boot_domU_map(struct xc_dom_image *dom, 
xen_pfn_t pfn,
                            xen_pfn_t count);
 int xc_dom_boot_image(struct xc_dom_image *dom);
 int xc_dom_compat_check(struct xc_dom_image *dom);
+int xc_dom_gnttab_init(struct xc_dom_image *dom);
+int xc_dom_gnttab_hvm_seed(xc_interface *xch, uint32_t domid,
+                           unsigned long console_gmfn,
+                           unsigned long xenstore_gmfn,
+                           uint32_t console_domid,
+                           uint32_t xenstore_domid);
+int xc_dom_gnttab_seed(xc_interface *xch, uint32_t domid,
+                       unsigned long console_gmfn,
+                       unsigned long xenstore_gmfn,
+                       uint32_t console_domid,
+                       uint32_t xenstore_domid);
 
 /* --- debugging bits ---------------------------------------------- */
 
diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c
index 65f60df..1a55a6d 100644
--- a/tools/libxc/xc_dom_boot.c
+++ b/tools/libxc/xc_dom_boot.c
@@ -34,6 +34,7 @@
 #include "xg_private.h"
 #include "xc_dom.h"
 #include <xen/hvm/params.h>
+#include <xen/grant_table.h>
 
 /* ------------------------------------------------------------------------ */
 
@@ -275,6 +276,169 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
     return rc;
 }
 
+static unsigned long xc_dom_gnttab_setup(xc_interface *xch, uint32_t domid)
+{
+    DECLARE_HYPERCALL;
+    gnttab_setup_table_t setup_table;
+    DECLARE_HYPERCALL_BUFFER(unsigned long, gmfnp);
+    int rc;
+       unsigned long gmfn;
+
+    gmfnp = xc_hypercall_buffer_alloc(xch, gmfnp, sizeof(*gmfnp));
+       if (gmfnp == NULL)
+               return -1;
+
+    setup_table.dom = domid;
+    setup_table.nr_frames = 1;
+    set_xen_guest_handle(setup_table.frame_list, gmfnp);
+    setup_table.status = 0;
+
+    hypercall.op = __HYPERVISOR_grant_table_op;
+    hypercall.arg[0] = GNTTABOP_setup_table;
+    hypercall.arg[1] = (unsigned long) &setup_table;
+    hypercall.arg[2] = 1;
+
+    rc = do_xen_hypercall(xch, &hypercall);
+       gmfn = *gmfnp;
+    xc_hypercall_buffer_free(xch, gmfnp);
+
+    if ( rc != 0 || setup_table.status != GNTST_okay )
+    {
+        xc_dom_panic(xch, XC_INTERNAL_ERROR,
+                     "%s: failed to setup domU grant table "
+                     "[errno=%d, status=%" PRId16 "]\n",
+                     __FUNCTION__, rc != 0 ? errno : 0, setup_table.status);
+        return -1;
+    }
+
+    return gmfn;
+}
+
+int xc_dom_gnttab_seed(xc_interface *xch, uint32_t domid,
+                       unsigned long console_gmfn,
+                       unsigned long xenstore_gmfn,
+                       uint32_t console_domid,
+                       uint32_t xenstore_domid)
+{
+
+    unsigned long gnttab_gmfn;
+    grant_entry_v1_t *gnttab;
+
+    gnttab_gmfn = xc_dom_gnttab_setup(xch, domid);
+    if ( gnttab_gmfn == -1 )
+        return -1;
+
+    gnttab = xc_map_foreign_range(xch,
+                                  domid,
+                                  PAGE_SIZE,
+                                  PROT_READ|PROT_WRITE,
+                                  gnttab_gmfn);
+    if ( gnttab == NULL )
+    {
+        xc_dom_panic(xch, XC_INTERNAL_ERROR,
+                     "%s: failed to map domU grant table "
+                     "[errno=%d]\n",
+                     __FUNCTION__, errno);
+        return -1;
+    }
+
+    if ( domid != console_domid  && console_gmfn != -1)
+    {
+        gnttab[GNTTAB_RESERVED_CONSOLE].flags = GTF_permit_access;
+        gnttab[GNTTAB_RESERVED_CONSOLE].domid = console_domid;
+        gnttab[GNTTAB_RESERVED_CONSOLE].frame = console_gmfn;
+    }
+    if ( domid != xenstore_domid && xenstore_gmfn != -1)
+    {
+        gnttab[GNTTAB_RESERVED_XENSTORE].flags = GTF_permit_access;
+        gnttab[GNTTAB_RESERVED_XENSTORE].domid = xenstore_domid;
+        gnttab[GNTTAB_RESERVED_XENSTORE].frame = xenstore_gmfn;
+    }
+
+    if ( munmap(gnttab, PAGE_SIZE) == -1 )
+    {
+        xc_dom_panic(xch, XC_INTERNAL_ERROR,
+                     "%s: failed to unmap domU grant table "
+                     "[errno=%d]\n",
+                     __FUNCTION__, errno);
+        return -1;
+    }
+
+    return 0;
+}
+
+int xc_dom_gnttab_hvm_seed(xc_interface *xch, uint32_t domid,
+                           unsigned long console_gpfn,
+                           unsigned long xenstore_gpfn,
+                           uint32_t console_domid,
+                           uint32_t xenstore_domid)
+{
+#define SCRATCH_PFN_GNTTAB 0xFFFFE
+
+    int rc;
+    struct xen_add_to_physmap xatp = {
+        .domid = domid,
+        .space = XENMAPSPACE_grant_table,
+        .idx   = 0, /* TODO: what's this? */
+        .gpfn  = SCRATCH_PFN_GNTTAB
+    };
+    struct xen_remove_from_physmap xrfp = {
+    .domid = domid,
+    .gpfn  = SCRATCH_PFN_GNTTAB
+    };
+
+    rc = do_memory_op(xch, XENMEM_add_to_physmap, &xatp, sizeof(xatp));
+    if ( rc != 0 )
+    {
+        xc_dom_panic(xch, XC_INTERNAL_ERROR,
+                     "%s: failed to add gnttab to physmap "
+                     "[errno=%d]\n",
+                     __FUNCTION__, errno);
+        return -1;
+    }
+
+    rc = xc_dom_gnttab_seed(xch, domid,
+                            console_gpfn, xenstore_gpfn,
+                            console_domid, xenstore_domid);
+    if (rc != 0)
+    {
+        xc_dom_panic(xch, XC_INTERNAL_ERROR,
+                     "%s: failed to seed gnttab entries\n",
+                     __FUNCTION__);
+        (void) do_memory_op(xch, XENMEM_remove_from_physmap, &xrfp, 
sizeof(xrfp));
+        return -1;
+    }
+
+    rc = do_memory_op(xch, XENMEM_remove_from_physmap, &xrfp, sizeof(xrfp));
+    if (rc != 0)
+    {
+        xc_dom_panic(xch, XC_INTERNAL_ERROR,
+                     "%s: failed to remove gnttab from physmap "
+                     "[errno=%d]\n",
+                     __FUNCTION__, errno);
+        return -1;
+    }
+
+    return 0;
+}
+
+int xc_dom_gnttab_init(struct xc_dom_image *dom)
+{
+    unsigned long console_gmfn;
+    unsigned long xenstore_gmfn;
+    int autotranslated;
+
+    autotranslated = xc_dom_feature_translated(dom);
+    console_gmfn = autotranslated ?
+           dom->console_pfn : xc_dom_p2m_host(dom, dom->console_pfn);
+    xenstore_gmfn = autotranslated ?
+           dom->xenstore_pfn : xc_dom_p2m_host(dom, dom->xenstore_pfn);
+
+    return xc_dom_gnttab_seed(dom->xch, dom->guest_domid,
+                              console_gmfn, xenstore_gmfn,
+                              dom->console_domid, dom->xenstore_domid);
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libxc/xc_dom_compat_linux.c 
b/tools/libxc/xc_dom_compat_linux.c
index 0e78842..2183a3b 100644
--- a/tools/libxc/xc_dom_compat_linux.c
+++ b/tools/libxc/xc_dom_compat_linux.c
@@ -62,6 +62,8 @@ static int xc_linux_build_internal(struct xc_dom_image *dom,
         goto out;
     if ( (rc = xc_dom_boot_image(dom)) != 0 )
         goto out;
+    if ( (rc = xc_dom_gnttab_init(dom)) != 0)
+        goto out;
 
     *console_mfn = xc_dom_p2m_host(dom, dom->console_pfn);
     *store_mfn = xc_dom_p2m_host(dom, dom->xenstore_pfn);
diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
index 3fda6f8..23619da 100644
--- a/tools/libxc/xc_domain_restore.c
+++ b/tools/libxc/xc_domain_restore.c
@@ -2018,6 +2018,15 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
         memcpy(ctx->live_p2m, ctx->p2m, dinfo->p2m_size * sizeof(xen_pfn_t));
     munmap(ctx->live_p2m, P2M_FL_ENTRIES * PAGE_SIZE);
 
+/* TODO don't hardcode zero here */
+    rc = xc_dom_gnttab_seed(xch, dom,
+                            *console_mfn, *store_mfn, 0, 0);
+    if (rc != 0)
+    {
+        ERROR("error seeding grant table");
+        goto out;
+    }
+
     DPRINTF("Domain ready to be built.\n");
     rc = 0;
     goto out;
@@ -2076,6 +2085,14 @@ int xc_domain_restore(xc_interface *xch, int io_fd, 
uint32_t dom,
         goto out;
     }
 
+       /* TODO don't hardcode zero here */
+    rc = xc_dom_gnttab_hvm_seed(xch, dom, *console_mfn, *store_mfn, 0, 0);
+    if (rc != 0)
+    {
+        ERROR("error seeding grant table");
+        goto out;
+    }
+
     /* HVM success! */
     rc = 0;
 
diff --git a/tools/libxc/xc_hvm_build.c b/tools/libxc/xc_hvm_build.c
index 9831bab..453f8a5 100644
--- a/tools/libxc/xc_hvm_build.c
+++ b/tools/libxc/xc_hvm_build.c
@@ -24,6 +24,7 @@
 
 #include "xg_private.h"
 #include "xc_private.h"
+#include "xc_dom.h"
 
 #include <xen/foreign/x86_32.h>
 #include <xen/foreign/x86_64.h>
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index e12d687..7f7bca6 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -104,7 +104,9 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
         xc_shadow_control(ctx->xch, domid, 
XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION, NULL, 0, &shadow, 0, NULL);
     }
 
+    state->store_domid = info->xenstore_dom;
     state->store_port = xc_evtchn_alloc_unbound(ctx->xch, domid, 
info->xenstore_dom);
+    state->console_domid = info->console_dom;
     state->console_port = xc_evtchn_alloc_unbound(ctx->xch, domid, 
info->console_dom);
     state->vm_generationid_addr = 0;
     return 0;
@@ -223,7 +225,9 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
 
     dom->flags = flags;
     dom->console_evtchn = state->console_port;
+    dom->console_domid = state->console_domid;
     dom->xenstore_evtchn = state->store_port;
+    dom->xenstore_domid = state->store_domid;
 
     if ( (ret = xc_dom_boot_xen_init(dom, ctx->xch, domid)) != 0 ) {
         LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_boot_xen_init failed");
@@ -249,6 +253,10 @@ int libxl__build_pv(libxl__gc *gc, uint32_t domid,
         LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_boot_image failed");
         goto out;
     }
+    if ( (ret = xc_dom_gnttab_init(dom)) != 0 ) {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "xc_dom_gnttab_init failed");
+        goto out;
+    }
 
     state->console_mfn = xc_dom_p2m_host(dom, dom->console_pfn);
     state->store_mfn = xc_dom_p2m_host(dom, dom->xenstore_pfn);
@@ -262,7 +270,8 @@ out:
 static int hvm_build_set_params(xc_interface *handle, uint32_t domid,
                                 libxl_domain_build_info *info,
                                 int store_evtchn, unsigned long *store_mfn,
-                                int console_evtchn, unsigned long *console_mfn)
+                                int console_evtchn, unsigned long *console_mfn,
+                                uint32_t store_domid, uint32_t console_domid)
 {
     struct hvm_info_table *va_hvm;
     uint8_t *va_map, sum;
@@ -295,6 +304,8 @@ static int hvm_build_set_params(xc_interface *handle, 
uint32_t domid,
     xc_set_hvm_param(handle, domid, HVM_PARAM_NESTEDHVM, 
info->u.hvm.nested_hvm);
     xc_set_hvm_param(handle, domid, HVM_PARAM_STORE_EVTCHN, store_evtchn);
     xc_set_hvm_param(handle, domid, HVM_PARAM_CONSOLE_EVTCHN, console_evtchn);
+
+    xc_dom_gnttab_hvm_seed(handle, domid, *console_mfn, *store_mfn, 
console_domid, store_domid);
     return 0;
 }
 
@@ -348,7 +359,9 @@ int libxl__build_hvm(libxl__gc *gc, uint32_t domid,
         goto out;
     }
     ret = hvm_build_set_params(ctx->xch, domid, info, state->store_port,
-                               &state->store_mfn, state->console_port, 
&state->console_mfn);
+                               &state->store_mfn, state->console_port,
+                               &state->console_mfn, state->store_domid,
+                               state->console_domid);
     if (ret) {
         LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, ret, "hvm build set params 
failed");
         goto out;
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 288c03c..97ead08 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -219,9 +219,11 @@ _hidden int libxl__domain_shutdown_reason(libxl__gc *gc, 
uint32_t domid);
     libxl__domain_type((gc), (domid)) == LIBXL_DOMAIN_TYPE_##type
 typedef struct {
     uint32_t store_port;
+    uint32_t store_domid;
     unsigned long store_mfn;
 
     uint32_t console_port;
+    uint32_t console_domid;
     unsigned long console_mfn;
     unsigned long vm_generationid_addr;
 } libxl__domain_build_state;
diff --git a/xen/include/public/grant_table.h b/xen/include/public/grant_table.h
index 0bf20bc..36d1ac7 100644
--- a/xen/include/public/grant_table.h
+++ b/xen/include/public/grant_table.h
@@ -117,6 +117,12 @@ struct grant_entry_v1 {
 };
 typedef struct grant_entry_v1 grant_entry_v1_t;
 
+/* External tools reserve first few grant table entries. */
+#define GNTTAB_NR_RESERVED_ENTRIES     8
+#define GNTTAB_RESERVED_CONSOLE        0
+#define GNTTAB_RESERVED_XENSTORE       1
+/* (the next 6 are reserved for future use) */
+
 /*
  * Type of grant entry.
  *  GTF_invalid: This grant entry grants no privileges.
-- 
1.7.7.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.