/* * 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 . */ #ifndef XENCALL_H #define XENCALL_H /* * This library allows you to make arbitrary hypercalls (subject to * sufficient permission for the process and the domain itself). Note * that while the library interface is stable the hypercalls are * subject to their own rules. */ #include #include /* Callers who don't care don't need to #include */ struct xentoollog_logger; typedef struct xencall_handle xencall_handle; /* */ #define XENCALL_OPENFLAG_NON_REENTRANT (1U<<0) /* * Return a handle onto the hypercall driver. Logs errors. * * * Note: After fork(2) a child process must not use any opened * xencall handle inherited from their parent, nor access any * hypercall argument buffers associated with that handle. * * The child must open a new handle if they want to interact with * xencall. * * Calling exec(2) in a child will safely (and reliably) reclaim any * resources which were allocated via a xencall_handle in the parent. * * A child which does not call exec(2) may safely call xencall_close() * on a xencall_handle inherited from their parent. This will attempt * to reclaim any resources associated with that handle. Note that in * some implementations this reclamation may not be completely * effective, in this case any affected resources remain allocated. * * Calling xencall_close() is the only safe operation on a * xencall_handle which has been inherited. */ xencall_handle *xencall_open(struct xentoollog_logger *logger, unsigned open_flags); /* * Close a handle previously allocated with xencall_open(). * * Under normal circumstances (i.e. not in the child after a fork) any * allocated hypercall argument buffers should be freed using the * appropriate xencall_free_*() prior to closing the handle in order * to free up resources associated with those mappings. * * This is the only function which may be safely called on a * xencall_handle in a child after a fork. xencall_free_*() must not * be called under such circumstances. */ int xencall_close(xencall_handle *xcall); /* * Return the fd used internally by xencall. selecting on it is not * useful. But it could be useful for unusual use cases; perhaps, * passing to other programs, calling ioctls on directly, or maybe * calling fcntl. */ int xencall_fd(xencall_handle *xcall); /* * Call hypercalls with varying numbers of arguments. * * On success the return value of the hypercall is the return value of * the xencall function. On error these functions set errno and * return -1. * * The errno values will be either: * - The Xen hypercall error return (from xen/include/public/errno.h) * translated into the corresponding local value for that POSIX error. * - An errno value produced by the OS driver or the library * implementation. Such values may be defined by POSIX or by the OS. * * Note that under some circumstances it will not be possible to tell * whether an error came from Xen or from the OS/library. * * These functions never log. */ int xencall0(xencall_handle *xcall, unsigned int op); int xencall1(xencall_handle *xcall, unsigned int op, uint64_t arg1); int xencall2(xencall_handle *xcall, unsigned int op, uint64_t arg1, uint64_t arg2); int xencall3(xencall_handle *xcall, unsigned int op, uint64_t arg1, uint64_t arg2, uint64_t arg3); int xencall4(xencall_handle *xcall, unsigned int op, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4); int xencall5(xencall_handle *xcall, unsigned int op, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5); /* Variant(s) of the above, as needed, returning "long" instead of "int". */ long xencall2L(xencall_handle *xcall, unsigned int op, uint64_t arg1, uint64_t arg2); /* * Allocate and free memory which is suitable for use as a pointer * argument to a hypercall. */ void *xencall_alloc_buffer_pages(xencall_handle *xcall, size_t nr_pages); void xencall_free_buffer_pages(xencall_handle *xcall, void *p, size_t nr_pages); void *xencall_alloc_buffer(xencall_handle *xcall, size_t size); void xencall_free_buffer(xencall_handle *xcall, void *p); /* * Are allocated hypercall buffers safe to be accessed by the hypervisor all * the time? * Returns 0 if EFAULT might be possible. */ int xencall_buffers_never_fault(xencall_handle *xcall); #endif /* * Local variables: * mode: C * c-file-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil * End: */