|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v4 14/16] libs/guest: use new hypercall if available
From: Frediano Ziglio <frediano.ziglio@xxxxxxxxxx>
Use new hypercall if available, otherwise fall back to map+copy+unmap
sequence.
Signed-off-by: Frediano Ziglio <frediano.ziglio@xxxxxxxxxx>
---
tools/libs/guest/xg_sr_common.c | 47 ++++++++++++++++++++++++++-------
1 file changed, 38 insertions(+), 9 deletions(-)
diff --git a/tools/libs/guest/xg_sr_common.c b/tools/libs/guest/xg_sr_common.c
index a94e9dfbff..cb3e6a5658 100644
--- a/tools/libs/guest/xg_sr_common.c
+++ b/tools/libs/guest/xg_sr_common.c
@@ -156,11 +156,6 @@ static void __attribute__((unused)) build_assertions(void)
BUILD_BUG_ON(sizeof(struct xc_sr_rec_hvm_params) != 8);
}
-enum {
- foreigncopy_from,
- foreigncopy_to
-};
-
static int xg_foreignmemory_copy(xc_interface *xch, domid_t domid,
int dir, size_t nr_pages, void *buffer,
const xen_pfn_t foreign_pfns[nr_pages])
@@ -174,8 +169,42 @@ static int xg_foreignmemory_copy(xc_interface *xch,
domid_t domid,
return -1;
}
+ /*
+ * If foreign copy is supported, -1 not initialized, 0 not supported,
+ * 1 supported.
+ */
+ static char foreign_copy_supported = -1;
+
+ if ( foreign_copy_supported )
+ {
+ int rc;
+ privcmd_foreigncopy_t copy = {
+ .dom = domid,
+ .dir = dir,
+ .num = nr_pages,
+ .buffer = buffer,
+ };
+ DECLARE_HYPERCALL_BOUNCE_IN(foreign_pfns, nr_pages *
sizeof(xen_pfn_t));
+
+ if ( xc_hypercall_bounce_pre(xch, foreign_pfns) )
+ return -1;
+
+ copy.pfns = foreign_pfns;
+
+ rc = ioctl(xencall_fd(xch->xcall), IOCTL_PRIVCMD_FOREIGNCOPY, ©);
+ if ( foreign_copy_supported < 0 )
+ foreign_copy_supported =
+ (!rc || (errno != ENOTTY && errno != ENOSYS));
+
+ xc_hypercall_bounce_post(xch, foreign_pfns);
+
+ if ( foreign_copy_supported )
+ return rc;
+ }
+
+ /* Fallback, emulate. */
int err[nr_pages];
- const int prot = (dir == foreigncopy_from) ? PROT_READ :
PROT_READ|PROT_WRITE;
+ const int prot = (dir == XENMEM_foreigncopy_from) ? PROT_READ :
PROT_READ|PROT_WRITE;
void *p = xenforeignmemory_map(xch->fmem, domid, prot, nr_pages,
foreign_pfns, err);
if ( !p )
@@ -192,7 +221,7 @@ static int xg_foreignmemory_copy(xc_interface *xch, domid_t
domid,
return -1;
}
- if ( dir == foreigncopy_from )
+ if ( dir == XENMEM_foreigncopy_from )
memcpy(buffer, p, nr_pages * XC_PAGE_SIZE);
else
memcpy(p, buffer, nr_pages * XC_PAGE_SIZE);
@@ -204,7 +233,7 @@ int xg_foreignmemory_copy_from(xc_interface *xch, domid_t
dom,
size_t nr_pages, void *dest,
const xen_pfn_t source[nr_pages])
{
- return xg_foreignmemory_copy(xch, dom, foreigncopy_from,
+ return xg_foreignmemory_copy(xch, dom, XENMEM_foreigncopy_from,
nr_pages, dest, source);
}
@@ -212,7 +241,7 @@ int xg_foreignmemory_copy_to(xc_interface *xch, domid_t dom,
size_t nr_pages, const xen_pfn_t dest[nr_pages],
const void *source)
{
- return xg_foreignmemory_copy(xch, dom, foreigncopy_to,
+ return xg_foreignmemory_copy(xch, dom, XENMEM_foreigncopy_to,
nr_pages, (void *) source, dest);
}
--
2.54.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |