|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v4 10/16] libs/guest: add xg_foreignmemory_copy_{from,to}
From: Frediano Ziglio <frediano.ziglio@xxxxxxxxxx>
This change prepare code to use a new "foreign copy" hypercall.
The new hypercall will copy memory from/to a foreign domain.
The new hypercall can be emulated with a sequence of:
- map foreign memory;
- copy memory;
- unmap foreign memory.
Signed-off-by: Frediano Ziglio <frediano.ziglio@xxxxxxxxxx>
---
tools/libs/guest/xg_sr_common.c | 60 +++++++++++++++++++++++++++++++++
tools/libs/guest/xg_sr_common.h | 8 +++++
2 files changed, 68 insertions(+)
diff --git a/tools/libs/guest/xg_sr_common.c b/tools/libs/guest/xg_sr_common.c
index 86c148c62f..a94e9dfbff 100644
--- a/tools/libs/guest/xg_sr_common.c
+++ b/tools/libs/guest/xg_sr_common.c
@@ -156,6 +156,66 @@ 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])
+{
+ if ( nr_pages == 0 )
+ return 0;
+
+ if ( !buffer || !foreign_pfns )
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ int err[nr_pages];
+ const int prot = (dir == foreigncopy_from) ? PROT_READ :
PROT_READ|PROT_WRITE;
+
+ void *p = xenforeignmemory_map(xch->fmem, domid, prot, nr_pages,
foreign_pfns, err);
+ if ( !p )
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ for ( size_t n = 0; n < nr_pages; ++n )
+ if ( err[n] )
+ {
+ xenforeignmemory_unmap(xch->fmem, p, nr_pages);
+ errno = -err[n];
+ return -1;
+ }
+
+ if ( dir == foreigncopy_from )
+ memcpy(buffer, p, nr_pages * XC_PAGE_SIZE);
+ else
+ memcpy(p, buffer, nr_pages * XC_PAGE_SIZE);
+
+ return xenforeignmemory_unmap(xch->fmem, p, nr_pages);
+}
+
+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,
+ nr_pages, dest, source);
+}
+
+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,
+ nr_pages, (void *) source, dest);
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_common.h
index e8452746e4..72c9511f38 100644
--- a/tools/libs/guest/xg_sr_common.h
+++ b/tools/libs/guest/xg_sr_common.h
@@ -553,6 +553,14 @@ static inline bool page_type_has_stream_data(uint32_t type)
}
}
+int xg_foreignmemory_copy_from(xc_interface *xch, domid_t dom,
+ size_t nr_pages, void *dest,
+ const xen_pfn_t source[nr_pages]);
+
+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);
+
#endif
/*
* Local variables:
--
2.54.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |