static int all_restrict_cb(Xentoolcore__Active_Handle *ah, domid_t domid) {
xencall_handle *xcall = CONTAINER_OF(ah, *xcall, tc_ah);
- return xentoolcore__restrict_by_dup2_null(xcall->fd);
+ int rc;
+
+ rc = xentoolcore__restrict_by_dup2_null(xcall->buf_fd);
+ if ( rc )
+ goto out;
+
+ rc = xentoolcore__restrict_by_dup2_null(xcall->fd);
+
+out:
+ return rc;
}
xencall_handle *xencall_open(xentoollog_logger *logger, unsigned open_flags)
if (!xcall) return NULL;
xcall->fd = -1;
+ xcall->buf_fd = -1;
xcall->tc_ah.restrict_callback = all_restrict_cb;
xentoolcore__register_active_handle(&xcall->tc_ah);
}
xcall->fd = fd;
+
+ /*
+ * Try the same for the hypercall buffer device.
+ */
+ fd = open("/dev/xen/hypercall", O_RDWR|O_CLOEXEC);
+ if ( fd == -1 && errno != ENOENT )
+ {
+ PERROR("Error on trying to open hypercall buffer device");
+ return -1;
+ }
+ xcall->buf_fd = fd;
+
return 0;
}
int osdep_xencall_close(xencall_handle *xcall)
{
- int fd = xcall->fd;
- if (fd == -1)
- return 0;
- return close(fd);
+ if ( xcall->buf_fd >= 0 )
+ close(xcall->buf_fd);
+ if ( xcall->fd >= 0 )
+ close(xcall->fd);
+ return 0;
}
int osdep_hypercall(xencall_handle *xcall, privcmd_hypercall_t *hypercall)
return ioctl(xcall->fd, IOCTL_PRIVCMD_HYPERCALL, hypercall);
}
-void *osdep_alloc_pages(xencall_handle *xcall, size_t npages)
+static void *alloc_pages_bufdev(xencall_handle *xcall, size_t npages)
+{
+ void *p;
+
+ p = mmap(NULL, npages * PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED,
+ xcall->buf_fd, 0);
+ if ( p == MAP_FAILED )
+ {
+ PERROR("alloc_pages: mmap failed");
+ p = NULL;
+ }
+
+ return p;
+}
+
+static void *alloc_pages_nobufdev(xencall_handle *xcall, size_t npages)
{
size_t size = npages * PAGE_SIZE;
void *p;
return NULL;
}
+void *osdep_alloc_pages(xencall_handle *xcall, size_t npages)
+{
+ void *p;
+
+ if ( xcall->buf_fd >= 0 )
+ p = alloc_pages_bufdev(xcall, npages);
+ else
+ p = alloc_pages_nobufdev(xcall, npages);
+
+ return p;
+}
+
void osdep_free_pages(xencall_handle *xcall, void *ptr, size_t npages)
{
int saved_errno = errno;
- /* Recover the VMA flags. Maybe it's not necessary */
- madvise(ptr, npages * PAGE_SIZE, MADV_DOFORK);
+
+ if ( xcall->buf_fd < 0 )
+ {
+ /* Recover the VMA flags. Maybe it's not necessary */
+ madvise(ptr, npages * PAGE_SIZE, MADV_DOFORK);
+ }
munmap(ptr, npages * PAGE_SIZE);
/* We MUST propagate the hypercall errno, not unmap call's. */