]> xenbits.xensource.com Git - xen.git/commitdiff
lib{xc,xl}: Seed grant tables with xenstore and console grants
authorAlex Zeffertt <alex.zeffertt@eu.citrix.com>
Thu, 9 Feb 2012 18:33:30 +0000 (18:33 +0000)
committerAlex Zeffertt <alex.zeffertt@eu.citrix.com>
Thu, 9 Feb 2012 18:33:30 +0000 (18:33 +0000)
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.

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@citrix.com>
Signed-off-by: Alex Zeffertt <alex.zeffertt@eu.citrix.com>
Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Committed-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
tools/libxc/xc_dom.h
tools/libxc/xc_dom_boot.c
tools/libxc/xc_dom_compat_linux.c
tools/libxc/xc_domain_restore.c
tools/libxc/xenguest.h
tools/libxl/libxl_dom.c
tools/xcutils/xc_restore.c

index e72f066f5db8e23486a3ed5f2ccd3bbc4c24c266..2aef64af263c8dbb2494d16c8d067b983462a4fc 100644 (file)
@@ -18,6 +18,9 @@
 
 #define INVALID_P2M_ENTRY   ((xen_pfn_t)-1)
 
+/* Scrach PFN for temporary mappings in HVM */
+#define SCRATCH_PFN_GNTTAB 0xFFFFE
+
 /* --- typedefs and structs ---------------------------------------- */
 
 typedef uint64_t xen_vaddr_t;
@@ -107,6 +110,8 @@ struct xc_dom_image {
     unsigned long flags;
     unsigned int console_evtchn;
     unsigned int xenstore_evtchn;
+    domid_t console_domid;
+    domid_t xenstore_domid;
     xen_pfn_t shared_info_mfn;
 
     xc_interface *xch;
@@ -200,6 +205,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, domid_t domid,
+                           xen_pfn_t console_gmfn,
+                           xen_pfn_t xenstore_gmfn,
+                           domid_t console_domid,
+                           domid_t xenstore_domid);
+int xc_dom_gnttab_seed(xc_interface *xch, domid_t domid,
+                       xen_pfn_t console_gmfn,
+                       xen_pfn_t xenstore_gmfn,
+                       domid_t console_domid,
+                       domid_t xenstore_domid);
 
 /* --- debugging bits ---------------------------------------------- */
 
index 65f60df32fd46cbc5e2fdb9b7f24cda557cac733..a9a868c06e98422f987d2af513e441b6b24123c4 100644 (file)
@@ -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,161 @@ int xc_dom_boot_image(struct xc_dom_image *dom)
     return rc;
 }
 
+static xen_pfn_t xc_dom_gnttab_setup(xc_interface *xch, domid_t domid)
+{
+    gnttab_setup_table_t setup;
+    DECLARE_HYPERCALL_BUFFER(xen_pfn_t, gmfnp);
+    int rc;
+    xen_pfn_t gmfn;
+
+    gmfnp = xc_hypercall_buffer_alloc(xch, gmfnp, sizeof(*gmfnp));
+    if (gmfnp == NULL)
+        return -1;
+
+    setup.dom = domid;
+    setup.nr_frames = 1;
+    set_xen_guest_handle(setup.frame_list, gmfnp);
+    setup.status = 0;
+
+    rc = xc_gnttab_op(xch, GNTTABOP_setup_table, &setup, sizeof(setup), 1);
+    gmfn = *gmfnp;
+    xc_hypercall_buffer_free(xch, gmfnp);
+
+    if ( rc != 0 || setup.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.status);
+        return -1;
+    }
+
+    return gmfn;
+}
+
+int xc_dom_gnttab_seed(xc_interface *xch, domid_t domid,
+                       xen_pfn_t console_gmfn,
+                       xen_pfn_t xenstore_gmfn,
+                       domid_t console_domid,
+                       domid_t xenstore_domid)
+{
+
+    xen_pfn_t 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, domid_t domid,
+                           xen_pfn_t console_gpfn,
+                           xen_pfn_t xenstore_gpfn,
+                           domid_t console_domid,
+                           domid_t xenstore_domid)
+{
+    int rc;
+    struct xen_add_to_physmap xatp = {
+        .domid = domid,
+        .space = XENMAPSPACE_grant_table,
+        .idx   = 0,
+        .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)
+{
+    xen_pfn_t console_gmfn;
+    xen_pfn_t 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
index 0e78842ef77c5dfc4f7a84d038ce28cb8d663f4c..2183a3be23d809fdfef24a185aec36d1b1486a9d 100644 (file)
@@ -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);
index 3fda6f8c6856b79bb8125333a1da41bb90b348a4..06bea8671839fb5d991bc6cc4c9e029b1ec3125f 100644 (file)
@@ -1259,7 +1259,8 @@ static int apply_batch(xc_interface *xch, uint32_t dom, struct restore_ctx *ctx,
 
 int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
                       unsigned int store_evtchn, unsigned long *store_mfn,
-                      unsigned int console_evtchn, unsigned long *console_mfn,
+                      domid_t store_domid, unsigned int console_evtchn,
+                      unsigned long *console_mfn, domid_t console_domid,
                       unsigned int hvm, unsigned int pae, int superpages,
                       int no_incr_generationid,
                       unsigned long *vm_generationid_addr)
@@ -2018,6 +2019,14 @@ 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);
 
+    rc = xc_dom_gnttab_seed(xch, dom, *console_mfn, *store_mfn,
+                            console_domid, store_domid);
+    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;
     }
 
+    rc = xc_dom_gnttab_hvm_seed(xch, dom, *console_mfn, *store_mfn,
+                                console_domid, store_domid);
+    if (rc != 0)
+    {
+        ERROR("error seeding grant table");
+        goto out;
+    }
+
     /* HVM success! */
     rc = 0;
 
index 60263709ce8544dcfec830d3ffc8c054106514bf..533e70279b5feef70f06c18f3458d3feb2128837 100644 (file)
@@ -79,7 +79,8 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter
  */
 int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
                       unsigned int store_evtchn, unsigned long *store_mfn,
-                      unsigned int console_evtchn, unsigned long *console_mfn,
+                      domid_t store_domid, unsigned int console_evtchn,
+                      unsigned long *console_mfn, domid_t console_domid,
                       unsigned int hvm, unsigned int pae, int superpages,
                       int no_incr_generationid,
                      unsigned long *vm_generationid_addr);
index e4961ebb527d5c6effd4771e817f4c2bf44aafeb..60ed1d55ad823604ab489f94fbc2056de1bd8839 100644 (file)
@@ -225,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");
@@ -251,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);
@@ -271,7 +277,8 @@ static unsigned long timer_mode(const libxl_domain_build_info *info)
 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,
+                                domid_t store_domid, domid_t console_domid)
 {
     struct hvm_info_table *va_hvm;
     uint8_t *va_map, sum;
@@ -304,6 +311,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;
 }
 
@@ -355,7 +364,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;
@@ -402,7 +413,8 @@ int libxl__domain_restore_common(libxl__gc *gc, uint32_t domid,
     }
     rc = xc_domain_restore(ctx->xch, fd, domid,
                            state->store_port, &state->store_mfn,
-                           state->console_port, &state->console_mfn,
+                           state->store_domid, state->console_port,
+                           &state->console_mfn, state->console_domid,
                            hvm, pae, superpages, no_incr_generationid,
                            &state->vm_generationid_addr);
     if ( rc ) {
index 63d53a88b0ac3cbdb396594f03d8d20917d1f77a..e41a1337327eb38d8014fa26d7f317e48312b62f 100644 (file)
@@ -45,8 +45,8 @@ main(int argc, char **argv)
     else
            superpages = !!hvm;
 
-    ret = xc_domain_restore(xch, io_fd, domid, store_evtchn, &store_mfn,
-                            console_evtchn, &console_mfn, hvm, pae, superpages,
+    ret = xc_domain_restore(xch, io_fd, domid, store_evtchn, &store_mfn, 0,
+                            console_evtchn, &console_mfn, 0, hvm, pae, superpages,
                             0, NULL);
 
     if ( ret == 0 )