@@ -325,12 +325,8 @@ void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn,
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,
+int xc_dom_gnttab_seed(xc_interface *xch, domid_t guest_domid,
+ bool is_hvm,
xen_pfn_t console_gmfn,
xen_pfn_t xenstore_gmfn,
domid_t console_domid,
@@ -282,11 +282,29 @@ static xen_pfn_t xc_dom_gnttab_setup(xc_interface *xch, domid_t domid)
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)
+static void xc_dom_set_gnttab_entry(xc_interface *xch,
+ grant_entry_v1_t *gnttab,
+ unsigned int idx,
+ domid_t guest_domid,
+ domid_t backend_domid,
+ xen_pfn_t backend_gmfn)
+{
+ if ( guest_domid == backend_domid || backend_gmfn == -1)
+ return;
+
+ xc_dom_printf(xch, "%s: [%u] -> 0x%"PRI_xen_pfn,
+ __FUNCTION__, idx, backend_gmfn);
+
+ gnttab[idx].flags = GTF_permit_access;
+ gnttab[idx].domid = backend_domid;
+ gnttab[idx].frame = backend_gmfn;
+}
+
+static int compat_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;
@@ -310,18 +328,10 @@ int xc_dom_gnttab_seed(xc_interface *xch, domid_t domid,
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;
- }
+ xc_dom_set_gnttab_entry(xch, gnttab, GNTTAB_RESERVED_CONSOLE,
+ domid, console_domid, console_gmfn);
+ xc_dom_set_gnttab_entry(xch, gnttab, GNTTAB_RESERVED_XENSTORE,
+ domid, xenstore_domid, xenstore_gmfn);
if ( munmap(gnttab, PAGE_SIZE) == -1 )
{
@@ -339,11 +349,11 @@ int xc_dom_gnttab_seed(xc_interface *xch, domid_t domid,
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)
+static int compat_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;
xen_pfn_t scratch_gpfn;
@@ -382,7 +392,7 @@ int xc_dom_gnttab_hvm_seed(xc_interface *xch, domid_t domid,
return -1;
}
- rc = xc_dom_gnttab_seed(xch, domid,
+ rc = compat_gnttab_seed(xch, domid,
console_gpfn, xenstore_gpfn,
console_domid, xenstore_domid);
if (rc != 0)
@@ -407,18 +417,56 @@ int xc_dom_gnttab_hvm_seed(xc_interface *xch, domid_t domid,
return 0;
}
-int xc_dom_gnttab_init(struct xc_dom_image *dom)
+int xc_dom_gnttab_seed(xc_interface *xch, domid_t guest_domid,
+ bool is_hvm, xen_pfn_t console_gmfn,
+ xen_pfn_t xenstore_gmfn, domid_t console_domid,
+ domid_t xenstore_domid)
{
- if ( xc_dom_translated(dom) ) {
- return xc_dom_gnttab_hvm_seed(dom->xch, dom->guest_domid,
- dom->console_pfn, dom->xenstore_pfn,
- dom->console_domid, dom->xenstore_domid);
- } else {
- return xc_dom_gnttab_seed(dom->xch, dom->guest_domid,
- xc_dom_p2m(dom, dom->console_pfn),
- xc_dom_p2m(dom, dom->xenstore_pfn),
- dom->console_domid, dom->xenstore_domid);
+ xenforeignmemory_handle* fmem = xch->fmem;
+ xenforeignmemory_resource_handle *fres;
+ void *addr = NULL;
+
+ fres = xenforeignmemory_map_resource(
+ fmem, guest_domid, XENMEM_resource_grant_table,
+ XENMEM_resource_grant_table_id_grant, 0, 1, &addr,
+ PROT_READ | PROT_WRITE, 0);
+ if ( !fres )
+ {
+ if ( errno == EOPNOTSUPP )
+ return is_hvm ?
+ compat_gnttab_hvm_seed(xch, guest_domid,
+ console_gmfn, xenstore_gmfn,
+ console_domid, xenstore_domid) :
+ compat_gnttab_seed(xch, guest_domid,
+ console_gmfn, xenstore_gmfn,
+ console_domid, xenstore_domid);
+
+ xc_dom_panic(xch, XC_INTERNAL_ERROR,
+ "%s: failed to acquire grant table "
+ "[errno=%d]\n",
+ __FUNCTION__, errno);
+ return -1;
}
+
+ xc_dom_set_gnttab_entry(xch, addr, GNTTAB_RESERVED_CONSOLE,
+ guest_domid, console_domid, console_gmfn);
+ xc_dom_set_gnttab_entry(xch, addr, GNTTAB_RESERVED_XENSTORE,
+ guest_domid, xenstore_domid, xenstore_gmfn);
+
+ xenforeignmemory_unmap_resource(fmem, fres);
+
+ return 0;
+}
+
+int xc_dom_gnttab_init(struct xc_dom_image *dom)
+{
+ bool is_hvm = xc_dom_translated(dom);
+ xen_pfn_t console_gmfn = xc_dom_p2m(dom, dom->console_pfn);
+ xen_pfn_t xenstore_gmfn = xc_dom_p2m(dom, dom->xenstore_pfn);
+
+ return xc_dom_gnttab_seed(dom->xch, dom->guest_domid, is_hvm,
+ console_gmfn, xenstore_gmfn,
+ dom->console_domid, dom->xenstore_domid);
}
/*
@@ -207,11 +207,11 @@ static int x86_hvm_stream_complete(struct xc_sr_context *ctx)
return rc;
}
- rc = xc_dom_gnttab_hvm_seed(xch, ctx->domid,
- ctx->restore.console_gfn,
- ctx->restore.xenstore_gfn,
- ctx->restore.console_domid,
- ctx->restore.xenstore_domid);
+ rc = xc_dom_gnttab_seed(xch, ctx->domid, true,
+ ctx->restore.console_gfn,
+ ctx->restore.xenstore_gfn,
+ ctx->restore.console_domid,
+ ctx->restore.xenstore_domid);
if ( rc )
{
PERROR("Failed to seed grant table");
@@ -1104,7 +1104,7 @@ static int x86_pv_stream_complete(struct xc_sr_context *ctx)
if ( rc )
return rc;
- rc = xc_dom_gnttab_seed(xch, ctx->domid,
+ rc = xc_dom_gnttab_seed(xch, ctx->domid, false,
ctx->restore.console_gfn,
ctx->restore.xenstore_gfn,
ctx->restore.console_domid,
@@ -903,7 +903,6 @@ static int hvm_build_set_params(xc_interface *handle, uint32_t domid,
*store_mfn = str_mfn;
*console_mfn = cons_mfn;
- xc_dom_gnttab_hvm_seed(handle, domid, *console_mfn, *store_mfn, console_domid, store_domid);
return 0;
}
@@ -800,9 +800,9 @@ static PyObject *pyxc_gnttab_hvm_seed(XcObject *self,
&console_domid, &xenstore_domid) )
return NULL;
- if ( xc_dom_gnttab_hvm_seed(self->xc_handle, dom,
- console_gmfn, xenstore_gmfn,
- console_domid, xenstore_domid) != 0 )
+ if ( xc_dom_gnttab_seed(self->xc_handle, dom, true,
+ console_gmfn, xenstore_gmfn,
+ console_domid, xenstore_domid) != 0 )
return pyxc_error_to_exception(self->xc_handle);
return Py_None;