Share interrupt irq From: George Dunlap --- m4/depends.m4 | 15 - stubdom/grub/osdep.h | 30 - tools/libxc/xc_linux_osdep.c | 873 ------------------------------------ tools/libxc/xenctrl_osdep_ENOSYS.c | 206 -------- tools/libxc/xenctrlosdep.h | 172 ------- tools/libxl/libxl_osdeps.h | 62 --- tools/libxl/osdeps.c | 76 --- tools/python/xen/xend/osdep.py | 268 ----------- xen/arch/x86/hvm/rtc.c | 14 - xen/arch/x86/hvm/vpt.c | 7 xen/include/asm-x86/hvm/vpt.h | 1 11 files changed, 16 insertions(+), 1708 deletions(-) delete mode 100644 m4/depends.m4 delete mode 100644 stubdom/grub/osdep.h delete mode 100644 tools/libxc/xc_linux_osdep.c delete mode 100644 tools/libxc/xenctrl_osdep_ENOSYS.c delete mode 100644 tools/libxc/xenctrlosdep.h delete mode 100644 tools/libxl/libxl_osdeps.h delete mode 100644 tools/libxl/osdeps.c delete mode 100644 tools/python/xen/xend/osdep.py diff --git a/m4/depends.m4 b/m4/depends.m4 deleted file mode 100644 index 916e665..0000000 --- a/m4/depends.m4 +++ /dev/null @@ -1,15 +0,0 @@ - -AC_DEFUN([AX_DEPENDS_PATH_PROG], [ -AS_IF([test "x$$1" = "xy"], [AX_PATH_PROG_OR_FAIL([$2], [$3])], [ -AS_IF([test "x$$1" = "xn"], [ -$2="/$3-disabled-in-configure-script" -], [ -AC_PATH_PROG([$2], [$3], [no]) -AS_IF([test x"${$2}" = "xno"], [ -$1=n -$2="/$3-disabled-in-configure-script" -]) -]) -]) -AC_SUBST($2) -]) diff --git a/stubdom/grub/osdep.h b/stubdom/grub/osdep.h deleted file mode 100644 index 1d3e50a..0000000 --- a/stubdom/grub/osdep.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef __OSDEP_H__ -#define __OSDEP_H__ - -#include -#define swap32(x) bswap_32(x) -#define swap16(x) bswap_16(x) - -#include -#if BYTE_ORDER == BIG_ENDIAN -#define htons(x) (x) -#define ntohs(x) (x) -#define htonl(x) (x) -#define ntohl(x) (x) -#else -#define htons(x) swap16(x) -#define ntohs(x) swap16(x) -#define htonl(x) swap32(x) -#define ntohl(x) swap32(x) -#endif - -typedef unsigned long Address; - -/* ANSI prototyping macro */ -#ifdef __STDC__ -#define P(x) x -#else -#define P(x) () -#endif - -#endif diff --git a/tools/libxc/xc_linux_osdep.c b/tools/libxc/xc_linux_osdep.c deleted file mode 100644 index ca545d8..0000000 --- a/tools/libxc/xc_linux_osdep.c +++ /dev/null @@ -1,873 +0,0 @@ - /****************************************************************************** - * - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - * xc_gnttab functions: - * Copyright (c) 2007-2008, D G Murray - * - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include "xenctrl.h" -#include "xenctrlosdep.h" - -#define ROUNDUP(_x,_w) (((unsigned long)(_x)+(1UL<<(_w))-1) & ~((1UL<<(_w))-1)) -#define ERROR(_m, _a...) xc_osdep_log(xch,XTL_ERROR,XC_INTERNAL_ERROR,_m , ## _a ) -#define PERROR(_m, _a...) xc_osdep_log(xch,XTL_ERROR,XC_INTERNAL_ERROR,_m \ - " (%d = %s)", ## _a , errno, xc_strerror(xch, errno)) - -static xc_osdep_handle linux_privcmd_open(xc_interface *xch) -{ - int flags, saved_errno; - int fd = open("/proc/xen/privcmd", O_RDWR); - - if ( fd == -1 ) - { - PERROR("Could not obtain handle on privileged command interface"); - return XC_OSDEP_OPEN_ERROR; - } - - /* 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 (xc_osdep_handle)fd; - - error: - saved_errno = errno; - close(fd); - errno = saved_errno; - return XC_OSDEP_OPEN_ERROR; -} - -static int linux_privcmd_close(xc_interface *xch, xc_osdep_handle h) -{ - int fd = (int)h; - return close(fd); -} - -static void *linux_privcmd_alloc_hypercall_buffer(xc_interface *xch, xc_osdep_handle h, int npages) -{ - size_t size = npages * XC_PAGE_SIZE; - void *p; - - /* Address returned by mmap is page aligned. */ - p = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED, -1, 0); - - /* Do not copy the VMA to child process on fork. Avoid the page being COW - on hypercall. */ - madvise(p, npages * XC_PAGE_SIZE, MADV_DONTFORK); - return p; -} - -static void linux_privcmd_free_hypercall_buffer(xc_interface *xch, xc_osdep_handle h, void *ptr, int npages) -{ - /* Recover the VMA flags. Maybe it's not necessary */ - madvise(ptr, npages * XC_PAGE_SIZE, MADV_DOFORK); - - munmap(ptr, npages * XC_PAGE_SIZE); -} - -static int linux_privcmd_hypercall(xc_interface *xch, xc_osdep_handle h, privcmd_hypercall_t *hypercall) -{ - int fd = (int)h; - return ioctl(fd, IOCTL_PRIVCMD_HYPERCALL, hypercall); -} - -static int xc_map_foreign_batch_single(int fd, uint32_t dom, - xen_pfn_t *mfn, unsigned long addr) -{ - privcmd_mmapbatch_t ioctlx; - int rc; - - ioctlx.num = 1; - ioctlx.dom = dom; - ioctlx.addr = addr; - ioctlx.arr = mfn; - - do - { - *mfn ^= PRIVCMD_MMAPBATCH_PAGED_ERROR; - usleep(100); - rc = ioctl(fd, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx); - } - while ( (rc < 0) && (errno == ENOENT) ); - - return rc; -} - -static void *linux_privcmd_map_foreign_batch(xc_interface *xch, xc_osdep_handle h, - uint32_t dom, int prot, - xen_pfn_t *arr, int num) -{ - int fd = (int)h; - privcmd_mmapbatch_t ioctlx; - void *addr; - int rc; - - addr = mmap(NULL, num << XC_PAGE_SHIFT, prot, MAP_SHARED, fd, 0); - if ( addr == MAP_FAILED ) - { - PERROR("xc_map_foreign_batch: mmap failed"); - return NULL; - } - - ioctlx.num = num; - ioctlx.dom = dom; - ioctlx.addr = (unsigned long)addr; - ioctlx.arr = arr; - - rc = ioctl(fd, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx); - if ( (rc < 0) && (errno == ENOENT) ) - { - int i; - - for ( i = 0; i < num; i++ ) - { - if ( (arr[i] & PRIVCMD_MMAPBATCH_MFN_ERROR) == - PRIVCMD_MMAPBATCH_PAGED_ERROR ) - { - unsigned long paged_addr = (unsigned long)addr + (i << XC_PAGE_SHIFT); - rc = xc_map_foreign_batch_single(fd, dom, &arr[i], - paged_addr); - if ( rc < 0 ) - goto out; - } - } - } - - out: - if ( rc < 0 ) - { - int saved_errno = errno; - PERROR("xc_map_foreign_batch: ioctl failed"); - (void)munmap(addr, num << XC_PAGE_SHIFT); - errno = saved_errno; - return NULL; - } - - return addr; -} - -/* - * Retry mmap of all paged gfns in batches - * retuns < 0 on fatal error - * returns 0 if all gfns left paging state - * returns > 0 if some gfns are still in paging state - * - * Walk all gfns and try to assemble blocks of gfns in paging state. - * This will keep the request ring full and avoids delays. - */ -static int retry_paged(int fd, uint32_t dom, void *addr, - const xen_pfn_t *arr, int *err, unsigned int num) -{ - privcmd_mmapbatch_v2_t ioctlx; - int rc, paged = 0, i = 0; - - do - { - /* Skip gfns not in paging state */ - if ( err[i] != -ENOENT ) - { - i++; - continue; - } - - paged++; - - /* At least one gfn is still in paging state */ - ioctlx.num = 1; - ioctlx.dom = dom; - ioctlx.addr = (unsigned long)addr + ((unsigned long)i< 0 ); - } - /* Command was not recognized, use fall back */ - else if ( rc < 0 && errno == EINVAL && (int)num > 0 ) - { - /* - * IOCTL_PRIVCMD_MMAPBATCH_V2 is not supported - fall back to - * IOCTL_PRIVCMD_MMAPBATCH. - */ - privcmd_mmapbatch_t ioctlx; - xen_pfn_t *pfn; - unsigned int pfn_arr_size = ROUNDUP((num * sizeof(*pfn)), XC_PAGE_SHIFT); - - if ( pfn_arr_size <= XC_PAGE_SIZE ) - pfn = alloca(num * sizeof(*pfn)); - else - { - pfn = mmap(NULL, pfn_arr_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON | MAP_POPULATE, -1, 0); - if ( pfn == MAP_FAILED ) - { - PERROR("xc_map_foreign_bulk: mmap of pfn array failed"); - return NULL; - } - } - - memcpy(pfn, arr, num * sizeof(*arr)); - - ioctlx.num = num; - ioctlx.dom = dom; - ioctlx.addr = (unsigned long)addr; - ioctlx.arr = pfn; - - rc = ioctl(fd, IOCTL_PRIVCMD_MMAPBATCH, &ioctlx); - - rc = rc < 0 ? -errno : 0; - - for ( i = 0; i < num; ++i ) - { - switch ( pfn[i] ^ arr[i] ) - { - case 0: - err[i] = rc != -ENOENT ? rc : 0; - continue; - default: - err[i] = -EINVAL; - continue; - case PRIVCMD_MMAPBATCH_PAGED_ERROR: - if ( rc != -ENOENT ) - { - err[i] = rc ?: -EINVAL; - continue; - } - rc = xc_map_foreign_batch_single(fd, dom, pfn + i, - (unsigned long)addr + ((unsigned long)i< XC_PAGE_SIZE ) - munmap(pfn, pfn_arr_size); - - if ( rc == -ENOENT && i == num ) - rc = 0; - else if ( rc ) - { - errno = -rc; - rc = -1; - } - } - - if ( rc < 0 ) - { - int saved_errno = errno; - - PERROR("xc_map_foreign_bulk: ioctl failed"); - (void)munmap(addr, (unsigned long)num << XC_PAGE_SHIFT); - errno = saved_errno; - return NULL; - } - - return addr; -} - -static void *linux_privcmd_map_foreign_range(xc_interface *xch, xc_osdep_handle h, - uint32_t dom, int size, int prot, - unsigned long mfn) -{ - xen_pfn_t *arr; - int num; - int i; - void *ret; - - num = (size + XC_PAGE_SIZE - 1) >> XC_PAGE_SHIFT; - arr = calloc(num, sizeof(xen_pfn_t)); - - for ( i = 0; i < num; i++ ) - arr[i] = mfn + i; - - ret = xc_map_foreign_pages(xch, dom, prot, arr, num); - free(arr); - return ret; -} - -static void *linux_privcmd_map_foreign_ranges(xc_interface *xch, xc_osdep_handle h, - uint32_t dom, size_t size, int prot, - size_t chunksize, privcmd_mmap_entry_t entries[], - int nentries) -{ - xen_pfn_t *arr; - int num_per_entry; - int num; - int i; - int j; - void *ret; - - num_per_entry = chunksize >> XC_PAGE_SHIFT; - num = num_per_entry * nentries; - arr = calloc(num, sizeof(xen_pfn_t)); - - for ( i = 0; i < nentries; i++ ) - for ( j = 0; j < num_per_entry; j++ ) - arr[i * num_per_entry + j] = entries[i].mfn + j; - - ret = xc_map_foreign_pages(xch, dom, prot, arr, num); - free(arr); - return ret; -} - -static struct xc_osdep_ops linux_privcmd_ops = { - .open = &linux_privcmd_open, - .close = &linux_privcmd_close, - - .u.privcmd = { - .alloc_hypercall_buffer = &linux_privcmd_alloc_hypercall_buffer, - .free_hypercall_buffer = &linux_privcmd_free_hypercall_buffer, - - .hypercall = &linux_privcmd_hypercall, - - .map_foreign_batch = &linux_privcmd_map_foreign_batch, - .map_foreign_bulk = &linux_privcmd_map_foreign_bulk, - .map_foreign_range = &linux_privcmd_map_foreign_range, - .map_foreign_ranges = &linux_privcmd_map_foreign_ranges, - }, -}; - -#define DEVXEN "/dev/xen/" - -static xc_osdep_handle linux_evtchn_open(xc_evtchn *xce) -{ - int fd = open(DEVXEN "evtchn", O_RDWR); - if ( fd == -1 ) - return XC_OSDEP_OPEN_ERROR; - - return (xc_osdep_handle)fd; -} - -static int linux_evtchn_close(xc_evtchn *xce, xc_osdep_handle h) -{ - int fd = (int)h; - return close(fd); -} - -static int linux_evtchn_fd(xc_evtchn *xce, xc_osdep_handle h) -{ - return (int)h; -} - -static int linux_evtchn_notify(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port) -{ - int fd = (int)h; - struct ioctl_evtchn_notify notify; - - notify.port = port; - - return ioctl(fd, IOCTL_EVTCHN_NOTIFY, ¬ify); -} - -static evtchn_port_or_error_t -linux_evtchn_bind_unbound_port(xc_evtchn *xce, xc_osdep_handle h, int domid) -{ - int fd = (int)h; - struct ioctl_evtchn_bind_unbound_port bind; - - bind.remote_domain = domid; - - return ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind); -} - -static evtchn_port_or_error_t -linux_evtchn_bind_interdomain(xc_evtchn *xce, xc_osdep_handle h, int domid, - evtchn_port_t remote_port) -{ - int fd = (int)h; - struct ioctl_evtchn_bind_interdomain bind; - - bind.remote_domain = domid; - bind.remote_port = remote_port; - - return ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); -} - -static evtchn_port_or_error_t -linux_evtchn_bind_virq(xc_evtchn *xce, xc_osdep_handle h, unsigned int virq) -{ - int fd = (int)h; - struct ioctl_evtchn_bind_virq bind; - - bind.virq = virq; - - return ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind); -} - -static int linux_evtchn_unbind(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port) -{ - int fd = (int)h; - struct ioctl_evtchn_unbind unbind; - - unbind.port = port; - - return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind); -} - -static evtchn_port_or_error_t linux_evtchn_pending(xc_evtchn *xce, xc_osdep_handle h) -{ - int fd = (int)h; - evtchn_port_t port; - - if ( read(fd, &port, sizeof(port)) != sizeof(port) ) - return -1; - - return port; -} - -static int linux_evtchn_unmask(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port) -{ - int fd = (int)h; - - if ( write(fd, &port, sizeof(port)) != sizeof(port) ) - return -1; - return 0; -} - -static struct xc_osdep_ops linux_evtchn_ops = { - .open = &linux_evtchn_open, - .close = &linux_evtchn_close, - - .u.evtchn = { - .fd = &linux_evtchn_fd, - .notify = &linux_evtchn_notify, - .bind_unbound_port = &linux_evtchn_bind_unbound_port, - .bind_interdomain = &linux_evtchn_bind_interdomain, - .bind_virq = &linux_evtchn_bind_virq, - .unbind = &linux_evtchn_unbind, - .pending = &linux_evtchn_pending, - .unmask = &linux_evtchn_unmask, - }, -}; - -static xc_osdep_handle linux_gnttab_open(xc_gnttab *xcg) -{ - int fd = open(DEVXEN "gntdev", O_RDWR); - - if ( fd == -1 ) - return XC_OSDEP_OPEN_ERROR; - - return (xc_osdep_handle)fd; -} - -static int linux_gnttab_close(xc_gnttab *xcg, xc_osdep_handle h) -{ - int fd = (int)h; - return close(fd); -} - -static int linux_gnttab_set_max_grants(xc_gnttab *xch, xc_osdep_handle h, - uint32_t count) -{ - int fd = (int)h, rc; - struct ioctl_gntdev_set_max_grants max_grants = { .count = count }; - - rc = ioctl(fd, IOCTL_GNTDEV_SET_MAX_GRANTS, &max_grants); - if (rc) { - /* - * Newer (e.g. pv-ops) kernels don't implement this IOCTL, - * so ignore the resulting specific failure. - */ - if (errno == ENOTTY) - rc = 0; - else - PERROR("linux_gnttab_set_max_grants: ioctl SET_MAX_GRANTS failed"); - } - - return rc; -} - -static void *linux_gnttab_grant_map(xc_gnttab *xch, xc_osdep_handle h, - uint32_t count, int flags, int prot, - uint32_t *domids, uint32_t *refs, - uint32_t notify_offset, - evtchn_port_t notify_port) -{ - int fd = (int)h; - struct ioctl_gntdev_map_grant_ref *map; - unsigned int map_size = ROUNDUP((sizeof(*map) + (count - 1) * - sizeof(struct ioctl_gntdev_map_grant_ref)), - XC_PAGE_SHIFT); - void *addr = NULL; - int domids_stride = 1; - int i; - - if (flags & XC_GRANT_MAP_SINGLE_DOMAIN) - domids_stride = 0; - - if ( map_size <= XC_PAGE_SIZE ) - map = alloca(sizeof(*map) + - (count - 1) * sizeof(struct ioctl_gntdev_map_grant_ref)); - else - { - map = mmap(NULL, map_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON | MAP_POPULATE, -1, 0); - if ( map == MAP_FAILED ) - { - PERROR("linux_gnttab_grant_map: mmap of map failed"); - return NULL; - } - } - - for ( i = 0; i < count; i++ ) - { - map->refs[i].domid = domids[i * domids_stride]; - map->refs[i].ref = refs[i]; - } - - map->count = count; - - if ( ioctl(fd, IOCTL_GNTDEV_MAP_GRANT_REF, map) ) { - PERROR("linux_gnttab_grant_map: ioctl MAP_GRANT_REF failed"); - goto out; - } - - retry: - addr = mmap(NULL, XC_PAGE_SIZE * count, prot, MAP_SHARED, fd, - map->index); - - if (addr == MAP_FAILED && errno == EAGAIN) - { - /* - * The grant hypercall can return EAGAIN if the granted page is - * swapped out. Since the paging daemon may be in the same domain, the - * hypercall cannot block without causing a deadlock. - * - * Because there are no notificaitons when the page is swapped in, wait - * a bit before retrying, and hope that the page will arrive eventually. - */ - usleep(1000); - goto retry; - } - - if (addr != MAP_FAILED) - { - int rv = 0; - struct ioctl_gntdev_unmap_notify notify; - notify.index = map->index; - notify.action = 0; - if (notify_offset < XC_PAGE_SIZE * count) { - notify.index += notify_offset; - notify.action |= UNMAP_NOTIFY_CLEAR_BYTE; - } - if (notify_port != -1) { - notify.event_channel_port = notify_port; - notify.action |= UNMAP_NOTIFY_SEND_EVENT; - } - if (notify.action) - rv = ioctl(fd, IOCTL_GNTDEV_SET_UNMAP_NOTIFY, ¬ify); - if (rv) { - PERROR("linux_gnttab_grant_map: ioctl SET_UNMAP_NOTIFY failed"); - munmap(addr, count * XC_PAGE_SIZE); - addr = MAP_FAILED; - } - } - - if (addr == MAP_FAILED) - { - int saved_errno = errno; - struct ioctl_gntdev_unmap_grant_ref unmap_grant; - - /* Unmap the driver slots used to store the grant information. */ - PERROR("xc_gnttab_map_grant_refs: mmap failed"); - unmap_grant.index = map->index; - unmap_grant.count = count; - ioctl(fd, IOCTL_GNTDEV_UNMAP_GRANT_REF, &unmap_grant); - errno = saved_errno; - addr = NULL; - } - - out: - if ( map_size > XC_PAGE_SIZE ) - munmap(map, map_size); - - return addr; -} - - - -static int linux_gnttab_munmap(xc_gnttab *xcg, xc_osdep_handle h, - void *start_address, uint32_t count) -{ - int fd = (int)h; - struct ioctl_gntdev_get_offset_for_vaddr get_offset; - struct ioctl_gntdev_unmap_grant_ref unmap_grant; - int rc; - - if ( start_address == NULL ) - { - errno = EINVAL; - return -1; - } - - /* First, it is necessary to get the offset which was initially used to - * mmap() the pages. - */ - get_offset.vaddr = (unsigned long)start_address; - if ( (rc = ioctl(fd, IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR, - &get_offset)) ) - return rc; - - if ( get_offset.count != count ) - { - errno = EINVAL; - return -1; - } - - /* Next, unmap the memory. */ - if ( (rc = munmap(start_address, count * getpagesize())) ) - return rc; - - /* Finally, unmap the driver slots used to store the grant information. */ - unmap_grant.index = get_offset.offset; - unmap_grant.count = count; - if ( (rc = ioctl(fd, IOCTL_GNTDEV_UNMAP_GRANT_REF, &unmap_grant)) ) - return rc; - - return 0; -} - -static struct xc_osdep_ops linux_gnttab_ops = { - .open = &linux_gnttab_open, - .close = &linux_gnttab_close, - - .u.gnttab = { - .set_max_grants = linux_gnttab_set_max_grants, - .grant_map = &linux_gnttab_grant_map, - .munmap = &linux_gnttab_munmap, - }, -}; - -static xc_osdep_handle linux_gntshr_open(xc_gntshr *xcg) -{ - int fd = open(DEVXEN "gntalloc", O_RDWR); - - if ( fd == -1 ) - return XC_OSDEP_OPEN_ERROR; - - return (xc_osdep_handle)fd; -} - -static int linux_gntshr_close(xc_gntshr *xcg, xc_osdep_handle h) -{ - int fd = (int)h; - return close(fd); -} - -static void *linux_gntshr_share_pages(xc_gntshr *xch, xc_osdep_handle h, - uint32_t domid, int count, - uint32_t *refs, int writable, - uint32_t notify_offset, - evtchn_port_t notify_port) -{ - struct ioctl_gntalloc_alloc_gref *gref_info = NULL; - struct ioctl_gntalloc_unmap_notify notify; - struct ioctl_gntalloc_dealloc_gref gref_drop; - int fd = (int)h; - int err; - void *area = NULL; - gref_info = malloc(sizeof(*gref_info) + count * sizeof(uint32_t)); - if (!gref_info) - return NULL; - gref_info->domid = domid; - gref_info->flags = writable ? GNTALLOC_FLAG_WRITABLE : 0; - gref_info->count = count; - - err = ioctl(fd, IOCTL_GNTALLOC_ALLOC_GREF, gref_info); - if (err) { - PERROR("linux_gntshr_share_pages: ioctl failed"); - goto out; - } - - area = mmap(NULL, count * XC_PAGE_SIZE, PROT_READ | PROT_WRITE, - MAP_SHARED, fd, gref_info->index); - - if (area == MAP_FAILED) { - area = NULL; - PERROR("linux_gntshr_share_pages: mmap failed"); - goto out_remove_fdmap; - } - - notify.index = gref_info->index; - notify.action = 0; - if (notify_offset < XC_PAGE_SIZE * count) { - notify.index += notify_offset; - notify.action |= UNMAP_NOTIFY_CLEAR_BYTE; - } - if (notify_port != -1) { - notify.event_channel_port = notify_port; - notify.action |= UNMAP_NOTIFY_SEND_EVENT; - } - if (notify.action) - err = ioctl(fd, IOCTL_GNTALLOC_SET_UNMAP_NOTIFY, ¬ify); - if (err) { - PERROR("linux_gntshr_share_page_notify: ioctl SET_UNMAP_NOTIFY failed"); - munmap(area, count * XC_PAGE_SIZE); - area = NULL; - } - - memcpy(refs, gref_info->gref_ids, count * sizeof(uint32_t)); - - out_remove_fdmap: - /* Removing the mapping from the file descriptor does not cause the pages to - * be deallocated until the mapping is removed. - */ - gref_drop.index = gref_info->index; - gref_drop.count = count; - ioctl(fd, IOCTL_GNTALLOC_DEALLOC_GREF, &gref_drop); - out: - free(gref_info); - return area; -} - -static int linux_gntshr_munmap(xc_gntshr *xcg, xc_osdep_handle h, - void *start_address, uint32_t count) -{ - return munmap(start_address, count); -} - -static struct xc_osdep_ops linux_gntshr_ops = { - .open = &linux_gntshr_open, - .close = &linux_gntshr_close, - - .u.gntshr = { - .share_pages = &linux_gntshr_share_pages, - .munmap = &linux_gntshr_munmap, - }, -}; - - -static struct xc_osdep_ops *linux_osdep_init(xc_interface *xch, enum xc_osdep_type type) -{ - switch ( type ) - { - case XC_OSDEP_PRIVCMD: - return &linux_privcmd_ops; - case XC_OSDEP_EVTCHN: - return &linux_evtchn_ops; - case XC_OSDEP_GNTTAB: - return &linux_gnttab_ops; - case XC_OSDEP_GNTSHR: - return &linux_gntshr_ops; - default: - return NULL; - } -} - -xc_osdep_info_t xc_osdep_info = { - .name = "Linux Native OS interface", - .init = &linux_osdep_init, - .fake = 0, -}; - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/tools/libxc/xenctrl_osdep_ENOSYS.c b/tools/libxc/xenctrl_osdep_ENOSYS.c deleted file mode 100644 index 4c156e9..0000000 --- a/tools/libxc/xenctrl_osdep_ENOSYS.c +++ /dev/null @@ -1,206 +0,0 @@ -/* Dummy backend which just logs and returns ENOSYS. */ - -#include -#include -#include - -#include "xenctrl.h" -#include "xenctrlosdep.h" - -#define IPRINTF(_x, _f, _a...) xc_osdep_log(_x,XTL_INFO,0, _f , ## _a) - -#define ERROR(_x, _m, _a...) xc_osdep_log(_x,XTL_ERROR,XC_INTERNAL_ERROR,_m , ## _a ) -#define PERROR(_x, _m, _a...) xc_osdep_log(_x,XTL_ERROR,XC_INTERNAL_ERROR,_m \ - " (%d = %s)", ## _a , errno, xc_strerror(xch, errno)) - -static xc_osdep_handle ENOSYS_privcmd_open(xc_interface *xch) -{ - IPRINTF(xch, "ENOSYS_privcmd: opening handle %p\n", (void *)1); - return (xc_osdep_handle)1; /*dummy*/ -} - -static int ENOSYS_privcmd_close(xc_interface *xch, xc_osdep_handle h) -{ - IPRINTF(xch, "ENOSYS_privcmd: closing handle %p\n", h); - return 0; -} - -static int ENOSYS_privcmd_hypercall(xc_interface *xch, xc_osdep_handle h, privcmd_hypercall_t *hypercall) -{ - IPRINTF(xch, "ENOSYS_privcmd %p: hypercall: %02lld(%#llx,%#llx,%#llx,%#llx,%#llx)\n", - h, hypercall->op, - hypercall->arg[0], hypercall->arg[1], hypercall->arg[2], - hypercall->arg[3], hypercall->arg[4]); - return -ENOSYS; -} - -static void *ENOSYS_privcmd_map_foreign_batch(xc_interface *xch, xc_osdep_handle h, uint32_t dom, int prot, - xen_pfn_t *arr, int num) -{ - IPRINTF(xch, "ENOSYS_privcmd %p: map_foreign_batch: dom%d prot %#x arr %p num %d\n", h, dom, prot, arr, num); - return MAP_FAILED; -} - -static void *ENOSYS_privcmd_map_foreign_bulk(xc_interface *xch, xc_osdep_handle h, uint32_t dom, int prot, - const xen_pfn_t *arr, int *err, unsigned int num) -{ - IPRINTF(xch, "ENOSYS_privcmd %p: map_foreign_buld: dom%d prot %#x arr %p err %p num %d\n", h, dom, prot, arr, err, num); - return MAP_FAILED; -} - -static void *ENOSYS_privcmd_map_foreign_range(xc_interface *xch, xc_osdep_handle h, uint32_t dom, int size, int prot, - unsigned long mfn) -{ - IPRINTF(xch, "ENOSYS_privcmd %p: map_foreign_range: dom%d size %#x prot %#x mfn %ld\n", h, dom, size, prot, mfn); - return MAP_FAILED; -} - -static void *ENOSYS_privcmd_map_foreign_ranges(xc_interface *xch, xc_osdep_handle h, uint32_t dom, size_t size, int prot, - size_t chunksize, privcmd_mmap_entry_t entries[], - int nentries) -{ - IPRINTF(xch, "ENOSYS_privcmd %p: map_foreign_ranges: dom%d size %zd prot %#x chunksize %zd entries %p num %d\n", h, dom, size, prot, chunksize, entries, nentries); - return MAP_FAILED; -} - -static struct xc_osdep_ops ENOSYS_privcmd_ops = -{ - .open = &ENOSYS_privcmd_open, - .close = &ENOSYS_privcmd_close, - .u.privcmd = { - .hypercall = &ENOSYS_privcmd_hypercall, - - .map_foreign_batch = &ENOSYS_privcmd_map_foreign_batch, - .map_foreign_bulk = &ENOSYS_privcmd_map_foreign_bulk, - .map_foreign_range = &ENOSYS_privcmd_map_foreign_range, - .map_foreign_ranges = &ENOSYS_privcmd_map_foreign_ranges, - } -}; - -static xc_osdep_handle ENOSYS_evtchn_open(xc_interface *xce) -{ - IPRINTF(xce, "ENOSYS_evtchn: opening handle %p\n", (void *)1); - return (xc_osdep_handle)2; /*dummy*/ -} - -static int ENOSYS_evtchn_close(xc_interface *xce, xc_osdep_handle h) -{ - IPRINTF(xce, "ENOSYS_evtchn: closing handle %p\n", h); - return 0; -} - -static int ENOSYS_evtchn_fd(xc_interface *xce, xc_osdep_handle h) -{ - IPRINTF(xce, "ENOSYS_fd %p: fd\n", h); - return (int)h; -} - -static int ENOSYS_evtchn_notify(xc_interface *xce, xc_osdep_handle h, evtchn_port_t port) -{ - IPRINTF(xce, "ENOSYS_evtchn %p: notify: %d\n", h, port); - return -ENOSYS; -} - -static int ENOSYS_evtchn_bind_unbound_port(xc_interface *xce, xc_osdep_handle h, int domid) -{ - IPRINTF(xce, "ENOSYS_evtchn %p: bind_unbound_port: dom%d\n", h, domid); - return -ENOSYS; -} - - -static int ENOSYS_evtchn_bind_interdomain(xc_interface *xce, xc_osdep_handle h, int domid, evtchn_port_t remote_port) -{ - IPRINTF(xce, "ENOSYS_evtchn %p: bind_interdomain: dmo%d %d\n", h, domid, remote_port); - return -ENOSYS; -} - - -static int ENOSYS_evtchn_bind_virq(xc_interface *xce, xc_osdep_handle h, unsigned int virq) -{ - IPRINTF(xce, "ENOSYS_evtchn %p: bind_virq: %d\n", h, virq); - return -ENOSYS; -} - - -static int ENOSYS_evtchn_unbind(xc_interface *xce, xc_osdep_handle h, evtchn_port_t port) -{ - IPRINTF(xce, "ENOSYS_evtchn %p: unbind: %d\n", h, port); - return -ENOSYS; -} - - -static evtchn_port_or_error_t ENOSYS_evtchn_pending(xc_interface *xce, xc_osdep_handle h) -{ - IPRINTF(xce, "ENOSYS_evtchn %p: pending\n", h); - return -ENOSYS; -} - -static int ENOSYS_evtchn_unmask(xc_interface *xce, xc_osdep_handle h, evtchn_port_t port) -{ - IPRINTF(xce, "ENOSYS_evtchn %p: unmask: %d\n", h, port); - return -ENOSYS; -} - -static struct xc_osdep_ops ENOSYS_evtchn_ops = { - .open = &ENOSYS_evtchn_open, - .close = &ENOSYS_evtchn_close, - - .u.evtchn = { - .fd = &ENOSYS_evtchn_fd, - - .notify = &ENOSYS_evtchn_notify, - - .bind_unbound_port = &ENOSYS_evtchn_bind_unbound_port, - .bind_interdomain = &ENOSYS_evtchn_bind_interdomain, - .bind_virq = &ENOSYS_evtchn_bind_virq, - - .unbind = &ENOSYS_evtchn_unbind, - - .pending = &ENOSYS_evtchn_pending, - .unmask = &ENOSYS_evtchn_unmask, - }, -}; - -static struct xc_osdep_ops * ENOSYS_osdep_init(xc_interface *xch, enum xc_osdep_type type) -{ - struct xc_osdep_ops *ops; - - if (getenv("ENOSYS") == NULL) - { - PERROR(xch, "ENOSYS: not configured\n"); - return NULL; - } - - switch ( type ) - { - case XC_OSDEP_PRIVCMD: - ops = &ENOSYS_privcmd_ops; - break; - case XC_OSDEP_EVTCHN: - ops = &ENOSYS_evtchn_ops; - break; - default: - ops = NULL; - break; - } - - IPRINTF(xch, "ENOSYS_osdep_init: initialising handle ops at %p\n", ops); - - return ops; -} - -xc_osdep_info_t xc_osdep_info = { - .name = "Pessimistic ENOSYS OS interface", - .init = &ENOSYS_osdep_init, - .fake = 1, -}; - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/tools/libxc/xenctrlosdep.h b/tools/libxc/xenctrlosdep.h deleted file mode 100644 index a36c4aa..0000000 --- a/tools/libxc/xenctrlosdep.h +++ /dev/null @@ -1,172 +0,0 @@ -/****************************************************************************** - * - * Interface to OS specific low-level operations - * - * Copyright (c) 2010, Citrix Systems Inc. - * - * 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * This interface defines the interactions between the Xen control - * libraries and the OS facilities used to communicate with the - * hypervisor. - * - * It is possible to override the default (native) implementation by - * setting the XENCTRL_OSDEP environment variable to point to a - * plugin library. Userspace can use this facility to intercept - * hypervisor operations. This can be used e.g. to implement a - * userspace simulator for Xen hypercalls. - * - * The plugin must contain a data structure: - * xc_osdep_info_t xc_osdep_info; - * - * xc_osdep_init: - * Must return a suitable struct xc_osdep_ops pointer or NULL on failure. - */ - -#ifndef XC_OSDEP_H -#define XC_OSDEP_H - -/* Tell the Xen public headers we are a user-space tools build. */ -#ifndef __XEN_TOOLS__ -#define __XEN_TOOLS__ 1 -#endif - -#include -#include - -#include - -enum xc_osdep_type { - XC_OSDEP_PRIVCMD, - XC_OSDEP_EVTCHN, - XC_OSDEP_GNTTAB, - XC_OSDEP_GNTSHR, -}; - -/* Opaque handle internal to the backend */ -typedef unsigned long xc_osdep_handle; - -#define XC_OSDEP_OPEN_ERROR ((xc_osdep_handle)-1) - -struct xc_osdep_ops -{ - /* Opens an interface. - * - * Must return an opaque handle on success or - * XC_OSDEP_OPEN_ERROR on failure - */ - xc_osdep_handle (*open)(xc_interface *xch); - - int (*close)(xc_interface *xch, xc_osdep_handle h); - - union { - struct { - void *(*alloc_hypercall_buffer)(xc_interface *xch, xc_osdep_handle h, int npages); - void (*free_hypercall_buffer)(xc_interface *xch, xc_osdep_handle h, void *ptr, int npages); - - int (*hypercall)(xc_interface *xch, xc_osdep_handle h, privcmd_hypercall_t *hypercall); - - void *(*map_foreign_batch)(xc_interface *xch, xc_osdep_handle h, uint32_t dom, int prot, - xen_pfn_t *arr, int num); - void *(*map_foreign_bulk)(xc_interface *xch, xc_osdep_handle h, uint32_t dom, int prot, - const xen_pfn_t *arr, int *err, unsigned int num); - void *(*map_foreign_range)(xc_interface *xch, xc_osdep_handle h, uint32_t dom, int size, int prot, - unsigned long mfn); - void *(*map_foreign_ranges)(xc_interface *xch, xc_osdep_handle h, uint32_t dom, size_t size, int prot, - size_t chunksize, privcmd_mmap_entry_t entries[], - int nentries); - } privcmd; - struct { - int (*fd)(xc_evtchn *xce, xc_osdep_handle h); - - int (*notify)(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port); - - evtchn_port_or_error_t (*bind_unbound_port)(xc_evtchn *xce, xc_osdep_handle h, int domid); - evtchn_port_or_error_t (*bind_interdomain)(xc_evtchn *xce, xc_osdep_handle h, int domid, - evtchn_port_t remote_port); - evtchn_port_or_error_t (*bind_virq)(xc_evtchn *xce, xc_osdep_handle h, unsigned int virq); - - int (*unbind)(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port); - - evtchn_port_or_error_t (*pending)(xc_evtchn *xce, xc_osdep_handle h); - int (*unmask)(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port); - } evtchn; - struct { -#define XC_GRANT_MAP_SINGLE_DOMAIN 0x1 - void *(*grant_map)(xc_gnttab *xcg, xc_osdep_handle h, - uint32_t count, int flags, int prot, - uint32_t *domids, uint32_t *refs, - uint32_t notify_offset, - evtchn_port_t notify_port); - int (*munmap)(xc_gnttab *xcg, xc_osdep_handle h, - void *start_address, - uint32_t count); - int (*set_max_grants)(xc_gnttab *xcg, xc_osdep_handle h, uint32_t count); - } gnttab; - struct { - void *(*share_pages)(xc_gntshr *xcg, xc_osdep_handle h, - uint32_t domid, int count, - uint32_t *refs, int writable, - uint32_t notify_offset, - evtchn_port_t notify_port); - int (*munmap)(xc_gntshr *xcg, xc_osdep_handle h, - void *start_address, uint32_t count); - } gntshr; - } u; -}; -typedef struct xc_osdep_ops xc_osdep_ops; - -typedef xc_osdep_ops *(*xc_osdep_init_fn)(xc_interface *xch, enum xc_osdep_type); - -struct xc_osdep_info -{ - /* Describes this backend. */ - const char *name; - - /* Returns ops function. */ - xc_osdep_init_fn init; - - /* True if this interface backs onto a fake Xen. */ - int fake; - - /* For internal use by loader. */ - void *dl_handle; -}; -typedef struct xc_osdep_info xc_osdep_info_t; - -/* All backends, including the builtin backend, must supply this structure. */ -extern xc_osdep_info_t xc_osdep_info; - -/* Stub for not yet converted OSes */ -void *xc_map_foreign_bulk_compat(xc_interface *xch, xc_osdep_handle h, - uint32_t dom, int prot, - const xen_pfn_t *arr, int *err, unsigned int num); - -/* Report errors through xc_interface */ -void xc_osdep_log(xc_interface *xch, xentoollog_level level, int code, const char *fmt, ...); - -#endif - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/tools/libxl/libxl_osdeps.h b/tools/libxl/libxl_osdeps.h deleted file mode 100644 index f91bc79..0000000 --- a/tools/libxl/libxl_osdeps.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2009 Citrix Ltd. - * Author Stefano Stabellini - * - * This program 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 only. with the special - * exception on linking described in file LICENSE. - * - * This program 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. - */ - -/* - * This header must be included first, before any system headers, - * so that _GNU_SOURCE takes effect properly. - */ - -#ifndef LIBXL_OSDEP -#define LIBXL_OSDEP - -#define _GNU_SOURCE - -#if defined(__NetBSD__) -#define SYSFS_PCI_DEV "/sys/bus/pci/devices" -#define SYSFS_PCIBACK_DRIVER "/kern/xen/pci" -#include -#elif defined(__OpenBSD__) -#include -#elif defined(__linux__) -#define SYSFS_PCI_DEV "/sys/bus/pci/devices" -#define SYSFS_PCIBACK_DRIVER "/sys/bus/pci/drivers/pciback" -#include -#elif defined(__sun__) -#include -#endif - -#ifndef SYSFS_PCIBACK_DRIVER -#error define SYSFS_PCIBACK_DRIVER for your platform -#endif -#ifndef SYSFS_PCI_DEV -#error define SYSFS_PCI_DEV for your platform -#endif - -#ifdef NEED_OWN_ASPRINTF -#include - -int asprintf(char **buffer, char *fmt, ...); -int vasprintf(char **buffer, const char *fmt, va_list ap); -#endif /*NEED_OWN_ASPRINTF*/ - -#endif - -/* - * Local variables: - * mode: C - * c-basic-offset: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/tools/libxl/osdeps.c b/tools/libxl/osdeps.c deleted file mode 100644 index 0e0b447..0000000 --- a/tools/libxl/osdeps.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2009 Citrix Ltd. - * Author Stefano Stabellini - * - * This program 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 only. with the special - * exception on linking described in file LICENSE. - * - * This program 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. - */ - -#include "libxl_osdeps.h" - -#include -#include -#include -#include -#include - -#ifdef NEED_OWN_ASPRINTF - -int vasprintf(char **buffer, const char *fmt, va_list ap) -{ - int size = 0; - int nchars; - - *buffer = 0; - - nchars = vsnprintf(*buffer, 0, fmt, ap); - - if (nchars >= size) - { - char *tmpbuff; - /* Reallocate buffer now that we know how much space is needed. */ - size = nchars+1; - tmpbuff = (char*)realloc(*buffer, size); - - - if (tmpbuff == NULL) { /* we need to free it*/ - free(*buffer); - return -1; - } - - *buffer=tmpbuff; - /* Try again. */ - nchars = vsnprintf(*buffer, size, fmt, ap); - } - - if (nchars < 0) return nchars; - return size; -} - -int asprintf(char **buffer, char *fmt, ...) -{ - int status; - va_list ap; - - va_start (ap, fmt); - status = vasprintf (buffer, fmt, ap); - va_end (ap); - return status; -} - -#endif - -/* - * Local variables: - * mode: C - * c-basic-offset: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/tools/python/xen/xend/osdep.py b/tools/python/xen/xend/osdep.py deleted file mode 100644 index b51dd2e..0000000 --- a/tools/python/xen/xend/osdep.py +++ /dev/null @@ -1,268 +0,0 @@ -#!/usr/bin/env python -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of version 2.1 of the GNU Lesser General Public -# License as published by the Free Software Foundation. -# -# 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, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# - -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. - -import os -import commands - -_xend_autorestart = { - "NetBSD": True, - "Linux": True, - "SunOS": False, -} - -_vif_script = { - "SunOS": "vif-vnic" -} - -_tapif_script = { - "Linux": "no", -} - -PROC_XEN_BALLOON = '/proc/xen/balloon' -SYSFS_XEN_MEMORY = '/sys/devices/system/xen_memory/xen_memory0' - -def _linux_balloon_stat_proc(label): - """Returns the value for the named label, or None if an error occurs.""" - - xend2linux_labels = { 'current' : 'Current allocation', - 'target' : 'Requested target', - 'low-balloon' : 'Low-mem balloon', - 'high-balloon' : 'High-mem balloon', - 'limit' : 'Xen hard limit' } - - f = file(PROC_XEN_BALLOON, 'r') - try: - for line in f: - keyvalue = line.split(':') - if keyvalue[0] == xend2linux_labels[label]: - values = keyvalue[1].split() - if values[0].isdigit(): - return int(values[0]) - else: - return None - return None - finally: - f.close() - -def _linux_balloon_stat_sysfs(label): - sysfiles = { 'target' : 'target_kb', - 'current' : 'info/current_kb', - 'low-balloon' : 'info/low_kb', - 'high-balloon' : 'info/high_kb', - 'limit' : 'info/hard_limit_kb' } - - name = os.path.join(SYSFS_XEN_MEMORY, sysfiles[label]) - f = file(name, 'r') - - val = f.read().strip() - if val.isdigit(): - return int(val) - return None - -def _linux_balloon_stat(label): - if os.access(PROC_XEN_BALLOON, os.F_OK): - return _linux_balloon_stat_proc(label) - elif os.access(SYSFS_XEN_MEMORY, os.F_OK): - return _linux_balloon_stat_sysfs(label) - return None - -def _netbsd_balloon_stat(label): - """Returns the value for the named label, or None if an error occurs.""" - - import commands - - xend2netbsd_labels = { 'current' : 'kern.xen.balloon.current', - 'target' : 'kern.xen.balloon.target', - 'low-balloon' : None, - 'high-balloon' : None, - 'limit' : None } - - cmdarg = xend2netbsd_labels[label] - if cmdarg is None: - return None - cmd = "/sbin/sysctl " + cmdarg - sysctloutput = commands.getoutput(cmd) - (name, value) = sysctloutput.split('=') - return int(value) - -def _solaris_balloon_stat(label): - """Returns the value for the named label, or None if an error occurs.""" - - import fcntl - import array - DEV_XEN_BALLOON = '/dev/xen/balloon' - BLN_IOCTL_CURRENT = 0x42410001 - BLN_IOCTL_TARGET = 0x42410002 - BLN_IOCTL_LOW = 0x42410003 - BLN_IOCTL_HIGH = 0x42410004 - BLN_IOCTL_LIMIT = 0x42410005 - label_to_ioctl = { 'current' : BLN_IOCTL_CURRENT, - 'target' : BLN_IOCTL_TARGET, - 'low-balloon' : BLN_IOCTL_LOW, - 'high-balloon' : BLN_IOCTL_HIGH, - 'limit' : BLN_IOCTL_LIMIT } - - f = file(DEV_XEN_BALLOON, 'r') - try: - values = array.array('L', [0]) - if fcntl.ioctl(f.fileno(), label_to_ioctl[label], values, 1) == 0: - return values[0] - else: - return None - finally: - f.close() - -_balloon_stat = { - "SunOS": _solaris_balloon_stat, - "NetBSD": _netbsd_balloon_stat, -} - -def _linux_get_cpuinfo(): - cpuinfo = {} - f = file('/proc/cpuinfo', 'r') - try: - p = -1 - d = {} - for line in f: - keyvalue = line.split(':') - if len(keyvalue) != 2: - continue - key = keyvalue[0].strip() - val = keyvalue[1].strip() - if key == 'processor': - if p != -1: - cpuinfo[p] = d - p = int(val) - d = {} - else: - d[key] = val - cpuinfo[p] = d - return cpuinfo - finally: - f.close() - -def _solaris_get_cpuinfo(): - cpuinfo = {} - - # call kstat to extrace specific cpu_info output - cmd = "/usr/bin/kstat -p -c misc -m cpu_info" - kstatoutput = commands.getoutput (cmd) - - # walk each line - for kstatline in kstatoutput.split('\n'): - - # split the line on - # module:cpu #:module#:name value - (module, cpunum, combo, namevalue) = kstatline.split (":") - - # check to see if this cpunum is already a key. If not, - # initialize an empty hash table - if not cpuinfo.has_key (int(cpunum)): - cpuinfo[int(cpunum)] = {} - - # split the namevalue output on whitespace - data = namevalue.split() - - # the key will be data[0] - key = data[0] - - # check the length of the data list. If it's larger than - # 2, join the rest of the list together with a space. - # Otherwise, value is just data[1] - if len (data) > 2: - value = ' '.join (data[1:]) - else: - value = data[1] - - # add this key/value pair to the cpuhash - cpuinfo[int(cpunum)][key] = value - - # Translate Solaris tokens into what Xend expects - for key in cpuinfo.keys(): - cpuinfo[key]["flags"] = "" - cpuinfo[key]["model name"] = cpuinfo[key]["brand"] - cpuinfo[key]["cpu MHz"] = cpuinfo[key]["clock_MHz"] - - # return the hash table - return cpuinfo - -def _netbsd_get_cpuinfo(): - import commands - cpuinfo = {} - - cmd = "/sbin/sysctl hw.ncpu" - sysctloutput = commands.getoutput(cmd) - (name, ncpu) = sysctloutput.split('=') - - for i in range(int(ncpu)): - if not cpuinfo.has_key(i): - cpuinfo[i] = {} - - # Translate NetBSD tokens into what xend expects - for key in cpuinfo.keys(): - cpuinfo[key]['flags'] = "" - cpuinfo[key]['vendor_id'] = "" - cpuinfo[key]['model name'] = "" - cpuinfo[key]['stepping'] = "" - cpuinfo[key]['cpu MHz'] = 0 - - return cpuinfo - - -_get_cpuinfo = { - "SunOS": _solaris_get_cpuinfo, - "NetBSD": _netbsd_get_cpuinfo -} - -def _default_prefork(name): - pass - -def _default_postfork(ct, abandon=False): - pass - -# call this for long-running processes that should survive a xend -# restart -def _solaris_prefork(name): - from xen.lowlevel import process - return process.activate(name) - -def _solaris_postfork(ct, abandon=False): - from xen.lowlevel import process - process.clear(ct) - if abandon: - process.abandon_latest() - -_get_prefork = { - "SunOS": _solaris_prefork -} - -_get_postfork = { - "SunOS": _solaris_postfork -} - -def _get(var, default=None): - return var.get(os.uname()[0], default) - -xend_autorestart = _get(_xend_autorestart) -vif_script = _get(_vif_script, "vif-bridge") -tapif_script = _get(_tapif_script) -lookup_balloon_stat = _get(_balloon_stat, _linux_balloon_stat) -get_cpuinfo = _get(_get_cpuinfo, _linux_get_cpuinfo) -prefork = _get(_get_prefork, _default_prefork) -postfork = _get(_get_postfork, _default_postfork) diff --git a/xen/arch/x86/hvm/rtc.c b/xen/arch/x86/hvm/rtc.c index 1d5c06c..d8f9f89 100644 --- a/xen/arch/x86/hvm/rtc.c +++ b/xen/arch/x86/hvm/rtc.c @@ -60,12 +60,19 @@ static void rtc_toggle_irq(RTCState *s) hvm_isa_irq_assert(d, RTC_IRQ); } -static void rtc_periodic_cb(struct vcpu *v, void *opaque) +void rtc_periodic_interrupt(void *opaque) { RTCState *s = opaque; spin_lock(&s->lock); - s->hw.cmos_data[RTC_REG_C] |= RTC_PF | RTC_IRQF; + if ( s->hw.cmos_data[RTC_REG_C] & RTC_PF ) + destroy_periodic_time(&s->pt); + else + { + s->hw.cmos_data[RTC_REG_C] |= RTC_PF; + if ( s->hw.cmos_data[RTC_REG_B] & RTC_PIE ) + rtc_toggle_irq(s); + } spin_unlock(&s->lock); } @@ -91,8 +98,7 @@ static void rtc_timer_update(RTCState *s) { period = 1 << (period_code - 1); /* period in 32 Khz cycles */ period = DIV_ROUND(period * 1000000000ULL, 32768); /* in ns */ - create_periodic_time(v, &s->pt, period, period, RTC_IRQ, - rtc_periodic_cb, s); + create_periodic_time(v, &s->pt, period, period, RTC_IRQ, NULL, s); break; } /* fall through */ diff --git a/xen/arch/x86/hvm/vpt.c b/xen/arch/x86/hvm/vpt.c index 15abad8..46d3ec6 100644 --- a/xen/arch/x86/hvm/vpt.c +++ b/xen/arch/x86/hvm/vpt.c @@ -22,6 +22,7 @@ #include #include #include +#include #define mode_is(d, name) \ ((d)->arch.hvm_domain.params[HVM_PARAM_TIMER_MODE] == HVMPTM_##name) @@ -218,6 +219,7 @@ int pt_update_irq(struct vcpu *v) struct periodic_time *pt, *temp, *earliest_pt = NULL; uint64_t max_lag = -1ULL; int irq, is_lapic; + void *pt_priv; spin_lock(&v->arch.hvm_vcpu.tm_lock); @@ -251,13 +253,14 @@ int pt_update_irq(struct vcpu *v) earliest_pt->irq_issued = 1; irq = earliest_pt->irq; is_lapic = (earliest_pt->source == PTSRC_lapic); + pt_priv = earliest_pt->priv; spin_unlock(&v->arch.hvm_vcpu.tm_lock); if ( is_lapic ) - { vlapic_set_irq(vcpu_vlapic(v), irq, 0); - } + else if ( irq == RTC_IRQ && pt_priv ) + rtc_periodic_interrupt(pt_priv); else { hvm_isa_irq_deassert(v->domain, irq); diff --git a/xen/include/asm-x86/hvm/vpt.h b/xen/include/asm-x86/hvm/vpt.h index 951c26c..c75297b 100644 --- a/xen/include/asm-x86/hvm/vpt.h +++ b/xen/include/asm-x86/hvm/vpt.h @@ -181,6 +181,7 @@ void rtc_migrate_timers(struct vcpu *v); void rtc_deinit(struct domain *d); void rtc_reset(struct domain *d); void rtc_update_clock(struct domain *d); +void rtc_periodic_interrupt(void *); void pmtimer_init(struct vcpu *v); void pmtimer_deinit(struct domain *d);