mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
libxc: NetBSD-specific pieces.
Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
This commit is contained in:
1 parent
a62f71bad5
commit
3a0667d17e
4 files changed
+466
No files matched your search
@@ -0,0 +1,89 @@
|
||||
/* $NetBSD: evtchn.h,v 1.1.1.1 2007/06/14 19:39:45 bouyer Exp $ */
|
||||
/******************************************************************************
|
||||
* evtchn.h
|
||||
*
|
||||
* Interface to /dev/xen/evtchn.
|
||||
*
|
||||
* Copyright (c) 2003-2005, K A Fraser
|
||||
*
|
||||
* This file may be distributed separately from the Linux kernel, or
|
||||
* incorporated into other software packages, subject to the following license:
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this source file (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __NetBSD_EVTCHN_H__
|
||||
#define __NetBSD_EVTCHN_H__
|
||||
|
||||
/*
|
||||
* Bind a fresh port to VIRQ @virq.
|
||||
* Return allocated port.
|
||||
*/
|
||||
#define IOCTL_EVTCHN_BIND_VIRQ \
|
||||
_IOWR('E', 4, struct ioctl_evtchn_bind_virq)
|
||||
struct ioctl_evtchn_bind_virq {
|
||||
unsigned int virq;
|
||||
unsigned int port;
|
||||
};
|
||||
|
||||
/*
|
||||
* Bind a fresh port to remote <@remote_domain, @remote_port>.
|
||||
* Return allocated port.
|
||||
*/
|
||||
#define IOCTL_EVTCHN_BIND_INTERDOMAIN \
|
||||
_IOWR('E', 5, struct ioctl_evtchn_bind_interdomain)
|
||||
struct ioctl_evtchn_bind_interdomain {
|
||||
unsigned int remote_domain, remote_port;
|
||||
unsigned int port;
|
||||
};
|
||||
|
||||
/*
|
||||
* Allocate a fresh port for binding to @remote_domain.
|
||||
* Return allocated port.
|
||||
*/
|
||||
#define IOCTL_EVTCHN_BIND_UNBOUND_PORT \
|
||||
_IOWR('E', 6, struct ioctl_evtchn_bind_unbound_port)
|
||||
struct ioctl_evtchn_bind_unbound_port {
|
||||
unsigned int remote_domain;
|
||||
unsigned int port;
|
||||
};
|
||||
|
||||
/*
|
||||
* Unbind previously allocated @port.
|
||||
*/
|
||||
#define IOCTL_EVTCHN_UNBIND \
|
||||
_IOW('E', 7, struct ioctl_evtchn_unbind)
|
||||
struct ioctl_evtchn_unbind {
|
||||
unsigned int port;
|
||||
};
|
||||
|
||||
/*
|
||||
* Send event to previously allocated @port.
|
||||
*/
|
||||
#define IOCTL_EVTCHN_NOTIFY \
|
||||
_IOW('E', 8, struct ioctl_evtchn_notify)
|
||||
struct ioctl_evtchn_notify {
|
||||
unsigned int port;
|
||||
};
|
||||
|
||||
/* Clear and reinitialise the event buffer. Clear error condition. */
|
||||
#define IOCTL_EVTCHN_RESET \
|
||||
_IO('E', 9)
|
||||
|
||||
#endif /* __NetBSD_EVTCHN_H__ */
|
||||
@@ -0,0 +1,105 @@
|
||||
/* NetBSD: xenio.h,v 1.3 2005/05/24 12:07:12 yamt Exp $ */
|
||||
|
||||
/******************************************************************************
|
||||
* privcmd.h
|
||||
*
|
||||
* Copyright (c) 2003-2004, K A Fraser
|
||||
*
|
||||
* This file may be distributed separately from the Linux kernel, or
|
||||
* incorporated into other software packages, subject to the following license:
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this source file (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy, modify,
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __NetBSD_PRIVCMD_H__
|
||||
#define __NetBSD_PRIVCMD_H__
|
||||
|
||||
/* Interface to /proc/xen/privcmd */
|
||||
|
||||
typedef struct privcmd_hypercall
|
||||
{
|
||||
unsigned long op;
|
||||
unsigned long arg[5];
|
||||
} privcmd_hypercall_t;
|
||||
|
||||
typedef struct privcmd_mmap_entry {
|
||||
unsigned long va;
|
||||
unsigned long mfn;
|
||||
unsigned long npages;
|
||||
} privcmd_mmap_entry_t;
|
||||
|
||||
typedef struct privcmd_mmap {
|
||||
int num;
|
||||
domid_t dom; /* target domain */
|
||||
privcmd_mmap_entry_t *entry;
|
||||
} privcmd_mmap_t;
|
||||
|
||||
typedef struct privcmd_mmapbatch {
|
||||
int num; /* number of pages to populate */
|
||||
domid_t dom; /* target domain */
|
||||
unsigned long addr; /* virtual address */
|
||||
unsigned long *arr; /* array of mfns - top nibble set on err */
|
||||
} privcmd_mmapbatch_t;
|
||||
|
||||
typedef struct privcmd_blkmsg
|
||||
{
|
||||
unsigned long op;
|
||||
void *buf;
|
||||
int buf_size;
|
||||
} privcmd_blkmsg_t;
|
||||
|
||||
/*
|
||||
* @cmd: IOCTL_PRIVCMD_HYPERCALL
|
||||
* @arg: &privcmd_hypercall_t
|
||||
* Return: Value returned from execution of the specified hypercall.
|
||||
*/
|
||||
#define IOCTL_PRIVCMD_HYPERCALL \
|
||||
_IOWR('P', 0, privcmd_hypercall_t)
|
||||
|
||||
#if defined(_KERNEL)
|
||||
/* compat */
|
||||
#define IOCTL_PRIVCMD_INITDOMAIN_EVTCHN_OLD \
|
||||
_IO('P', 1)
|
||||
#endif /* defined(_KERNEL) */
|
||||
|
||||
#define IOCTL_PRIVCMD_MMAP \
|
||||
_IOW('P', 2, privcmd_mmap_t)
|
||||
#define IOCTL_PRIVCMD_MMAPBATCH \
|
||||
_IOW('P', 3, privcmd_mmapbatch_t)
|
||||
#define IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN \
|
||||
_IOR('P', 4, unsigned long)
|
||||
|
||||
/*
|
||||
* @cmd: IOCTL_PRIVCMD_INITDOMAIN_EVTCHN
|
||||
* @arg: n/a
|
||||
* Return: Port associated with domain-controller end of control event channel
|
||||
* for the initial domain.
|
||||
*/
|
||||
#define IOCTL_PRIVCMD_INITDOMAIN_EVTCHN \
|
||||
_IOR('P', 5, int)
|
||||
|
||||
/* Interface to /dev/xenevt */
|
||||
/* EVTCHN_RESET: Clear and reinit the event buffer. Clear error condition. */
|
||||
#define EVTCHN_RESET _IO('E', 1)
|
||||
/* EVTCHN_BIND: Bind to the specified event-channel port. */
|
||||
#define EVTCHN_BIND _IOW('E', 2, unsigned long)
|
||||
/* EVTCHN_UNBIND: Unbind from the specified event-channel port. */
|
||||
#define EVTCHN_UNBIND _IOW('E', 3, unsigned long)
|
||||
|
||||
#endif /* __NetBSD_PRIVCMD_H__ */
|
||||
@@ -23,6 +23,7 @@ CTRL_SRCS-$(CONFIG_X86) += xc_pagetab.c
|
||||
CTRL_SRCS-$(CONFIG_Linux) += xc_linux.c
|
||||
CTRL_SRCS-$(CONFIG_SunOS) += xc_solaris.c
|
||||
CTRL_SRCS-$(CONFIG_X86_Linux) += xc_ptrace.c xc_ptrace_core.c
|
||||
CTRL_SRCS-$(CONFIG_NetBSD) += xc_netbsd.c
|
||||
|
||||
GUEST_SRCS-y :=
|
||||
GUEST_SRCS-y += xg_private.c
|
||||
|
||||
@@ -0,0 +1,271 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
|
||||
* Use is subject to license terms.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation, version 2 of the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include "xc_private.h"
|
||||
|
||||
#include <xen/memory.h>
|
||||
#include <xen/sys/evtchn.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
int xc_interface_open(void)
|
||||
{
|
||||
int flags, saved_errno;
|
||||
int fd = open("/kern/xen/privcmd", O_RDWR);
|
||||
|
||||
if ( fd == -1 )
|
||||
{
|
||||
PERROR("Could not obtain handle on privileged command interface");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Although we return the file handle as the 'xc handle' the API
|
||||
does not specify / guarentee that this integer is in fact
|
||||
a file handle. Thus we must take responsiblity to ensure
|
||||
it doesn't propagate (ie leak) outside the process */
|
||||
if ( (flags = fcntl(fd, F_GETFD)) < 0 )
|
||||
{
|
||||
PERROR("Could not get file handle flags");
|
||||
goto error;
|
||||
}
|
||||
flags |= FD_CLOEXEC;
|
||||
if ( fcntl(fd, F_SETFD, flags) < 0 )
|
||||
{
|
||||
PERROR("Could not set file handle flags");
|
||||
goto error;
|
||||
}
|
||||
|
||||
return fd;
|
||||
|
||||
error:
|
||||
saved_errno = errno;
|
||||
close(fd);
|
||||
errno = saved_errno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int xc_interface_close(int xc_handle)
|
||||
{
|
||||
return close(xc_handle);
|
||||
}
|
||||
|
||||
void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
|
||||
xen_pfn_t *arr, int num)
|
||||
{
|
||||
privcmd_mmapbatch_t ioctlx;
|
||||
void *addr;
|
||||
addr = mmap(NULL, num*PAGE_SIZE, prot, MAP_ANON | MAP_SHARED, -1, 0);
|
||||
if ( addr == MAP_FAILED )
|
||||
return NULL;
|
||||
|
||||
ioctlx.num=num;
|
||||
ioctlx.dom=dom;
|
||||
ioctlx.addr=(unsigned long)addr;
|
||||
ioctlx.arr=arr;
|
||||
if ( ioctl(xc_handle, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx) < 0 )
|
||||
{
|
||||
int saved_errno = errno;
|
||||
perror("XXXXXXXX");
|
||||
(void)munmap(addr, num*PAGE_SIZE);
|
||||
errno = saved_errno;
|
||||
return NULL;
|
||||
}
|
||||
return addr;
|
||||
|
||||
}
|
||||
|
||||
void *xc_map_foreign_range(int xc_handle, uint32_t dom,
|
||||
int size, int prot,
|
||||
unsigned long mfn)
|
||||
{
|
||||
privcmd_mmap_t ioctlx;
|
||||
privcmd_mmap_entry_t entry;
|
||||
void *addr;
|
||||
addr = mmap(NULL, size, prot, MAP_ANON | MAP_SHARED, -1, 0);
|
||||
if ( addr == MAP_FAILED )
|
||||
return NULL;
|
||||
|
||||
ioctlx.num=1;
|
||||
ioctlx.dom=dom;
|
||||
ioctlx.entry=&entry;
|
||||
entry.va=(unsigned long) addr;
|
||||
entry.mfn=mfn;
|
||||
entry.npages=(size+PAGE_SIZE-1)>>PAGE_SHIFT;
|
||||
if ( ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx) < 0 )
|
||||
{
|
||||
int saved_errno = errno;
|
||||
(void)munmap(addr, size);
|
||||
errno = saved_errno;
|
||||
return NULL;
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
int xc_map_foreign_ranges(int xc_handle, uint32_t dom,
|
||||
privcmd_mmap_entry_t *entries, int nr)
|
||||
{
|
||||
privcmd_mmap_t ioctlx;
|
||||
int err;
|
||||
|
||||
ioctlx.num = nr;
|
||||
ioctlx.dom = dom;
|
||||
ioctlx.entry = entries;
|
||||
|
||||
err = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx);
|
||||
if (err == 0)
|
||||
return 0;
|
||||
else
|
||||
return -errno;
|
||||
}
|
||||
|
||||
static int do_privcmd(int xc_handle, unsigned int cmd, unsigned long data)
|
||||
{
|
||||
int err = ioctl(xc_handle, cmd, data);
|
||||
if (err == 0)
|
||||
return 0;
|
||||
else
|
||||
return -errno;
|
||||
}
|
||||
|
||||
int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall)
|
||||
{
|
||||
return do_privcmd(xc_handle,
|
||||
IOCTL_PRIVCMD_HYPERCALL,
|
||||
(unsigned long)hypercall);
|
||||
}
|
||||
|
||||
#define EVTCHN_DEV_NAME "/dev/xenevt"
|
||||
|
||||
int xc_evtchn_open(void)
|
||||
{
|
||||
return open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR);
|
||||
}
|
||||
|
||||
int xc_evtchn_close(int xce_handle)
|
||||
{
|
||||
return close(xce_handle);
|
||||
}
|
||||
|
||||
int xc_evtchn_fd(int xce_handle)
|
||||
{
|
||||
return xce_handle;
|
||||
}
|
||||
|
||||
int xc_evtchn_notify(int xce_handle, evtchn_port_t port)
|
||||
{
|
||||
struct ioctl_evtchn_notify notify;
|
||||
|
||||
notify.port = port;
|
||||
|
||||
return ioctl(xce_handle, IOCTL_EVTCHN_NOTIFY, ¬ify);
|
||||
}
|
||||
|
||||
evtchn_port_or_error_t
|
||||
xc_evtchn_bind_interdomain(int xce_handle, int domid,
|
||||
evtchn_port_t remote_port)
|
||||
{
|
||||
struct ioctl_evtchn_bind_interdomain bind;
|
||||
int ret;
|
||||
|
||||
bind.remote_domain = domid;
|
||||
bind.remote_port = remote_port;
|
||||
|
||||
ret = ioctl(xce_handle, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
|
||||
if (ret == 0)
|
||||
return bind.port;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
int xc_evtchn_unbind(int xce_handle, evtchn_port_t port)
|
||||
{
|
||||
struct ioctl_evtchn_unbind unbind;
|
||||
|
||||
unbind.port = port;
|
||||
|
||||
return ioctl(xce_handle, IOCTL_EVTCHN_UNBIND, &unbind);
|
||||
}
|
||||
|
||||
evtchn_port_or_error_t
|
||||
xc_evtchn_bind_virq(int xce_handle, unsigned int virq)
|
||||
{
|
||||
struct ioctl_evtchn_bind_virq bind;
|
||||
int err;
|
||||
|
||||
bind.virq = virq;
|
||||
|
||||
err = ioctl(xce_handle, IOCTL_EVTCHN_BIND_VIRQ, &bind);
|
||||
if (err)
|
||||
return -1;
|
||||
else
|
||||
return bind.port;
|
||||
}
|
||||
|
||||
static int dorw(int fd, char *data, size_t size, int do_write)
|
||||
{
|
||||
size_t offset = 0;
|
||||
ssize_t len;
|
||||
|
||||
while ( offset < size )
|
||||
{
|
||||
if (do_write)
|
||||
len = write(fd, data + offset, size - offset);
|
||||
else
|
||||
len = read(fd, data + offset, size - offset);
|
||||
|
||||
if ( len == -1 )
|
||||
{
|
||||
if ( errno == EINTR )
|
||||
continue;
|
||||
return -1;
|
||||
}
|
||||
|
||||
offset += len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
evtchn_port_or_error_t
|
||||
xc_evtchn_pending(int xce_handle)
|
||||
{
|
||||
evtchn_port_t port;
|
||||
|
||||
if ( dorw(xce_handle, (char *)&port, sizeof(port), 0) == -1 )
|
||||
return -1;
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
int xc_evtchn_unmask(int xce_handle, evtchn_port_t port)
|
||||
{
|
||||
return dorw(xce_handle, (char *)&port, sizeof(port), 1);
|
||||
}
|
||||
|
||||
/* Optionally flush file to disk and discard page cache */
|
||||
void discard_file_cache(int fd, int flush)
|
||||
{
|
||||
|
||||
if ( flush && (fsync(fd) < 0) )
|
||||
{
|
||||
/*PERROR("Failed to flush file: %s", strerror(errno));*/
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||