aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Zeffertt <alex.zeffertt@eu.citrix.com>2012-02-09 18:33:30 +0000
committerAlex Zeffertt <alex.zeffertt@eu.citrix.com>2012-02-09 18:33:30 +0000
commit6a2de353a969bdcb448ea977eca39401be312051 (patch)
tree34a84e2f65370b5eb1d7a44b9de51195c733e398
parent9b4964de7c6fa69a28688685bc9531f9408cf58b (diff)
downloadxen-6a2de353a969bdcb448ea977eca39401be312051.tar.gz
xen-6a2de353a969bdcb448ea977eca39401be312051.tar.bz2
xen-6a2de353a969bdcb448ea977eca39401be312051.zip
lib{xc,xl}: Seed grant tables with xenstore and console grants
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>
-rw-r--r--tools/libxc/xc_dom.h16
-rw-r--r--tools/libxc/xc_dom_boot.c156
-rw-r--r--tools/libxc/xc_dom_compat_linux.c2
-rw-r--r--tools/libxc/xc_domain_restore.c19
-rw-r--r--tools/libxc/xenguest.h3
-rw-r--r--tools/libxl/libxl_dom.c18
-rw-r--r--tools/xcutils/xc_restore.c4
7 files changed, 211 insertions, 7 deletions
diff --git a/tools/libxc/xc_dom.h b/tools/libxc/xc_dom.h
index e72f066f5d..2aef64af26 100644
--- a/tools/libxc/xc_dom.h
+++ b/tools/libxc/xc_dom.h
@@ -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 ---------------------------------------------- */
diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c
index 65f60df32f..a9a868c06e 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,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
diff --git a/tools/libxc/xc_dom_compat_linux.c b/tools/libxc/xc_dom_compat_linux.c
index 0e78842ef7..2183a3be23 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 3fda6f8c68..06bea86718 100644
--- a/tools/libxc/xc_domain_restore.c
+++ b/tools/libxc/xc_domain_restore.c
@@ -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;
diff --git a/tools/libxc/xenguest.h b/tools/libxc/xenguest.h
index 60263709ce..533e70279b 100644
--- a/tools/libxc/xenguest.h
+++ b/tools/libxc/xenguest.h
@@ -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);
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index e4961ebb52..60ed1d55ad 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -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 ) {
diff --git a/tools/xcutils/xc_restore.c b/tools/xcutils/xc_restore.c
index 63d53a88b0..e41a133732 100644
--- a/tools/xcutils/xc_restore.c
+++ b/tools/xcutils/xc_restore.c
@@ -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 )