aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xc_dom_boot.c
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 /tools/libxc/xc_dom_boot.c
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>
Diffstat (limited to 'tools/libxc/xc_dom_boot.c')
-rw-r--r--tools/libxc/xc_dom_boot.c156
1 files changed, 156 insertions, 0 deletions
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