/* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see . */ #include #include #include #include #include "private.h" static int all_restrict_cb(Xentoolcore__Active_Handle *ah, domid_t domid) { xenforeignmemory_handle *fmem = CONTAINER_OF(ah, *fmem, tc_ah); if (fmem->fd < 0) /* just in case */ return 0; return xenforeignmemory_restrict(fmem, domid); } xenforeignmemory_handle *xenforeignmemory_open(xentoollog_logger *logger, unsigned open_flags) { xenforeignmemory_handle *fmem = malloc(sizeof(*fmem)); int rc; if (!fmem) return NULL; fmem->fd = -1; fmem->logger = logger; fmem->logger_tofree = NULL; fmem->tc_ah.restrict_callback = all_restrict_cb; xentoolcore__register_active_handle(&fmem->tc_ah); if (!fmem->logger) { fmem->logger = fmem->logger_tofree = (xentoollog_logger*) xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0); if (!fmem->logger) goto err; } rc = osdep_xenforeignmemory_open(fmem); if ( rc < 0 ) goto err; return fmem; err: xentoolcore__deregister_active_handle(&fmem->tc_ah); osdep_xenforeignmemory_close(fmem); xtl_logger_destroy(fmem->logger_tofree); free(fmem); return NULL; } int xenforeignmemory_close(xenforeignmemory_handle *fmem) { int rc; if ( !fmem ) return 0; xentoolcore__deregister_active_handle(&fmem->tc_ah); rc = osdep_xenforeignmemory_close(fmem); xtl_logger_destroy(fmem->logger_tofree); free(fmem); return rc; } void *xenforeignmemory_map2(xenforeignmemory_handle *fmem, uint32_t dom, void *addr, int prot, int flags, size_t num, const xen_pfn_t arr[/*num*/], int err[/*num*/]) { void *ret; int *err_to_free = NULL; if ( err == NULL ) err = err_to_free = malloc(num * sizeof(int)); if ( err == NULL ) return NULL; ret = osdep_xenforeignmemory_map(fmem, dom, addr, prot, flags, num, arr, err); if ( ret && err_to_free ) { int i; for ( i = 0 ; i < num ; i++ ) { if ( err[i] ) { errno = -err[i]; (void)osdep_xenforeignmemory_unmap(fmem, ret, num); ret = NULL; break; } } } free(err_to_free); return ret; } void *xenforeignmemory_map(xenforeignmemory_handle *fmem, uint32_t dom, int prot, size_t num, const xen_pfn_t arr[/*num*/], int err[/*num*/]) { return xenforeignmemory_map2(fmem, dom, NULL, prot, 0, num, arr, err); } int xenforeignmemory_unmap(xenforeignmemory_handle *fmem, void *addr, size_t num) { return osdep_xenforeignmemory_unmap(fmem, addr, num); } int xenforeignmemory_restrict(xenforeignmemory_handle *fmem, domid_t domid) { return osdep_xenforeignmemory_restrict(fmem, domid); } xenforeignmemory_resource_handle *xenforeignmemory_map_resource( xenforeignmemory_handle *fmem, domid_t domid, unsigned int type, unsigned int id, unsigned long frame, unsigned long nr_frames, void **paddr, int prot, int flags) { xenforeignmemory_resource_handle *fres; int rc; /* Check flags only contains POSIX defined values */ if ( flags & ~(MAP_SHARED | MAP_PRIVATE) ) { errno = EINVAL; return NULL; } fres = calloc(1, sizeof(*fres)); if ( !fres ) { errno = ENOMEM; return NULL; } fres->domid = domid; fres->type = type; fres->id = id; fres->frame = frame; fres->nr_frames = nr_frames; fres->addr = *paddr; fres->prot = prot; fres->flags = flags; rc = osdep_xenforeignmemory_map_resource(fmem, fres); if ( rc ) { free(fres); fres = NULL; } else *paddr = fres->addr; return fres; } int xenforeignmemory_unmap_resource( xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres) { int rc = osdep_xenforeignmemory_unmap_resource(fmem, fres); free(fres); return rc; } /* * Local variables: * mode: C * c-file-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil * End: */