[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] Re: [PATCH 2/3] libxc: add xc_gntshr_* functions
On Thu, Sep 01, 2011 at 12:22:17PM -0400, Daniel De Graaf wrote: > These functions and the xc_gntshr device (/dev/xen/gntalloc on linux) > allow applications to create pages shared with other domains. > > Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx> > --- > tools/libxc/xc_gnttab.c | 27 +++++++++ > tools/libxc/xc_linux_osdep.c | 121 > ++++++++++++++++++++++++++++++++++++++++++ > tools/libxc/xc_private.c | 13 +++++ > tools/libxc/xenctrl.h | 48 +++++++++++++++++ > tools/libxc/xenctrlosdep.h | 13 +++++ > 5 files changed, 222 insertions(+), 0 deletions(-) > > diff --git a/tools/libxc/xc_gnttab.c b/tools/libxc/xc_gnttab.c > index dc7aa0c..ffa3550 100644 > --- a/tools/libxc/xc_gnttab.c > +++ b/tools/libxc/xc_gnttab.c > @@ -204,6 +204,33 @@ int xc_gnttab_set_max_grants(xc_gnttab *xcg, uint32_t > count) > return xcg->ops->u.gnttab.set_max_grants(xcg, xcg->ops_handle, count); > } > > +void *xc_gntshr_share_pages(xc_gntshr *xcg, uint32_t domid, > + int count, uint32_t *refs, int writable) > +{ > + return xcg->ops->u.gntshr.share_pages(xcg, xcg->ops_handle, domid, > + count, refs, writable); > +} > + > +void *xc_gntshr_share_page_notify(xc_gntshr *xcg, uint32_t domid, > + uint32_t *ref, int writable, > + uint32_t notify_offset, > + evtchn_port_t notify_port) > +{ > + return xcg->ops->u.gntshr.share_page_notify(xcg, xcg->ops_handle, > + domid, ref, writable, notify_offset, notify_port); > +} > + > +/* > + * Unmaps the @count pages starting at @start_address, which were mapped by a > + * call to xc_gntshr_share_*. Never logs. > + */ > +int xc_gntshr_munmap(xc_gntshr *xcg, void *start_address, uint32_t count) > +{ > + return xcg->ops->u.gntshr.munmap(xcg, xcg->ops_handle, > + start_address, count); > +} > + > + > /* > * Local variables: > * mode: C > diff --git a/tools/libxc/xc_linux_osdep.c b/tools/libxc/xc_linux_osdep.c > index 8f7718f..871d37c 100644 > --- a/tools/libxc/xc_linux_osdep.c > +++ b/tools/libxc/xc_linux_osdep.c > @@ -34,6 +34,7 @@ > #include <xen/memory.h> > #include <xen/sys/evtchn.h> > #include <xen/sys/gntdev.h> > +#include <xen/sys/gntalloc.h> > > #include "xenctrl.h" > #include "xenctrlosdep.h" > @@ -718,6 +719,124 @@ static struct xc_osdep_ops linux_gnttab_ops = { > }, > }; > > +static xc_osdep_handle linux_gntshr_open(xc_gntshr *xcg) > +{ > + int fd = open(DEVXEN "gntalloc", O_RDWR); > + > + if ( fd == -1 ) > + return XC_OSDEP_OPEN_ERROR; > + > + return (xc_osdep_handle)fd; > +} > + > +static int linux_gntshr_close(xc_gntshr *xcg, xc_osdep_handle h) > +{ > + int fd = (int)h; > + return close(fd); > +} > + > +static void *linux_gntshr_share_pages(xc_gntshr *xch, xc_osdep_handle h, > + uint32_t domid, int count, > + uint32_t *refs, int writable) > +{ > + struct ioctl_gntalloc_alloc_gref *gref_info = NULL; > + int err; > + void *area = NULL; > + gref_info = malloc(sizeof(*gref_info) + count * sizeof(uint32_t)); > + if (!gref_info) > + return NULL; > + gref_info->domid = domid; > + gref_info->flags = writable ? GNTALLOC_FLAG_WRITABLE : 0; > + gref_info->count = count; > + > + err = ioctl((int)h, IOCTL_GNTALLOC_ALLOC_GREF, gref_info); > + if (err) { > + PERROR("linux_gntshr_share_pages: ioctl failed"); > + goto out; > + } > + > + area = mmap(NULL, count * XC_PAGE_SIZE, PROT_READ | PROT_WRITE, > + MAP_SHARED, (int)h, gref_info->index); > + > + if (area == MAP_FAILED) { > + area = NULL; > + PERROR("linux_gntshr_share_pages: mmap failed"); > + goto out; > + } > + > + memcpy(refs, gref_info->gref_ids, count * sizeof(uint32_t)); > + out: > + free(gref_info); > + return area; > +} > + > +static void *linux_gntshr_share_page_notify(xc_gntshr *xch, xc_osdep_handle > h, > + uint32_t domid, uint32_t *ref, > + int writable, uint32_t > notify_offset, > + evtchn_port_t notify_port) > +{ > + struct ioctl_gntalloc_alloc_gref gref_info; > + struct ioctl_gntalloc_unmap_notify notify; > + int err; > + int fd = (int)h; > + void *area = NULL; > + gref_info.domid = domid; > + gref_info.flags = writable ? GNTALLOC_FLAG_WRITABLE : 0; > + gref_info.count = 1; > + > + err = ioctl(fd, IOCTL_GNTALLOC_ALLOC_GREF, &gref_info); > + if (err) { > + PERROR("linux_gntshr_share_page_notify: ioctl failed"); > + goto out; > + } > + > + area = mmap(NULL, XC_PAGE_SIZE, PROT_READ | PROT_WRITE, > + MAP_SHARED, fd, gref_info.index); > + > + if (area == MAP_FAILED) { > + PERROR("linux_gntshr_share_page_notify: mmap failed"); > + area = NULL; > + goto out; > + } > + > + notify.index = gref_info.index; > + notify.action = 0; > + if (notify_offset >= 0) { > + notify.index += notify_offset; > + notify.action |= UNMAP_NOTIFY_CLEAR_BYTE; > + } > + if (notify_port >= 0) { > + notify.event_channel_port = notify_port; > + notify.action |= UNMAP_NOTIFY_SEND_EVENT; > + } > + if (notify.action && ioctl(fd, IOCTL_GNTALLOC_SET_UNMAP_NOTIFY, > ¬ify)) { > + PERROR("linux_gntshr_share_page_notify: ioctl SET_UNMAP_NOTIFY > failed"); Should we report to the caller that we can't set it up? Say by reporting via a bool (as in through the arguments )? > + } > + > + *ref = gref_info.gref_ids[0]; > + out: > + return area; > +} > + > + > +static int linux_gntshr_munmap(xc_gntshr *xcg, xc_osdep_handle h, > + void *start_address, uint32_t count) > +{ > + return munmap(start_address, count); > +} > + > +static struct xc_osdep_ops linux_gntshr_ops = { > + .open = &linux_gntshr_open, > + .close = &linux_gntshr_close, > + > + .u.gntshr = { > + .share_pages = &linux_gntshr_share_pages, > + .share_page_notify = &linux_gntshr_share_page_notify, > + .munmap = &linux_gntshr_munmap, > + }, > +}; > + > + > static struct xc_osdep_ops *linux_osdep_init(xc_interface *xch, enum > xc_osdep_type type) > { > switch ( type ) > @@ -728,6 +847,8 @@ static struct xc_osdep_ops *linux_osdep_init(xc_interface > *xch, enum xc_osdep_ty > return &linux_evtchn_ops; > case XC_OSDEP_GNTTAB: > return &linux_gnttab_ops; > + case XC_OSDEP_GNTSHR: > + return &linux_gntshr_ops; > default: > return NULL; > } > diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c > index 09c8f23..09a91e7 100644 > --- a/tools/libxc/xc_private.c > +++ b/tools/libxc/xc_private.c > @@ -258,6 +258,19 @@ int xc_gnttab_close(xc_gnttab *xcg) > return xc_interface_close_common(xcg); > } > > +xc_gntshr *xc_gntshr_open(xentoollog_logger *logger, > + unsigned open_flags) > +{ > + return xc_interface_open_common(logger, NULL, open_flags, > + XC_OSDEP_GNTSHR); > +} > + > +int xc_gntshr_close(xc_gntshr *xcg) > +{ > + return xc_interface_close_common(xcg); > +} > + > + > static pthread_key_t errbuf_pkey; > static pthread_once_t errbuf_pkey_once = PTHREAD_ONCE_INIT; > > diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h > index 7859571..374c705 100644 > --- a/tools/libxc/xenctrl.h > +++ b/tools/libxc/xenctrl.h > @@ -115,6 +115,7 @@ > typedef struct xc_interface_core xc_interface; > typedef struct xc_interface_core xc_evtchn; > typedef struct xc_interface_core xc_gnttab; > +typedef struct xc_interface_core xc_gntshr; > typedef enum xc_error_code xc_error_code; > > > @@ -1400,6 +1401,53 @@ grant_entry_v1_t *xc_gnttab_map_table_v1(xc_interface > *xch, int domid, int *gnt_ > grant_entry_v2_t *xc_gnttab_map_table_v2(xc_interface *xch, int domid, int > *gnt_num); > /* Sometimes these don't set errno [fixme], and sometimes they don't log. */ > > +/* > + * Return an fd onto the grant sharing driver. Logs errors. > + */ > +xc_gntshr *xc_gntshr_open(xentoollog_logger *logger, > + unsigned open_flags); > + > +/* > + * Close a handle previously allocated with xc_gntshr_open(). > + * Never logs errors. > + */ > +int xc_gntshr_close(xc_gntshr *xcg); > + > +/* > + * Creates and shares pages with another domain. > + * > + * @parm xcg a handle to an open grant sharing instance > + * @parm domid the domain to share memory with > + * @parm count the number of pages to share > + * @parm refs the grant references of the pages (output) > + * @parm writable true if the other domain can write to the pages > + * @return local mapping of the pages > + */ > +void *xc_gntshr_share_pages(xc_gntshr *xcg, uint32_t domid, > + int count, uint32_t *refs, int writable); > + > +/* > + * Creates and shares a page with another domain, with unmap notification. > + * > + * @parm xcg a handle to an open grant sharing instance > + * @parm domid the domain to share memory with > + * @parm refs the grant reference of the pages (output) > + * @parm writable true if the other domain can write to the page > + * @parm notify_offset The byte offset in the page to use for unmap > + * notification; -1 for none. > + * @parm notify_port The event channel port to use for unmap notify, or -1 > + * @return local mapping of the page > + */ > +void *xc_gntshr_share_page_notify(xc_gntshr *xcg, uint32_t domid, > + uint32_t *ref, int writable, > + uint32_t notify_offset, > + evtchn_port_t notify_port); > +/* > + * Unmaps the @count pages starting at @start_address, which were mapped by a > + * call to xc_gntshr_share_*. Never logs. > + */ > +int xc_gntshr_munmap(xc_gntshr *xcg, void *start_address, uint32_t count); > + > int xc_physdev_map_pirq(xc_interface *xch, > int domid, > int index, > diff --git a/tools/libxc/xenctrlosdep.h b/tools/libxc/xenctrlosdep.h > index 01969c5..e1c1ba5 100644 > --- a/tools/libxc/xenctrlosdep.h > +++ b/tools/libxc/xenctrlosdep.h > @@ -54,6 +54,7 @@ enum xc_osdep_type { > XC_OSDEP_PRIVCMD, > XC_OSDEP_EVTCHN, > XC_OSDEP_GNTTAB, > + XC_OSDEP_GNTSHR, > }; > > /* Opaque handle internal to the backend */ > @@ -129,6 +130,18 @@ struct xc_osdep_ops > uint32_t count); > int (*set_max_grants)(xc_gnttab *xcg, xc_osdep_handle h, > uint32_t count); > } gnttab; > + struct { > + void *(*share_pages)(xc_gntshr *xcg, xc_osdep_handle h, > + uint32_t domid, int count, > + uint32_t *refs, int writable); > + void *(*share_page_notify)(xc_gntshr *xcg, xc_osdep_handle h, > + uint32_t domid, > + uint32_t *ref, int writable, > + uint32_t notify_offset, > + evtchn_port_t notify_port); > + int (*munmap)(xc_gntshr *xcg, xc_osdep_handle h, > + void *start_address, uint32_t count); > + } gntshr; > } u; > }; > typedef struct xc_osdep_ops xc_osdep_ops; > -- > 1.7.6 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |