(Also seed grant table with grant of console page to consoled domain to support
creation of a console stub domain in the future.)
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. At this stage, the grant
entries just give access to domain 0 (addressed in a later patch).
This depends on Samuel's XENMEM_remove_from_physmap.
This has not been tested with regular or live migration, or anything too
weird. I did test pausing and unpausing pv and hvm domains at some
point.
TODO: Keir says not to call setup_table for hvm domains. It's a no-op
in the hypervisor currently.
TODO: We don't want to even alloc the xenstore page for the xenstore
domain, since it won't use it all. Theoretically, you might have the
same thing with a console domain. The easiest way to handle this is to
make {console,xenstore}_domid global and compare the domid we're
allocating a page for to those.
A previous version of this patch was sent to xen-devel. See
http://lists.xensource.com/archives/html/xen-devel/2008-07/msg00610.html
Derek Murray is particularly interested in this, and previously made a
similar patch series but instead modified the hypervisor to do the
seeding.
Signed-off-by: Diego Ongaro <diego.ongaro@xxxxxxxxxx>
Signed-off-by: Alex Zeffertt <alex.zeffertt@xxxxxxxxxxxxx>
---
diff -r c27d56b60dad tools/libxc/xc_dom.h
--- a/tools/libxc/xc_dom.h Wed Feb 25 16:02:57 2009 +0000
+++ b/tools/libxc/xc_dom.h Thu Feb 26 11:38:57 2009 +0000
@@ -179,6 +179,12 @@
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(int xc_handle, uint32_t domid,
+ unsigned long xenstore_gpfn);
+int xc_dom_gnttab_seed(int xc_handle, uint32_t domid,
+ unsigned long console_gmfn,
+ unsigned long xenstore_gmfn);
/* --- debugging bits ---------------------------------------------- */
diff -r c27d56b60dad tools/libxc/xc_dom_boot.c
--- a/tools/libxc/xc_dom_boot.c Wed Feb 25 16:02:57 2009 +0000
+++ b/tools/libxc/xc_dom_boot.c Thu Feb 26 11:38:57 2009 +0000
@@ -20,6 +20,7 @@
#include "xg_private.h"
#include "xc_dom.h"
#include <xen/hvm/params.h>
+#include <xen/grant_table.h>
/* ------------------------------------------------------------------------ */
@@ -254,6 +255,160 @@
return rc;
}
+static unsigned long xc_dom_gnttab_setup(int xc_handle, uint32_t domid)
+{
+ DECLARE_HYPERCALL;
+ gnttab_setup_table_t setup_table;
+ unsigned long gmfn = -1;
+ int rc;
+
+ setup_table.dom = domid;
+ setup_table.nr_frames = 1;
+ set_xen_guest_handle(setup_table.frame_list, &gmfn);
+ 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(xc_handle, &hypercall);
+ if ( rc != 0 || setup_table.status != GNTST_okay )
+ {
+ xc_dom_panic(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(int xc_handle, 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_t *gnttab;
+
+ /* TODO: don't hard-code these */
+ console_domid = 0;
+ xenstore_domid = 0;
+
+ gnttab_gmfn = xc_dom_gnttab_setup(xc_handle, domid);
+ if ( gnttab_gmfn == -1 )
+ return -1;
+
+ gnttab = xc_map_foreign_range(xc_handle,
+ domid,
+ PAGE_SIZE,
+ PROT_READ|PROT_WRITE,
+ gnttab_gmfn);
+ if ( gnttab == NULL )
+ {
+ xc_dom_panic(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(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(int xc_handle, uint32_t domid,
+ unsigned long xenstore_gpfn)
+{
+#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 = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
+ if ( rc != 0 )
+ {
+ xc_dom_panic(XC_INTERNAL_ERROR,
+ "%s: failed to add gnttab to physmap "
+ "[errno=%d]\n",
+ __FUNCTION__, errno);
+ return -1;
+ }
+
+ rc = xc_dom_gnttab_seed(xc_handle, domid,
+ -1, xenstore_gpfn);
+ if (rc != 0)
+ {
+ xc_dom_panic(XC_INTERNAL_ERROR,
+ "%s: failed to seed gnttab entries\n",
+ __FUNCTION__);
+ (void) xc_memory_op(xc_handle, XENMEM_remove_from_physmap, &xrfp);
+ return -1;
+ }
+
+ rc = xc_memory_op(xc_handle, XENMEM_remove_from_physmap, &xrfp);
+ if (rc != 0)
+ {
+ xc_dom_panic(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->guest_xc, dom->guest_domid,
+ console_gmfn, xenstore_gmfn);
+}
+
/*
* Local variables:
* mode: C
diff -r c27d56b60dad tools/libxc/xc_dom_compat_linux.c
--- a/tools/libxc/xc_dom_compat_linux.c Wed Feb 25 16:02:57 2009 +0000
+++ b/tools/libxc/xc_dom_compat_linux.c Thu Feb 26 11:38:57 2009 +0000
@@ -47,6 +47,8 @@
if ( (rc = xc_dom_build_image(dom)) != 0 )
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);
diff -r c27d56b60dad tools/libxc/xc_domain_restore.c
--- a/tools/libxc/xc_domain_restore.c Wed Feb 25 16:02:57 2009 +0000
+++ b/tools/libxc/xc_domain_restore.c Thu Feb 26 11:38:57 2009 +0000
@@ -778,6 +778,13 @@
goto out;
}
+ rc = xc_dom_gnttab_hvm_seed(xc_handle, dom, *store_mfn);
+ if (rc != 0)
+ {
+ ERROR("error seeding grant table");
+ goto out;
+ }
+
/* HVM success! */
rc = 0;
goto out;
@@ -1205,6 +1212,15 @@
memcpy(live_p2m, p2m, p2m_size * sizeof(xen_pfn_t));
munmap(live_p2m, P2M_FL_ENTRIES * PAGE_SIZE);
+ /* TODO: what about non-hvm but auto-translated? */
+ rc = xc_dom_gnttab_seed(xc_handle, dom,
+ *console_mfn, *store_mfn);
+ if (rc != 0)
+ {
+ ERROR("error seeding grant table");
+ goto out;
+ }
+
DPRINTF("Domain ready to be built.\n");
rc = 0;
diff -r c27d56b60dad tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c Wed Feb 25 16:02:57 2009 +0000
+++ b/tools/libxc/xc_hvm_build.c Thu Feb 26 11:38:57 2009 +0000
@@ -10,6 +10,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>
@@ -318,6 +319,12 @@
munmap(page0, PAGE_SIZE);
}
+ rc = xc_dom_gnttab_hvm_seed(xc_handle, dom,
+ special_pfn(SPECIALPAGE_XENSTORE));
+
+ if (rc != 0)
+ goto error_out;
+
free(page_array);
return 0;
diff -r c27d56b60dad xen/include/public/grant_table.h
--- a/xen/include/public/grant_table.h Wed Feb 25 16:02:57 2009 +0000
+++ b/xen/include/public/grant_table.h Thu Feb 26 11:38:57 2009 +0000
@@ -101,6 +101,12 @@
uint32_t frame;
};
typedef struct grant_entry grant_entry_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.
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|