mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
1. platform_op -- used by dom0 kernel to perform actions on the
hardware platform (e.g., MTRR access, microcode update, platform
quirks, ...)
2. domctl -- used by management tools to control a specified domain
3. sysctl -- used by management tools for system-wide actions
Benefits include more sensible factoring of actions to
hypercalls. Also allows tool compatibility to be tracked separately
from the dom0 kernel. The assumption is that it will be easier to
replace libxenctrl, libxenguest and Xen as a matched set if the
dom0 kernel does not need to be replaced too (e.g., because that
would require vendor revalidation).
From here on we hope to maintain dom0 kernel compatibility. This
promise is not extended to tool compatibility beyond the existing
guarantee that compatibility will not be broken within a three-level
stable release [3.0.2, 3.0.3, etc.].
Signed-off-by: Keir Fraser <keir@xensource.com>
161 lines
4.1 KiB
C
161 lines
4.1 KiB
C
|
|
#ifndef XC_PRIVATE_H
|
|
#define XC_PRIVATE_H
|
|
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <stdlib.h>
|
|
#include <sys/ioctl.h>
|
|
|
|
#include "xenctrl.h"
|
|
|
|
#include <xen/sys/privcmd.h>
|
|
|
|
/* valgrind cannot see when a hypercall has filled in some values. For this
|
|
reason, we must zero the privcmd_hypercall_t or domctl/sysctl instance
|
|
before a call, if using valgrind. */
|
|
#ifdef VALGRIND
|
|
#define DECLARE_HYPERCALL privcmd_hypercall_t hypercall = { 0 }
|
|
#define DECLARE_DOMCTL struct xen_domctl domctl = { 0 }
|
|
#define DECLARE_SYSCTL struct xen_sysctl sysctl = { 0 }
|
|
#else
|
|
#define DECLARE_HYPERCALL privcmd_hypercall_t hypercall
|
|
#define DECLARE_DOMCTL struct xen_domctl domctl
|
|
#define DECLARE_SYSCTL struct xen_sysctl sysctl
|
|
#endif
|
|
|
|
#define PAGE_SHIFT XC_PAGE_SHIFT
|
|
#define PAGE_SIZE (1UL << PAGE_SHIFT)
|
|
#define PAGE_MASK (~(PAGE_SIZE-1))
|
|
|
|
#define DEBUG 1
|
|
#define INFO 1
|
|
#define PROGRESS 0
|
|
|
|
#if INFO
|
|
#define IPRINTF(_f, _a...) printf(_f , ## _a)
|
|
#else
|
|
#define IPRINTF(_f, _a...) ((void)0)
|
|
#endif
|
|
|
|
#if DEBUG
|
|
#define DPRINTF(_f, _a...) fprintf(stderr, _f , ## _a)
|
|
#else
|
|
#define DPRINTF(_f, _a...) ((void)0)
|
|
#endif
|
|
|
|
#if PROGRESS
|
|
#define PPRINTF(_f, _a...) fprintf(stderr, _f , ## _a)
|
|
#else
|
|
#define PPRINTF(_f, _a...)
|
|
#endif
|
|
|
|
#define ERR(_f, _a...) do { \
|
|
DPRINTF(_f ": %d\n" , ## _a, errno); \
|
|
fflush(stderr); } \
|
|
while (0)
|
|
|
|
#define ERROR(_m, _a...) \
|
|
do { \
|
|
int __saved_errno = errno; \
|
|
DPRINTF("ERROR: " _m "\n" , ## _a ); \
|
|
errno = __saved_errno; \
|
|
} while (0)
|
|
|
|
#define PERROR(_m, _a...) \
|
|
do { \
|
|
int __saved_errno = errno; \
|
|
DPRINTF("ERROR: " _m " (%d = %s)\n" , ## _a , \
|
|
__saved_errno, strerror(__saved_errno)); \
|
|
errno = __saved_errno; \
|
|
} while (0)
|
|
|
|
static inline void safe_munlock(const void *addr, size_t len)
|
|
{
|
|
int saved_errno = errno;
|
|
(void)munlock(addr, len);
|
|
errno = saved_errno;
|
|
}
|
|
|
|
int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall);
|
|
|
|
static inline int do_xen_version(int xc_handle, int cmd, void *dest)
|
|
{
|
|
DECLARE_HYPERCALL;
|
|
|
|
hypercall.op = __HYPERVISOR_xen_version;
|
|
hypercall.arg[0] = (unsigned long) cmd;
|
|
hypercall.arg[1] = (unsigned long) dest;
|
|
|
|
return do_xen_hypercall(xc_handle, &hypercall);
|
|
}
|
|
|
|
static inline int do_domctl(int xc_handle, struct xen_domctl *domctl)
|
|
{
|
|
int ret = -1;
|
|
DECLARE_HYPERCALL;
|
|
|
|
domctl->interface_version = XEN_DOMCTL_INTERFACE_VERSION;
|
|
|
|
hypercall.op = __HYPERVISOR_domctl;
|
|
hypercall.arg[0] = (unsigned long)domctl;
|
|
|
|
if ( mlock(domctl, sizeof(*domctl)) != 0 )
|
|
{
|
|
PERROR("Could not lock memory for Xen hypercall");
|
|
goto out1;
|
|
}
|
|
|
|
if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
|
|
{
|
|
if ( errno == EACCES )
|
|
DPRINTF("domctl operation failed -- need to"
|
|
" rebuild the user-space tool set?\n");
|
|
}
|
|
|
|
safe_munlock(domctl, sizeof(*domctl));
|
|
|
|
out1:
|
|
return ret;
|
|
}
|
|
|
|
static inline int do_sysctl(int xc_handle, struct xen_sysctl *sysctl)
|
|
{
|
|
int ret = -1;
|
|
DECLARE_HYPERCALL;
|
|
|
|
sysctl->interface_version = XEN_SYSCTL_INTERFACE_VERSION;
|
|
|
|
hypercall.op = __HYPERVISOR_sysctl;
|
|
hypercall.arg[0] = (unsigned long)sysctl;
|
|
|
|
if ( mlock(sysctl, sizeof(*sysctl)) != 0 )
|
|
{
|
|
PERROR("Could not lock memory for Xen hypercall");
|
|
goto out1;
|
|
}
|
|
|
|
if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
|
|
{
|
|
if ( errno == EACCES )
|
|
DPRINTF("sysctl operation failed -- need to"
|
|
" rebuild the user-space tool set?\n");
|
|
}
|
|
|
|
safe_munlock(sysctl, sizeof(*sysctl));
|
|
|
|
out1:
|
|
return ret;
|
|
}
|
|
|
|
int xc_map_foreign_ranges(int xc_handle, uint32_t dom,
|
|
privcmd_mmap_entry_t *entries, int nr);
|
|
|
|
#endif /* __XC_PRIVATE_H__ */
|