diff options
73 files changed, 2531 insertions, 3093 deletions
diff --git a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c index ad4e4224fc..c87096d1c4 100644 --- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c +++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c @@ -54,15 +54,6 @@ curvcpuid() } - -#define DOMFLAGS_DYING (1<<0) /* Domain is scheduled to die. */ -#define DOMFLAGS_SHUTDOWN (1<<2) /* The guest OS has shut down. */ -#define DOMFLAGS_PAUSED (1<<3) /* Currently paused by control software. */ -#define DOMFLAGS_BLOCKED (1<<4) /* Currently blocked pending an event. */ -#define DOMFLAGS_RUNNING (1<<5) /* Domain is currently running. */ - - - struct inferior_list all_processes; static int current_domid; static int expect_signal = 0; diff --git a/tools/debugger/libxendebug/Makefile b/tools/debugger/libxendebug/Makefile deleted file mode 100644 index 2e16446253..0000000000 --- a/tools/debugger/libxendebug/Makefile +++ /dev/null @@ -1,75 +0,0 @@ - -INSTALL = install -INSTALL_PROG = $(INSTALL) -m0755 -INSTALL_DATA = $(INSTALL) -m0644 -INSTALL_DIR = $(INSTALL) -d -m0755 - -MAJOR = 3.0 -MINOR = 0 - -XEN_ROOT = ../../.. -include $(XEN_ROOT)/tools/Rules.mk - -SRCS := xendebug.c - -CFLAGS += -Werror -fno-strict-aliasing -CFLAGS += $(INCLUDES) -I. -I$(XEN_ROOT)/tools/libxc -# Get gcc to generate the dependencies for us. -CFLAGS += -Wp,-MD,.$(@F).d -DEPS = .*.d - -LDFLAGS += -L$(XEN_ROOT)/tools/libxc -lxenctrl - -LIB_OBJS := $(patsubst %.c,%.o,$(SRCS)) -PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS)) - -LIB := libxendebug.a libxendebug.so -LIB += libxendebug.so.$(MAJOR) libxendebug.so.$(MAJOR).$(MINOR) - -.PHONY: all -all: build - -.PHONY: build -build: - $(MAKE) $(LIB) - -.PHONY: install -install: build - [ -d $(DESTDIR)/usr/$(LIBDIR) ] || $(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR) - [ -d $(DESTDIR)/usr/include ] || $(INSTALL_DIR) $(DESTDIR)/usr/include - $(INSTALL_PROG) libxendebug.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR) - $(INSTALL_DATA) libxendebug.a $(DESTDIR)/usr/$(LIBDIR) - ln -sf libxendebug.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)/libxendebug.so.$(MAJOR) - ln -sf libxendebug.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libxendebug.so - $(INSTALL_DATA) xendebug.h $(DESTDIR)/usr/include - -.PHONY: TAGS -TAGS: - etags -t $(SRCS) *.h - -.PHONY: clean -clean: - rm -rf *.a *.so* *.o *.opic *.rpm $(LIB) *~ $(DEPS) xen - -.PHONY: rpm -rpm: build - rm -rf staging - mkdir staging - mkdir staging/i386 - rpmbuild --define "staging$$PWD/staging" --define '_builddir.' \ - --define "_rpmdir$$PWD/staging" -bb rpm.spec - mv staging/i386/*.rpm . - rm -rf staging - -libxendebug.a: $(LIB_OBJS) - $(AR) rc $@ $^ - -libxendebug.so: libxendebug.so.$(MAJOR) - ln -sf $< $@ -libxendebug.so.$(MAJOR): libxendebug.so.$(MAJOR).$(MINOR) - ln -sf $< $@ - -libxendebug.so.$(MAJOR).$(MINOR): $(PIC_OBJS) - $(CC) $(CFLAGS) $(LDFLAGS) -Wl,-soname -Wl,libxendebug.so.$(MAJOR) -shared -o $@ $^ - --include $(DEPS) diff --git a/tools/debugger/libxendebug/list.h b/tools/debugger/libxendebug/list.h deleted file mode 100644 index d2ee720f34..0000000000 --- a/tools/debugger/libxendebug/list.h +++ /dev/null @@ -1,186 +0,0 @@ -#ifndef _LINUX_LIST_H -#define _LINUX_LIST_H - -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ - -struct list_head { - struct list_head *next, *prev; -}; - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -#define INIT_LIST_HEAD(ptr) do { \ - (ptr)->next = (ptr); (ptr)->prev = (ptr); \ -} while (0) - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static __inline__ void __list_add(struct list_head * new, - struct list_head * prev, - struct list_head * next) -{ - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; -} - -/** - * list_add - add a new entry - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - * This is good for implementing stacks. - */ -static __inline__ void list_add(struct list_head *new, struct list_head *head) -{ - __list_add(new, head, head->next); -} - -/** - * list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static __inline__ void list_add_tail(struct list_head *new, struct list_head *head) -{ - __list_add(new, head->prev, head); -} - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static __inline__ void __list_del(struct list_head * prev, - struct list_head * next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * list_del - deletes entry from list. - * @entry: the element to delete from the list. - * Note: list_empty on entry does not return true after this, the entry is in an undefined state. - */ -static __inline__ void list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); -} - -/** - * list_del_init - deletes entry from list and reinitialize it. - * @entry: the element to delete from the list. - */ -static __inline__ void list_del_init(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - INIT_LIST_HEAD(entry); -} - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static __inline__ int list_empty(struct list_head *head) -{ - return head->next == head; -} - -/** - * list_splice - join two lists - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static __inline__ void list_splice(struct list_head *list, struct list_head *head) -{ - struct list_head *first = list->next; - - if (first != list) { - struct list_head *last = list->prev; - struct list_head *at = head->next; - - first->prev = head; - head->next = first; - - last->next = at; - at->prev = last; - } -} - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) - -/** - * list_for_each - iterate over a list - * @pos: the &struct list_head to use as a loop counter. - * @head: the head for your list. - */ -#define list_for_each(pos, head) \ - for (pos = (head)->next; pos != (head); pos = pos->next) - -/** - * list_for_each_safe - iterate over a list safe against removal of list entry - * @pos: the &struct list_head to use as a loop counter. - * @n: another &struct list_head to use as temporary storage - * @head: the head for your list. - */ -#define list_for_each_safe(pos, n, head) \ - for (pos = (head)->next, n = pos->next; pos != (head); \ - pos = n, n = pos->next) - -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop counter. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - prefetch(pos->member.next); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member), \ - prefetch(pos->member.next)) - -/** - * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop counter. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) -#endif /* _LINUX_LIST_H */ - diff --git a/tools/debugger/libxendebug/xendebug.c b/tools/debugger/libxendebug/xendebug.c deleted file mode 100644 index c5d6143b77..0000000000 --- a/tools/debugger/libxendebug/xendebug.c +++ /dev/null @@ -1,599 +0,0 @@ -/* - * xendebug.c - * - * alex ho - * http://www.cl.cam.ac.uk/netos/pdb - * - * xendebug_memory_page adapted from xc_ptrace.c - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/mman.h> -#include <xenctrl.h> -#include "list.h" - -#if defined(__i386__) -#define L1_PAGETABLE_SHIFT 12 -#define L2_PAGETABLE_SHIFT 22 -#elif defined(__x86_64__) -#define L1_PAGETABLE_SHIFT 12 -#define L2_PAGETABLE_SHIFT 21 -#define L3_PAGETABLE_SHIFT 30 -#define L4_PAGETABLE_SHIFT 39 -#endif - -#define PAGE_SHIFT L1_PAGETABLE_SHIFT -#define PAGE_SIZE (1UL<<PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE - 1)) - -/* from xen/include/asm-x86/processor.h */ -#define X86_EFLAGS_TF 0x00000100 /* Trap Flag */ - -typedef int boolean; -#define true 1 -#define false 0 - - -typedef struct bwcpoint /* break/watch/catch point */ -{ - struct list_head list; - unsigned long address; - uint32_t domain; - uint8_t old_value; /* old value for software bkpt */ -} bwcpoint_t, *bwcpoint_p; - -static bwcpoint_t bwcpoint_list; - - - -typedef struct domain_context /* local cache of domain state */ -{ - struct list_head list; - uint32_t domid; - boolean valid[MAX_VIRT_CPUS]; - vcpu_guest_context_t context[MAX_VIRT_CPUS]; - - long total_pages; - xen_pfn_t *page_array; - - unsigned long cr3_phys[MAX_VIRT_CPUS]; - unsigned long *cr3_virt[MAX_VIRT_CPUS]; - unsigned long pde_phys[MAX_VIRT_CPUS]; - unsigned long *pde_virt[MAX_VIRT_CPUS]; - unsigned long page_phys[MAX_VIRT_CPUS]; - unsigned long *page_virt[MAX_VIRT_CPUS]; - int page_perm[MAX_VIRT_CPUS]; -} domain_context_t, *domain_context_p; - -static domain_context_t domain_context_list; - -/* initialization */ - -static boolean xendebug_initialized = false; - -static __inline__ void -xendebug_initialize() -{ - if ( !xendebug_initialized ) - { - memset((void *) &domain_context_list, 0, sizeof(domain_context_t)); - INIT_LIST_HEAD(&domain_context_list.list); - - memset((void *) &bwcpoint_list, 0, sizeof(bwcpoint_t)); - INIT_LIST_HEAD(&bwcpoint_list.list); - - xendebug_initialized = true; - } -} - -/**************/ - -static domain_context_p -xendebug_domain_context_search (uint32_t domid) -{ - struct list_head *entry; - domain_context_p ctxt; - - list_for_each(entry, &domain_context_list.list) - { - ctxt = list_entry(entry, domain_context_t, list); - if ( domid == ctxt->domid ) - return ctxt; - } - return (domain_context_p)NULL; -} - -static __inline__ domain_context_p -xendebug_get_context (int xc_handle, uint32_t domid, uint32_t vcpu) -{ - int rc; - domain_context_p ctxt; - - xendebug_initialize(); - - if ( (ctxt = xendebug_domain_context_search(domid)) == NULL) - return NULL; - - if ( !ctxt->valid[vcpu] ) - { - if ( (rc = xc_vcpu_getcontext(xc_handle, domid, vcpu, - &ctxt->context[vcpu])) ) - return NULL; - - ctxt->valid[vcpu] = true; - } - - return ctxt; -} - -static __inline__ int -xendebug_set_context (int xc_handle, domain_context_p ctxt, uint32_t vcpu) -{ - dom0_op_t op; - int rc; - - if ( !ctxt->valid[vcpu] ) - return -EINVAL; - - op.interface_version = DOM0_INTERFACE_VERSION; - op.cmd = DOM0_SETVCPUCONTEXT; - op.u.setvcpucontext.domain = ctxt->domid; - op.u.setvcpucontext.vcpu = vcpu; - op.u.setvcpucontext.ctxt = &ctxt->context[vcpu]; - - if ( (rc = mlock(&ctxt->context[vcpu], sizeof(vcpu_guest_context_t))) ) - return rc; - - rc = xc_dom0_op(xc_handle, &op); - (void) munlock(&ctxt->context[vcpu], sizeof(vcpu_guest_context_t)); - - return rc; -} - -/**************/ - -int -xendebug_attach(int xc_handle, - uint32_t domid, - uint32_t vcpu) -{ - domain_context_p ctxt; - - xendebug_initialize(); - - if ( (ctxt = malloc(sizeof(domain_context_t))) == NULL ) - return -1; - memset(ctxt, 0, sizeof(domain_context_t)); - - ctxt->domid = domid; - list_add(&ctxt->list, &domain_context_list.list); - - return xc_domain_pause(xc_handle, domid); -} - -int -xendebug_detach(int xc_handle, - uint32_t domid, - uint32_t vcpu) -{ - domain_context_p ctxt; - - xendebug_initialize(); - - if ( (ctxt = xendebug_domain_context_search (domid)) == NULL) - return -EINVAL; - - list_del(&ctxt->list); - - if ( ctxt->page_array ) free(ctxt->page_array); - - free(ctxt); - - return xc_domain_unpause(xc_handle, domid); -} - -int -xendebug_read_registers(int xc_handle, - uint32_t domid, - uint32_t vcpu, - cpu_user_regs_t **regs) -{ - domain_context_p ctxt; - int rc = -1; - - xendebug_initialize(); - - ctxt = xendebug_get_context(xc_handle, domid, vcpu); - if (ctxt) - { - *regs = &ctxt->context[vcpu].user_regs; - rc = 0; - } - - return rc; -} - -int -xendebug_read_fpregisters (int xc_handle, - uint32_t domid, - uint32_t vcpu, - char **regs) -{ - domain_context_p ctxt; - int rc = -1; - - xendebug_initialize(); - - ctxt = xendebug_get_context(xc_handle, domid, vcpu); - if (ctxt) - { - *regs = ctxt->context[vcpu].fpu_ctxt.x; - rc = 0; - } - - return rc; -} - -int -xendebug_write_registers(int xc_handle, - uint32_t domid, - uint32_t vcpu, - cpu_user_regs_t *regs) -{ - domain_context_p ctxt; - int rc = -1; - - xendebug_initialize(); - - ctxt = xendebug_get_context(xc_handle, domid, vcpu); - if (ctxt) - { - memcpy(&ctxt->context[vcpu].user_regs, regs, sizeof(cpu_user_regs_t)); - rc = xendebug_set_context(xc_handle, ctxt, vcpu); - } - - return rc; -} - -int -xendebug_step(int xc_handle, - uint32_t domid, - uint32_t vcpu) -{ - domain_context_p ctxt; - int rc; - - xendebug_initialize(); - - ctxt = xendebug_get_context(xc_handle, domid, vcpu); - if (!ctxt) return -EINVAL; - - ctxt->context[vcpu].user_regs.eflags |= X86_EFLAGS_TF; - - if ( (rc = xendebug_set_context(xc_handle, ctxt, vcpu)) ) - return rc; - - ctxt->valid[vcpu] = false; - return xc_domain_unpause(xc_handle, domid); -} - -int -xendebug_continue(int xc_handle, - uint32_t domid, - uint32_t vcpu) -{ - domain_context_p ctxt; - int rc; - - xendebug_initialize(); - - ctxt = xendebug_get_context(xc_handle, domid, vcpu); - if (!ctxt) return -EINVAL; - - if ( ctxt->context[vcpu].user_regs.eflags & X86_EFLAGS_TF ) - { - ctxt->context[vcpu].user_regs.eflags &= ~X86_EFLAGS_TF; - if ( (rc = xendebug_set_context(xc_handle, ctxt, vcpu)) ) - return rc; - } - ctxt->valid[vcpu] = false; - return xc_domain_unpause(xc_handle, domid); -} - -/*************************************************/ - -#define vtopdi(va) ((va) >> L2_PAGETABLE_SHIFT) -#define vtopti(va) (((va) >> PAGE_SHIFT) & 0x3ff) - -/* access to one page */ -static int -xendebug_memory_page (domain_context_p ctxt, int xc_handle, uint32_t vcpu, - int protection, unsigned long address, int length, uint8_t *buffer) -{ - vcpu_guest_context_t *vcpu_ctxt = &ctxt->context[vcpu]; - unsigned long pde, page; - unsigned long va = (unsigned long)address; - void *ptr; - long pages; - - pages = xc_get_tot_pages(xc_handle, ctxt->domid); - - if ( ctxt->total_pages != pages ) - { - if ( ctxt->total_pages > 0 ) free( ctxt->page_array ); - ctxt->total_pages = pages; - - ctxt->page_array = malloc(pages * sizeof(unsigned long)); - if ( ctxt->page_array == NULL ) - { - printf("Could not allocate memory\n"); - return 0; - } - - if ( xc_get_pfn_list(xc_handle, ctxt->domid, ctxt->page_array,pages) != - pages ) - { - printf("Could not get the page frame list\n"); - return 0; - } - } - - if ( vcpu_ctxt->ctrlreg[3] != ctxt->cr3_phys[vcpu]) - { - ctxt->cr3_phys[vcpu] = vcpu_ctxt->ctrlreg[3]; - if ( ctxt->cr3_virt[vcpu] ) - munmap(ctxt->cr3_virt[vcpu], PAGE_SIZE); - ctxt->cr3_virt[vcpu] = xc_map_foreign_range( - xc_handle, ctxt->domid, PAGE_SIZE, PROT_READ, - xen_cr3_to_pfn(ctxt->cr3_phys[vcpu])); - if ( ctxt->cr3_virt[vcpu] == NULL ) - return 0; - } - - - if ( (pde = ctxt->cr3_virt[vcpu][vtopdi(va)]) == 0) /* logical address */ - return 0; - if (ctxt->context[vcpu].flags & VGCF_HVM_GUEST) - pde = ctxt->page_array[pde >> PAGE_SHIFT] << PAGE_SHIFT; - if (pde != ctxt->pde_phys[vcpu]) - { - ctxt->pde_phys[vcpu] = pde; - if ( ctxt->pde_virt[vcpu]) - munmap(ctxt->pde_virt[vcpu], PAGE_SIZE); - ctxt->pde_virt[vcpu] = xc_map_foreign_range(xc_handle, ctxt->domid, - PAGE_SIZE, PROT_READ, ctxt->pde_phys[vcpu] >> PAGE_SHIFT); - if ( ctxt->pde_virt[vcpu] == NULL ) - return 0; - } - - if ((page = ctxt->pde_virt[vcpu][vtopti(va)]) == 0) /* logical address */ - return 0; - if (ctxt->context[vcpu].flags & VGCF_HVM_GUEST) - page = ctxt->page_array[page >> PAGE_SHIFT] << PAGE_SHIFT; - if (page != ctxt->page_phys[vcpu] || protection != ctxt->page_perm[vcpu]) - { - ctxt->page_phys[vcpu] = page; - if (ctxt->page_virt[vcpu]) - munmap(ctxt->page_virt[vcpu], PAGE_SIZE); - ctxt->page_virt[vcpu] = xc_map_foreign_range(xc_handle, ctxt->domid, - PAGE_SIZE, protection, ctxt->page_phys[vcpu] >> PAGE_SHIFT); - if ( ctxt->page_virt[vcpu] == NULL ) - { - printf("cr3 %lx pde %lx page %lx pti %lx\n", - vcpu_ctxt->ctrlreg[3], pde, page, vtopti(va)); - ctxt->page_phys[vcpu] = 0; - return 0; - } - ctxt->page_perm[vcpu] = protection; - } - - ptr = (void *)( (unsigned long)ctxt->page_virt[vcpu] | - (va & ~PAGE_MASK) ); - - if ( protection & PROT_WRITE ) - { - memcpy(ptr, buffer, length); - } - else - { - memcpy(buffer, ptr, length); - } - - return length; -} - -/* divide a memory operation into accesses to individual pages */ -static int -xendebug_memory_op (domain_context_p ctxt, int xc_handle, uint32_t vcpu, - int protection, unsigned long address, int length, uint8_t *buffer) -{ - int remain; /* number of bytes to touch past this page */ - int bytes = 0; - - while ( (remain = (address + length - 1) - (address | (PAGE_SIZE-1))) > 0) - { - bytes += xendebug_memory_page(ctxt, xc_handle, vcpu, protection, - address, length - remain, buffer); - buffer += (length - remain); - length = remain; - address = (address | (PAGE_SIZE - 1)) + 1; - } - - bytes += xendebug_memory_page(ctxt, xc_handle, vcpu, protection, - address, length, buffer); - - return bytes; -} - -int -xendebug_read_memory(int xc_handle, - uint32_t domid, - uint32_t vcpu, - unsigned long address, - uint32_t length, - uint8_t *data) -{ - domain_context_p ctxt; - - xendebug_initialize(); - - ctxt = xendebug_get_context(xc_handle, domid, vcpu); - - xendebug_memory_op(ctxt, xc_handle, vcpu, PROT_READ, - address, length, data); - - return 0; -} - -int -xendebug_write_memory(int xc_handle, - uint32_t domid, - uint32_t vcpu, - unsigned long address, - uint32_t length, - uint8_t *data) -{ - domain_context_p ctxt; - - xendebug_initialize(); - - ctxt = xendebug_get_context(xc_handle, domid, vcpu); - xendebug_memory_op(ctxt, xc_handle, vcpu, PROT_READ | PROT_WRITE, - - address, length, data); - - return 0; -} - -int -xendebug_insert_memory_breakpoint(int xc_handle, - uint32_t domid, - uint32_t vcpu, - unsigned long address, - uint32_t length) -{ - bwcpoint_p bkpt; - uint8_t breakpoint_opcode = 0xcc; - - printf("insert breakpoint %d:%lx %d\n", - domid, address, length); - - xendebug_initialize(); - - bkpt = malloc(sizeof(bwcpoint_t)); - if ( bkpt == NULL ) - { - printf("error: breakpoint length should be 1\n"); - return -1; - } - - if ( length != 1 ) - { - printf("error: breakpoint length should be 1\n"); - free(bkpt); - return -1; - } - - bkpt->address = address; - bkpt->domain = domid; - - xendebug_read_memory(xc_handle, domid, vcpu, address, 1, - &bkpt->old_value); - - xendebug_write_memory(xc_handle, domid, vcpu, address, 1, - &breakpoint_opcode); - - list_add(&bkpt->list, &bwcpoint_list.list); - - printf("breakpoint_set %d:%lx 0x%x\n", - domid, address, bkpt->old_value); - - return 0; -} - -int -xendebug_remove_memory_breakpoint(int xc_handle, - uint32_t domid, - uint32_t vcpu, - unsigned long address, - uint32_t length) -{ - bwcpoint_p bkpt = NULL; - - printf ("remove breakpoint %d:%lx\n", - domid, address); - - struct list_head *entry; - list_for_each(entry, &bwcpoint_list.list) - { - bkpt = list_entry(entry, bwcpoint_t, list); - if ( domid == bkpt->domain && address == bkpt->address ) - break; - } - - if (bkpt == &bwcpoint_list || bkpt == NULL) - { - printf ("error: no breakpoint found\n"); - return -1; - } - - list_del(&bkpt->list); - - xendebug_write_memory(xc_handle, domid, vcpu, address, 1, - &bkpt->old_value); - - free(bkpt); - return 0; -} - -int -xendebug_query_domain_stop(int xc_handle, int *dom_list, int dom_list_size) -{ - xc_dominfo_t *info; - uint32_t first_dom = 0; - int max_doms = 1024; - int nr_doms, loop; - int count = 0; - - if ( (info = malloc(max_doms * sizeof(xc_dominfo_t))) == NULL ) - return -ENOMEM; - - nr_doms = xc_domain_getinfo(xc_handle, first_dom, max_doms, info); - - for (loop = 0; loop < nr_doms; loop++) - { - printf ("domid: %d", info[loop].domid); - printf (" %c%c%c%c%c%c", - info[loop].dying ? 'D' : '-', - info[loop].crashed ? 'C' : '-', - info[loop].shutdown ? 'S' : '-', - info[loop].paused ? 'P' : '-', - info[loop].blocked ? 'B' : '-', - info[loop].running ? 'R' : '-'); - printf (" pages: %ld, vcpus %d", - info[loop].nr_pages, info[loop].vcpus); - printf ("\n"); - - if ( info[loop].paused && count < dom_list_size) - { - dom_list[count++] = info[loop].domid; - } - } - - free(info); - - return count; -} - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/tools/debugger/libxendebug/xendebug.h b/tools/debugger/libxendebug/xendebug.h deleted file mode 100644 index dfd2c3e2d3..0000000000 --- a/tools/debugger/libxendebug/xendebug.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * xendebug.h - * - * alex ho - * http://www.cl.cam.ac.uk/netos/pdb - * - */ - -#ifndef _XENDEBUG_H_DEFINED -#define _XENDEBUG_H_DEFINED - -#include <xenctrl.h> - -int xendebug_attach(int xc_handle, - uint32_t domid, - uint32_t vcpu); - -int xendebug_detach(int xc_handle, - uint32_t domid, - uint32_t vcpu); - -int xendebug_read_registers(int xc_handle, - uint32_t domid, - uint32_t vcpu, - cpu_user_regs_t **regs); - -int xendebug_read_fpregisters (int xc_handle, - uint32_t domid, - uint32_t vcpu, - char **regs); - -int xendebug_write_registers(int xc_handle, - uint32_t domid, - uint32_t vcpu, - cpu_user_regs_t *regs); - -int xendebug_step(int xc_handle, - uint32_t domid, - uint32_t vcpu); - -int xendebug_continue(int xc_handle, - uint32_t domid, - uint32_t vcpu); - -int xendebug_read_memory(int xc_handle, - uint32_t domid, - uint32_t vcpu, - unsigned long address, - uint32_t length, - uint8_t *data); - - -int xendebug_write_memory(int xc_handle, - uint32_t domid, - uint32_t vcpu, - unsigned long address, - uint32_t length, - uint8_t *data); - - -int xendebug_insert_memory_breakpoint(int xc_handle, - uint32_t domid, - uint32_t vcpu, - unsigned long address, - uint32_t length); - -int xendebug_remove_memory_breakpoint(int xc_handle, - uint32_t domid, - uint32_t vcpu, - unsigned long address, - uint32_t length); - -int xendebug_query_domain_stop(int xc_handle, - int *dom_list, - int dom_list_size); - - -#endif /* _XENDEBUG_H_DEFINED */ diff --git a/tools/libxc/ia64/xc_ia64_hvm_build.c b/tools/libxc/ia64/xc_ia64_hvm_build.c index ededfe6e5d..b400162192 100644 --- a/tools/libxc/ia64/xc_ia64_hvm_build.c +++ b/tools/libxc/ia64/xc_ia64_hvm_build.c @@ -555,7 +555,7 @@ setup_guest(int xc_handle, uint32_t dom, unsigned long memsize, shared_iopage_t *sp; int i; unsigned long dom_memsize = (memsize << 20); - DECLARE_DOM0_OP; + DECLARE_DOMCTL; if ((image_size > 12 * MEM_M) || (image_size & (PAGE_SIZE - 1))) { PERROR("Guest firmware size is incorrect [%ld]?", image_size); @@ -563,13 +563,12 @@ setup_guest(int xc_handle, uint32_t dom, unsigned long memsize, } /* This will creates the physmap. */ - op.u.domain_setup.flags = XEN_DOMAINSETUP_hvm_guest; - op.u.domain_setup.domain = (domid_t)dom; - op.u.domain_setup.bp = 0; - op.u.domain_setup.maxmem = 0; - - op.cmd = DOM0_DOMAIN_SETUP; - if (xc_dom0_op(xc_handle, &op)) + domctl.u.arch_setup.flags = XEN_DOMAINSETUP_hvm_guest; + domctl.u.arch_setup.bp = 0; + domctl.u.arch_setup.maxmem = 0; + domctl.cmd = XEN_DOMCTL_arch_setup; + domctl.domain = (domid_t)dom; + if (xc_domctl(xc_handle, &domctl)) goto error_out; /* Load guest firmware */ @@ -631,7 +630,7 @@ xc_hvm_build(int xc_handle, uint32_t domid, int memsize, unsigned int acpi, unsigned int apic, unsigned int store_evtchn, unsigned long *store_mfn) { - dom0_op_t launch_op, op; + struct xen_domctl launch_domctl, domctl; int rc; vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt; char *image = NULL; @@ -657,10 +656,10 @@ xc_hvm_build(int xc_handle, uint32_t domid, int memsize, return 1; } - op.cmd = DOM0_GETDOMAININFO; - op.u.getdomaininfo.domain = (domid_t)domid; - if (do_dom0_op(xc_handle, &op) < 0 || - (uint16_t)op.u.getdomaininfo.domain != domid) { + domctl.cmd = XEN_DOMCTL_getdomaininfo; + domctl.domain = (domid_t)domid; + if (do_domctl(xc_handle, &domctl) < 0 || + (uint16_t)domctl.domain != domid) { PERROR("Could not get info on domain"); goto error_out; } @@ -677,14 +676,14 @@ xc_hvm_build(int xc_handle, uint32_t domid, int memsize, ctxt->user_regs.cr_iip = 0x80000000ffffffb0UL; - memset(&launch_op, 0, sizeof(launch_op)); + memset(&launch_domctl, 0, sizeof(launch_domctl)); - launch_op.u.setvcpucontext.domain = (domid_t)domid; - launch_op.u.setvcpucontext.vcpu = 0; - set_xen_guest_handle(launch_op.u.setvcpucontext.ctxt, ctxt); + launch_domctl.domain = (domid_t)domid; + launch_domctl.u.vcpucontext.vcpu = 0; + set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, ctxt); - launch_op.cmd = DOM0_SETVCPUCONTEXT; - rc = do_dom0_op(xc_handle, &launch_op); + launch_domctl.cmd = XEN_DOMCTL_setvcpucontext; + rc = do_domctl(xc_handle, &launch_domctl); return rc; error_out: diff --git a/tools/libxc/ia64/xc_ia64_linux_restore.c b/tools/libxc/ia64/xc_ia64_linux_restore.c index 36e075ea8a..ef8476126b 100644 --- a/tools/libxc/ia64/xc_ia64_linux_restore.c +++ b/tools/libxc/ia64/xc_ia64_linux_restore.c @@ -61,7 +61,7 @@ xc_linux_restore(int xc_handle, int io_fd, uint32_t dom, unsigned long *store_mfn, unsigned int console_evtchn, unsigned long *console_mfn) { - DECLARE_DOM0_OP; + DECLARE_DOMCTL; int rc = 1, i; unsigned long mfn, pfn; unsigned long ver; @@ -94,19 +94,19 @@ xc_linux_restore(int xc_handle, int io_fd, uint32_t dom, } if (mlock(&ctxt, sizeof(ctxt))) { - /* needed for build dom0 op, but might as well do early */ + /* needed for build domctl, but might as well do early */ ERR("Unable to mlock ctxt"); return 1; } /* Get the domain's shared-info frame. */ - op.cmd = DOM0_GETDOMAININFO; - op.u.getdomaininfo.domain = (domid_t)dom; - if (xc_dom0_op(xc_handle, &op) < 0) { + domctl.cmd = XEN_DOMCTL_getdomaininfo; + domctl.domain = (domid_t)dom; + if (xc_domctl(xc_handle, &domctl) < 0) { ERR("Could not get information on new domain"); goto out; } - shared_info_frame = op.u.getdomaininfo.shared_info_frame; + shared_info_frame = domctl.u.getdomaininfo.shared_info_frame; if (xc_domain_setmaxmem(xc_handle, dom, PFN_TO_KB(max_pfn)) != 0) { errno = ENOMEM; @@ -122,20 +122,20 @@ xc_linux_restore(int xc_handle, int io_fd, uint32_t dom, DPRINTF("Increased domain reservation by %ld KB\n", PFN_TO_KB(max_pfn)); - if (!read_exact(io_fd, &op.u.domain_setup, sizeof(op.u.domain_setup))) { + if (!read_exact(io_fd, &domctl.u.arch_setup, sizeof(domctl.u.arch_setup))) { ERR("read: domain setup"); goto out; } /* Build firmware (will be overwritten). */ - op.u.domain_setup.domain = (domid_t)dom; - op.u.domain_setup.flags &= ~XEN_DOMAINSETUP_query; - op.u.domain_setup.bp = ((nr_pfns - 3) << PAGE_SHIFT) + domctl.domain = (domid_t)dom; + domctl.u.arch_setup.flags &= ~XEN_DOMAINSETUP_query; + domctl.u.arch_setup.bp = ((nr_pfns - 3) << PAGE_SHIFT) + sizeof (start_info_t); - op.u.domain_setup.maxmem = (nr_pfns - 3) << PAGE_SHIFT; + domctl.u.arch_setup.maxmem = (nr_pfns - 3) << PAGE_SHIFT; - op.cmd = DOM0_DOMAIN_SETUP; - if (xc_dom0_op(xc_handle, &op)) + domctl.cmd = XEN_DOMCTL_arch_setup; + if (xc_domctl(xc_handle, &domctl)) goto out; /* Get pages. */ @@ -226,22 +226,22 @@ xc_linux_restore(int xc_handle, int io_fd, uint32_t dom, } /* First to initialize. */ - op.cmd = DOM0_SETVCPUCONTEXT; - op.u.setvcpucontext.domain = (domid_t)dom; - op.u.setvcpucontext.vcpu = 0; - set_xen_guest_handle(op.u.setvcpucontext.ctxt, &ctxt); - if (xc_dom0_op(xc_handle, &op) != 0) { + domctl.cmd = XEN_DOMCTL_setvcpucontext; + domctl.domain = (domid_t)dom; + domctl.u.vcpucontext.vcpu = 0; + set_xen_guest_handle(domctl.u.vcpucontext.ctxt, &ctxt); + if (xc_domctl(xc_handle, &domctl) != 0) { ERR("Couldn't set vcpu context"); goto out; } /* Second to set registers... */ ctxt.flags = VGCF_EXTRA_REGS; - op.cmd = DOM0_SETVCPUCONTEXT; - op.u.setvcpucontext.domain = (domid_t)dom; - op.u.setvcpucontext.vcpu = 0; - set_xen_guest_handle(op.u.setvcpucontext.ctxt, &ctxt); - if (xc_dom0_op(xc_handle, &op) != 0) { + domctl.cmd = XEN_DOMCTL_setvcpucontext; + domctl.domain = (domid_t)dom; + domctl.u.vcpucontext.vcpu = 0; + set_xen_guest_handle(domctl.u.vcpucontext.ctxt, &ctxt); + if (xc_domctl(xc_handle, &domctl) != 0) { ERR("Couldn't set vcpu context"); goto out; } diff --git a/tools/libxc/ia64/xc_ia64_linux_save.c b/tools/libxc/ia64/xc_ia64_linux_save.c index 72183f1383..50f09773e0 100644 --- a/tools/libxc/ia64/xc_ia64_linux_save.c +++ b/tools/libxc/ia64/xc_ia64_linux_save.c @@ -60,7 +60,7 @@ static int xc_ia64_shadow_control(int xc_handle, unsigned int sop, unsigned long *dirty_bitmap, unsigned long pages, - xc_shadow_control_stats_t *stats) + xc_shadow_op_stats_t *stats) { if (dirty_bitmap != NULL && pages > 0) { int i; @@ -137,7 +137,7 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, uint32_t max_factor, uint32_t flags, int (*suspend)(int)) { - DECLARE_DOM0_OP; + DECLARE_DOMCTL; xc_dominfo_t info; int rc = 1; @@ -242,15 +242,15 @@ xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, } } - op.cmd = DOM0_DOMAIN_SETUP; - op.u.domain_setup.domain = (domid_t)dom; - op.u.domain_setup.flags = XEN_DOMAINSETUP_query; - if (xc_dom0_op(xc_handle, &op) < 0) { + domctl.cmd = XEN_DOMCTL_arch_setup; + domctl.domain = (domid_t)dom; + domctl.u.arch_setup.flags = XEN_DOMAINSETUP_query; + if (xc_domctl(xc_handle, &domctl) < 0) { ERR("Could not get domain setup"); goto out; } - op.u.domain_setup.domain = 0; - if (!write_exact(io_fd, &op.u.domain_setup, sizeof(op.u.domain_setup))) { + if (!write_exact(io_fd, &domctl.u.arch_setup, + sizeof(domctl.u.arch_setup))) { ERR("write: domain setup"); goto out; } @@ -259,7 +259,7 @@ xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, if (live) { if (xc_ia64_shadow_control(xc_handle, dom, - DOM0_SHADOW_CONTROL_OP_ENABLE_LOGDIRTY, + XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY, NULL, 0, NULL ) < 0) { ERR("Couldn't enable shadow mode"); goto out; @@ -324,7 +324,7 @@ xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, but this is fast enough for the moment. */ if (!last_iter) { if (xc_ia64_shadow_control(xc_handle, dom, - DOM0_SHADOW_CONTROL_OP_PEEK, + XEN_DOMCTL_SHADOW_OP_PEEK, to_skip, max_pfn, NULL) != max_pfn) { ERR("Error peeking shadow bitmap"); goto out; @@ -392,7 +392,7 @@ xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, /* Pages to be sent are pages which were dirty. */ if (xc_ia64_shadow_control(xc_handle, dom, - DOM0_SHADOW_CONTROL_OP_CLEAN, + XEN_DOMCTL_SHADOW_OP_CLEAN, to_send, max_pfn, NULL ) != max_pfn) { ERR("Error flushing shadow PT"); goto out; @@ -481,7 +481,7 @@ xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, out: if (live) { - if (xc_ia64_shadow_control(xc_handle, dom, DOM0_SHADOW_CONTROL_OP_OFF, + if (xc_ia64_shadow_control(xc_handle, dom, XEN_DOMCTL_SHADOW_OP_OFF, NULL, 0, NULL ) < 0) { DPRINTF("Warning - couldn't disable shadow mode"); } diff --git a/tools/libxc/ia64/xc_ia64_stubs.c b/tools/libxc/ia64/xc_ia64_stubs.c index 85f5d732fa..6b3639ff52 100644 --- a/tools/libxc/ia64/xc_ia64_stubs.c +++ b/tools/libxc/ia64/xc_ia64_stubs.c @@ -33,7 +33,7 @@ int xc_ia64_get_pfn_list(int xc_handle, uint32_t domid, xen_pfn_t *pfn_buf, unsigned int start_page, unsigned int nr_pages) { - dom0_op_t op; + struct xen_domctl domctl; int num_pfns,ret; unsigned int __start_page, __nr_pages; unsigned long max_pfns; @@ -45,11 +45,11 @@ xc_ia64_get_pfn_list(int xc_handle, uint32_t domid, xen_pfn_t *pfn_buf, while (__nr_pages) { max_pfns = ((unsigned long)__start_page << 32) | __nr_pages; - op.cmd = DOM0_GETMEMLIST; - op.u.getmemlist.domain = (domid_t)domid; - op.u.getmemlist.max_pfns = max_pfns; - op.u.getmemlist.num_pfns = 0; - set_xen_guest_handle(op.u.getmemlist.buffer, __pfn_buf); + domctl.cmd = XEN_DOMCTL_getmemlist; + domctl.domain = (domid_t)domid; + domctl.u.getmemlist.max_pfns = max_pfns; + domctl.u.getmemlist.num_pfns = 0; + set_xen_guest_handle(domctl.u.getmemlist.buffer, __pfn_buf); if ((max_pfns != -1UL) && mlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t)) != 0) { @@ -57,7 +57,7 @@ xc_ia64_get_pfn_list(int xc_handle, uint32_t domid, xen_pfn_t *pfn_buf, return -1; } - ret = do_dom0_op(xc_handle, &op); + ret = do_domctl(xc_handle, &domctl); if (max_pfns != -1UL) (void)munlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t)); @@ -65,7 +65,7 @@ xc_ia64_get_pfn_list(int xc_handle, uint32_t domid, xen_pfn_t *pfn_buf, if (max_pfns == -1UL) return 0; - num_pfns = op.u.getmemlist.num_pfns; + num_pfns = domctl.u.getmemlist.num_pfns; __start_page += num_pfns; __nr_pages -= num_pfns; __pfn_buf += num_pfns; @@ -89,10 +89,10 @@ xc_get_pfn_list(int xc_handle, uint32_t domid, xen_pfn_t *pfn_buf, long xc_get_max_pages(int xc_handle, uint32_t domid) { - dom0_op_t op; - op.cmd = DOM0_GETDOMAININFO; - op.u.getdomaininfo.domain = (domid_t)domid; - return (do_dom0_op(xc_handle, &op) < 0) ? -1 : op.u.getdomaininfo.max_pages; + struct xen_domctl domctl; + domctl.cmd = XEN_DOMCTL_getdomaininfo; + domctl.domain = (domid_t)domid; + return (do_domctl(xc_handle, &domctl) < 0) ? -1 : domctl.u.getdomaininfo.max_pages; } /* diff --git a/tools/libxc/powerpc64/xc_linux_build.c b/tools/libxc/powerpc64/xc_linux_build.c index df3da87aef..2624ed400f 100644 --- a/tools/libxc/powerpc64/xc_linux_build.c +++ b/tools/libxc/powerpc64/xc_linux_build.c @@ -27,7 +27,6 @@ #include <sys/types.h> #include <inttypes.h> -#include <xen/dom0_ops.h> #include <xen/memory.h> #include <xc_private.h> #include <xg_private.h> diff --git a/tools/libxc/xc_csched.c b/tools/libxc/xc_csched.c index 944529fea0..4ea986fae2 100644 --- a/tools/libxc/xc_csched.c +++ b/tools/libxc/xc_csched.c @@ -15,36 +15,36 @@ int xc_sched_credit_domain_set( int xc_handle, uint32_t domid, - struct sched_credit_adjdom *sdom) + struct xen_domctl_sched_credit *sdom) { - DECLARE_DOM0_OP; + DECLARE_DOMCTL; - op.cmd = DOM0_ADJUSTDOM; - op.u.adjustdom.domain = (domid_t) domid; - op.u.adjustdom.sched_id = SCHED_CREDIT; - op.u.adjustdom.direction = SCHED_INFO_PUT; - op.u.adjustdom.u.credit = *sdom; + domctl.cmd = XEN_DOMCTL_scheduler_op; + domctl.domain = (domid_t) domid; + domctl.u.scheduler_op.sched_id = XEN_SCHEDULER_CREDIT; + domctl.u.scheduler_op.cmd = XEN_DOMCTL_SCHEDOP_putinfo; + domctl.u.scheduler_op.u.credit = *sdom; - return do_dom0_op(xc_handle, &op); + return do_domctl(xc_handle, &domctl); } int xc_sched_credit_domain_get( int xc_handle, uint32_t domid, - struct sched_credit_adjdom *sdom) + struct xen_domctl_sched_credit *sdom) { - DECLARE_DOM0_OP; + DECLARE_DOMCTL; int err; - op.cmd = DOM0_ADJUSTDOM; - op.u.adjustdom.domain = (domid_t) domid; - op.u.adjustdom.sched_id = SCHED_CREDIT; - op.u.adjustdom.direction = SCHED_INFO_GET; + domctl.cmd = XEN_DOMCTL_scheduler_op; + domctl.domain = (domid_t) domid; + domctl.u.scheduler_op.sched_id = XEN_SCHEDULER_CREDIT; + domctl.u.scheduler_op.cmd = XEN_DOMCTL_SCHEDOP_getinfo; - err = do_dom0_op(xc_handle, &op); + err = do_domctl(xc_handle, &domctl); if ( err == 0 ) - *sdom = op.u.adjustdom.u.credit; + *sdom = domctl.u.scheduler_op.u.credit; return err; } diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index f182f43a43..20b0c764c3 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -15,16 +15,16 @@ int xc_domain_create(int xc_handle, uint32_t *pdomid) { int err; - DECLARE_DOM0_OP; + DECLARE_DOMCTL; - op.cmd = DOM0_CREATEDOMAIN; - op.u.createdomain.domain = (domid_t)*pdomid; - op.u.createdomain.ssidref = ssidref; - memcpy(op.u.createdomain.handle, handle, sizeof(xen_domain_handle_t)); - if ( (err = do_dom0_op(xc_handle, &op)) != 0 ) + domctl.cmd = XEN_DOMCTL_createdomain; + domctl.domain = (domid_t)*pdomid; + domctl.u.createdomain.ssidref = ssidref; + memcpy(domctl.u.createdomain.handle, handle, sizeof(xen_domain_handle_t)); + if ( (err = do_domctl(xc_handle, &domctl)) != 0 ) return err; - *pdomid = (uint16_t)op.u.createdomain.domain; + *pdomid = (uint16_t)domctl.domain; return 0; } @@ -32,30 +32,30 @@ int xc_domain_create(int xc_handle, int xc_domain_pause(int xc_handle, uint32_t domid) { - DECLARE_DOM0_OP; - op.cmd = DOM0_PAUSEDOMAIN; - op.u.pausedomain.domain = (domid_t)domid; - return do_dom0_op(xc_handle, &op); + DECLARE_DOMCTL; + domctl.cmd = XEN_DOMCTL_pausedomain; + domctl.domain = (domid_t)domid; + return do_domctl(xc_handle, &domctl); } int xc_domain_unpause(int xc_handle, uint32_t domid) { - DECLARE_DOM0_OP; - op.cmd = DOM0_UNPAUSEDOMAIN; - op.u.unpausedomain.domain = (domid_t)domid; - return do_dom0_op(xc_handle, &op); + DECLARE_DOMCTL; + domctl.cmd = XEN_DOMCTL_unpausedomain; + domctl.domain = (domid_t)domid; + return do_domctl(xc_handle, &domctl); } int xc_domain_destroy(int xc_handle, uint32_t domid) { - DECLARE_DOM0_OP; - op.cmd = DOM0_DESTROYDOMAIN; - op.u.destroydomain.domain = (domid_t)domid; - return do_dom0_op(xc_handle, &op); + DECLARE_DOMCTL; + domctl.cmd = XEN_DOMCTL_destroydomain; + domctl.domain = (domid_t)domid; + return do_domctl(xc_handle, &domctl); } int xc_domain_shutdown(int xc_handle, @@ -90,14 +90,62 @@ int xc_domain_shutdown(int xc_handle, int xc_vcpu_setaffinity(int xc_handle, uint32_t domid, int vcpu, - cpumap_t cpumap) + uint64_t cpumap) { - DECLARE_DOM0_OP; - op.cmd = DOM0_SETVCPUAFFINITY; - op.u.setvcpuaffinity.domain = (domid_t)domid; - op.u.setvcpuaffinity.vcpu = vcpu; - op.u.setvcpuaffinity.cpumap = cpumap; - return do_dom0_op(xc_handle, &op); + DECLARE_DOMCTL; + int ret = -1; + + domctl.cmd = XEN_DOMCTL_setvcpuaffinity; + domctl.domain = (domid_t)domid; + domctl.u.vcpuaffinity.vcpu = vcpu; + + set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, + (uint8_t *)&cpumap); + domctl.u.vcpuaffinity.cpumap.nr_cpus = sizeof(cpumap) * 8; + + if ( mlock(&cpumap, sizeof(cpumap)) != 0 ) + { + PERROR("Could not lock memory for Xen hypercall"); + goto out; + } + + ret = do_domctl(xc_handle, &domctl); + + safe_munlock(&cpumap, sizeof(cpumap)); + + out: + return ret; +} + + +int xc_vcpu_getaffinity(int xc_handle, + uint32_t domid, + int vcpu, + uint64_t *cpumap) +{ + DECLARE_DOMCTL; + int ret = -1; + + domctl.cmd = XEN_DOMCTL_getvcpuaffinity; + domctl.domain = (domid_t)domid; + domctl.u.vcpuaffinity.vcpu = vcpu; + + set_xen_guest_handle(domctl.u.vcpuaffinity.cpumap.bitmap, + (uint8_t *)cpumap); + domctl.u.vcpuaffinity.cpumap.nr_cpus = sizeof(*cpumap) * 8; + + if ( mlock(cpumap, sizeof(*cpumap)) != 0 ) + { + PERROR("Could not lock memory for Xen hypercall"); + goto out; + } + + ret = do_domctl(xc_handle, &domctl); + + safe_munlock(cpumap, sizeof(*cpumap)); + + out: + return ret; } @@ -108,27 +156,27 @@ int xc_domain_getinfo(int xc_handle, { unsigned int nr_doms; uint32_t next_domid = first_domid; - DECLARE_DOM0_OP; + DECLARE_DOMCTL; int rc = 0; memset(info, 0, max_doms*sizeof(xc_dominfo_t)); for ( nr_doms = 0; nr_doms < max_doms; nr_doms++ ) { - op.cmd = DOM0_GETDOMAININFO; - op.u.getdomaininfo.domain = (domid_t)next_domid; - if ( (rc = do_dom0_op(xc_handle, &op)) < 0 ) + domctl.cmd = XEN_DOMCTL_getdomaininfo; + domctl.domain = (domid_t)next_domid; + if ( (rc = do_domctl(xc_handle, &domctl)) < 0 ) break; - info->domid = (uint16_t)op.u.getdomaininfo.domain; + info->domid = (uint16_t)domctl.domain; - info->dying = !!(op.u.getdomaininfo.flags & DOMFLAGS_DYING); - info->shutdown = !!(op.u.getdomaininfo.flags & DOMFLAGS_SHUTDOWN); - info->paused = !!(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED); - info->blocked = !!(op.u.getdomaininfo.flags & DOMFLAGS_BLOCKED); - info->running = !!(op.u.getdomaininfo.flags & DOMFLAGS_RUNNING); + info->dying = !!(domctl.u.getdomaininfo.flags & DOMFLAGS_DYING); + info->shutdown = !!(domctl.u.getdomaininfo.flags & DOMFLAGS_SHUTDOWN); + info->paused = !!(domctl.u.getdomaininfo.flags & DOMFLAGS_PAUSED); + info->blocked = !!(domctl.u.getdomaininfo.flags & DOMFLAGS_BLOCKED); + info->running = !!(domctl.u.getdomaininfo.flags & DOMFLAGS_RUNNING); info->shutdown_reason = - (op.u.getdomaininfo.flags>>DOMFLAGS_SHUTDOWNSHIFT) & + (domctl.u.getdomaininfo.flags>>DOMFLAGS_SHUTDOWNSHIFT) & DOMFLAGS_SHUTDOWNMASK; if ( info->shutdown && (info->shutdown_reason == SHUTDOWN_crash) ) @@ -137,18 +185,18 @@ int xc_domain_getinfo(int xc_handle, info->crashed = 1; } - info->ssidref = op.u.getdomaininfo.ssidref; - info->nr_pages = op.u.getdomaininfo.tot_pages; - info->max_memkb = op.u.getdomaininfo.max_pages << (PAGE_SHIFT - 10); - info->shared_info_frame = op.u.getdomaininfo.shared_info_frame; - info->cpu_time = op.u.getdomaininfo.cpu_time; - info->nr_online_vcpus = op.u.getdomaininfo.nr_online_vcpus; - info->max_vcpu_id = op.u.getdomaininfo.max_vcpu_id; + info->ssidref = domctl.u.getdomaininfo.ssidref; + info->nr_pages = domctl.u.getdomaininfo.tot_pages; + info->max_memkb = domctl.u.getdomaininfo.max_pages << (PAGE_SHIFT-10); + info->shared_info_frame = domctl.u.getdomaininfo.shared_info_frame; + info->cpu_time = domctl.u.getdomaininfo.cpu_time; + info->nr_online_vcpus = domctl.u.getdomaininfo.nr_online_vcpus; + info->max_vcpu_id = domctl.u.getdomaininfo.max_vcpu_id; - memcpy(info->handle, op.u.getdomaininfo.handle, + memcpy(info->handle, domctl.u.getdomaininfo.handle, sizeof(xen_domain_handle_t)); - next_domid = (uint16_t)op.u.getdomaininfo.domain + 1; + next_domid = (uint16_t)domctl.domain + 1; info++; } @@ -163,20 +211,20 @@ int xc_domain_getinfolist(int xc_handle, xc_domaininfo_t *info) { int ret = 0; - DECLARE_DOM0_OP; + DECLARE_SYSCTL; if ( mlock(info, max_domains*sizeof(xc_domaininfo_t)) != 0 ) return -1; - op.cmd = DOM0_GETDOMAININFOLIST; - op.u.getdomaininfolist.first_domain = first_domain; - op.u.getdomaininfolist.max_domains = max_domains; - set_xen_guest_handle(op.u.getdomaininfolist.buffer, info); + sysctl.cmd = XEN_SYSCTL_getdomaininfolist; + sysctl.u.getdomaininfolist.first_domain = first_domain; + sysctl.u.getdomaininfolist.max_domains = max_domains; + set_xen_guest_handle(sysctl.u.getdomaininfolist.buffer, info); - if ( xc_dom0_op(xc_handle, &op) < 0 ) + if ( xc_sysctl(xc_handle, &sysctl) < 0 ) ret = -1; else - ret = op.u.getdomaininfolist.num_domains; + ret = sysctl.u.getdomaininfolist.num_domains; if ( munlock(info, max_domains*sizeof(xc_domaininfo_t)) != 0 ) ret = -1; @@ -190,17 +238,17 @@ int xc_vcpu_getcontext(int xc_handle, vcpu_guest_context_t *ctxt) { int rc; - DECLARE_DOM0_OP; + DECLARE_DOMCTL; - op.cmd = DOM0_GETVCPUCONTEXT; - op.u.getvcpucontext.domain = (domid_t)domid; - op.u.getvcpucontext.vcpu = (uint16_t)vcpu; - set_xen_guest_handle(op.u.getvcpucontext.ctxt, ctxt); + domctl.cmd = XEN_DOMCTL_getvcpucontext; + domctl.domain = (domid_t)domid; + domctl.u.vcpucontext.vcpu = (uint16_t)vcpu; + set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt); if ( (rc = mlock(ctxt, sizeof(*ctxt))) != 0 ) return rc; - rc = do_dom0_op(xc_handle, &op); + rc = do_domctl(xc_handle, &domctl); safe_munlock(ctxt, sizeof(*ctxt)); @@ -215,28 +263,28 @@ int xc_shadow_control(int xc_handle, unsigned long pages, unsigned long *mb, uint32_t mode, - xc_shadow_control_stats_t *stats) + xc_shadow_op_stats_t *stats) { int rc; - DECLARE_DOM0_OP; - op.cmd = DOM0_SHADOW_CONTROL; - op.u.shadow_control.domain = (domid_t)domid; - op.u.shadow_control.op = sop; - op.u.shadow_control.pages = pages; - op.u.shadow_control.mb = mb ? *mb : 0; - op.u.shadow_control.mode = mode; - set_xen_guest_handle(op.u.shadow_control.dirty_bitmap, dirty_bitmap); + DECLARE_DOMCTL; + domctl.cmd = XEN_DOMCTL_shadow_op; + domctl.domain = (domid_t)domid; + domctl.u.shadow_op.op = sop; + domctl.u.shadow_op.pages = pages; + domctl.u.shadow_op.mb = mb ? *mb : 0; + domctl.u.shadow_op.mode = mode; + set_xen_guest_handle(domctl.u.shadow_op.dirty_bitmap, dirty_bitmap); - rc = do_dom0_op(xc_handle, &op); + rc = do_domctl(xc_handle, &domctl); if ( stats ) - memcpy(stats, &op.u.shadow_control.stats, - sizeof(xc_shadow_control_stats_t)); + memcpy(stats, &domctl.u.shadow_op.stats, + sizeof(xc_shadow_op_stats_t)); if ( mb ) - *mb = op.u.shadow_control.mb; + *mb = domctl.u.shadow_op.mb; - return (rc == 0) ? op.u.shadow_control.pages : rc; + return (rc == 0) ? domctl.u.shadow_op.pages : rc; } int xc_domain_setcpuweight(int xc_handle, @@ -258,22 +306,22 @@ int xc_domain_setmaxmem(int xc_handle, uint32_t domid, unsigned int max_memkb) { - DECLARE_DOM0_OP; - op.cmd = DOM0_SETDOMAINMAXMEM; - op.u.setdomainmaxmem.domain = (domid_t)domid; - op.u.setdomainmaxmem.max_memkb = max_memkb; - return do_dom0_op(xc_handle, &op); + DECLARE_DOMCTL; + domctl.cmd = XEN_DOMCTL_max_mem; + domctl.domain = (domid_t)domid; + domctl.u.max_mem.max_memkb = max_memkb; + return do_domctl(xc_handle, &domctl); } int xc_domain_set_time_offset(int xc_handle, uint32_t domid, int32_t time_offset_seconds) { - DECLARE_DOM0_OP; - op.cmd = DOM0_SETTIMEOFFSET; - op.u.settimeoffset.domain = (domid_t)domid; - op.u.settimeoffset.time_offset_seconds = time_offset_seconds; - return do_dom0_op(xc_handle, &op); + DECLARE_DOMCTL; + domctl.cmd = XEN_DOMCTL_settimeoffset; + domctl.domain = (domid_t)domid; + domctl.u.settimeoffset.time_offset_seconds = time_offset_seconds; + return do_domctl(xc_handle, &domctl); } int xc_domain_memory_increase_reservation(int xc_handle, @@ -397,21 +445,22 @@ int xc_domain_translate_gpfn_list(int xc_handle, int xc_domain_max_vcpus(int xc_handle, uint32_t domid, unsigned int max) { - DECLARE_DOM0_OP; - op.cmd = DOM0_MAX_VCPUS; - op.u.max_vcpus.domain = (domid_t)domid; - op.u.max_vcpus.max = max; - return do_dom0_op(xc_handle, &op); + DECLARE_DOMCTL; + domctl.cmd = XEN_DOMCTL_max_vcpus; + domctl.domain = (domid_t)domid; + domctl.u.max_vcpus.max = max; + return do_domctl(xc_handle, &domctl); } int xc_domain_sethandle(int xc_handle, uint32_t domid, xen_domain_handle_t handle) { - DECLARE_DOM0_OP; - op.cmd = DOM0_SETDOMAINHANDLE; - op.u.setdomainhandle.domain = (domid_t)domid; - memcpy(op.u.setdomainhandle.handle, handle, sizeof(xen_domain_handle_t)); - return do_dom0_op(xc_handle, &op); + DECLARE_DOMCTL; + domctl.cmd = XEN_DOMCTL_setdomainhandle; + domctl.domain = (domid_t)domid; + memcpy(domctl.u.setdomainhandle.handle, handle, + sizeof(xen_domain_handle_t)); + return do_domctl(xc_handle, &domctl); } int xc_vcpu_getinfo(int xc_handle, @@ -420,14 +469,15 @@ int xc_vcpu_getinfo(int xc_handle, xc_vcpuinfo_t *info) { int rc; - DECLARE_DOM0_OP; - op.cmd = DOM0_GETVCPUINFO; - op.u.getvcpuinfo.domain = (domid_t)domid; - op.u.getvcpuinfo.vcpu = (uint16_t)vcpu; + DECLARE_DOMCTL; + + domctl.cmd = XEN_DOMCTL_getvcpuinfo; + domctl.domain = (domid_t)domid; + domctl.u.getvcpuinfo.vcpu = (uint16_t)vcpu; - rc = do_dom0_op(xc_handle, &op); + rc = do_domctl(xc_handle, &domctl); - memcpy(info, &op.u.getvcpuinfo, sizeof(*info)); + memcpy(info, &domctl.u.getvcpuinfo, sizeof(*info)); return rc; } @@ -438,15 +488,15 @@ int xc_domain_ioport_permission(int xc_handle, uint32_t nr_ports, uint32_t allow_access) { - DECLARE_DOM0_OP; + DECLARE_DOMCTL; - op.cmd = DOM0_IOPORT_PERMISSION; - op.u.ioport_permission.domain = (domid_t)domid; - op.u.ioport_permission.first_port = first_port; - op.u.ioport_permission.nr_ports = nr_ports; - op.u.ioport_permission.allow_access = allow_access; + domctl.cmd = XEN_DOMCTL_ioport_permission; + domctl.domain = (domid_t)domid; + domctl.u.ioport_permission.first_port = first_port; + domctl.u.ioport_permission.nr_ports = nr_ports; + domctl.u.ioport_permission.allow_access = allow_access; - return do_dom0_op(xc_handle, &op); + return do_domctl(xc_handle, &domctl); } int xc_vcpu_setcontext(int xc_handle, @@ -454,18 +504,18 @@ int xc_vcpu_setcontext(int xc_handle, uint32_t vcpu, vcpu_guest_context_t *ctxt) { - dom0_op_t op; + DECLARE_DOMCTL; int rc; - op.cmd = DOM0_SETVCPUCONTEXT; - op.u.setvcpucontext.domain = domid; - op.u.setvcpucontext.vcpu = vcpu; - set_xen_guest_handle(op.u.setvcpucontext.ctxt, ctxt); + domctl.cmd = XEN_DOMCTL_setvcpucontext; + domctl.domain = domid; + domctl.u.vcpucontext.vcpu = vcpu; + set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt); if ( (rc = mlock(ctxt, sizeof(*ctxt))) != 0 ) return rc; - rc = do_dom0_op(xc_handle, &op); + rc = do_domctl(xc_handle, &domctl); safe_munlock(ctxt, sizeof(*ctxt)); @@ -478,14 +528,14 @@ int xc_domain_irq_permission(int xc_handle, uint8_t pirq, uint8_t allow_access) { - dom0_op_t op; + DECLARE_DOMCTL; - op.cmd = DOM0_IRQ_PERMISSION; - op.u.irq_permission.domain = domid; - op.u.irq_permission.pirq = pirq; - op.u.irq_permission.allow_access = allow_access; + domctl.cmd = XEN_DOMCTL_irq_permission; + domctl.domain = domid; + domctl.u.irq_permission.pirq = pirq; + domctl.u.irq_permission.allow_access = allow_access; - return do_dom0_op(xc_handle, &op); + return do_domctl(xc_handle, &domctl); } int xc_domain_iomem_permission(int xc_handle, @@ -494,15 +544,15 @@ int xc_domain_iomem_permission(int xc_handle, unsigned long nr_mfns, uint8_t allow_access) { - dom0_op_t op; + DECLARE_DOMCTL; - op.cmd = DOM0_IOMEM_PERMISSION; - op.u.iomem_permission.domain = domid; - op.u.iomem_permission.first_mfn = first_mfn; - op.u.iomem_permission.nr_mfns = nr_mfns; - op.u.iomem_permission.allow_access = allow_access; + domctl.cmd = XEN_DOMCTL_iomem_permission; + domctl.domain = domid; + domctl.u.iomem_permission.first_mfn = first_mfn; + domctl.u.iomem_permission.nr_mfns = nr_mfns; + domctl.u.iomem_permission.allow_access = allow_access; - return do_dom0_op(xc_handle, &op); + return do_domctl(xc_handle, &domctl); } /* diff --git a/tools/libxc/xc_hvm_build.c b/tools/libxc/xc_hvm_build.c index 98cb5ebd68..c39ffa323f 100644 --- a/tools/libxc/xc_hvm_build.c +++ b/tools/libxc/xc_hvm_build.c @@ -395,7 +395,7 @@ static int xc_hvm_build_internal(int xc_handle, unsigned int store_evtchn, unsigned long *store_mfn) { - dom0_op_t launch_op, op; + struct xen_domctl launch_domctl, domctl; int rc, i; vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt; unsigned long nr_pages; @@ -432,21 +432,21 @@ static int xc_hvm_build_internal(int xc_handle, return 1; } - op.cmd = DOM0_GETDOMAININFO; - op.u.getdomaininfo.domain = (domid_t)domid; - if ( (xc_dom0_op(xc_handle, &op) < 0) || - ((uint16_t)op.u.getdomaininfo.domain != domid) ) + domctl.cmd = XEN_DOMCTL_getdomaininfo; + domctl.domain = (domid_t)domid; + if ( (xc_domctl(xc_handle, &domctl) < 0) || + ((uint16_t)domctl.domain != domid) ) { PERROR("Could not get info on domain"); goto error_out; } /* HVM domains must be put into shadow2 mode at the start of day */ - if ( xc_shadow_control(xc_handle, domid, DOM0_SHADOW_CONTROL_OP_ENABLE, + if ( xc_shadow_control(xc_handle, domid, XEN_DOMCTL_SHADOW_OP_ENABLE, NULL, 0, NULL, - DOM0_SHADOW_ENABLE_REFCOUNT | - DOM0_SHADOW_ENABLE_TRANSLATE | - DOM0_SHADOW_ENABLE_EXTERNAL, + XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT | + XEN_DOMCTL_SHADOW_ENABLE_TRANSLATE | + XEN_DOMCTL_SHADOW_ENABLE_EXTERNAL, NULL) ) { PERROR("Could not enable shadow paging for domain.\n"); @@ -457,7 +457,7 @@ static int xc_hvm_build_internal(int xc_handle, ctxt->flags = VGCF_HVM_GUEST; if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages, - ctxt, op.u.getdomaininfo.shared_info_frame, + ctxt, domctl.u.getdomaininfo.shared_info_frame, vcpus, pae, acpi, apic, store_evtchn, store_mfn) < 0) { ERROR("Error constructing guest OS"); @@ -495,14 +495,14 @@ static int xc_hvm_build_internal(int xc_handle, ctxt->syscall_callback_eip = 0; #endif - memset( &launch_op, 0, sizeof(launch_op) ); + memset(&launch_domctl, 0, sizeof(launch_domctl)); - launch_op.u.setvcpucontext.domain = (domid_t)domid; - launch_op.u.setvcpucontext.vcpu = 0; - set_xen_guest_handle(launch_op.u.setvcpucontext.ctxt, ctxt); + launch_domctl.domain = (domid_t)domid; + launch_domctl.u.vcpucontext.vcpu = 0; + set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, ctxt); - launch_op.cmd = DOM0_SETVCPUCONTEXT; - rc = xc_dom0_op(xc_handle, &launch_op); + launch_domctl.cmd = XEN_DOMCTL_setvcpucontext; + rc = xc_domctl(xc_handle, &launch_domctl); return rc; diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index d9802b640c..98c84da3b2 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -474,7 +474,7 @@ static int setup_guest(int xc_handle, struct xen_ia64_boot_param *bp; shared_info_t *shared_info; int i; - DECLARE_DOM0_OP; + DECLARE_DOMCTL; int rc; rc = probeimageformat(image, image_size, &load_funcs); @@ -494,14 +494,13 @@ static int setup_guest(int xc_handle, start_info_mpa = (nr_pages - 3) << PAGE_SHIFT; /* Build firmware. */ - memset(&op.u.domain_setup, 0, sizeof(op.u.domain_setup)); - op.u.domain_setup.flags = 0; - op.u.domain_setup.domain = (domid_t)dom; - op.u.domain_setup.bp = start_info_mpa + sizeof (start_info_t); - op.u.domain_setup.maxmem = (nr_pages - 3) << PAGE_SHIFT; - - op.cmd = DOM0_DOMAIN_SETUP; - if ( xc_dom0_op(xc_handle, &op) ) + memset(&domctl.u.arch_setup, 0, sizeof(domctl.u.arch_setup)); + domctl.u.arch_setup.flags = 0; + domctl.u.arch_setup.bp = start_info_mpa + sizeof (start_info_t); + domctl.u.arch_setup.maxmem = (nr_pages - 3) << PAGE_SHIFT; + domctl.cmd = XEN_DOMCTL_arch_setup; + domctl.domain = (domid_t)dom; + if ( xc_domctl(xc_handle, &domctl) ) goto error_out; start_page = dsi.v_start >> PAGE_SHIFT; @@ -662,7 +661,7 @@ static int setup_guest(int xc_handle, shared_info_t *shared_info; xc_mmu_t *mmu = NULL; const char *p; - DECLARE_DOM0_OP; + DECLARE_DOMCTL; int rc; unsigned long nr_pt_pages; @@ -966,7 +965,7 @@ static int setup_guest(int xc_handle, /* Enable shadow translate mode */ if ( xc_shadow_control(xc_handle, dom, - DOM0_SHADOW_CONTROL_OP_ENABLE_TRANSLATE, + XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE, NULL, 0, NULL, 0, NULL) < 0 ) { PERROR("Could not enable translation mode"); @@ -1077,11 +1076,11 @@ static int setup_guest(int xc_handle, unsigned long long pfn = (hypercall_page - dsi.v_start) >> PAGE_SHIFT; if ( pfn >= nr_pages ) goto error_out; - op.u.hypercall_init.domain = (domid_t)dom; - op.u.hypercall_init.gmfn = shadow_mode_enabled ? + domctl.domain = (domid_t)dom; + domctl.u.hypercall_init.gmfn = shadow_mode_enabled ? pfn : page_array[pfn]; - op.cmd = DOM0_HYPERCALL_INIT; - if ( xc_dom0_op(xc_handle, &op) ) + domctl.cmd = XEN_DOMCTL_hypercall_init; + if ( xc_domctl(xc_handle, &domctl) ) goto error_out; } @@ -1114,8 +1113,8 @@ static int xc_linux_build_internal(int xc_handle, unsigned int console_evtchn, unsigned long *console_mfn) { - dom0_op_t launch_op; - DECLARE_DOM0_OP; + struct xen_domctl launch_domctl; + DECLARE_DOMCTL; int rc, i; vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt; unsigned long nr_pages; @@ -1147,10 +1146,10 @@ static int xc_linux_build_internal(int xc_handle, return 1; } - op.cmd = DOM0_GETDOMAININFO; - op.u.getdomaininfo.domain = (domid_t)domid; - if ( (xc_dom0_op(xc_handle, &op) < 0) || - ((uint16_t)op.u.getdomaininfo.domain != domid) ) + domctl.cmd = XEN_DOMCTL_getdomaininfo; + domctl.domain = (domid_t)domid; + if ( (xc_domctl(xc_handle, &domctl) < 0) || + ((uint16_t)domctl.domain != domid) ) { PERROR("Could not get info on domain"); goto error_out; @@ -1163,7 +1162,7 @@ static int xc_linux_build_internal(int xc_handle, nr_pages, &vstartinfo_start, &vkern_entry, &vstack_start, ctxt, cmdline, - op.u.getdomaininfo.shared_info_frame, + domctl.u.getdomaininfo.shared_info_frame, flags, store_evtchn, store_mfn, console_evtchn, console_mfn, features_bitmap) < 0 ) @@ -1239,14 +1238,14 @@ static int xc_linux_build_internal(int xc_handle, #endif #endif /* x86 */ - memset( &launch_op, 0, sizeof(launch_op) ); + memset( &launch_domctl, 0, sizeof(launch_domctl) ); - launch_op.u.setvcpucontext.domain = (domid_t)domid; - launch_op.u.setvcpucontext.vcpu = 0; - set_xen_guest_handle(launch_op.u.setvcpucontext.ctxt, ctxt); + launch_domctl.domain = (domid_t)domid; + launch_domctl.u.vcpucontext.vcpu = 0; + set_xen_guest_handle(launch_domctl.u.vcpucontext.ctxt, ctxt); - launch_op.cmd = DOM0_SETVCPUCONTEXT; - rc = xc_dom0_op(xc_handle, &launch_op); + launch_domctl.cmd = XEN_DOMCTL_setvcpucontext; + rc = xc_domctl(xc_handle, &launch_domctl); return rc; diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c index 7eed8cead8..6243701911 100644 --- a/tools/libxc/xc_linux_restore.c +++ b/tools/libxc/xc_linux_restore.c @@ -107,7 +107,7 @@ int xc_linux_restore(int xc_handle, int io_fd, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, unsigned long *console_mfn) { - DECLARE_DOM0_OP; + DECLARE_DOMCTL; int rc = 1, i, n, pae_extended_cr3 = 0; unsigned long mfn, pfn; unsigned int prev_pc, this_pc; @@ -163,7 +163,7 @@ int xc_linux_restore(int xc_handle, int io_fd, } if (mlock(&ctxt, sizeof(ctxt))) { - /* needed for build dom0 op, but might as well do early */ + /* needed for build domctl, but might as well do early */ ERR("Unable to mlock ctxt"); return 1; } @@ -257,13 +257,13 @@ int xc_linux_restore(int xc_handle, int io_fd, } /* Get the domain's shared-info frame. */ - op.cmd = DOM0_GETDOMAININFO; - op.u.getdomaininfo.domain = (domid_t)dom; - if (xc_dom0_op(xc_handle, &op) < 0) { + domctl.cmd = XEN_DOMCTL_getdomaininfo; + domctl.domain = (domid_t)dom; + if (xc_domctl(xc_handle, &domctl) < 0) { ERR("Could not get information on new domain"); goto out; } - shared_info_frame = op.u.getdomaininfo.shared_info_frame; + shared_info_frame = domctl.u.getdomaininfo.shared_info_frame; if(xc_domain_setmaxmem(xc_handle, dom, PFN_TO_KB(max_pfn)) != 0) { errno = ENOMEM; @@ -337,17 +337,22 @@ int xc_linux_restore(int xc_handle, int io_fd, goto out; } - for (i = 0; i < j; i++) { + for ( i = 0; i < j; i++ ) + { + unsigned long pfn, pagetype; + pfn = region_pfn_type[i] & ~XEN_DOMCTL_PFINFO_LTAB_MASK; + pagetype = region_pfn_type[i] & XEN_DOMCTL_PFINFO_LTAB_MASK; - if ((region_pfn_type[i] & LTAB_MASK) == XTAB) + if ( pagetype == XEN_DOMCTL_PFINFO_XTAB) region_mfn[i] = 0; /* we know map will fail, but don't care */ else - region_mfn[i] = p2m[region_pfn_type[i] & ~LTAB_MASK]; - + region_mfn[i] = p2m[pfn]; } - if (!(region_base = xc_map_foreign_batch( - xc_handle, dom, PROT_WRITE, region_mfn, j))) { + region_base = xc_map_foreign_batch( + xc_handle, dom, PROT_WRITE, region_mfn, j); + if ( region_base == NULL ) + { ERR("map batch failed"); goto out; } @@ -357,14 +362,15 @@ int xc_linux_restore(int xc_handle, int io_fd, void *page; unsigned long pagetype; - pfn = region_pfn_type[i] & ~LTAB_MASK; - pagetype = region_pfn_type[i] & LTAB_MASK; + pfn = region_pfn_type[i] & ~XEN_DOMCTL_PFINFO_LTAB_MASK; + pagetype = region_pfn_type[i] & XEN_DOMCTL_PFINFO_LTAB_MASK; - if (pagetype == XTAB) + if ( pagetype == XEN_DOMCTL_PFINFO_XTAB ) /* a bogus/unmapped page: skip it */ continue; - if (pfn > max_pfn) { + if ( pfn > max_pfn ) + { ERR("pfn out of range"); goto out; } @@ -381,10 +387,11 @@ int xc_linux_restore(int xc_handle, int io_fd, goto out; } - pagetype &= LTABTYPE_MASK; - - if(pagetype >= L1TAB && pagetype <= L4TAB) { + pagetype &= XEN_DOMCTL_PFINFO_LTABTYPE_MASK; + if ( (pagetype >= XEN_DOMCTL_PFINFO_L1TAB) && + (pagetype <= XEN_DOMCTL_PFINFO_L4TAB) ) + { /* ** A page table page - need to 'uncanonicalize' it, i.e. ** replace all the references to pfns with the corresponding @@ -396,7 +403,7 @@ int xc_linux_restore(int xc_handle, int io_fd, */ if ((pt_levels != 3) || pae_extended_cr3 || - (pagetype != L1TAB)) { + (pagetype != XEN_DOMCTL_PFINFO_L1TAB)) { if (!uncanonicalize_pagetable(pagetype, page)) { /* @@ -412,8 +419,9 @@ int xc_linux_restore(int xc_handle, int io_fd, } - } else if(pagetype != NOTAB) { - + } + else if ( pagetype != XEN_DOMCTL_PFINFO_NOTAB ) + { ERR("Bogus page type %lx page table is out of range: " "i=%d max_pfn=%lu", pagetype, i, max_pfn); goto out; @@ -484,10 +492,12 @@ int xc_linux_restore(int xc_handle, int io_fd, int j, k; /* First pass: find all L3TABs current in > 4G mfns and get new mfns */ - for (i = 0; i < max_pfn; i++) { - - if (((pfn_type[i] & LTABTYPE_MASK)==L3TAB) && (p2m[i]>0xfffffUL)) { - + for ( i = 0; i < max_pfn; i++ ) + { + if ( ((pfn_type[i] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK) == + XEN_DOMCTL_PFINFO_L3TAB) && + (p2m[i] > 0xfffffUL) ) + { unsigned long new_mfn; uint64_t l3ptes[4]; uint64_t *l3tab; @@ -530,9 +540,11 @@ int xc_linux_restore(int xc_handle, int io_fd, /* Second pass: find all L1TABs and uncanonicalize them */ j = 0; - for(i = 0; i < max_pfn; i++) { - - if (((pfn_type[i] & LTABTYPE_MASK)==L1TAB)) { + for ( i = 0; i < max_pfn; i++ ) + { + if ( ((pfn_type[i] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK) == + XEN_DOMCTL_PFINFO_L1TAB) ) + { region_mfn[j] = p2m[i]; j++; } @@ -547,7 +559,7 @@ int xc_linux_restore(int xc_handle, int io_fd, } for(k = 0; k < j; k++) { - if(!uncanonicalize_pagetable(L1TAB, + if(!uncanonicalize_pagetable(XEN_DOMCTL_PFINFO_L1TAB, region_base + k*PAGE_SIZE)) { ERR("failed uncanonicalize pt!"); goto out; @@ -570,26 +582,26 @@ int xc_linux_restore(int xc_handle, int io_fd, * will barf when doing the type-checking. */ nr_pins = 0; - for (i = 0; i < max_pfn; i++) { - - if ( (pfn_type[i] & LPINTAB) == 0 ) + for ( i = 0; i < max_pfn; i++ ) + { + if ( (pfn_type[i] & XEN_DOMCTL_PFINFO_LPINTAB) == 0 ) continue; - switch (pfn_type[i]) { - - case (L1TAB|LPINTAB): + switch ( pfn_type[i] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK ) + { + case XEN_DOMCTL_PFINFO_L1TAB: pin[nr_pins].cmd = MMUEXT_PIN_L1_TABLE; break; - case (L2TAB|LPINTAB): + case XEN_DOMCTL_PFINFO_L2TAB: pin[nr_pins].cmd = MMUEXT_PIN_L2_TABLE; break; - case (L3TAB|LPINTAB): + case XEN_DOMCTL_PFINFO_L3TAB: pin[nr_pins].cmd = MMUEXT_PIN_L3_TABLE; break; - case (L4TAB|LPINTAB): + case XEN_DOMCTL_PFINFO_L4TAB: pin[nr_pins].cmd = MMUEXT_PIN_L4_TABLE; break; @@ -678,7 +690,7 @@ int xc_linux_restore(int xc_handle, int io_fd, /* Uncanonicalise the suspend-record frame number and poke resume rec. */ pfn = ctxt.user_regs.edx; - if ((pfn >= max_pfn) || (pfn_type[pfn] != NOTAB)) { + if ((pfn >= max_pfn) || (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB)) { ERR("Suspend record frame number is bad"); goto out; } @@ -703,7 +715,7 @@ int xc_linux_restore(int xc_handle, int io_fd, for (i = 0; i < ctxt.gdt_ents; i += 512) { pfn = ctxt.gdt_frames[i]; - if ((pfn >= max_pfn) || (pfn_type[pfn] != NOTAB)) { + if ((pfn >= max_pfn) || (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB)) { ERR("GDT frame number is bad"); goto out; } @@ -719,11 +731,11 @@ int xc_linux_restore(int xc_handle, int io_fd, goto out; } - if ( (pfn_type[pfn] & LTABTYPE_MASK) != - ((unsigned long)pt_levels<<LTAB_SHIFT) ) { + if ( (pfn_type[pfn] & XEN_DOMCTL_PFINFO_LTABTYPE_MASK) != + ((unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT) ) { ERR("PT base is bad. pfn=%lu nr=%lu type=%08lx %08lx", pfn, max_pfn, pfn_type[pfn], - (unsigned long)pt_levels<<LTAB_SHIFT); + (unsigned long)pt_levels<<XEN_DOMCTL_PFINFO_LTAB_SHIFT); goto out; } @@ -744,7 +756,7 @@ int xc_linux_restore(int xc_handle, int io_fd, /* Uncanonicalise the pfn-to-mfn table frame-number list. */ for (i = 0; i < P2M_FL_ENTRIES; i++) { pfn = p2m_frame_list[i]; - if ((pfn >= max_pfn) || (pfn_type[pfn] != NOTAB)) { + if ((pfn >= max_pfn) || (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB)) { ERR("PFN-to-MFN frame number is bad"); goto out; } @@ -797,11 +809,11 @@ int xc_linux_restore(int xc_handle, int io_fd, DPRINTF("Domain ready to be built.\n"); - op.cmd = DOM0_SETVCPUCONTEXT; - op.u.setvcpucontext.domain = (domid_t)dom; - op.u.setvcpucontext.vcpu = 0; - set_xen_guest_handle(op.u.setvcpucontext.ctxt, &ctxt); - rc = xc_dom0_op(xc_handle, &op); + domctl.cmd = XEN_DOMCTL_setvcpucontext; + domctl.domain = (domid_t)dom; + domctl.u.vcpucontext.vcpu = 0; + set_xen_guest_handle(domctl.u.vcpucontext.ctxt, &ctxt); + rc = xc_domctl(xc_handle, &domctl); if (rc != 0) { ERR("Couldn't build the domain"); diff --git a/tools/libxc/xc_linux_save.c b/tools/libxc/xc_linux_save.c index af388f572e..b5008a6cee 100644 --- a/tools/libxc/xc_linux_save.c +++ b/tools/libxc/xc_linux_save.c @@ -271,7 +271,7 @@ static inline ssize_t write_exact(int fd, void *buf, size_t count) static int print_stats(int xc_handle, uint32_t domid, int pages_sent, - xc_shadow_control_stats_t *stats, int print) + xc_shadow_op_stats_t *stats, int print) { static struct timeval wall_last; static long long d0_cpu_last; @@ -329,7 +329,7 @@ static int analysis_phase(int xc_handle, uint32_t domid, int max_pfn, unsigned long *arr, int runs) { long long start, now; - xc_shadow_control_stats_t stats; + xc_shadow_op_stats_t stats; int j; start = llgettimeofday(); @@ -337,13 +337,13 @@ static int analysis_phase(int xc_handle, uint32_t domid, int max_pfn, for (j = 0; j < runs; j++) { int i; - xc_shadow_control(xc_handle, domid, DOM0_SHADOW_CONTROL_OP_CLEAN, + xc_shadow_control(xc_handle, domid, XEN_DOMCTL_SHADOW_OP_CLEAN, arr, max_pfn, NULL, 0, NULL); DPRINTF("#Flush\n"); for ( i = 0; i < 40; i++ ) { usleep(50000); now = llgettimeofday(); - xc_shadow_control(xc_handle, domid, DOM0_SHADOW_CONTROL_OP_PEEK, + xc_shadow_control(xc_handle, domid, XEN_DOMCTL_SHADOW_OP_PEEK, NULL, 0, NULL, 0, &stats); DPRINTF("now= %lld faults= %"PRId32" dirty= %"PRId32"\n", @@ -427,10 +427,10 @@ int canonicalize_pagetable(unsigned long type, unsigned long pfn, */ xen_start = xen_end = pte_last = PAGE_SIZE / ((pt_levels == 2)? 4 : 8); - if (pt_levels == 2 && type == L2TAB) + if (pt_levels == 2 && type == XEN_DOMCTL_PFINFO_L2TAB) xen_start = (hvirt_start >> L2_PAGETABLE_SHIFT); - if (pt_levels == 3 && type == L3TAB) + if (pt_levels == 3 && type == XEN_DOMCTL_PFINFO_L3TAB) xen_start = L3_PAGETABLE_ENTRIES_PAE; /* @@ -439,7 +439,7 @@ int canonicalize_pagetable(unsigned long type, unsigned long pfn, ** Xen always ensures is present in that L2. Guests must ensure ** that this check will fail for other L2s. */ - if (pt_levels == 3 && type == L2TAB) { + if (pt_levels == 3 && type == XEN_DOMCTL_PFINFO_L2TAB) { /* XXX index of the L2 entry in PAE mode which holds the guest LPT */ #define PAE_GLPT_L2ENTRY (495) @@ -449,7 +449,7 @@ int canonicalize_pagetable(unsigned long type, unsigned long pfn, xen_start = (hvirt_start >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff; } - if (pt_levels == 4 && type == L4TAB) { + if (pt_levels == 4 && type == XEN_DOMCTL_PFINFO_L4TAB) { /* ** XXX SMH: should compute these from hvirt_start (which we have) ** and hvirt_end (which we don't) @@ -603,7 +603,7 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, - to fixup by sending at the end if not already resent; */ unsigned long *to_send = NULL, *to_skip = NULL, *to_fix = NULL; - xc_shadow_control_stats_t stats; + xc_shadow_op_stats_t stats; unsigned long needed_to_fix = 0; unsigned long total_sent = 0; @@ -724,7 +724,7 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, if (live) { if (xc_shadow_control(xc_handle, dom, - DOM0_SHADOW_CONTROL_OP_ENABLE_LOGDIRTY, + XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY, NULL, 0, NULL, 0, NULL) < 0) { ERR("Couldn't enable shadow mode"); goto out; @@ -781,8 +781,8 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, analysis_phase(xc_handle, dom, max_pfn, to_skip, 0); /* We want zeroed memory so use calloc rather than malloc. */ - pfn_type = calloc(MAX_BATCH_SIZE, sizeof(unsigned long)); - pfn_batch = calloc(MAX_BATCH_SIZE, sizeof(unsigned long)); + pfn_type = calloc(MAX_BATCH_SIZE, sizeof(*pfn_type)); + pfn_batch = calloc(MAX_BATCH_SIZE, sizeof(*pfn_batch)); if ((pfn_type == NULL) || (pfn_batch == NULL)) { ERR("failed to alloc memory for pfn_type and/or pfn_batch arrays"); @@ -790,12 +790,11 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, goto out; } - if (mlock(pfn_type, MAX_BATCH_SIZE * sizeof(unsigned long))) { + if (mlock(pfn_type, MAX_BATCH_SIZE * sizeof(*pfn_type))) { ERR("Unable to mlock"); goto out; } - /* * Quick belt and braces sanity check. */ @@ -876,7 +875,7 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, /* slightly wasteful to peek the whole array evey time, but this is fast enough for the moment. */ if (!last_iter && xc_shadow_control( - xc_handle, dom, DOM0_SHADOW_CONTROL_OP_PEEK, + xc_handle, dom, XEN_DOMCTL_SHADOW_OP_PEEK, to_skip, max_pfn, NULL, 0, NULL) != max_pfn) { ERR("Error peeking shadow bitmap"); goto out; @@ -930,7 +929,7 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, if(last_iter && test_bit(n, to_fix) && !test_bit(n, to_send)) { needed_to_fix++; DPRINTF("Fix! iter %d, pfn %x. mfn %lx\n", - iter,n,pfn_type[batch]); + iter, n, pfn_type[batch]); } clear_bit(n, to_fix); @@ -952,9 +951,12 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, goto out; } - for (j = 0; j < batch; j++) { + for ( j = 0; j < batch; j++ ) + { - if ((pfn_type[j] & LTAB_MASK) == XTAB) { + if ( (pfn_type[j] & XEN_DOMCTL_PFINFO_LTAB_MASK) == + XEN_DOMCTL_PFINFO_XTAB ) + { DPRINTF("type fail: page %i mfn %08lx\n", j, pfn_type[j]); continue; } @@ -963,13 +965,16 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, DPRINTF("%d pfn= %08lx mfn= %08lx [mfn]= %08lx" " sum= %08lx\n", iter, - (pfn_type[j] & LTAB_MASK) | pfn_batch[j], + (pfn_type[j] & XEN_DOMCTL_PFINFO_LTAB_MASK) | + pfn_batch[j], pfn_type[j], - mfn_to_pfn(pfn_type[j]&(~LTAB_MASK)), + mfn_to_pfn(pfn_type[j] & + ~XEN_DOMCTL_PFINFO_LTAB_MASK), csum_page(region_base + (PAGE_SIZE*j))); /* canonicalise mfn->pfn */ - pfn_type[j] = (pfn_type[j] & LTAB_MASK) | pfn_batch[j]; + pfn_type[j] = (pfn_type[j] & XEN_DOMCTL_PFINFO_LTAB_MASK) | + pfn_batch[j]; } if(!write_exact(io_fd, &batch, sizeof(unsigned int))) { @@ -983,21 +988,23 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, } /* entering this loop, pfn_type is now in pfns (Not mfns) */ - for (j = 0; j < batch; j++) { - - unsigned long pfn = pfn_type[j] & ~LTAB_MASK; - unsigned long pagetype = pfn_type[j] & LTAB_MASK; - void *spage = (void *) region_base + (PAGE_SIZE*j); + for ( j = 0; j < batch; j++ ) + { + unsigned long pfn, pagetype; + void *spage = (char *)region_base + (PAGE_SIZE*j); + pfn = pfn_type[j] & ~XEN_DOMCTL_PFINFO_LTAB_MASK; + pagetype = pfn_type[j] & XEN_DOMCTL_PFINFO_LTAB_MASK; /* write out pages in batch */ - if (pagetype == XTAB) + if ( pagetype == XEN_DOMCTL_PFINFO_XTAB ) continue; - pagetype &= LTABTYPE_MASK; - - if (pagetype >= L1TAB && pagetype <= L4TAB) { + pagetype &= XEN_DOMCTL_PFINFO_LTABTYPE_MASK; + if ( (pagetype >= XEN_DOMCTL_PFINFO_L1TAB) && + (pagetype <= XEN_DOMCTL_PFINFO_L4TAB) ) + { /* We have a pagetable page: need to rewrite it. */ race = canonicalize_pagetable(pagetype, pfn, spage, page); @@ -1083,7 +1090,7 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, } if (xc_shadow_control(xc_handle, dom, - DOM0_SHADOW_CONTROL_OP_CLEAN, to_send, + XEN_DOMCTL_SHADOW_OP_CLEAN, to_send, max_pfn, NULL, 0, &stats) != max_pfn) { ERR("Error flushing shadow PT"); goto out; @@ -1174,7 +1181,7 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, if (live) { if(xc_shadow_control(xc_handle, dom, - DOM0_SHADOW_CONTROL_OP_OFF, + XEN_DOMCTL_SHADOW_OP_OFF, NULL, 0, NULL, 0, NULL) < 0) { DPRINTF("Warning - couldn't disable shadow mode"); } diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c index 3fc8536a47..7b598124c4 100644 --- a/tools/libxc/xc_misc.c +++ b/tools/libxc/xc_misc.c @@ -12,20 +12,20 @@ int xc_readconsolering(int xc_handle, int clear) { int ret; - DECLARE_DOM0_OP; + DECLARE_SYSCTL; char *buffer = *pbuffer; unsigned int nr_chars = *pnr_chars; - op.cmd = DOM0_READCONSOLE; - set_xen_guest_handle(op.u.readconsole.buffer, buffer); - op.u.readconsole.count = nr_chars; - op.u.readconsole.clear = clear; + sysctl.cmd = XEN_SYSCTL_readconsole; + set_xen_guest_handle(sysctl.u.readconsole.buffer, buffer); + sysctl.u.readconsole.count = nr_chars; + sysctl.u.readconsole.clear = clear; if ( (ret = mlock(buffer, nr_chars)) != 0 ) return ret; - if ( (ret = do_dom0_op(xc_handle, &op)) == 0 ) - *pnr_chars = op.u.readconsole.count; + if ( (ret = do_sysctl(xc_handle, &sysctl)) == 0 ) + *pnr_chars = sysctl.u.readconsole.count; safe_munlock(buffer, nr_chars); @@ -36,15 +36,14 @@ int xc_physinfo(int xc_handle, xc_physinfo_t *put_info) { int ret; - DECLARE_DOM0_OP; + DECLARE_SYSCTL; - op.cmd = DOM0_PHYSINFO; - op.interface_version = DOM0_INTERFACE_VERSION; + sysctl.cmd = XEN_SYSCTL_physinfo; - if ( (ret = do_dom0_op(xc_handle, &op)) != 0 ) + if ( (ret = do_sysctl(xc_handle, &sysctl)) != 0 ) return ret; - memcpy(put_info, &op.u.physinfo, sizeof(*put_info)); + memcpy(put_info, &sysctl.u.physinfo, sizeof(*put_info)); return 0; } @@ -53,15 +52,14 @@ int xc_sched_id(int xc_handle, int *sched_id) { int ret; - DECLARE_DOM0_OP; + DECLARE_SYSCTL; - op.cmd = DOM0_SCHED_ID; - op.interface_version = DOM0_INTERFACE_VERSION; + sysctl.cmd = XEN_SYSCTL_sched_id; - if ( (ret = do_dom0_op(xc_handle, &op)) != 0 ) + if ( (ret = do_sysctl(xc_handle, &sysctl)) != 0 ) return ret; - *sched_id = op.u.sched_id.sched_id; + *sched_id = sysctl.u.sched_id.sched_id; return 0; } @@ -74,19 +72,19 @@ int xc_perfc_control(int xc_handle, int *nbr_val) { int rc; - DECLARE_DOM0_OP; + DECLARE_SYSCTL; - op.cmd = DOM0_PERFCCONTROL; - op.u.perfccontrol.op = opcode; - set_xen_guest_handle(op.u.perfccontrol.desc, desc); - set_xen_guest_handle(op.u.perfccontrol.val, val); + sysctl.cmd = XEN_SYSCTL_perfc_op; + sysctl.u.perfc_op.cmd = opcode; + set_xen_guest_handle(sysctl.u.perfc_op.desc, desc); + set_xen_guest_handle(sysctl.u.perfc_op.val, val); - rc = do_dom0_op(xc_handle, &op); + rc = do_sysctl(xc_handle, &sysctl); if (nbr_desc) - *nbr_desc = op.u.perfccontrol.nr_counters; + *nbr_desc = sysctl.u.perfc_op.nr_counters; if (nbr_val) - *nbr_val = op.u.perfccontrol.nr_vals; + *nbr_val = sysctl.u.perfc_op.nr_vals; return rc; } diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c index e307fc7f02..93537ef811 100644 --- a/tools/libxc/xc_private.c +++ b/tools/libxc/xc_private.c @@ -11,12 +11,12 @@ int xc_get_pfn_type_batch(int xc_handle, uint32_t dom, int num, unsigned long *arr) { - DECLARE_DOM0_OP; - op.cmd = DOM0_GETPAGEFRAMEINFO2; - op.u.getpageframeinfo2.domain = (domid_t)dom; - op.u.getpageframeinfo2.num = num; - set_xen_guest_handle(op.u.getpageframeinfo2.array, arr); - return do_dom0_op(xc_handle, &op); + DECLARE_DOMCTL; + domctl.cmd = XEN_DOMCTL_getpageframeinfo2; + domctl.domain = (domid_t)dom; + domctl.u.getpageframeinfo2.num = num; + set_xen_guest_handle(domctl.u.getpageframeinfo2.array, arr); + return do_domctl(xc_handle, &domctl); } #define GETPFN_ERR (~0U) @@ -24,16 +24,16 @@ unsigned int get_pfn_type(int xc_handle, unsigned long mfn, uint32_t dom) { - DECLARE_DOM0_OP; - op.cmd = DOM0_GETPAGEFRAMEINFO; - op.u.getpageframeinfo.gmfn = mfn; - op.u.getpageframeinfo.domain = (domid_t)dom; - if ( do_dom0_op(xc_handle, &op) < 0 ) + DECLARE_DOMCTL; + domctl.cmd = XEN_DOMCTL_getpageframeinfo; + domctl.u.getpageframeinfo.gmfn = mfn; + domctl.domain = (domid_t)dom; + if ( do_domctl(xc_handle, &domctl) < 0 ) { PERROR("Unexpected failure when getting page frame info!"); return GETPFN_ERR; } - return op.u.getpageframeinfo.type; + return domctl.u.getpageframeinfo.type; } int xc_mmuext_op( @@ -248,17 +248,17 @@ int xc_memory_op(int xc_handle, long long xc_domain_get_cpu_usage( int xc_handle, domid_t domid, int vcpu ) { - DECLARE_DOM0_OP; + DECLARE_DOMCTL; - op.cmd = DOM0_GETVCPUINFO; - op.u.getvcpuinfo.domain = (domid_t)domid; - op.u.getvcpuinfo.vcpu = (uint16_t)vcpu; - if ( (do_dom0_op(xc_handle, &op) < 0) ) + domctl.cmd = XEN_DOMCTL_getvcpuinfo; + domctl.domain = (domid_t)domid; + domctl.u.getvcpuinfo.vcpu = (uint16_t)vcpu; + if ( (do_domctl(xc_handle, &domctl) < 0) ) { PERROR("Could not get info on domain"); return -1; } - return op.u.getvcpuinfo.cpu_time; + return domctl.u.getvcpuinfo.cpu_time; } @@ -268,12 +268,12 @@ int xc_get_pfn_list(int xc_handle, xen_pfn_t *pfn_buf, unsigned long max_pfns) { - DECLARE_DOM0_OP; + DECLARE_DOMCTL; int ret; - op.cmd = DOM0_GETMEMLIST; - op.u.getmemlist.domain = (domid_t)domid; - op.u.getmemlist.max_pfns = max_pfns; - set_xen_guest_handle(op.u.getmemlist.buffer, pfn_buf); + domctl.cmd = XEN_DOMCTL_getmemlist; + domctl.domain = (domid_t)domid; + domctl.u.getmemlist.max_pfns = max_pfns; + set_xen_guest_handle(domctl.u.getmemlist.buffer, pfn_buf); #ifdef VALGRIND memset(pfn_buf, 0, max_pfns * sizeof(xen_pfn_t)); @@ -285,7 +285,7 @@ int xc_get_pfn_list(int xc_handle, return -1; } - ret = do_dom0_op(xc_handle, &op); + ret = do_domctl(xc_handle, &domctl); safe_munlock(pfn_buf, max_pfns * sizeof(xen_pfn_t)); @@ -294,7 +294,7 @@ int xc_get_pfn_list(int xc_handle, DPRINTF(("Ret for xc_get_pfn_list is %d\n", ret)); if (ret >= 0) { int i, j; - for (i = 0; i < op.u.getmemlist.num_pfns; i += 16) { + for (i = 0; i < domctl.u.getmemlist.num_pfns; i += 16) { DPRINTF("0x%x: ", i); for (j = 0; j < 16; j++) DPRINTF("0x%lx ", pfn_buf[i + j]); @@ -304,17 +304,17 @@ int xc_get_pfn_list(int xc_handle, #endif #endif - return (ret < 0) ? -1 : op.u.getmemlist.num_pfns; + return (ret < 0) ? -1 : domctl.u.getmemlist.num_pfns; } #endif long xc_get_tot_pages(int xc_handle, uint32_t domid) { - DECLARE_DOM0_OP; - op.cmd = DOM0_GETDOMAININFO; - op.u.getdomaininfo.domain = (domid_t)domid; - return (do_dom0_op(xc_handle, &op) < 0) ? - -1 : op.u.getdomaininfo.tot_pages; + DECLARE_DOMCTL; + domctl.cmd = XEN_DOMCTL_getdomaininfo; + domctl.domain = (domid_t)domid; + return (do_domctl(xc_handle, &domctl) < 0) ? + -1 : domctl.u.getdomaininfo.tot_pages; } int xc_copy_to_domain_page(int xc_handle, @@ -386,9 +386,14 @@ void xc_map_memcpy(unsigned long dst, const char *src, unsigned long size, } } -int xc_dom0_op(int xc_handle, dom0_op_t *op) +int xc_domctl(int xc_handle, struct xen_domctl *domctl) { - return do_dom0_op(xc_handle, op); + return do_domctl(xc_handle, domctl); +} + +int xc_sysctl(int xc_handle, struct xen_sysctl *sysctl) +{ + return do_sysctl(xc_handle, sysctl); } int xc_version(int xc_handle, int cmd, void *arg) diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h index 6e1b262375..513daed6f9 100644 --- a/tools/libxc/xc_private.h +++ b/tools/libxc/xc_private.h @@ -18,14 +18,16 @@ #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 dom0_op_t instance before a - call, if using valgrind. */ + 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_DOM0_OP dom0_op_t op = { 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_DOM0_OP dom0_op_t op +#define DECLARE_DOMCTL struct xen_domctl domctl +#define DECLARE_SYSCTL struct xen_sysctl sysctl #endif #define PAGE_SHIFT XC_PAGE_SHIFT @@ -94,17 +96,17 @@ static inline int do_xen_version(int xc_handle, int cmd, void *dest) return do_xen_hypercall(xc_handle, &hypercall); } -static inline int do_dom0_op(int xc_handle, dom0_op_t *op) +static inline int do_domctl(int xc_handle, struct xen_domctl *domctl) { int ret = -1; DECLARE_HYPERCALL; - op->interface_version = DOM0_INTERFACE_VERSION; + domctl->interface_version = XEN_DOMCTL_INTERFACE_VERSION; - hypercall.op = __HYPERVISOR_dom0_op; - hypercall.arg[0] = (unsigned long)op; + hypercall.op = __HYPERVISOR_domctl; + hypercall.arg[0] = (unsigned long)domctl; - if ( mlock(op, sizeof(*op)) != 0 ) + if ( mlock(domctl, sizeof(*domctl)) != 0 ) { PERROR("Could not lock memory for Xen hypercall"); goto out1; @@ -113,11 +115,40 @@ static inline int do_dom0_op(int xc_handle, dom0_op_t *op) if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) { if ( errno == EACCES ) - DPRINTF("Dom0 operation failed -- need to" + DPRINTF("domctl operation failed -- need to" " rebuild the user-space tool set?\n"); } - safe_munlock(op, sizeof(*op)); + 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; diff --git a/tools/libxc/xc_ptrace.c b/tools/libxc/xc_ptrace.c index bfe455bd5a..ab9c2fae45 100644 --- a/tools/libxc/xc_ptrace.c +++ b/tools/libxc/xc_ptrace.c @@ -41,8 +41,8 @@ static char *ptrace_names[] = { static int current_domid = -1; static int current_isfile; -static cpumap_t online_cpumap; -static cpumap_t regs_valid; +static uint64_t online_cpumap; +static uint64_t regs_valid; static vcpu_guest_context_t ctxt[MAX_VIRT_CPUS]; extern int ffsll(long long int); @@ -111,7 +111,8 @@ paging_enabled(vcpu_guest_context_t *v) */ static int -get_online_cpumap(int xc_handle, dom0_getdomaininfo_t *d, cpumap_t *cpumap) +get_online_cpumap(int xc_handle, struct xen_domctl_getdomaininfo *d, + uint64_t *cpumap) { int i, online, retval; @@ -133,9 +134,9 @@ get_online_cpumap(int xc_handle, dom0_getdomaininfo_t *d, cpumap_t *cpumap) */ static void -online_vcpus_changed(cpumap_t cpumap) +online_vcpus_changed(uint64_t cpumap) { - cpumap_t changed_cpumap = cpumap ^ online_cpumap; + uint64_t changed_cpumap = cpumap ^ online_cpumap; int index; while ( (index = ffsll(changed_cpumap)) ) { @@ -418,25 +419,25 @@ __xc_waitdomain( int *status, int options) { - DECLARE_DOM0_OP; + DECLARE_DOMCTL; int retval; struct timespec ts; - cpumap_t cpumap; + uint64_t cpumap; ts.tv_sec = 0; ts.tv_nsec = 10*1000*1000; - op.cmd = DOM0_GETDOMAININFO; - op.u.getdomaininfo.domain = domain; + domctl.cmd = XEN_DOMCTL_getdomaininfo; + domctl.domain = domain; retry: - retval = do_dom0_op(xc_handle, &op); - if ( retval || (op.u.getdomaininfo.domain != domain) ) + retval = do_domctl(xc_handle, &domctl); + if ( retval || (domctl.domain != domain) ) { IPRINTF("getdomaininfo failed\n"); goto done; } - *status = op.u.getdomaininfo.flags; + *status = domctl.u.getdomaininfo.flags; if ( options & WNOHANG ) goto done; @@ -447,13 +448,13 @@ __xc_waitdomain( goto done; } - if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ) + if ( !(domctl.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ) { nanosleep(&ts,NULL); goto retry; } done: - if (get_online_cpumap(xc_handle, &op.u.getdomaininfo, &cpumap)) + if (get_online_cpumap(xc_handle, &domctl.u.getdomaininfo, &cpumap)) IPRINTF("get_online_cpumap failed\n"); if (online_cpumap != cpumap) online_vcpus_changed(cpumap); @@ -470,11 +471,11 @@ xc_ptrace( long eaddr, long edata) { - DECLARE_DOM0_OP; + DECLARE_DOMCTL; struct gdb_regs pt; long retval = 0; unsigned long *guest_va; - cpumap_t cpumap; + uint64_t cpumap; int cpu, index; void *addr = (char *)eaddr; void *data = (char *)edata; @@ -535,7 +536,7 @@ xc_ptrace( SET_XC_REGS(((struct gdb_regs *)data), ctxt[cpu].user_regs); if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, &ctxt[cpu]))) - goto out_error_dom0; + goto out_error_domctl; break; case PTRACE_SINGLESTEP: @@ -547,7 +548,7 @@ xc_ptrace( ctxt[cpu].user_regs.eflags |= PSL_T; if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, &ctxt[cpu]))) - goto out_error_dom0; + goto out_error_domctl; /* FALLTHROUGH */ case PTRACE_CONT: @@ -566,22 +567,22 @@ xc_ptrace( ctxt[cpu].user_regs.eflags &= ~PSL_T; if ((retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, &ctxt[cpu]))) - goto out_error_dom0; + goto out_error_domctl; } } } if ( request == PTRACE_DETACH ) { - op.cmd = DOM0_SETDEBUGGING; - op.u.setdebugging.domain = current_domid; - op.u.setdebugging.enable = 0; - if ((retval = do_dom0_op(xc_handle, &op))) - goto out_error_dom0; + domctl.cmd = XEN_DOMCTL_setdebugging; + domctl.domain = current_domid; + domctl.u.setdebugging.enable = 0; + if ((retval = do_domctl(xc_handle, &domctl))) + goto out_error_domctl; } regs_valid = 0; if ((retval = xc_domain_unpause(xc_handle, current_domid > 0 ? current_domid : -current_domid))) - goto out_error_dom0; + goto out_error_domctl; break; case PTRACE_ATTACH: @@ -589,22 +590,22 @@ xc_ptrace( current_isfile = (int)edata; if (current_isfile) break; - op.cmd = DOM0_GETDOMAININFO; - op.u.getdomaininfo.domain = current_domid; - retval = do_dom0_op(xc_handle, &op); - if ( retval || (op.u.getdomaininfo.domain != current_domid) ) - goto out_error_dom0; - if ( op.u.getdomaininfo.flags & DOMFLAGS_PAUSED ) + domctl.cmd = XEN_DOMCTL_getdomaininfo; + domctl.domain = current_domid; + retval = do_domctl(xc_handle, &domctl); + if ( retval || (domctl.domain != current_domid) ) + goto out_error_domctl; + if ( domctl.u.getdomaininfo.flags & DOMFLAGS_PAUSED ) IPRINTF("domain currently paused\n"); else if ((retval = xc_domain_pause(xc_handle, current_domid))) - goto out_error_dom0; - op.cmd = DOM0_SETDEBUGGING; - op.u.setdebugging.domain = current_domid; - op.u.setdebugging.enable = 1; - if ((retval = do_dom0_op(xc_handle, &op))) - goto out_error_dom0; - - if (get_online_cpumap(xc_handle, &op.u.getdomaininfo, &cpumap)) + goto out_error_domctl; + domctl.cmd = XEN_DOMCTL_setdebugging; + domctl.domain = current_domid; + domctl.u.setdebugging.enable = 1; + if ((retval = do_domctl(xc_handle, &domctl))) + goto out_error_domctl; + + if (get_online_cpumap(xc_handle, &domctl.u.getdomaininfo, &cpumap)) IPRINTF("get_online_cpumap failed\n"); if (online_cpumap != cpumap) online_vcpus_changed(cpumap); @@ -625,8 +626,8 @@ xc_ptrace( return retval; - out_error_dom0: - perror("dom0 op failed"); + out_error_domctl: + perror("domctl failed"); out_error: errno = EINVAL; return retval; diff --git a/tools/libxc/xc_sedf.c b/tools/libxc/xc_sedf.c index 7097e4f9d7..20cffa5d35 100644 --- a/tools/libxc/xc_sedf.c +++ b/tools/libxc/xc_sedf.c @@ -10,37 +10,50 @@ #include "xc_private.h" -int xc_sedf_domain_set(int xc_handle, - uint32_t domid, uint64_t period, uint64_t slice,uint64_t latency, uint16_t extratime,uint16_t weight) +int xc_sedf_domain_set( + int xc_handle, + uint32_t domid, + uint64_t period, + uint64_t slice, + uint64_t latency, + uint16_t extratime, + uint16_t weight) { - DECLARE_DOM0_OP; - struct sedf_adjdom *p = &op.u.adjustdom.u.sedf; + DECLARE_DOMCTL; + struct xen_domctl_sched_sedf *p = &domctl.u.scheduler_op.u.sedf; - op.cmd = DOM0_ADJUSTDOM; - op.u.adjustdom.domain = (domid_t)domid; - op.u.adjustdom.sched_id = SCHED_SEDF; - op.u.adjustdom.direction = SCHED_INFO_PUT; + domctl.cmd = XEN_DOMCTL_scheduler_op; + domctl.domain = (domid_t)domid; + domctl.u.scheduler_op.sched_id = XEN_SCHEDULER_SEDF; + domctl.u.scheduler_op.cmd = XEN_DOMCTL_SCHEDOP_putinfo; p->period = period; p->slice = slice; p->latency = latency; p->extratime = extratime; p->weight = weight; - return do_dom0_op(xc_handle, &op); + return do_domctl(xc_handle, &domctl); } -int xc_sedf_domain_get(int xc_handle, uint32_t domid, uint64_t *period, uint64_t *slice, uint64_t* latency, uint16_t* extratime, uint16_t* weight) +int xc_sedf_domain_get( + int xc_handle, + uint32_t domid, + uint64_t *period, + uint64_t *slice, + uint64_t *latency, + uint16_t *extratime, + uint16_t *weight) { - DECLARE_DOM0_OP; + DECLARE_DOMCTL; int ret; - struct sedf_adjdom *p = &op.u.adjustdom.u.sedf; + struct xen_domctl_sched_sedf *p = &domctl.u.scheduler_op.u.sedf; - op.cmd = DOM0_ADJUSTDOM; - op.u.adjustdom.domain = (domid_t)domid; - op.u.adjustdom.sched_id = SCHED_SEDF; - op.u.adjustdom.direction = SCHED_INFO_GET; + domctl.cmd = XEN_DOMCTL_scheduler_op; + domctl.domain = (domid_t)domid; + domctl.u.scheduler_op.sched_id = XEN_SCHEDULER_SEDF; + domctl.u.scheduler_op.cmd = XEN_DOMCTL_SCHEDOP_getinfo; - ret = do_dom0_op(xc_handle, &op); + ret = do_domctl(xc_handle, &domctl); *period = p->period; *slice = p->slice; diff --git a/tools/libxc/xc_tbuf.c b/tools/libxc/xc_tbuf.c index 3160da1942..13614f0f8a 100644 --- a/tools/libxc/xc_tbuf.c +++ b/tools/libxc/xc_tbuf.c @@ -18,49 +18,49 @@ static int tbuf_enable(int xc_handle, int enable) { - DECLARE_DOM0_OP; + DECLARE_SYSCTL; - op.cmd = DOM0_TBUFCONTROL; - op.interface_version = DOM0_INTERFACE_VERSION; + sysctl.cmd = XEN_SYSCTL_tbuf_op; + sysctl.interface_version = XEN_SYSCTL_INTERFACE_VERSION; if (enable) - op.u.tbufcontrol.op = DOM0_TBUF_ENABLE; + sysctl.u.tbuf_op.cmd = XEN_SYSCTL_TBUFOP_enable; else - op.u.tbufcontrol.op = DOM0_TBUF_DISABLE; + sysctl.u.tbuf_op.cmd = XEN_SYSCTL_TBUFOP_disable; - return xc_dom0_op(xc_handle, &op); + return xc_sysctl(xc_handle, &sysctl); } int xc_tbuf_set_size(int xc_handle, unsigned long size) { - DECLARE_DOM0_OP; + DECLARE_SYSCTL; - op.cmd = DOM0_TBUFCONTROL; - op.interface_version = DOM0_INTERFACE_VERSION; - op.u.tbufcontrol.op = DOM0_TBUF_SET_SIZE; - op.u.tbufcontrol.size = size; + sysctl.cmd = XEN_SYSCTL_tbuf_op; + sysctl.interface_version = XEN_SYSCTL_INTERFACE_VERSION; + sysctl.u.tbuf_op.cmd = XEN_SYSCTL_TBUFOP_set_size; + sysctl.u.tbuf_op.size = size; - return xc_dom0_op(xc_handle, &op); + return xc_sysctl(xc_handle, &sysctl); } int xc_tbuf_get_size(int xc_handle, unsigned long *size) { int rc; - DECLARE_DOM0_OP; + DECLARE_SYSCTL; - op.cmd = DOM0_TBUFCONTROL; - op.interface_version = DOM0_INTERFACE_VERSION; - op.u.tbufcontrol.op = DOM0_TBUF_GET_INFO; + sysctl.cmd = XEN_SYSCTL_tbuf_op; + sysctl.interface_version = XEN_SYSCTL_INTERFACE_VERSION; + sysctl.u.tbuf_op.cmd = XEN_SYSCTL_TBUFOP_get_info; - rc = xc_dom0_op(xc_handle, &op); + rc = xc_sysctl(xc_handle, &sysctl); if (rc == 0) - *size = op.u.tbufcontrol.size; + *size = sysctl.u.tbuf_op.size; return rc; } int xc_tbuf_enable(int xc_handle, size_t cnt, unsigned long *mfn, unsigned long *size) { - DECLARE_DOM0_OP; + DECLARE_SYSCTL; int rc; /* @@ -73,15 +73,15 @@ int xc_tbuf_enable(int xc_handle, size_t cnt, unsigned long *mfn, if ( tbuf_enable(xc_handle, 1) != 0 ) return -1; - op.cmd = DOM0_TBUFCONTROL; - op.interface_version = DOM0_INTERFACE_VERSION; - op.u.tbufcontrol.op = DOM0_TBUF_GET_INFO; + sysctl.cmd = XEN_SYSCTL_tbuf_op; + sysctl.interface_version = XEN_SYSCTL_INTERFACE_VERSION; + sysctl.u.tbuf_op.cmd = XEN_SYSCTL_TBUFOP_get_info; - rc = xc_dom0_op(xc_handle, &op); + rc = xc_sysctl(xc_handle, &sysctl); if ( rc == 0 ) { - *size = op.u.tbufcontrol.size; - *mfn = op.u.tbufcontrol.buffer_mfn; + *size = sysctl.u.tbuf_op.size; + *mfn = sysctl.u.tbuf_op.buffer_mfn; } return 0; @@ -94,25 +94,39 @@ int xc_tbuf_disable(int xc_handle) int xc_tbuf_set_cpu_mask(int xc_handle, uint32_t mask) { - DECLARE_DOM0_OP; + DECLARE_SYSCTL; + int ret = -1; - op.cmd = DOM0_TBUFCONTROL; - op.interface_version = DOM0_INTERFACE_VERSION; - op.u.tbufcontrol.op = DOM0_TBUF_SET_CPU_MASK; - op.u.tbufcontrol.cpu_mask = mask; + sysctl.cmd = XEN_SYSCTL_tbuf_op; + sysctl.interface_version = XEN_SYSCTL_INTERFACE_VERSION; + sysctl.u.tbuf_op.cmd = XEN_SYSCTL_TBUFOP_set_cpu_mask; - return do_dom0_op(xc_handle, &op); + set_xen_guest_handle(sysctl.u.tbuf_op.cpu_mask.bitmap, (uint8_t *)&mask); + sysctl.u.tbuf_op.cpu_mask.nr_cpus = sizeof(mask) * 8; + + if ( mlock(&mask, sizeof(mask)) != 0 ) + { + PERROR("Could not lock memory for Xen hypercall"); + goto out; + } + + ret = do_sysctl(xc_handle, &sysctl); + + safe_munlock(&mask, sizeof(mask)); + + out: + return ret; } int xc_tbuf_set_evt_mask(int xc_handle, uint32_t mask) { - DECLARE_DOM0_OP; + DECLARE_SYSCTL; - op.cmd = DOM0_TBUFCONTROL; - op.interface_version = DOM0_INTERFACE_VERSION; - op.u.tbufcontrol.op = DOM0_TBUF_SET_EVT_MASK; - op.u.tbufcontrol.evt_mask = mask; + sysctl.cmd = XEN_SYSCTL_tbuf_op; + sysctl.interface_version = XEN_SYSCTL_INTERFACE_VERSION; + sysctl.u.tbuf_op.cmd = XEN_SYSCTL_TBUFOP_set_evt_mask; + sysctl.u.tbuf_op.evt_mask = mask; - return do_dom0_op(xc_handle, &op); + return do_sysctl(xc_handle, &sysctl); } diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 9ab9db9217..f2f32c47bd 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -13,11 +13,11 @@ #include <stdint.h> #include <sys/ptrace.h> #include <xen/xen.h> -#include <xen/dom0_ops.h> +#include <xen/domctl.h> +#include <xen/sysctl.h> #include <xen/version.h> #include <xen/event_channel.h> #include <xen/sched.h> -#include <xen/sched_ctl.h> #include <xen/memory.h> #include <xen/acm.h> #include <xen/acm_ops.h> @@ -139,7 +139,7 @@ typedef struct { xen_domain_handle_t handle; } xc_dominfo_t; -typedef dom0_getdomaininfo_t xc_domaininfo_t; +typedef xen_domctl_getdomaininfo_t xc_domaininfo_t; int xc_domain_create(int xc_handle, uint32_t ssidref, xen_domain_handle_t handle, @@ -231,7 +231,11 @@ int xc_domain_shutdown(int xc_handle, int xc_vcpu_setaffinity(int xc_handle, uint32_t domid, int vcpu, - cpumap_t cpumap); + uint64_t cpumap); +int xc_vcpu_getaffinity(int xc_handle, + uint32_t domid, + int vcpu, + uint64_t *cpumap); /** * This function will return information about one or more domains. It is @@ -301,7 +305,7 @@ int xc_vcpu_getcontext(int xc_handle, uint32_t vcpu, vcpu_guest_context_t *ctxt); -typedef dom0_getvcpuinfo_t xc_vcpuinfo_t; +typedef xen_domctl_getvcpuinfo_t xc_vcpuinfo_t; int xc_vcpu_getinfo(int xc_handle, uint32_t domid, uint32_t vcpu, @@ -317,7 +321,7 @@ long long xc_domain_get_cpu_usage(int xc_handle, int xc_domain_sethandle(int xc_handle, uint32_t domid, xen_domain_handle_t handle); -typedef dom0_shadow_control_stats_t xc_shadow_control_stats_t; +typedef xen_domctl_shadow_op_stats_t xc_shadow_op_stats_t; int xc_shadow_control(int xc_handle, uint32_t domid, unsigned int sop, @@ -325,7 +329,7 @@ int xc_shadow_control(int xc_handle, unsigned long pages, unsigned long *mb, uint32_t mode, - xc_shadow_control_stats_t *stats); + xc_shadow_op_stats_t *stats); int xc_sedf_domain_set(int xc_handle, uint32_t domid, @@ -341,11 +345,11 @@ int xc_sedf_domain_get(int xc_handle, int xc_sched_credit_domain_set(int xc_handle, uint32_t domid, - struct sched_credit_adjdom *sdom); + struct xen_domctl_sched_credit *sdom); int xc_sched_credit_domain_get(int xc_handle, uint32_t domid, - struct sched_credit_adjdom *sdom); + struct xen_domctl_sched_credit *sdom); /* * EVENT CHANNEL FUNCTIONS @@ -377,7 +381,7 @@ int xc_readconsolering(int xc_handle, unsigned int *pnr_chars, int clear); -typedef dom0_physinfo_t xc_physinfo_t; +typedef xen_sysctl_physinfo_t xc_physinfo_t; int xc_physinfo(int xc_handle, xc_physinfo_t *info); @@ -438,8 +442,8 @@ int xc_domain_iomem_permission(int xc_handle, unsigned long xc_make_page_below_4G(int xc_handle, uint32_t domid, unsigned long mfn); -typedef dom0_perfc_desc_t xc_perfc_desc_t; -typedef dom0_perfc_val_t xc_perfc_val_t; +typedef xen_sysctl_perfc_desc_t xc_perfc_desc_t; +typedef xen_sysctl_perfc_val_t xc_perfc_val_t; /* IMPORTANT: The caller is responsible for mlock()'ing the @desc and @val arrays. */ int xc_perfc_control(int xc_handle, @@ -561,8 +565,8 @@ int xc_tbuf_set_cpu_mask(int xc_handle, uint32_t mask); int xc_tbuf_set_evt_mask(int xc_handle, uint32_t mask); -/* Execute a privileged dom0 operation. */ -int xc_dom0_op(int xc_handle, dom0_op_t *op); +int xc_domctl(int xc_handle, struct xen_domctl *domctl); +int xc_sysctl(int xc_handle, struct xen_sysctl *sysctl); int xc_version(int xc_handle, int cmd, void *arg); diff --git a/tools/libxc/xg_private.h b/tools/libxc/xg_private.h index fcf8d25c7a..c471e94cb6 100644 --- a/tools/libxc/xg_private.h +++ b/tools/libxc/xg_private.h @@ -19,15 +19,6 @@ #include <xen/memory.h> #include <xen/elfnote.h> -/* valgrind cannot see when a hypercall has filled in some values. For this - reason, we must zero the dom0_op_t instance before a call, if using - valgrind. */ -#ifdef VALGRIND -#define DECLARE_DOM0_OP dom0_op_t op = { 0 } -#else -#define DECLARE_DOM0_OP dom0_op_t op -#endif - #ifndef ELFSIZE #include <limits.h> #if UINT_MAX == ULONG_MAX diff --git a/tools/misc/xenperf.c b/tools/misc/xenperf.c index 1054d022f7..44fc3b445a 100644 --- a/tools/misc/xenperf.c +++ b/tools/misc/xenperf.c @@ -64,7 +64,7 @@ int main(int argc, char *argv[]) if ( reset ) { - if ( xc_perfc_control(xc_handle, DOM0_PERFCCONTROL_OP_RESET, + if ( xc_perfc_control(xc_handle, XEN_SYSCTL_PERFCOP_reset, NULL, NULL, NULL, NULL) != 0 ) { fprintf(stderr, "Error reseting performance counters: %d (%s)\n", @@ -75,7 +75,7 @@ int main(int argc, char *argv[]) return 0; } - if ( xc_perfc_control(xc_handle, DOM0_PERFCCONTROL_OP_QUERY, + if ( xc_perfc_control(xc_handle, XEN_SYSCTL_PERFCOP_query, NULL, NULL, &num_desc, &num_val) != 0 ) { fprintf(stderr, "Error getting number of perf counters: %d (%s)\n", @@ -96,7 +96,7 @@ int main(int argc, char *argv[]) exit(-1); } - if ( xc_perfc_control(xc_handle, DOM0_PERFCCONTROL_OP_QUERY, + if ( xc_perfc_control(xc_handle, XEN_SYSCTL_PERFCOP_query, pcd, pcv, NULL, NULL) != 0 ) { fprintf(stderr, "Error getting perf counter: %d (%s)\n", diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 87356c7339..3137623505 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -141,7 +141,7 @@ static PyObject *pyxc_vcpu_setaffinity(XcObject *self, { uint32_t dom; int vcpu = 0, i; - cpumap_t cpumap = ~0ULL; + uint64_t cpumap = ~0ULL; PyObject *cpulist = NULL; static char *kwd_list[] = { "dom", "vcpu", "cpumap", NULL }; @@ -154,7 +154,7 @@ static PyObject *pyxc_vcpu_setaffinity(XcObject *self, { cpumap = 0ULL; for ( i = 0; i < PyList_Size(cpulist); i++ ) - cpumap |= (cpumap_t)1 << PyInt_AsLong(PyList_GetItem(cpulist, i)); + cpumap |= (uint64_t)1 << PyInt_AsLong(PyList_GetItem(cpulist, i)); } if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 ) @@ -289,7 +289,7 @@ static PyObject *pyxc_vcpu_getinfo(XcObject *self, uint32_t dom, vcpu = 0; xc_vcpuinfo_t info; int rc, i; - cpumap_t cpumap; + uint64_t cpumap; static char *kwd_list[] = { "dom", "vcpu", NULL }; @@ -300,6 +300,9 @@ static PyObject *pyxc_vcpu_getinfo(XcObject *self, rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info); if ( rc < 0 ) return PyErr_SetFromErrno(xc_error); + rc = xc_vcpu_getaffinity(self->xc_handle, dom, vcpu, &cpumap); + if ( rc < 0 ) + return PyErr_SetFromErrno(xc_error); info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}", "online", info.online, @@ -308,7 +311,6 @@ static PyObject *pyxc_vcpu_getinfo(XcObject *self, "cpu_time", info.cpu_time, "cpu", info.cpu); - cpumap = info.cpumap; cpulist = PyList_New(0); for ( i = 0; cpumap != 0; i++ ) { @@ -632,11 +634,11 @@ static PyObject *pyxc_shadow_mem_control(PyObject *self, return NULL; if ( mbarg < 0 ) - op = DOM0_SHADOW_CONTROL_OP_GET_ALLOCATION; + op = XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION; else { mb = mbarg; - op = DOM0_SHADOW_CONTROL_OP_SET_ALLOCATION; + op = XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION; } if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, &mb, 0, NULL) < 0 ) return PyErr_SetFromErrno(xc_error); @@ -654,7 +656,7 @@ static PyObject *pyxc_sched_credit_domain_set(XcObject *self, uint16_t cap; static char *kwd_list[] = { "dom", "weight", "cap", NULL }; static char kwd_type[] = "I|HH"; - struct sched_credit_adjdom sdom; + struct xen_domctl_sched_credit sdom; weight = 0; cap = (uint16_t)~0U; @@ -675,7 +677,7 @@ static PyObject *pyxc_sched_credit_domain_set(XcObject *self, static PyObject *pyxc_sched_credit_domain_get(XcObject *self, PyObject *args) { uint32_t domid; - struct sched_credit_adjdom sdom; + struct xen_domctl_sched_credit sdom; if( !PyArg_ParseTuple(args, "I", &domid) ) return NULL; diff --git a/tools/xenmon/setmask.c b/tools/xenmon/setmask.c index 333280d359..676dd6dcf7 100644 --- a/tools/xenmon/setmask.c +++ b/tools/xenmon/setmask.c @@ -40,15 +40,14 @@ typedef struct { int counter; } atomic_t; int main(int argc, char * argv[]) { - - dom0_op_t op; + struct xen_sysctl sysctl; int ret; int xc_handle = xc_interface_open(); - op.cmd = DOM0_TBUFCONTROL; - op.interface_version = DOM0_INTERFACE_VERSION; - op.u.tbufcontrol.op = DOM0_TBUF_GET_INFO; - ret = xc_dom0_op(xc_handle, &op); + sysctl.cmd = XEN_SYSCTL_tbuf_op; + sysctl.interface_version = XEN_SYSCTL_INTERFACE_VERSION; + sysctl.u.tbuf_op.cmd = XEN_SYSCTL_TBUFOP_get_info; + ret = xc_sysctl(xc_handle, &sysctl); if ( ret != 0 ) { perror("Failure to get event mask from Xen"); @@ -56,26 +55,26 @@ int main(int argc, char * argv[]) } else { - printf("Current event mask: 0x%.8x\n", op.u.tbufcontrol.evt_mask); + printf("Current event mask: 0x%.8x\n", sysctl.u.tbuf_op.evt_mask); } - op.cmd = DOM0_TBUFCONTROL; - op.interface_version = DOM0_INTERFACE_VERSION; - op.u.tbufcontrol.op = DOM0_TBUF_SET_EVT_MASK; - op.u.tbufcontrol.evt_mask = XENMON; + sysctl.cmd = XEN_SYSCTL_tbuf_op; + sysctl.interface_version = XEN_SYSCTL_INTERFACE_VERSION; + sysctl.u.tbuf_op.cmd = XEN_SYSCTL_TBUFOP_set_evt_mask; + sysctl.u.tbuf_op.evt_mask = XENMON; - ret = xc_dom0_op(xc_handle, &op); - printf("Setting mask to 0x%.8x\n", op.u.tbufcontrol.evt_mask); + ret = xc_sysctl(xc_handle, &sysctl); + printf("Setting mask to 0x%.8x\n", sysctl.u.tbuf_op.evt_mask); if ( ret != 0 ) { perror("Failure to get scheduler ID from Xen"); exit(1); } - op.cmd = DOM0_TBUFCONTROL; - op.interface_version = DOM0_INTERFACE_VERSION; - op.u.tbufcontrol.op = DOM0_TBUF_GET_INFO; - ret = xc_dom0_op(xc_handle, &op); + sysctl.cmd = XEN_SYSCTL_tbuf_op; + sysctl.interface_version = XEN_SYSCTL_INTERFACE_VERSION; + sysctl.u.tbuf_op.cmd = XEN_SYSCTL_TBUFOP_get_info; + ret = xc_sysctl(xc_handle, &sysctl); if ( ret != 0 ) { perror("Failure to get event mask from Xen"); @@ -83,7 +82,7 @@ int main(int argc, char * argv[]) } else { - printf("Current event mask: 0x%.8x\n", op.u.tbufcontrol.evt_mask); + printf("Current event mask: 0x%.8x\n", sysctl.u.tbuf_op.evt_mask); } xc_interface_close(xc_handle); return 0; diff --git a/tools/xenstat/libxenstat/src/xenstat.c b/tools/xenstat/libxenstat/src/xenstat.c index 37a0e52b53..4af20372d3 100644 --- a/tools/xenstat/libxenstat/src/xenstat.c +++ b/tools/xenstat/libxenstat/src/xenstat.c @@ -210,8 +210,8 @@ xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags) { #define DOMAIN_CHUNK_SIZE 256 xenstat_node *node; - dom0_physinfo_t physinfo; - dom0_getdomaininfo_t domaininfo[DOMAIN_CHUNK_SIZE]; + xc_physinfo_t physinfo; + xc_domaininfo_t domaininfo[DOMAIN_CHUNK_SIZE]; unsigned int new_domains; unsigned int i; @@ -530,7 +530,7 @@ static int xenstat_collect_vcpus(xenstat_node * node) for (vcpu = 0; vcpu < node->domains[i].num_vcpus; vcpu++) { /* FIXME: need to be using a more efficient mechanism*/ - dom0_getvcpuinfo_t info; + xc_vcpuinfo_t info; if (xc_vcpu_getinfo(node->handle->xc_handle, node->domains[i].id, vcpu, &info) != 0) { diff --git a/xen/arch/ia64/xen/dom0_ops.c b/xen/arch/ia64/xen/dom0_ops.c index e08da03964..0ff54d2507 100644 --- a/xen/arch/ia64/xen/dom0_ops.c +++ b/xen/arch/ia64/xen/dom0_ops.c @@ -10,14 +10,14 @@ #include <xen/types.h> #include <xen/lib.h> #include <xen/mm.h> -#include <public/dom0_ops.h> +#include <public/domctl.h> +#include <public/sysctl.h> #include <xen/sched.h> #include <xen/event.h> #include <asm/pdb.h> #include <xen/trace.h> #include <xen/console.h> #include <xen/guest_access.h> -#include <public/sched_ctl.h> #include <asm/vmx.h> #include <asm/dom_fw.h> #include <xen/iocap.h> @@ -25,7 +25,8 @@ void build_physmap_table(struct domain *d); extern unsigned long total_pages; -long arch_do_dom0_op(dom0_op_t *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) + +long arch_do_domctl(xen_domctl_t *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) { long ret = 0; @@ -34,10 +35,10 @@ long arch_do_dom0_op(dom0_op_t *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) switch ( op->cmd ) { - case DOM0_GETMEMLIST: + case XEN_DOMCTL_getmemlist: { unsigned long i; - struct domain *d = find_domain_by_id(op->u.getmemlist.domain); + struct domain *d = find_domain_by_id(op->domain); unsigned long start_page = op->u.getmemlist.max_pfns >> 32; unsigned long nr_pages = op->u.getmemlist.max_pfns & 0xffffffff; unsigned long mfn; @@ -63,39 +64,17 @@ long arch_do_dom0_op(dom0_op_t *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) } op->u.getmemlist.num_pfns = i; - if (copy_to_guest(u_dom0_op, op, 1)) + if (copy_to_guest(u_domctl, op, 1)) ret = -EFAULT; put_domain(d); } break; - case DOM0_PHYSINFO: - { - dom0_physinfo_t *pi = &op->u.physinfo; - - pi->threads_per_core = - cpus_weight(cpu_sibling_map[0]); - pi->cores_per_socket = - cpus_weight(cpu_core_map[0]) / pi->threads_per_core; - pi->sockets_per_node = - num_online_cpus() / cpus_weight(cpu_core_map[0]); - pi->nr_nodes = 1; - pi->total_pages = total_pages; - pi->free_pages = avail_domheap_pages(); - pi->cpu_khz = local_cpu_data->proc_freq / 1000; - memset(pi->hw_cap, 0, sizeof(pi->hw_cap)); - //memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4); - ret = 0; - if ( copy_to_guest(u_dom0_op, op, 1) ) - ret = -EFAULT; - } - break; - - case DOM0_DOMAIN_SETUP: + case XEN_DOMCTL_arch_setup: { - dom0_domain_setup_t *ds = &op->u.domain_setup; - struct domain *d = find_domain_by_id(ds->domain); + xen_domctl_arch_setup_t *ds = &op->u.arch_setup; + struct domain *d = find_domain_by_id(op->domain); if ( d == NULL) { ret = -EINVAL; @@ -112,7 +91,7 @@ long arch_do_dom0_op(dom0_op_t *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) ds->xsi_va = d->arch.shared_info_va; ds->hypercall_imm = d->arch.breakimm; /* Copy back. */ - if ( copy_to_guest(u_dom0_op, op, 1) ) + if ( copy_to_guest(u_domctl, op, 1) ) ret = -EFAULT; } else { @@ -152,21 +131,21 @@ long arch_do_dom0_op(dom0_op_t *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) } break; - case DOM0_SHADOW_CONTROL: + case XEN_DOMCTL_shadow_op: { struct domain *d; ret = -ESRCH; - d = find_domain_by_id(op->u.shadow_control.domain); + d = find_domain_by_id(op->domain); if ( d != NULL ) { - ret = shadow_mode_control(d, &op->u.shadow_control); + ret = shadow_mode_control(d, &op->u.shadow_op); put_domain(d); - copy_to_guest(u_dom0_op, op, 1); + copy_to_guest(u_domctl, op, 1); } } break; - case DOM0_IOPORT_PERMISSION: + case XEN_DOMCTL_ioport_permission: { struct domain *d; unsigned int fp = op->u.ioport_permission.first_port; @@ -174,7 +153,7 @@ long arch_do_dom0_op(dom0_op_t *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) unsigned int lp = fp + np - 1; ret = -ESRCH; - d = find_domain_by_id(op->u.ioport_permission.domain); + d = find_domain_by_id(op->domain); if (unlikely(d == NULL)) break; @@ -191,7 +170,47 @@ long arch_do_dom0_op(dom0_op_t *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) } break; default: - printf("arch_do_dom0_op: unrecognized dom0 op: %d!!!\n",op->cmd); + printf("arch_do_domctl: unrecognized domctl: %d!!!\n",op->cmd); + ret = -ENOSYS; + + } + + return ret; +} + +long arch_do_sysctl(xen_sysctl_t *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) +{ + long ret = 0; + + if ( !IS_PRIV(current->domain) ) + return -EPERM; + + switch ( op->cmd ) + { + case XEN_SYSCTL_physinfo: + { + xen_sysctl_physinfo_t *pi = &op->u.physinfo; + + pi->threads_per_core = + cpus_weight(cpu_sibling_map[0]); + pi->cores_per_socket = + cpus_weight(cpu_core_map[0]) / pi->threads_per_core; + pi->sockets_per_node = + num_online_cpus() / cpus_weight(cpu_core_map[0]); + pi->nr_nodes = 1; + pi->total_pages = total_pages; + pi->free_pages = avail_domheap_pages(); + pi->cpu_khz = local_cpu_data->proc_freq / 1000; + memset(pi->hw_cap, 0, sizeof(pi->hw_cap)); + //memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4); + ret = 0; + if ( copy_to_guest(u_sysctl, op, 1) ) + ret = -EFAULT; + } + break; + + default: + printf("arch_do_sysctl: unrecognized sysctl: %d!!!\n",op->cmd); ret = -ENOSYS; } diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index 520adaf314..b0b833f611 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -591,7 +591,7 @@ domain_set_shared_info_va (unsigned long va) /* Transfer and clear the shadow bitmap in 1kB chunks for L1 cache. */ #define SHADOW_COPY_CHUNK (1024 / sizeof (unsigned long)) -int shadow_mode_control(struct domain *d, dom0_shadow_control_t *sc) +int shadow_mode_control(struct domain *d, xen_domctl_shadow_ops_t *sc) { unsigned int op = sc->op; int rc = 0; @@ -607,7 +607,7 @@ int shadow_mode_control(struct domain *d, dom0_shadow_control_t *sc) switch (op) { - case DOM0_SHADOW_CONTROL_OP_OFF: + case XEN_DOMCTL_SHADOW_OP_OFF: if (shadow_mode_enabled (d)) { u64 *bm = d->arch.shadow_bitmap; @@ -621,12 +621,12 @@ int shadow_mode_control(struct domain *d, dom0_shadow_control_t *sc) } break; - case DOM0_SHADOW_CONTROL_OP_ENABLE_TEST: - case DOM0_SHADOW_CONTROL_OP_ENABLE_TRANSLATE: + case XEN_DOMCTL_SHADOW_OP_ENABLE_TEST: + case XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE: rc = -EINVAL; break; - case DOM0_SHADOW_CONTROL_OP_ENABLE_LOGDIRTY: + case XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY: if (shadow_mode_enabled(d)) { rc = -EINVAL; break; @@ -653,7 +653,7 @@ int shadow_mode_control(struct domain *d, dom0_shadow_control_t *sc) } break; - case DOM0_SHADOW_CONTROL_OP_CLEAN: + case XEN_DOMCTL_SHADOW_OP_CLEAN: { int nbr_longs; @@ -692,7 +692,7 @@ int shadow_mode_control(struct domain *d, dom0_shadow_control_t *sc) break; } - case DOM0_SHADOW_CONTROL_OP_PEEK: + case XEN_DOMCTL_SHADOW_OP_PEEK: { unsigned long size; diff --git a/xen/arch/ia64/xen/hypercall.c b/xen/arch/ia64/xen/hypercall.c index 97924b8776..b6586c9106 100644 --- a/xen/arch/ia64/xen/hypercall.c +++ b/xen/arch/ia64/xen/hypercall.c @@ -18,7 +18,8 @@ #include <asm/vcpu.h> #include <asm/dom_fw.h> -#include <public/dom0_ops.h> +#include <public/domctl.h> +#include <public/sysctl.h> #include <public/event_channel.h> #include <public/memory.h> #include <public/sched.h> @@ -43,7 +44,7 @@ hypercall_t ia64_hypercall_table[] = (hypercall_t)do_ni_hypercall, /* do_set_callbacks */ (hypercall_t)do_ni_hypercall, /* do_fpu_taskswitch */ /* 5 */ (hypercall_t)do_sched_op_compat, - (hypercall_t)do_dom0_op, + (hypercall_t)do_ni_hypercall, (hypercall_t)do_ni_hypercall, /* do_set_debugreg */ (hypercall_t)do_ni_hypercall, /* do_get_debugreg */ (hypercall_t)do_ni_hypercall, /* do_update_descriptor */ /* 10 */ @@ -71,8 +72,8 @@ hypercall_t ia64_hypercall_table[] = (hypercall_t)do_event_channel_op, (hypercall_t)do_physdev_op, (hypercall_t)do_hvm_op, /* */ - (hypercall_t)do_ni_hypercall, /* */ /* 35 */ - (hypercall_t)do_ni_hypercall, /* */ + (hypercall_t)do_sysctl, /* */ /* 35 */ + (hypercall_t)do_domctl, /* */ (hypercall_t)do_ni_hypercall, /* */ (hypercall_t)do_ni_hypercall, /* */ (hypercall_t)do_ni_hypercall, /* */ diff --git a/xen/arch/powerpc/dom0_ops.c b/xen/arch/powerpc/dom0_ops.c index babc92945d..ff4813d92c 100644 --- a/xen/arch/powerpc/dom0_ops.c +++ b/xen/arch/powerpc/dom0_ops.c @@ -24,10 +24,8 @@ #include <xen/sched.h> #include <xen/guest_access.h> #include <public/xen.h> -#include <public/dom0_ops.h> - -extern void arch_getdomaininfo_ctxt(struct vcpu *v, vcpu_guest_context_t *c); -extern long arch_do_dom0_op(struct dom0_op *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op); +#include <public/domctl.h> +#include <public/sysctl.h> void arch_getdomaininfo_ctxt(struct vcpu *v, vcpu_guest_context_t *c) { @@ -35,16 +33,17 @@ void arch_getdomaininfo_ctxt(struct vcpu *v, vcpu_guest_context_t *c) /* XXX fill in rest of vcpu_guest_context_t */ } -long arch_do_dom0_op(struct dom0_op *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) +long arch_do_domctl(struct xen_domctl *domctl, + XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) { long ret = 0; - switch (op->cmd) { - case DOM0_GETMEMLIST: + switch (domctl->cmd) { + case XEN_DOMCTL_getmemlist: { int i; - struct domain *d = find_domain_by_id(op->u.getmemlist.domain); - unsigned long max_pfns = op->u.getmemlist.max_pfns; + struct domain *d = find_domain_by_id(domctl->domain); + unsigned long max_pfns = domctl->u.getmemlist.max_pfns; xen_pfn_t mfn; struct list_head *list_ent; @@ -59,7 +58,7 @@ long arch_do_dom0_op(struct dom0_op *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) { mfn = page_to_mfn(list_entry( list_ent, struct page_info, list)); - if ( copy_to_guest_offset(op->u.getmemlist.buffer, + if ( copy_to_guest_offset(domctl->u.getmemlist.buffer, i, &mfn, 1) ) { ret = -EFAULT; @@ -69,17 +68,31 @@ long arch_do_dom0_op(struct dom0_op *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) } spin_unlock(&d->page_alloc_lock); - op->u.getmemlist.num_pfns = i; - copy_to_guest(u_dom0_op, op, 1); + domctl->u.getmemlist.num_pfns = i; + copy_to_guest(u_domctl, domctl, 1); put_domain(d); } } break; - case DOM0_PHYSINFO: + default: + ret = -ENOSYS; + break; + } + + return ret; +} + +long arch_do_sysctl(struct xen_sysctl *sysctl, + XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) +{ + long ret = 0; + + switch (sysctl->cmd) { + case XEN_SYSCTL_physinfo: { - dom0_physinfo_t *pi = &op->u.physinfo; + xen_sysctl_physinfo_t *pi = &sysctl->u.physinfo; pi->threads_per_core = 1; pi->cores_per_socket = 1; @@ -90,7 +103,7 @@ long arch_do_dom0_op(struct dom0_op *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) pi->cpu_khz = cpu_khz; memset(pi->hw_cap, 0, sizeof(pi->hw_cap)); ret = 0; - if ( copy_to_guest(u_dom0_op, op, 1) ) + if ( copy_to_guest(u_sysctl, sysctl, 1) ) ret = -EFAULT; } break; @@ -102,3 +115,4 @@ long arch_do_dom0_op(struct dom0_op *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) return ret; } + diff --git a/xen/arch/powerpc/powerpc64/hypercall_table.S b/xen/arch/powerpc/powerpc64/hypercall_table.S index 5562b021cd..a54c838db0 100644 --- a/xen/arch/powerpc/powerpc64/hypercall_table.S +++ b/xen/arch/powerpc/powerpc64/hypercall_table.S @@ -11,7 +11,7 @@ __hypercall_table: .quad 0 /* do_set_callbacks */ .quad 0 /* do_fpu_taskswitch */ /* 5 */ .quad do_sched_op - .quad do_dom0_op + .quad 0 /* do_platform_op */ .quad 0 /* do_set_debugreg */ .quad 0 /* do_get_debugreg */ .quad 0 /* do_update_descriptor */ /* 10 */ @@ -38,46 +38,9 @@ __hypercall_table: .quad 0 /* do_xenoprof_op */ .quad do_event_channel_op .quad do_physdev_op + .quad 0 /* do_hvm_op */ + .quad do_sysctl /* 35 */ + .quad do_domctl .rept NR_hypercalls-((.-__hypercall_table)/8) .quad do_ni_hypercall .endr - - .globl hypercall_args_table -hypercall_args_table: - .byte 1 /* do_set_trap_table */ /* 0 */ - .byte 4 /* do_mmu_update */ - .byte 2 /* do_set_gdt */ - .byte 2 /* do_stack_switch */ - .byte 4 /* do_set_callbacks */ - .byte 1 /* do_fpu_taskswitch */ /* 5 */ - .byte 2 /* do_arch_sched_op */ - .byte 1 /* do_dom0_op */ - .byte 2 /* do_set_debugreg */ - .byte 1 /* do_get_debugreg */ - .byte 4 /* do_update_descriptor */ /* 10 */ - .byte 0 /* do_ni_hypercall */ - .byte 2 /* do_memory_op */ - .byte 2 /* do_multicall */ - .byte 4 /* do_update_va_mapping */ - .byte 2 /* do_set_timer_op */ /* 15 */ - .byte 1 /* do_event_channel_op */ - .byte 2 /* do_xen_version */ - .byte 3 /* do_console_io */ - .byte 1 /* do_physdev_op */ - .byte 3 /* do_grant_table_op */ /* 20 */ - .byte 2 /* do_vm_assist */ - .byte 5 /* do_update_va_mapping_otherdomain */ - .byte 0 /* do_switch_vm86 */ - .byte 2 /* do_boot_vcpu */ - .byte 0 /* do_ni_hypercall */ /* 25 */ - .byte 4 /* do_mmuext_op */ - .byte 1 /* do_acm_op */ - .byte 2 /* do_nmi_op */ - .byte 2 /* do_arch_sched_op */ - .byte 2 /* do_callback_op */ /* 30 */ - .byte 2 /* do_xenoprof_op */ - .byte 2 /* do_event_channel_op */ - .byte 2 /* do_physdev_op */ - .rept NR_hypercalls-(.-hypercall_args_table) - .byte 0 /* do_ni_hypercall */ - .endr diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index e246594245..6c3552c6c9 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -12,12 +12,13 @@ obj-y += bitops.o obj-y += compat.o obj-y += delay.o obj-y += dmi_scan.o -obj-y += dom0_ops.o +obj-y += domctl.o obj-y += domain.o obj-y += domain_build.o obj-y += e820.o obj-y += extable.o obj-y += flushtlb.o +obj-y += platform_hypercall.o obj-y += i387.o obj-y += i8259.o obj-y += io_apic.o @@ -33,6 +34,7 @@ obj-y += shutdown.o obj-y += smp.o obj-y += smpboot.o obj-y += string.o +obj-y += sysctl.o obj-y += time.o obj-y += trampoline.o obj-y += traps.o diff --git a/xen/arch/x86/dom0_ops.c b/xen/arch/x86/dom0_ops.c deleted file mode 100644 index 0038112d63..0000000000 --- a/xen/arch/x86/dom0_ops.c +++ /dev/null @@ -1,486 +0,0 @@ -/****************************************************************************** - * Arch-specific dom0_ops.c - * - * Process command requests from domain-0 guest OS. - * - * Copyright (c) 2002, K A Fraser - */ - -#include <xen/config.h> -#include <xen/types.h> -#include <xen/lib.h> -#include <xen/mm.h> -#include <xen/guest_access.h> -#include <public/dom0_ops.h> -#include <xen/sched.h> -#include <xen/event.h> -#include <xen/domain_page.h> -#include <asm/msr.h> -#include <xen/trace.h> -#include <xen/console.h> -#include <xen/iocap.h> -#include <asm/shadow.h> -#include <asm/irq.h> -#include <asm/hvm/hvm.h> -#include <asm/hvm/support.h> -#include <asm/processor.h> -#include <public/sched_ctl.h> - -#include <asm/mtrr.h> -#include "cpu/mtrr/mtrr.h" - -#define TRC_DOM0OP_ENTER_BASE 0x00020000 -#define TRC_DOM0OP_LEAVE_BASE 0x00030000 - -static int msr_cpu_mask; -static unsigned long msr_addr; -static unsigned long msr_lo; -static unsigned long msr_hi; - -static void write_msr_for(void *unused) -{ - if ( ((1 << smp_processor_id()) & msr_cpu_mask) ) - (void)wrmsr_safe(msr_addr, msr_lo, msr_hi); -} - -static void read_msr_for(void *unused) -{ - if ( ((1 << smp_processor_id()) & msr_cpu_mask) ) - (void)rdmsr_safe(msr_addr, msr_lo, msr_hi); -} - -long arch_do_dom0_op(struct dom0_op *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) -{ - long ret = 0; - - switch ( op->cmd ) - { - - case DOM0_MSR: - { - if ( op->u.msr.write ) - { - msr_cpu_mask = op->u.msr.cpu_mask; - msr_addr = op->u.msr.msr; - msr_lo = op->u.msr.in1; - msr_hi = op->u.msr.in2; - smp_call_function(write_msr_for, NULL, 1, 1); - write_msr_for(NULL); - } - else - { - msr_cpu_mask = op->u.msr.cpu_mask; - msr_addr = op->u.msr.msr; - smp_call_function(read_msr_for, NULL, 1, 1); - read_msr_for(NULL); - - op->u.msr.out1 = msr_lo; - op->u.msr.out2 = msr_hi; - copy_to_guest(u_dom0_op, op, 1); - } - ret = 0; - } - break; - - case DOM0_SHADOW_CONTROL: - { - struct domain *d; - ret = -ESRCH; - d = find_domain_by_id(op->u.shadow_control.domain); - if ( d != NULL ) - { - ret = shadow2_control_op(d, &op->u.shadow_control, u_dom0_op); - put_domain(d); - copy_to_guest(u_dom0_op, op, 1); - } - } - break; - - case DOM0_ADD_MEMTYPE: - { - ret = mtrr_add_page( - op->u.add_memtype.mfn, - op->u.add_memtype.nr_mfns, - op->u.add_memtype.type, - 1); - if ( ret > 0 ) - { - op->u.add_memtype.handle = 0; - op->u.add_memtype.reg = ret; - (void)copy_to_guest(u_dom0_op, op, 1); - ret = 0; - } - } - break; - - case DOM0_DEL_MEMTYPE: - { - if (op->u.del_memtype.handle == 0 - /* mtrr/main.c otherwise does a lookup */ - && (int)op->u.del_memtype.reg >= 0) - { - ret = mtrr_del_page(op->u.del_memtype.reg, 0, 0); - if (ret > 0) - ret = 0; - } - else - ret = -EINVAL; - } - break; - - case DOM0_READ_MEMTYPE: - { - unsigned long mfn; - unsigned int nr_mfns; - mtrr_type type; - - ret = -EINVAL; - if ( op->u.read_memtype.reg < num_var_ranges ) - { - mtrr_if->get(op->u.read_memtype.reg, &mfn, &nr_mfns, &type); - op->u.read_memtype.mfn = mfn; - op->u.read_memtype.nr_mfns = nr_mfns; - op->u.read_memtype.type = type; - (void)copy_to_guest(u_dom0_op, op, 1); - ret = 0; - } - } - break; - - case DOM0_MICROCODE: - { - extern int microcode_update(void *buf, unsigned long len); - ret = microcode_update(op->u.microcode.data.p, op->u.microcode.length); - } - break; - - case DOM0_IOPORT_PERMISSION: - { - struct domain *d; - unsigned int fp = op->u.ioport_permission.first_port; - unsigned int np = op->u.ioport_permission.nr_ports; - - ret = -EINVAL; - if ( (fp + np) > 65536 ) - break; - - ret = -ESRCH; - if ( unlikely((d = find_domain_by_id( - op->u.ioport_permission.domain)) == NULL) ) - break; - - if ( np == 0 ) - ret = 0; - else if ( op->u.ioport_permission.allow_access ) - ret = ioports_permit_access(d, fp, fp + np - 1); - else - ret = ioports_deny_access(d, fp, fp + np - 1); - - put_domain(d); - } - break; - - case DOM0_PHYSINFO: - { - dom0_physinfo_t *pi = &op->u.physinfo; - - pi->threads_per_core = - cpus_weight(cpu_sibling_map[0]); - pi->cores_per_socket = - cpus_weight(cpu_core_map[0]) / pi->threads_per_core; - pi->sockets_per_node = - num_online_cpus() / cpus_weight(cpu_core_map[0]); - - pi->nr_nodes = 1; - pi->total_pages = total_pages; - pi->free_pages = avail_domheap_pages(); - pi->scrub_pages = avail_scrub_pages(); - pi->cpu_khz = cpu_khz; - memset(pi->hw_cap, 0, sizeof(pi->hw_cap)); - memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4); - ret = 0; - if ( copy_to_guest(u_dom0_op, op, 1) ) - ret = -EFAULT; - } - break; - - case DOM0_GETPAGEFRAMEINFO: - { - struct page_info *page; - unsigned long mfn = op->u.getpageframeinfo.gmfn; - domid_t dom = op->u.getpageframeinfo.domain; - struct domain *d; - - ret = -EINVAL; - - if ( unlikely(!mfn_valid(mfn)) || - unlikely((d = find_domain_by_id(dom)) == NULL) ) - break; - - page = mfn_to_page(mfn); - - if ( likely(get_page(page, d)) ) - { - ret = 0; - - op->u.getpageframeinfo.type = NOTAB; - - if ( (page->u.inuse.type_info & PGT_count_mask) != 0 ) - { - switch ( page->u.inuse.type_info & PGT_type_mask ) - { - case PGT_l1_page_table: - op->u.getpageframeinfo.type = L1TAB; - break; - case PGT_l2_page_table: - op->u.getpageframeinfo.type = L2TAB; - break; - case PGT_l3_page_table: - op->u.getpageframeinfo.type = L3TAB; - break; - case PGT_l4_page_table: - op->u.getpageframeinfo.type = L4TAB; - break; - } - } - - put_page(page); - } - - put_domain(d); - - copy_to_guest(u_dom0_op, op, 1); - } - break; - - case DOM0_GETPAGEFRAMEINFO2: - { -#define GPF2_BATCH (PAGE_SIZE / sizeof(unsigned long)) - int n,j; - int num = op->u.getpageframeinfo2.num; - domid_t dom = op->u.getpageframeinfo2.domain; - struct domain *d; - unsigned long *l_arr; - ret = -ESRCH; - - if ( unlikely((d = find_domain_by_id(dom)) == NULL) ) - break; - - if ( unlikely(num > 1024) ) - { - ret = -E2BIG; - put_domain(d); - break; - } - - l_arr = alloc_xenheap_page(); - - ret = 0; - for( n = 0; n < num; ) - { - int k = ((num-n)>GPF2_BATCH)?GPF2_BATCH:(num-n); - - if ( copy_from_guest_offset(l_arr, op->u.getpageframeinfo2.array, - n, k) ) - { - ret = -EINVAL; - break; - } - - for( j = 0; j < k; j++ ) - { - struct page_info *page; - unsigned long mfn = l_arr[j]; - - page = mfn_to_page(mfn); - - if ( likely(mfn_valid(mfn) && get_page(page, d)) ) - { - unsigned long type = 0; - - switch( page->u.inuse.type_info & PGT_type_mask ) - { - case PGT_l1_page_table: - type = L1TAB; - break; - case PGT_l2_page_table: - type = L2TAB; - break; - case PGT_l3_page_table: - type = L3TAB; - break; - case PGT_l4_page_table: - type = L4TAB; - break; - } - - if ( page->u.inuse.type_info & PGT_pinned ) - type |= LPINTAB; - l_arr[j] |= type; - put_page(page); - } - else - l_arr[j] |= XTAB; - - } - - if ( copy_to_guest_offset(op->u.getpageframeinfo2.array, - n, l_arr, k) ) - { - ret = -EINVAL; - break; - } - - n += k; - } - - free_xenheap_page(l_arr); - - put_domain(d); - } - break; - - case DOM0_GETMEMLIST: - { - int i; - struct domain *d = find_domain_by_id(op->u.getmemlist.domain); - unsigned long max_pfns = op->u.getmemlist.max_pfns; - unsigned long mfn; - struct list_head *list_ent; - - ret = -EINVAL; - if ( d != NULL ) - { - ret = 0; - - spin_lock(&d->page_alloc_lock); - list_ent = d->page_list.next; - for ( i = 0; (i < max_pfns) && (list_ent != &d->page_list); i++ ) - { - mfn = page_to_mfn(list_entry( - list_ent, struct page_info, list)); - if ( copy_to_guest_offset(op->u.getmemlist.buffer, - i, &mfn, 1) ) - { - ret = -EFAULT; - break; - } - list_ent = mfn_to_page(mfn)->list.next; - } - spin_unlock(&d->page_alloc_lock); - - op->u.getmemlist.num_pfns = i; - copy_to_guest(u_dom0_op, op, 1); - - put_domain(d); - } - } - break; - - case DOM0_PLATFORM_QUIRK: - { - extern int opt_noirqbalance; - int quirk_id = op->u.platform_quirk.quirk_id; - switch ( quirk_id ) - { - case QUIRK_NOIRQBALANCING: - printk("Platform quirk -- Disabling IRQ balancing/affinity.\n"); - opt_noirqbalance = 1; - setup_ioapic_dest(); - break; - case QUIRK_IOAPIC_BAD_REGSEL: - case QUIRK_IOAPIC_GOOD_REGSEL: -#ifndef sis_apic_bug - sis_apic_bug = (quirk_id == QUIRK_IOAPIC_BAD_REGSEL); - DPRINTK("Domain 0 says that IO-APIC REGSEL is %s\n", - sis_apic_bug ? "bad" : "good"); -#else - BUG_ON(sis_apic_bug != (quirk_id == QUIRK_IOAPIC_BAD_REGSEL)); -#endif - break; - default: - ret = -EINVAL; - break; - } - } - break; - - case DOM0_HYPERCALL_INIT: - { - struct domain *d = find_domain_by_id(op->u.hypercall_init.domain); - unsigned long gmfn = op->u.hypercall_init.gmfn; - unsigned long mfn; - void *hypercall_page; - - ret = -ESRCH; - if ( unlikely(d == NULL) ) - break; - - mfn = gmfn_to_mfn(d, gmfn); - - ret = -EACCES; - if ( !mfn_valid(mfn) || - !get_page_and_type(mfn_to_page(mfn), d, PGT_writable_page) ) - { - put_domain(d); - break; - } - - ret = 0; - - hypercall_page = map_domain_page(mfn); - hypercall_page_initialise(d, hypercall_page); - unmap_domain_page(hypercall_page); - - put_page_and_type(mfn_to_page(mfn)); - - put_domain(d); - } - break; - - default: - ret = -ENOSYS; - break; - } - - return ret; -} - -void arch_getdomaininfo_ctxt( - struct vcpu *v, struct vcpu_guest_context *c) -{ - memcpy(c, &v->arch.guest_context, sizeof(*c)); - - if ( hvm_guest(v) ) - { - hvm_store_cpu_guest_regs(v, &c->user_regs, c->ctrlreg); - } - else - { - /* IOPL privileges are virtualised: merge back into returned eflags. */ - BUG_ON((c->user_regs.eflags & EF_IOPL) != 0); - c->user_regs.eflags |= v->arch.iopl << 12; - } - - c->flags = 0; - if ( test_bit(_VCPUF_fpu_initialised, &v->vcpu_flags) ) - c->flags |= VGCF_I387_VALID; - if ( guest_kernel_mode(v, &v->arch.guest_context.user_regs) ) - c->flags |= VGCF_IN_KERNEL; - if ( hvm_guest(v) ) - c->flags |= VGCF_HVM_GUEST; - - c->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); - - c->vm_assist = v->domain->vm_assist; -} - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c new file mode 100644 index 0000000000..45caf069e9 --- /dev/null +++ b/xen/arch/x86/domctl.c @@ -0,0 +1,326 @@ +/****************************************************************************** + * Arch-specific domctl.c + * + * Copyright (c) 2002-2006, K A Fraser + */ + +#include <xen/config.h> +#include <xen/types.h> +#include <xen/lib.h> +#include <xen/mm.h> +#include <xen/guest_access.h> +#include <public/domctl.h> +#include <xen/sched.h> +#include <xen/event.h> +#include <xen/domain_page.h> +#include <asm/msr.h> +#include <xen/trace.h> +#include <xen/console.h> +#include <xen/iocap.h> +#include <asm/shadow.h> +#include <asm/irq.h> +#include <asm/hvm/hvm.h> +#include <asm/hvm/support.h> +#include <asm/processor.h> + +long arch_do_domctl( + struct xen_domctl *domctl, + XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) +{ + long ret = 0; + + switch ( domctl->cmd ) + { + + case XEN_DOMCTL_shadow_op: + { + struct domain *d; + ret = -ESRCH; + d = find_domain_by_id(domctl->domain); + if ( d != NULL ) + { + ret = shadow2_domctl(d, &domctl->u.shadow_op, u_domctl); + put_domain(d); + copy_to_guest(u_domctl, domctl, 1); + } + } + break; + + case XEN_DOMCTL_ioport_permission: + { + struct domain *d; + unsigned int fp = domctl->u.ioport_permission.first_port; + unsigned int np = domctl->u.ioport_permission.nr_ports; + + ret = -EINVAL; + if ( (fp + np) > 65536 ) + break; + + ret = -ESRCH; + if ( unlikely((d = find_domain_by_id(domctl->domain)) == NULL) ) + break; + + if ( np == 0 ) + ret = 0; + else if ( domctl->u.ioport_permission.allow_access ) + ret = ioports_permit_access(d, fp, fp + np - 1); + else + ret = ioports_deny_access(d, fp, fp + np - 1); + + put_domain(d); + } + break; + + case XEN_DOMCTL_getpageframeinfo: + { + struct page_info *page; + unsigned long mfn = domctl->u.getpageframeinfo.gmfn; + domid_t dom = domctl->domain; + struct domain *d; + + ret = -EINVAL; + + if ( unlikely(!mfn_valid(mfn)) || + unlikely((d = find_domain_by_id(dom)) == NULL) ) + break; + + page = mfn_to_page(mfn); + + if ( likely(get_page(page, d)) ) + { + ret = 0; + + domctl->u.getpageframeinfo.type = XEN_DOMCTL_PFINFO_NOTAB; + + if ( (page->u.inuse.type_info & PGT_count_mask) != 0 ) + { + switch ( page->u.inuse.type_info & PGT_type_mask ) + { + case PGT_l1_page_table: + domctl->u.getpageframeinfo.type = XEN_DOMCTL_PFINFO_L1TAB; + break; + case PGT_l2_page_table: + domctl->u.getpageframeinfo.type = XEN_DOMCTL_PFINFO_L2TAB; + break; + case PGT_l3_page_table: + domctl->u.getpageframeinfo.type = XEN_DOMCTL_PFINFO_L3TAB; + break; + case PGT_l4_page_table: + domctl->u.getpageframeinfo.type = XEN_DOMCTL_PFINFO_L4TAB; + break; + } + } + + put_page(page); + } + + put_domain(d); + + copy_to_guest(u_domctl, domctl, 1); + } + break; + + case XEN_DOMCTL_getpageframeinfo2: + { +#define GPF2_BATCH (PAGE_SIZE / sizeof(long)) + int n,j; + int num = domctl->u.getpageframeinfo2.num; + domid_t dom = domctl->domain; + struct domain *d; + unsigned long *l_arr; + ret = -ESRCH; + + if ( unlikely((d = find_domain_by_id(dom)) == NULL) ) + break; + + if ( unlikely(num > 1024) ) + { + ret = -E2BIG; + put_domain(d); + break; + } + + l_arr = alloc_xenheap_page(); + + ret = 0; + for ( n = 0; n < num; ) + { + int k = ((num-n)>GPF2_BATCH)?GPF2_BATCH:(num-n); + + if ( copy_from_guest_offset(l_arr, + domctl->u.getpageframeinfo2.array, + n, k) ) + { + ret = -EINVAL; + break; + } + + for ( j = 0; j < k; j++ ) + { + struct page_info *page; + unsigned long mfn = l_arr[j]; + + page = mfn_to_page(mfn); + + if ( likely(mfn_valid(mfn) && get_page(page, d)) ) + { + unsigned long type = 0; + + switch( page->u.inuse.type_info & PGT_type_mask ) + { + case PGT_l1_page_table: + type = XEN_DOMCTL_PFINFO_L1TAB; + break; + case PGT_l2_page_table: + type = XEN_DOMCTL_PFINFO_L2TAB; + break; + case PGT_l3_page_table: + type = XEN_DOMCTL_PFINFO_L3TAB; + break; + case PGT_l4_page_table: + type = XEN_DOMCTL_PFINFO_L4TAB; + break; + } + + if ( page->u.inuse.type_info & PGT_pinned ) + type |= XEN_DOMCTL_PFINFO_LPINTAB; + l_arr[j] |= type; + put_page(page); + } + else + l_arr[j] |= XEN_DOMCTL_PFINFO_XTAB; + + } + + if ( copy_to_guest_offset(domctl->u.getpageframeinfo2.array, + n, l_arr, k) ) + { + ret = -EINVAL; + break; + } + + n += k; + } + + free_xenheap_page(l_arr); + + put_domain(d); + } + break; + + case XEN_DOMCTL_getmemlist: + { + int i; + struct domain *d = find_domain_by_id(domctl->domain); + unsigned long max_pfns = domctl->u.getmemlist.max_pfns; + unsigned long mfn; + struct list_head *list_ent; + + ret = -EINVAL; + if ( d != NULL ) + { + ret = 0; + + spin_lock(&d->page_alloc_lock); + list_ent = d->page_list.next; + for ( i = 0; (i < max_pfns) && (list_ent != &d->page_list); i++ ) + { + mfn = page_to_mfn(list_entry( + list_ent, struct page_info, list)); + if ( copy_to_guest_offset(domctl->u.getmemlist.buffer, + i, &mfn, 1) ) + { + ret = -EFAULT; + break; + } + list_ent = mfn_to_page(mfn)->list.next; + } + spin_unlock(&d->page_alloc_lock); + + domctl->u.getmemlist.num_pfns = i; + copy_to_guest(u_domctl, domctl, 1); + + put_domain(d); + } + } + break; + + case XEN_DOMCTL_hypercall_init: + { + struct domain *d = find_domain_by_id(domctl->domain); + unsigned long gmfn = domctl->u.hypercall_init.gmfn; + unsigned long mfn; + void *hypercall_page; + + ret = -ESRCH; + if ( unlikely(d == NULL) ) + break; + + mfn = gmfn_to_mfn(d, gmfn); + + ret = -EACCES; + if ( !mfn_valid(mfn) || + !get_page_and_type(mfn_to_page(mfn), d, PGT_writable_page) ) + { + put_domain(d); + break; + } + + ret = 0; + + hypercall_page = map_domain_page(mfn); + hypercall_page_initialise(d, hypercall_page); + unmap_domain_page(hypercall_page); + + put_page_and_type(mfn_to_page(mfn)); + + put_domain(d); + } + break; + + default: + ret = -ENOSYS; + break; + } + + return ret; +} + +void arch_getdomaininfo_ctxt( + struct vcpu *v, struct vcpu_guest_context *c) +{ + memcpy(c, &v->arch.guest_context, sizeof(*c)); + + if ( hvm_guest(v) ) + { + hvm_store_cpu_guest_regs(v, &c->user_regs, c->ctrlreg); + } + else + { + /* IOPL privileges are virtualised: merge back into returned eflags. */ + BUG_ON((c->user_regs.eflags & EF_IOPL) != 0); + c->user_regs.eflags |= v->arch.iopl << 12; + } + + c->flags = 0; + if ( test_bit(_VCPUF_fpu_initialised, &v->vcpu_flags) ) + c->flags |= VGCF_I387_VALID; + if ( guest_kernel_mode(v, &v->arch.guest_context.user_regs) ) + c->flags |= VGCF_IN_KERNEL; + if ( hvm_guest(v) ) + c->flags |= VGCF_HVM_GUEST; + + c->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); + + c->vm_assist = v->domain->vm_assist; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c new file mode 100644 index 0000000000..098c847112 --- /dev/null +++ b/xen/arch/x86/platform_hypercall.c @@ -0,0 +1,159 @@ +/****************************************************************************** + * platform_hypercall.c + * + * Hardware platform operations. Intended for use by domain-0 kernel. + * + * Copyright (c) 2002-2006, K Fraser + */ + +#include <xen/config.h> +#include <xen/types.h> +#include <xen/lib.h> +#include <xen/mm.h> +#include <xen/sched.h> +#include <xen/domain.h> +#include <xen/event.h> +#include <xen/domain_page.h> +#include <xen/trace.h> +#include <xen/console.h> +#include <xen/iocap.h> +#include <xen/guest_access.h> +#include <asm/current.h> +#include <public/platform.h> +#include <asm/mtrr.h> +#include "cpu/mtrr/mtrr.h" + +long do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) +{ + long ret = 0; + struct xen_platform_op curop, *op = &curop; + static DEFINE_SPINLOCK(xenpf_lock); + + if ( !IS_PRIV(current->domain) ) + return -EPERM; + + if ( copy_from_guest(op, u_xenpf_op, 1) ) + return -EFAULT; + + if ( op->interface_version != XENPF_INTERFACE_VERSION ) + return -EACCES; + + spin_lock(&xenpf_lock); + + switch ( op->cmd ) + { + case XENPF_settime: + { + do_settime(op->u.settime.secs, + op->u.settime.nsecs, + op->u.settime.system_time); + ret = 0; + } + break; + + case XENPF_add_memtype: + { + ret = mtrr_add_page( + op->u.add_memtype.mfn, + op->u.add_memtype.nr_mfns, + op->u.add_memtype.type, + 1); + if ( ret > 0 ) + { + op->u.add_memtype.handle = 0; + op->u.add_memtype.reg = ret; + (void)copy_to_guest(u_xenpf_op, op, 1); + ret = 0; + } + } + break; + + case XENPF_del_memtype: + { + if (op->u.del_memtype.handle == 0 + /* mtrr/main.c otherwise does a lookup */ + && (int)op->u.del_memtype.reg >= 0) + { + ret = mtrr_del_page(op->u.del_memtype.reg, 0, 0); + if (ret > 0) + ret = 0; + } + else + ret = -EINVAL; + } + break; + + case XENPF_read_memtype: + { + unsigned long mfn; + unsigned int nr_mfns; + mtrr_type type; + + ret = -EINVAL; + if ( op->u.read_memtype.reg < num_var_ranges ) + { + mtrr_if->get(op->u.read_memtype.reg, &mfn, &nr_mfns, &type); + op->u.read_memtype.mfn = mfn; + op->u.read_memtype.nr_mfns = nr_mfns; + op->u.read_memtype.type = type; + (void)copy_to_guest(u_xenpf_op, op, 1); + ret = 0; + } + } + break; + + case XENPF_microcode_update: + { + extern int microcode_update(void *buf, unsigned long len); + ret = microcode_update(op->u.microcode.data.p, + op->u.microcode.length); + } + break; + + case XENPF_platform_quirk: + { + extern int opt_noirqbalance; + int quirk_id = op->u.platform_quirk.quirk_id; + switch ( quirk_id ) + { + case QUIRK_NOIRQBALANCING: + printk("Platform quirk -- Disabling IRQ balancing/affinity.\n"); + opt_noirqbalance = 1; + setup_ioapic_dest(); + break; + case QUIRK_IOAPIC_BAD_REGSEL: + case QUIRK_IOAPIC_GOOD_REGSEL: +#ifndef sis_apic_bug + sis_apic_bug = (quirk_id == QUIRK_IOAPIC_BAD_REGSEL); + DPRINTK("Domain 0 says that IO-APIC REGSEL is %s\n", + sis_apic_bug ? "bad" : "good"); +#else + BUG_ON(sis_apic_bug != (quirk_id == QUIRK_IOAPIC_BAD_REGSEL)); +#endif + break; + default: + ret = -EINVAL; + break; + } + } + break; + + default: + ret = -ENOSYS; + break; + } + + spin_unlock(&xenpf_lock); + + return ret; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 31b5dadc17..6507d6fa86 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -15,6 +15,7 @@ #include <xen/version.h> #include <xen/gdbstub.h> #include <xen/percpu.h> +#include <xen/hypercall.h> #include <public/version.h> #include <asm/bitops.h> #include <asm/smp.h> @@ -416,9 +417,13 @@ void __init __start_xen(multiboot_info_t *mbi) nr_pages << (PAGE_SHIFT - 10)); total_pages = nr_pages; - /* Sanity check for unwanted bloat of dom0_op structure. */ - BUILD_BUG_ON(sizeof(((struct dom0_op *)0)->u) != - sizeof(((struct dom0_op *)0)->u.pad)); + /* Sanity check for unwanted bloat of certain hypercall structures. */ + BUILD_BUG_ON(sizeof(((struct xen_platform_op *)0)->u) != + sizeof(((struct xen_platform_op *)0)->u.pad)); + BUILD_BUG_ON(sizeof(((struct xen_domctl *)0)->u) != + sizeof(((struct xen_domctl *)0)->u.pad)); + BUILD_BUG_ON(sizeof(((struct xen_sysctl *)0)->u) != + sizeof(((struct xen_sysctl *)0)->u.pad)); BUILD_BUG_ON(sizeof(start_info_t) > PAGE_SIZE); BUILD_BUG_ON(sizeof(shared_info_t) > PAGE_SIZE); diff --git a/xen/arch/x86/shadow2-common.c b/xen/arch/x86/shadow2-common.c index 4ce7fe9b88..bdb7c38e87 100644 --- a/xen/arch/x86/shadow2-common.c +++ b/xen/arch/x86/shadow2-common.c @@ -2951,14 +2951,15 @@ void shadow2_convert_to_log_dirty(struct vcpu *v, mfn_t smfn) /* Read a domain's log-dirty bitmap and stats. * If the operation is a CLEAN, clear the bitmap and stats as well. */ -static int shadow2_log_dirty_op(struct domain *d, dom0_shadow_control_t *sc) -{ +static int shadow2_log_dirty_op( + struct domain *d, struct xen_domctl_shadow_op *sc) +{ int i, rv = 0, clean = 0; domain_pause(d); shadow2_lock(d); - clean = (sc->op == DOM0_SHADOW_CONTROL_OP_CLEAN); + clean = (sc->op == XEN_DOMCTL_SHADOW_OP_CLEAN); SHADOW2_DEBUG(LOGDIRTY, "log-dirty %s: dom %u faults=%u dirty=%u\n", (clean) ? "clean" : "peek", @@ -3081,11 +3082,11 @@ void sh2_do_mark_dirty(struct domain *d, mfn_t gmfn) /**************************************************************************/ -/* Shadow-control DOM0_OP dispatcher */ +/* Shadow-control XEN_DOMCTL dispatcher */ -int shadow2_control_op(struct domain *d, - dom0_shadow_control_t *sc, - XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) +int shadow2_domctl(struct domain *d, + xen_domctl_shadow_op_t *sc, + XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) { int rc, preempted = 0; @@ -3097,7 +3098,7 @@ int shadow2_control_op(struct domain *d, switch ( sc->op ) { - case DOM0_SHADOW_CONTROL_OP_OFF: + case XEN_DOMCTL_SHADOW_OP_OFF: if ( shadow2_mode_log_dirty(d) ) if ( (rc = shadow2_log_dirty_disable(d)) != 0 ) return rc; @@ -3106,34 +3107,34 @@ int shadow2_control_op(struct domain *d, return rc; return 0; - case DOM0_SHADOW_CONTROL_OP_ENABLE_TEST: + case XEN_DOMCTL_SHADOW_OP_ENABLE_TEST: return shadow2_test_enable(d); - case DOM0_SHADOW_CONTROL_OP_ENABLE_LOGDIRTY: + case XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY: return shadow2_log_dirty_enable(d); - case DOM0_SHADOW_CONTROL_OP_ENABLE_TRANSLATE: + case XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE: return shadow2_enable(d, SHM2_refcounts|SHM2_translate); - case DOM0_SHADOW_CONTROL_OP_CLEAN: - case DOM0_SHADOW_CONTROL_OP_PEEK: + case XEN_DOMCTL_SHADOW_OP_CLEAN: + case XEN_DOMCTL_SHADOW_OP_PEEK: return shadow2_log_dirty_op(d, sc); - case DOM0_SHADOW_CONTROL_OP_ENABLE: - if ( sc->mode & DOM0_SHADOW_ENABLE_LOG_DIRTY ) + case XEN_DOMCTL_SHADOW_OP_ENABLE: + if ( sc->mode & XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY ) return shadow2_log_dirty_enable(d); return shadow2_enable(d, sc->mode << SHM2_shift); - case DOM0_SHADOW_CONTROL_OP_GET_ALLOCATION: + case XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION: sc->mb = shadow2_get_allocation(d); return 0; - case DOM0_SHADOW_CONTROL_OP_SET_ALLOCATION: + case XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION: rc = shadow2_set_allocation(d, sc->mb, &preempted); if ( preempted ) /* Not finished. Set up to re-run the call. */ rc = hypercall_create_continuation( - __HYPERVISOR_dom0_op, "h", u_dom0_op); + __HYPERVISOR_domctl, "h", u_domctl); else /* Finished. Return the new allocation */ sc->mb = shadow2_get_allocation(d); diff --git a/xen/arch/x86/sysctl.c b/xen/arch/x86/sysctl.c new file mode 100644 index 0000000000..0f265825bd --- /dev/null +++ b/xen/arch/x86/sysctl.c @@ -0,0 +1,77 @@ +/****************************************************************************** + * Arch-specific sysctl.c + * + * System management operations. For use by node control stack. + * + * Copyright (c) 2002-2006, K Fraser + */ + +#include <xen/config.h> +#include <xen/types.h> +#include <xen/lib.h> +#include <xen/mm.h> +#include <xen/guest_access.h> +#include <public/sysctl.h> +#include <xen/sched.h> +#include <xen/event.h> +#include <xen/domain_page.h> +#include <asm/msr.h> +#include <xen/trace.h> +#include <xen/console.h> +#include <xen/iocap.h> +#include <asm/shadow.h> +#include <asm/irq.h> +#include <asm/hvm/hvm.h> +#include <asm/hvm/support.h> +#include <asm/processor.h> + +long arch_do_sysctl( + struct xen_sysctl *sysctl, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) +{ + long ret = 0; + + switch ( sysctl->cmd ) + { + + case XEN_SYSCTL_physinfo: + { + xen_sysctl_physinfo_t *pi = &sysctl->u.physinfo; + + pi->threads_per_core = + cpus_weight(cpu_sibling_map[0]); + pi->cores_per_socket = + cpus_weight(cpu_core_map[0]) / pi->threads_per_core; + pi->sockets_per_node = + num_online_cpus() / cpus_weight(cpu_core_map[0]); + + pi->nr_nodes = 1; + pi->total_pages = total_pages; + pi->free_pages = avail_domheap_pages(); + pi->scrub_pages = avail_scrub_pages(); + pi->cpu_khz = cpu_khz; + memset(pi->hw_cap, 0, sizeof(pi->hw_cap)); + memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4); + ret = 0; + if ( copy_to_guest(u_sysctl, sysctl, 1) ) + ret = -EFAULT; + } + break; + + + default: + ret = -ENOSYS; + break; + } + + return ret; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/x86/x86_32/entry.S b/xen/arch/x86/x86_32/entry.S index ed21fcc8b6..79f0f08815 100644 --- a/xen/arch/x86/x86_32/entry.S +++ b/xen/arch/x86/x86_32/entry.S @@ -630,7 +630,7 @@ ENTRY(hypercall_table) .long do_set_callbacks .long do_fpu_taskswitch /* 5 */ .long do_arch_sched_op_compat - .long do_dom0_op + .long do_platform_op .long do_set_debugreg .long do_get_debugreg .long do_update_descriptor /* 10 */ @@ -657,7 +657,9 @@ ENTRY(hypercall_table) .long do_xenoprof_op .long do_event_channel_op .long do_physdev_op - .long do_hvm_op /* 34 */ + .long do_hvm_op + .long do_sysctl /* 35 */ + .long do_domctl .rept NR_hypercalls-((.-hypercall_table)/4) .long do_ni_hypercall .endr @@ -670,7 +672,7 @@ ENTRY(hypercall_args_table) .byte 4 /* do_set_callbacks */ .byte 1 /* do_fpu_taskswitch */ /* 5 */ .byte 2 /* do_arch_sched_op_compat */ - .byte 1 /* do_dom0_op */ + .byte 1 /* do_platform_op */ .byte 2 /* do_set_debugreg */ .byte 1 /* do_get_debugreg */ .byte 4 /* do_update_descriptor */ /* 10 */ @@ -697,7 +699,9 @@ ENTRY(hypercall_args_table) .byte 2 /* do_xenoprof_op */ .byte 2 /* do_event_channel_op */ .byte 2 /* do_physdev_op */ - .byte 2 /* do_hvm_op */ /* 34 */ + .byte 2 /* do_hvm_op */ + .byte 1 /* do_sysctl */ /* 35 */ + .byte 1 /* do_domctl */ .rept NR_hypercalls-(.-hypercall_args_table) .byte 0 /* do_ni_hypercall */ .endr diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S index ce89b302b9..d1a6c19599 100644 --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -543,7 +543,7 @@ ENTRY(hypercall_table) .quad do_set_callbacks .quad do_fpu_taskswitch /* 5 */ .quad do_arch_sched_op_compat - .quad do_dom0_op + .quad do_platform_op .quad do_set_debugreg .quad do_get_debugreg .quad do_update_descriptor /* 10 */ @@ -571,6 +571,8 @@ ENTRY(hypercall_table) .quad do_event_channel_op .quad do_physdev_op .quad do_hvm_op + .quad do_sysctl /* 35 */ + .quad do_domctl .rept NR_hypercalls-((.-hypercall_table)/8) .quad do_ni_hypercall .endr @@ -583,7 +585,7 @@ ENTRY(hypercall_args_table) .byte 3 /* do_set_callbacks */ .byte 1 /* do_fpu_taskswitch */ /* 5 */ .byte 2 /* do_arch_sched_op_compat */ - .byte 1 /* do_dom0_op */ + .byte 1 /* do_platform_op */ .byte 2 /* do_set_debugreg */ .byte 1 /* do_get_debugreg */ .byte 2 /* do_update_descriptor */ /* 10 */ @@ -611,6 +613,8 @@ ENTRY(hypercall_args_table) .byte 2 /* do_event_channel_op */ .byte 2 /* do_physdev_op */ .byte 2 /* do_hvm_op */ + .byte 1 /* do_sysctl */ /* 35 */ + .byte 1 /* do_domctl */ .rept NR_hypercalls-(.-hypercall_args_table) .byte 0 /* do_ni_hypercall */ .endr diff --git a/xen/common/Makefile b/xen/common/Makefile index 5310716224..130e2b438b 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -1,6 +1,6 @@ obj-y += acm_ops.o obj-y += bitmap.o -obj-y += dom0_ops.o +obj-y += domctl.o obj-y += domain.o obj-y += elf.o obj-y += event_channel.o @@ -19,6 +19,7 @@ obj-y += shutdown.o obj-y += softirq.o obj-y += string.o obj-y += symbols.o +obj-y += sysctl.o obj-y += trace.o obj-y += timer.o obj-y += version.o diff --git a/xen/common/acm_ops.c b/xen/common/acm_ops.c index 3692577873..d6ed629398 100644 --- a/xen/common/acm_ops.c +++ b/xen/common/acm_ops.c @@ -26,7 +26,6 @@ #include <xen/trace.h> #include <xen/console.h> #include <xen/guest_access.h> -#include <public/sched_ctl.h> #include <acm/acm_hooks.h> #ifndef ACM_SECURITY diff --git a/xen/common/domain.c b/xen/common/domain.c index 2c9db4e3a3..1138a9aa5e 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -23,7 +23,6 @@ #include <xen/shutdown.h> #include <xen/percpu.h> #include <asm/debugger.h> -#include <public/dom0_ops.h> #include <public/sched.h> #include <public/vcpu.h> @@ -454,11 +453,12 @@ void domain_unpause_by_systemcontroller(struct domain *d) * of domains other than domain 0. ie. the domains that are being built by * the userspace dom0 domain builder. */ -int set_info_guest(struct domain *d, dom0_setvcpucontext_t *setvcpucontext) +int set_info_guest(struct domain *d, + xen_domctl_vcpucontext_t *vcpucontext) { int rc = 0; struct vcpu_guest_context *c = NULL; - unsigned long vcpu = setvcpucontext->vcpu; + unsigned long vcpu = vcpucontext->vcpu; struct vcpu *v; if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) ) @@ -470,7 +470,7 @@ int set_info_guest(struct domain *d, dom0_setvcpucontext_t *setvcpucontext) domain_pause(d); rc = -EFAULT; - if ( copy_from_guest(c, setvcpucontext->ctxt, 1) == 0 ) + if ( copy_from_guest(c, vcpucontext->ctxt, 1) == 0 ) rc = arch_set_info_guest(v, c); domain_unpause(d); diff --git a/xen/common/dom0_ops.c b/xen/common/domctl.c index 420cf83244..a053145a1a 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/domctl.c @@ -1,9 +1,9 @@ /****************************************************************************** - * dom0_ops.c + * domctl.c * - * Process command requests from domain-0 guest OS. + * Domain management operations. For use by node control stack. * - * Copyright (c) 2002, K A Fraser + * Copyright (c) 2002-2006, K A Fraser */ #include <xen/config.h> @@ -19,15 +19,52 @@ #include <xen/iocap.h> #include <xen/guest_access.h> #include <asm/current.h> -#include <public/dom0_ops.h> -#include <public/sched_ctl.h> +#include <public/domctl.h> #include <acm/acm_hooks.h> -extern long arch_do_dom0_op( - struct dom0_op *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op); +extern long arch_do_domctl( + struct xen_domctl *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl); extern void arch_getdomaininfo_ctxt( struct vcpu *, struct vcpu_guest_context *); +void cpumask_to_xenctl_cpumap( + struct xenctl_cpumap *xenctl_cpumap, cpumask_t *cpumask) +{ + unsigned int guest_bytes, copy_bytes, i; + uint8_t zero = 0; + + if ( guest_handle_is_null(xenctl_cpumap->bitmap) ) + return; + + guest_bytes = (xenctl_cpumap->nr_cpus + 7) / 8; + copy_bytes = min_t(unsigned int, guest_bytes, (NR_CPUS + 7) / 8); + + copy_to_guest(xenctl_cpumap->bitmap, + (uint8_t *)cpus_addr(*cpumask), + copy_bytes); + + for ( i = copy_bytes; i < guest_bytes; i++ ) + copy_to_guest_offset(xenctl_cpumap->bitmap, i, &zero, 1); +} + +void xenctl_cpumap_to_cpumask( + cpumask_t *cpumask, struct xenctl_cpumap *xenctl_cpumap) +{ + unsigned int guest_bytes, copy_bytes; + + guest_bytes = (xenctl_cpumap->nr_cpus + 7) / 8; + copy_bytes = min_t(unsigned int, guest_bytes, (NR_CPUS + 7) / 8); + + cpus_clear(*cpumask); + + if ( guest_handle_is_null(xenctl_cpumap->bitmap) ) + return; + + copy_from_guest((uint8_t *)cpus_addr(*cpumask), + xenctl_cpumap->bitmap, + copy_bytes); +} + static inline int is_free_domid(domid_t dom) { struct domain *d; @@ -42,7 +79,7 @@ static inline int is_free_domid(domid_t dom) return 0; } -static void getdomaininfo(struct domain *d, dom0_getdomaininfo_t *info) +void getdomaininfo(struct domain *d, struct xen_domctl_getdomaininfo *info) { struct vcpu *v; u64 cpu_time = 0; @@ -128,46 +165,45 @@ static unsigned int default_vcpu0_location(void) return cpu; } -long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) +long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) { long ret = 0; - struct dom0_op curop, *op = &curop; + struct xen_domctl curop, *op = &curop; void *ssid = NULL; /* save security ptr between pre and post/fail hooks */ - static DEFINE_SPINLOCK(dom0_lock); + static DEFINE_SPINLOCK(domctl_lock); if ( !IS_PRIV(current->domain) ) return -EPERM; - if ( copy_from_guest(op, u_dom0_op, 1) ) + if ( copy_from_guest(op, u_domctl, 1) ) return -EFAULT; - if ( (op->interface_version != DOM0_TOOLS_INTERFACE_VERSION) && - (op->interface_version != DOM0_KERNEL_INTERFACE_VERSION) ) + if ( op->interface_version != XEN_DOMCTL_INTERFACE_VERSION ) return -EACCES; - if ( acm_pre_dom0_op(op, &ssid) ) + if ( acm_pre_domctl(op, &ssid) ) return -EPERM; - spin_lock(&dom0_lock); + spin_lock(&domctl_lock); switch ( op->cmd ) { - case DOM0_SETVCPUCONTEXT: + case XEN_DOMCTL_setvcpucontext: { - struct domain *d = find_domain_by_id(op->u.setvcpucontext.domain); + struct domain *d = find_domain_by_id(op->domain); ret = -ESRCH; if ( d != NULL ) { - ret = set_info_guest(d, &op->u.setvcpucontext); + ret = set_info_guest(d, &op->u.vcpucontext); put_domain(d); } } break; - case DOM0_PAUSEDOMAIN: + case XEN_DOMCTL_pausedomain: { - struct domain *d = find_domain_by_id(op->u.pausedomain.domain); + struct domain *d = find_domain_by_id(op->domain); ret = -ESRCH; if ( d != NULL ) { @@ -182,9 +218,9 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) } break; - case DOM0_UNPAUSEDOMAIN: + case XEN_DOMCTL_unpausedomain: { - struct domain *d = find_domain_by_id(op->u.unpausedomain.domain); + struct domain *d = find_domain_by_id(op->domain); ret = -ESRCH; if ( d != NULL ) { @@ -200,7 +236,7 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) } break; - case DOM0_CREATEDOMAIN: + case XEN_DOMCTL_createdomain: { struct domain *d; domid_t dom; @@ -213,7 +249,7 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) if ( supervisor_mode_kernel ) return -EINVAL; - dom = op->u.createdomain.domain; + dom = op->domain; if ( (dom > 0) && (dom < DOMID_FIRST_RESERVED) ) { ret = -EINVAL; @@ -246,13 +282,13 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) ret = 0; - op->u.createdomain.domain = d->domain_id; - if ( copy_to_guest(u_dom0_op, op, 1) ) + op->domain = d->domain_id; + if ( copy_to_guest(u_domctl, op, 1) ) ret = -EFAULT; } break; - case DOM0_MAX_VCPUS: + case XEN_DOMCTL_max_vcpus: { struct domain *d; unsigned int i, max = op->u.max_vcpus.max, cpu; @@ -262,7 +298,7 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) break; ret = -ESRCH; - if ( (d = find_domain_by_id(op->u.max_vcpus.domain)) == NULL ) + if ( (d = find_domain_by_id(op->domain)) == NULL ) break; /* Needed, for example, to ensure writable p.t. state is synced. */ @@ -295,9 +331,9 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) } break; - case DOM0_DESTROYDOMAIN: + case XEN_DOMCTL_destroydomain: { - struct domain *d = find_domain_by_id(op->u.destroydomain.domain); + struct domain *d = find_domain_by_id(op->domain); ret = -ESRCH; if ( d != NULL ) { @@ -312,9 +348,10 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) } break; - case DOM0_SETVCPUAFFINITY: + case XEN_DOMCTL_setvcpuaffinity: + case XEN_DOMCTL_getvcpuaffinity: { - domid_t dom = op->u.setvcpuaffinity.domain; + domid_t dom = op->domain; struct domain *d = find_domain_by_id(dom); struct vcpu *v; cpumask_t new_affinity; @@ -325,15 +362,15 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) break; } - if ( (op->u.setvcpuaffinity.vcpu >= MAX_VIRT_CPUS) || - !d->vcpu[op->u.setvcpuaffinity.vcpu] ) + if ( (op->u.vcpuaffinity.vcpu >= MAX_VIRT_CPUS) || + !d->vcpu[op->u.vcpuaffinity.vcpu] ) { ret = -EINVAL; put_domain(d); break; } - v = d->vcpu[op->u.setvcpuaffinity.vcpu]; + v = d->vcpu[op->u.vcpuaffinity.vcpu]; if ( v == NULL ) { ret = -ESRCH; @@ -341,47 +378,51 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) break; } - if ( v == current ) + if ( op->cmd == XEN_DOMCTL_setvcpuaffinity ) { - ret = -EINVAL; - put_domain(d); - break; - } - - new_affinity = v->cpu_affinity; - memcpy(cpus_addr(new_affinity), - &op->u.setvcpuaffinity.cpumap, - min((int)(BITS_TO_LONGS(NR_CPUS) * sizeof(long)), - (int)sizeof(op->u.setvcpuaffinity.cpumap))); + if ( v == current ) + { + ret = -EINVAL; + put_domain(d); + break; + } - ret = vcpu_set_affinity(v, &new_affinity); + xenctl_cpumap_to_cpumask( + &new_affinity, &op->u.vcpuaffinity.cpumap); + ret = vcpu_set_affinity(v, &new_affinity); + } + else + { + cpumask_to_xenctl_cpumap( + &op->u.vcpuaffinity.cpumap, &v->cpu_affinity); + } put_domain(d); } break; - case DOM0_SCHEDCTL: + case XEN_DOMCTL_scheduler_op: { - ret = sched_ctl(&op->u.schedctl); - if ( copy_to_guest(u_dom0_op, op, 1) ) - ret = -EFAULT; - } - break; + struct domain *d; - case DOM0_ADJUSTDOM: - { - ret = sched_adjdom(&op->u.adjustdom); - if ( copy_to_guest(u_dom0_op, op, 1) ) + ret = -ESRCH; + if ( (d = find_domain_by_id(op->domain)) == NULL ) + break; + + ret = sched_adjust(d, &op->u.scheduler_op); + if ( copy_to_guest(u_domctl, op, 1) ) ret = -EFAULT; + + put_domain(d); } break; - case DOM0_GETDOMAININFO: + case XEN_DOMCTL_getdomaininfo: { struct domain *d; domid_t dom; - dom = op->u.getdomaininfo.domain; + dom = op->domain; if ( dom == DOMID_SELF ) dom = current->domain->domain_id; @@ -404,75 +445,30 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) getdomaininfo(d, &op->u.getdomaininfo); - if ( copy_to_guest(u_dom0_op, op, 1) ) + op->domain = op->u.getdomaininfo.domain; + if ( copy_to_guest(u_domctl, op, 1) ) ret = -EFAULT; put_domain(d); } break; - case DOM0_GETDOMAININFOLIST: - { - struct domain *d; - dom0_getdomaininfo_t info; - u32 num_domains = 0; - - read_lock(&domlist_lock); - - for_each_domain ( d ) - { - if ( d->domain_id < op->u.getdomaininfolist.first_domain ) - continue; - if ( num_domains == op->u.getdomaininfolist.max_domains ) - break; - if ( (d == NULL) || !get_domain(d) ) - { - ret = -ESRCH; - break; - } - - getdomaininfo(d, &info); - - put_domain(d); - - if ( copy_to_guest_offset(op->u.getdomaininfolist.buffer, - num_domains, &info, 1) ) - { - ret = -EFAULT; - break; - } - - num_domains++; - } - - read_unlock(&domlist_lock); - - if ( ret != 0 ) - break; - - op->u.getdomaininfolist.num_domains = num_domains; - - if ( copy_to_guest(u_dom0_op, op, 1) ) - ret = -EFAULT; - } - break; - - case DOM0_GETVCPUCONTEXT: + case XEN_DOMCTL_getvcpucontext: { struct vcpu_guest_context *c; struct domain *d; struct vcpu *v; ret = -ESRCH; - if ( (d = find_domain_by_id(op->u.getvcpucontext.domain)) == NULL ) + if ( (d = find_domain_by_id(op->domain)) == NULL ) break; ret = -EINVAL; - if ( op->u.getvcpucontext.vcpu >= MAX_VIRT_CPUS ) + if ( op->u.vcpucontext.vcpu >= MAX_VIRT_CPUS ) goto getvcpucontext_out; ret = -ESRCH; - if ( (v = d->vcpu[op->u.getvcpucontext.vcpu]) == NULL ) + if ( (v = d->vcpu[op->u.vcpucontext.vcpu]) == NULL ) goto getvcpucontext_out; ret = -ENODATA; @@ -492,12 +488,12 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) if ( v != current ) vcpu_unpause(v); - if ( copy_to_guest(op->u.getvcpucontext.ctxt, c, 1) ) + if ( copy_to_guest(op->u.vcpucontext.ctxt, c, 1) ) ret = -EFAULT; xfree(c); - if ( copy_to_guest(u_dom0_op, op, 1) ) + if ( copy_to_guest(u_domctl, op, 1) ) ret = -EFAULT; getvcpucontext_out: @@ -505,14 +501,14 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) } break; - case DOM0_GETVCPUINFO: + case XEN_DOMCTL_getvcpuinfo: { struct domain *d; struct vcpu *v; struct vcpu_runstate_info runstate; ret = -ESRCH; - if ( (d = find_domain_by_id(op->u.getvcpuinfo.domain)) == NULL ) + if ( (d = find_domain_by_id(op->domain)) == NULL ) break; ret = -EINVAL; @@ -530,14 +526,9 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) op->u.getvcpuinfo.running = test_bit(_VCPUF_running, &v->vcpu_flags); op->u.getvcpuinfo.cpu_time = runstate.time[RUNSTATE_running]; op->u.getvcpuinfo.cpu = v->processor; - op->u.getvcpuinfo.cpumap = 0; - memcpy(&op->u.getvcpuinfo.cpumap, - cpus_addr(v->cpu_affinity), - min((int)(BITS_TO_LONGS(NR_CPUS) * sizeof(long)), - (int)sizeof(op->u.getvcpuinfo.cpumap))); ret = 0; - if ( copy_to_guest(u_dom0_op, op, 1) ) + if ( copy_to_guest(u_domctl, op, 1) ) ret = -EFAULT; getvcpuinfo_out: @@ -545,56 +536,18 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) } break; - case DOM0_SETTIME: - { - do_settime(op->u.settime.secs, - op->u.settime.nsecs, - op->u.settime.system_time); - ret = 0; - } - break; - - case DOM0_TBUFCONTROL: - { - ret = tb_control(&op->u.tbufcontrol); - if ( copy_to_guest(u_dom0_op, op, 1) ) - ret = -EFAULT; - } - break; - - case DOM0_READCONSOLE: - { - ret = read_console_ring( - op->u.readconsole.buffer, - &op->u.readconsole.count, - op->u.readconsole.clear); - if ( copy_to_guest(u_dom0_op, op, 1) ) - ret = -EFAULT; - } - break; - - case DOM0_SCHED_ID: - { - op->u.sched_id.sched_id = sched_id(); - if ( copy_to_guest(u_dom0_op, op, 1) ) - ret = -EFAULT; - else - ret = 0; - } - break; - - case DOM0_SETDOMAINMAXMEM: + case XEN_DOMCTL_max_mem: { struct domain *d; unsigned long new_max; ret = -ESRCH; - d = find_domain_by_id(op->u.setdomainmaxmem.domain); + d = find_domain_by_id(op->domain); if ( d == NULL ) break; ret = -EINVAL; - new_max = op->u.setdomainmaxmem.max_memkb >> (PAGE_SHIFT-10); + new_max = op->u.max_mem.max_memkb >> (PAGE_SHIFT-10); spin_lock(&d->page_alloc_lock); if ( new_max >= d->tot_pages ) @@ -608,11 +561,11 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) } break; - case DOM0_SETDOMAINHANDLE: + case XEN_DOMCTL_setdomainhandle: { struct domain *d; ret = -ESRCH; - d = find_domain_by_id(op->u.setdomainhandle.domain); + d = find_domain_by_id(op->domain); if ( d != NULL ) { memcpy(d->handle, op->u.setdomainhandle.handle, @@ -623,11 +576,11 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) } break; - case DOM0_SETDEBUGGING: + case XEN_DOMCTL_setdebugging: { struct domain *d; ret = -ESRCH; - d = find_domain_by_id(op->u.setdebugging.domain); + d = find_domain_by_id(op->domain); if ( d != NULL ) { if ( op->u.setdebugging.enable ) @@ -640,7 +593,7 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) } break; - case DOM0_IRQ_PERMISSION: + case XEN_DOMCTL_irq_permission: { struct domain *d; unsigned int pirq = op->u.irq_permission.pirq; @@ -650,7 +603,7 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) break; ret = -ESRCH; - d = find_domain_by_id(op->u.irq_permission.domain); + d = find_domain_by_id(op->domain); if ( d == NULL ) break; @@ -663,7 +616,7 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) } break; - case DOM0_IOMEM_PERMISSION: + case XEN_DOMCTL_iomem_permission: { struct domain *d; unsigned long mfn = op->u.iomem_permission.first_mfn; @@ -674,7 +627,7 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) break; ret = -ESRCH; - d = find_domain_by_id(op->u.iomem_permission.domain); + d = find_domain_by_id(op->domain); if ( d == NULL ) break; @@ -687,23 +640,12 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) } break; -#ifdef PERF_COUNTERS - case DOM0_PERFCCONTROL: - { - extern int perfc_control(dom0_perfccontrol_t *); - ret = perfc_control(&op->u.perfccontrol); - if ( copy_to_guest(u_dom0_op, op, 1) ) - ret = -EFAULT; - } - break; -#endif - - case DOM0_SETTIMEOFFSET: + case XEN_DOMCTL_settimeoffset: { struct domain *d; ret = -ESRCH; - d = find_domain_by_id(op->u.settimeoffset.domain); + d = find_domain_by_id(op->domain); if ( d != NULL ) { d->time_offset_seconds = op->u.settimeoffset.time_offset_seconds; @@ -714,16 +656,16 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op) break; default: - ret = arch_do_dom0_op(op, u_dom0_op); + ret = arch_do_domctl(op, u_domctl); break; } - spin_unlock(&dom0_lock); + spin_unlock(&domctl_lock); - if (!ret) - acm_post_dom0_op(op, &ssid); + if ( ret == 0 ) + acm_post_domctl(op, &ssid); else - acm_fail_dom0_op(op, &ssid); + acm_fail_domctl(op, &ssid); return ret; } diff --git a/xen/common/perfc.c b/xen/common/perfc.c index 4eb696a594..92307b2341 100644 --- a/xen/common/perfc.c +++ b/xen/common/perfc.c @@ -7,7 +7,6 @@ #include <xen/spinlock.h> #include <xen/mm.h> #include <xen/guest_access.h> -#include <public/dom0_ops.h> #include <asm/perfc.h> #undef PERFCOUNTER @@ -218,20 +217,19 @@ static int perfc_copy_info(XEN_GUEST_HANDLE(dom0_perfc_desc_t) desc, int perfc_control(dom0_perfccontrol_t *pc) { static DEFINE_SPINLOCK(lock); - u32 op = pc->op; int rc; spin_lock(&lock); - switch ( op ) + switch ( pc->cmd ) { - case DOM0_PERFCCONTROL_OP_RESET: + case XEN_SYSCTL_PERFCOP_reset: perfc_copy_info(pc->desc, pc->val); perfc_reset(0); rc = 0; break; - case DOM0_PERFCCONTROL_OP_QUERY: + case XEN_SYSCTL_PERFCOP_query: perfc_copy_info(pc->desc, pc->val); rc = 0; break; diff --git a/xen/common/sched_credit.c b/xen/common/sched_credit.c index 2feb8752f6..a9de1c2119 100644 --- a/xen/common/sched_credit.c +++ b/xen/common/sched_credit.c @@ -614,34 +614,34 @@ csched_vcpu_set_affinity(struct vcpu *vc, cpumask_t *affinity) static int csched_dom_cntl( struct domain *d, - struct sched_adjdom_cmd *cmd) + struct xen_domctl_scheduler_op *op) { struct csched_dom * const sdom = CSCHED_DOM(d); unsigned long flags; - if ( cmd->direction == SCHED_INFO_GET ) + if ( op->cmd == XEN_DOMCTL_SCHEDOP_putinfo ) { - cmd->u.credit.weight = sdom->weight; - cmd->u.credit.cap = sdom->cap; + op->u.credit.weight = sdom->weight; + op->u.credit.cap = sdom->cap; } else { - ASSERT( cmd->direction == SCHED_INFO_PUT ); + ASSERT(op->cmd == XEN_DOMCTL_SCHEDOP_getinfo); spin_lock_irqsave(&csched_priv.lock, flags); - if ( cmd->u.credit.weight != 0 ) + if ( op->u.credit.weight != 0 ) { if ( !list_empty(&sdom->active_sdom_elem) ) { csched_priv.weight -= sdom->weight; - csched_priv.weight += cmd->u.credit.weight; + csched_priv.weight += op->u.credit.weight; } - sdom->weight = cmd->u.credit.weight; + sdom->weight = op->u.credit.weight; } - if ( cmd->u.credit.cap != (uint16_t)~0U ) - sdom->cap = cmd->u.credit.cap; + if ( op->u.credit.cap != (uint16_t)~0U ) + sdom->cap = op->u.credit.cap; spin_unlock_irqrestore(&csched_priv.lock, flags); } @@ -1215,7 +1215,7 @@ csched_init(void) struct scheduler sched_credit_def = { .name = "SMP Credit Scheduler", .opt_name = "credit", - .sched_id = SCHED_CREDIT, + .sched_id = XEN_SCHEDULER_CREDIT, .init_vcpu = csched_vcpu_init, .destroy_domain = csched_dom_destroy, @@ -1225,7 +1225,7 @@ struct scheduler sched_credit_def = { .set_affinity = csched_vcpu_set_affinity, - .adjdom = csched_dom_cntl, + .adjust = csched_dom_cntl, .tick = csched_tick, .do_schedule = csched_schedule, diff --git a/xen/common/sched_sedf.c b/xen/common/sched_sedf.c index f8913703ac..8559e3bdf5 100644 --- a/xen/common/sched_sedf.c +++ b/xen/common/sched_sedf.c @@ -8,7 +8,6 @@ #include <xen/lib.h> #include <xen/sched.h> #include <xen/sched-if.h> -#include <public/sched_ctl.h> #include <xen/timer.h> #include <xen/softirq.h> #include <xen/time.h> @@ -1297,7 +1296,7 @@ static void sedf_dump_cpu_state(int i) /* Adjusts periods and slices of the domains accordingly to their weights. */ -static int sedf_adjust_weights(struct sched_adjdom_cmd *cmd) +static int sedf_adjust_weights(struct xen_domctl_scheduler_op *cmd) { struct vcpu *p; struct domain *d; @@ -1352,29 +1351,29 @@ static int sedf_adjust_weights(struct sched_adjdom_cmd *cmd) /* set or fetch domain scheduling parameters */ -static int sedf_adjdom(struct domain *p, struct sched_adjdom_cmd *cmd) +static int sedf_adjust(struct domain *p, struct xen_domctl_scheduler_op *op) { struct vcpu *v; - PRINT(2,"sedf_adjdom was called, domain-id %i new period %"PRIu64" " + PRINT(2,"sedf_adjust was called, domain-id %i new period %"PRIu64" " "new slice %"PRIu64"\nlatency %"PRIu64" extra:%s\n", - p->domain_id, cmd->u.sedf.period, cmd->u.sedf.slice, - cmd->u.sedf.latency, (cmd->u.sedf.extratime)?"yes":"no"); + p->domain_id, op->u.sedf.period, op->u.sedf.slice, + op->u.sedf.latency, (op->u.sedf.extratime)?"yes":"no"); - if ( cmd->direction == SCHED_INFO_PUT ) + if ( op->cmd == XEN_DOMCTL_SCHEDOP_putinfo ) { /* Check for sane parameters. */ - if ( !cmd->u.sedf.period && !cmd->u.sedf.weight ) + if ( !op->u.sedf.period && !op->u.sedf.weight ) return -EINVAL; - if ( cmd->u.sedf.weight ) + if ( op->u.sedf.weight ) { - if ( (cmd->u.sedf.extratime & EXTRA_AWARE) && - (!cmd->u.sedf.period) ) + if ( (op->u.sedf.extratime & EXTRA_AWARE) && + (!op->u.sedf.period) ) { /* Weight-driven domains with extratime only. */ for_each_vcpu ( p, v ) { - EDOM_INFO(v)->extraweight = cmd->u.sedf.weight; + EDOM_INFO(v)->extraweight = op->u.sedf.weight; EDOM_INFO(v)->weight = 0; EDOM_INFO(v)->slice = 0; EDOM_INFO(v)->period = WEIGHT_PERIOD; @@ -1384,7 +1383,7 @@ static int sedf_adjdom(struct domain *p, struct sched_adjdom_cmd *cmd) { /* Weight-driven domains with real-time execution. */ for_each_vcpu ( p, v ) - EDOM_INFO(v)->weight = cmd->u.sedf.weight; + EDOM_INFO(v)->weight = op->u.sedf.weight; } } else @@ -1396,51 +1395,51 @@ static int sedf_adjdom(struct domain *p, struct sched_adjdom_cmd *cmd) * Sanity checking: note that disabling extra weight requires * that we set a non-zero slice. */ - if ( (cmd->u.sedf.period > PERIOD_MAX) || - (cmd->u.sedf.period < PERIOD_MIN) || - (cmd->u.sedf.slice > cmd->u.sedf.period) || - (cmd->u.sedf.slice < SLICE_MIN) ) + if ( (op->u.sedf.period > PERIOD_MAX) || + (op->u.sedf.period < PERIOD_MIN) || + (op->u.sedf.slice > op->u.sedf.period) || + (op->u.sedf.slice < SLICE_MIN) ) return -EINVAL; EDOM_INFO(v)->weight = 0; EDOM_INFO(v)->extraweight = 0; EDOM_INFO(v)->period_orig = - EDOM_INFO(v)->period = cmd->u.sedf.period; + EDOM_INFO(v)->period = op->u.sedf.period; EDOM_INFO(v)->slice_orig = - EDOM_INFO(v)->slice = cmd->u.sedf.slice; + EDOM_INFO(v)->slice = op->u.sedf.slice; } } - if ( sedf_adjust_weights(cmd) ) + if ( sedf_adjust_weights(op) ) return -EINVAL; for_each_vcpu ( p, v ) { EDOM_INFO(v)->status = (EDOM_INFO(v)->status & - ~EXTRA_AWARE) | (cmd->u.sedf.extratime & EXTRA_AWARE); - EDOM_INFO(v)->latency = cmd->u.sedf.latency; + ~EXTRA_AWARE) | (op->u.sedf.extratime & EXTRA_AWARE); + EDOM_INFO(v)->latency = op->u.sedf.latency; extraq_check(v); } } - else if ( cmd->direction == SCHED_INFO_GET ) + else if ( op->cmd == XEN_DOMCTL_SCHEDOP_getinfo ) { if ( p->vcpu[0] == NULL ) return -EINVAL; - cmd->u.sedf.period = EDOM_INFO(p->vcpu[0])->period; - cmd->u.sedf.slice = EDOM_INFO(p->vcpu[0])->slice; - cmd->u.sedf.extratime = EDOM_INFO(p->vcpu[0])->status & EXTRA_AWARE; - cmd->u.sedf.latency = EDOM_INFO(p->vcpu[0])->latency; - cmd->u.sedf.weight = EDOM_INFO(p->vcpu[0])->weight; + op->u.sedf.period = EDOM_INFO(p->vcpu[0])->period; + op->u.sedf.slice = EDOM_INFO(p->vcpu[0])->slice; + op->u.sedf.extratime = EDOM_INFO(p->vcpu[0])->status & EXTRA_AWARE; + op->u.sedf.latency = EDOM_INFO(p->vcpu[0])->latency; + op->u.sedf.weight = EDOM_INFO(p->vcpu[0])->weight; } - PRINT(2,"sedf_adjdom_finished\n"); + PRINT(2,"sedf_adjust_finished\n"); return 0; } struct scheduler sched_sedf_def = { .name = "Simple EDF Scheduler", .opt_name = "sedf", - .sched_id = SCHED_SEDF, + .sched_id = XEN_SCHEDULER_SEDF, .init_vcpu = sedf_init_vcpu, .destroy_domain = sedf_destroy_domain, @@ -1449,7 +1448,7 @@ struct scheduler sched_sedf_def = { .dump_cpu_state = sedf_dump_cpu_state, .sleep = sedf_sleep, .wake = sedf_wake, - .adjdom = sedf_adjdom, + .adjust = sedf_adjust, .set_affinity = sedf_set_affinity }; diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 8b96372a73..a31bdb369c 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -30,7 +30,6 @@ #include <xen/errno.h> #include <xen/guest_access.h> #include <public/sched.h> -#include <public/sched_ctl.h> extern void arch_getdomaininfo_ctxt(struct vcpu *, struct vcpu_guest_context *); @@ -427,32 +426,16 @@ int sched_id(void) return ops.sched_id; } -long sched_ctl(struct sched_ctl_cmd *cmd) -{ - if ( cmd->sched_id != ops.sched_id ) - return -EINVAL; - - SCHED_OP(control, cmd); - TRACE_0D(TRC_SCHED_CTL); - return 0; -} - - /* Adjust scheduling parameter for a given domain. */ -long sched_adjdom(struct sched_adjdom_cmd *cmd) +long sched_adjust(struct domain *d, struct xen_domctl_scheduler_op *op) { - struct domain *d; struct vcpu *v; - if ( (cmd->sched_id != ops.sched_id) || - ((cmd->direction != SCHED_INFO_PUT) && - (cmd->direction != SCHED_INFO_GET)) ) + if ( (op->sched_id != ops.sched_id) || + ((op->cmd != XEN_DOMCTL_SCHEDOP_putinfo) && + (op->cmd != XEN_DOMCTL_SCHEDOP_getinfo)) ) return -EINVAL; - d = find_domain_by_id(cmd->domain); - if ( d == NULL ) - return -ESRCH; - /* * Most VCPUs we can simply pause. If we are adjusting this VCPU then * we acquire the local schedule_lock to guard against concurrent updates. @@ -475,7 +458,7 @@ long sched_adjdom(struct sched_adjdom_cmd *cmd) if ( d == current->domain ) vcpu_schedule_lock_irq(current); - SCHED_OP(adjdom, d, cmd); + SCHED_OP(adjust, d, op); TRACE_1D(TRC_SCHED_ADJDOM, d->domain_id); if ( d == current->domain ) @@ -487,8 +470,6 @@ long sched_adjdom(struct sched_adjdom_cmd *cmd) vcpu_unpause(v); } - put_domain(d); - return 0; } diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c new file mode 100644 index 0000000000..90312ce71c --- /dev/null +++ b/xen/common/sysctl.c @@ -0,0 +1,152 @@ +/****************************************************************************** + * sysctl.c + * + * System management operations. For use by node control stack. + * + * Copyright (c) 2002-2006, K Fraser + */ + +#include <xen/config.h> +#include <xen/types.h> +#include <xen/lib.h> +#include <xen/mm.h> +#include <xen/sched.h> +#include <xen/domain.h> +#include <xen/event.h> +#include <xen/domain_page.h> +#include <xen/trace.h> +#include <xen/console.h> +#include <xen/iocap.h> +#include <xen/guest_access.h> +#include <asm/current.h> +#include <public/sysctl.h> + +extern long arch_do_sysctl( + struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl); +extern void getdomaininfo( + struct domain *d, struct xen_domctl_getdomaininfo *info); + +long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) +{ + long ret = 0; + struct xen_sysctl curop, *op = &curop; + static DEFINE_SPINLOCK(sysctl_lock); + + if ( !IS_PRIV(current->domain) ) + return -EPERM; + + if ( copy_from_guest(op, u_sysctl, 1) ) + return -EFAULT; + + if ( op->interface_version != XEN_SYSCTL_INTERFACE_VERSION ) + return -EACCES; + + spin_lock(&sysctl_lock); + + switch ( op->cmd ) + { + case XEN_SYSCTL_readconsole: + { + ret = read_console_ring( + guest_handle_cast(op->u.readconsole.buffer, char), + &op->u.readconsole.count, + op->u.readconsole.clear); + if ( copy_to_guest(u_sysctl, op, 1) ) + ret = -EFAULT; + } + break; + + case XEN_SYSCTL_tbuf_op: + { + ret = tb_control(&op->u.tbuf_op); + if ( copy_to_guest(u_sysctl, op, 1) ) + ret = -EFAULT; + } + break; + + case XEN_SYSCTL_sched_id: + { + op->u.sched_id.sched_id = sched_id(); + if ( copy_to_guest(u_sysctl, op, 1) ) + ret = -EFAULT; + else + ret = 0; + } + break; + + case XEN_SYSCTL_getdomaininfolist: + { + struct domain *d; + struct xen_domctl_getdomaininfo info; + u32 num_domains = 0; + + read_lock(&domlist_lock); + + for_each_domain ( d ) + { + if ( d->domain_id < op->u.getdomaininfolist.first_domain ) + continue; + if ( num_domains == op->u.getdomaininfolist.max_domains ) + break; + if ( (d == NULL) || !get_domain(d) ) + { + ret = -ESRCH; + break; + } + + getdomaininfo(d, &info); + + put_domain(d); + + if ( copy_to_guest_offset(op->u.getdomaininfolist.buffer, + num_domains, &info, 1) ) + { + ret = -EFAULT; + break; + } + + num_domains++; + } + + read_unlock(&domlist_lock); + + if ( ret != 0 ) + break; + + op->u.getdomaininfolist.num_domains = num_domains; + + if ( copy_to_guest(u_sysctl, op, 1) ) + ret = -EFAULT; + } + break; + +#ifdef PERF_COUNTERS + case XEN_SYSCTL_perfccontrol: + { + extern int perfc_control(xen_sysctl_perfccontrol_t *); + ret = perfc_control(&op->u.perfccontrol); + if ( copy_to_guest(u_sysctl, op, 1) ) + ret = -EFAULT; + } + break; +#endif + + default: + ret = arch_do_sysctl(op, u_sysctl); + break; + } + + spin_unlock(&sysctl_lock); + + return ret; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/trace.c b/xen/common/trace.c index 0b6df3c4d1..fde88764eb 100644 --- a/xen/common/trace.c +++ b/xen/common/trace.c @@ -14,9 +14,6 @@ * The trace buffer code is designed to allow debugging traces of Xen to be * generated on UP / SMP machines. Each trace entry is timestamped so that * it's possible to reconstruct a chronological record of trace events. - * - * See also include/xen/trace.h and the dom0 op in - * include/public/dom0_ops.h */ #include <xen/config.h> @@ -33,7 +30,7 @@ #include <xen/mm.h> #include <xen/percpu.h> #include <asm/atomic.h> -#include <public/dom0_ops.h> +#include <public/sysctl.h> /* opt_tbuf_size: trace buffer size (in pages) */ static unsigned int opt_tbuf_size = 0; @@ -56,7 +53,7 @@ static DEFINE_PER_CPU(unsigned long, lost_records); int tb_init_done; /* which CPUs tracing is enabled on */ -static unsigned long tb_cpu_mask = (~0UL); +static cpumask_t tb_cpu_mask = CPU_MASK_ALL; /* which tracing events are enabled */ static u32 tb_event_mask = TRC_ALL; @@ -171,43 +168,41 @@ void init_trace_bufs(void) } } - /** - * tb_control - DOM0 operations on trace buffers. - * @tbc: a pointer to a dom0_tbufcontrol_t to be filled out + * tb_control - sysctl operations on trace buffers. + * @tbc: a pointer to a xen_sysctl_tbuf_op_t to be filled out */ -int tb_control(dom0_tbufcontrol_t *tbc) +int tb_control(xen_sysctl_tbuf_op_t *tbc) { static DEFINE_SPINLOCK(lock); int rc = 0; spin_lock(&lock); - switch ( tbc->op ) + switch ( tbc->cmd ) { - case DOM0_TBUF_GET_INFO: - tbc->cpu_mask = tb_cpu_mask; + case XEN_SYSCTL_TBUFOP_get_info: tbc->evt_mask = tb_event_mask; tbc->buffer_mfn = opt_tbuf_size ? virt_to_mfn(per_cpu(t_bufs, 0)) : 0; tbc->size = opt_tbuf_size * PAGE_SIZE; break; - case DOM0_TBUF_SET_CPU_MASK: - tb_cpu_mask = tbc->cpu_mask; + case XEN_SYSCTL_TBUFOP_set_cpu_mask: + cpumask_to_xenctl_cpumap(&tbc->cpu_mask, &tb_cpu_mask); break; - case DOM0_TBUF_SET_EVT_MASK: + case XEN_SYSCTL_TBUFOP_set_evt_mask: tb_event_mask = tbc->evt_mask; break; - case DOM0_TBUF_SET_SIZE: + case XEN_SYSCTL_TBUFOP_set_size: rc = !tb_init_done ? tb_set_size(tbc->size) : -EINVAL; break; - case DOM0_TBUF_ENABLE: + case XEN_SYSCTL_TBUFOP_enable: /* Enable trace buffers. Check buffers are already allocated. */ if ( opt_tbuf_size == 0 ) rc = -EINVAL; else tb_init_done = 1; break; - case DOM0_TBUF_DISABLE: + case XEN_SYSCTL_TBUFOP_disable: /* * Disable trace buffers. Just stops new records from being written, * does not deallocate any memory. @@ -254,7 +249,7 @@ void trace(u32 event, unsigned long d1, unsigned long d2, & ((event >> TRC_SUBCLS_SHIFT) & 0xf )) == 0 ) return; - if ( (tb_cpu_mask & (1UL << smp_processor_id())) == 0 ) + if ( !cpu_isset(smp_processor_id(), tb_cpu_mask) ) return; /* Read tb_init_done /before/ t_bufs. */ diff --git a/xen/include/acm/acm_hooks.h b/xen/include/acm/acm_hooks.h index 1adb350a0b..fb652bf041 100644 --- a/xen/include/acm/acm_hooks.h +++ b/xen/include/acm/acm_hooks.h @@ -28,7 +28,7 @@ #include <xen/multiboot.h> #include <public/acm.h> #include <acm/acm_core.h> -#include <public/dom0_ops.h> +#include <public/domctl.h> #include <public/event_channel.h> #include <asm/current.h> @@ -129,11 +129,11 @@ extern struct acm_operations *acm_secondary_ops; #ifndef ACM_SECURITY -static inline int acm_pre_dom0_op(struct dom0_op *op, void **ssid) +static inline int acm_pre_domctl(struct xen_domctl *op, void **ssid) { return 0; } -static inline void acm_post_dom0_op(struct dom0_op *op, void *ssid) +static inline void acm_post_domctl(struct xen_domctl *op, void *ssid) { return; } -static inline void acm_fail_dom0_op(struct dom0_op *op, void *ssid) +static inline void acm_fail_domctl(struct xen_domctl *op, void *ssid) { return; } static inline int acm_pre_eventchannel_unbound(domid_t id1, domid_t id2) { return 0; } @@ -225,23 +225,23 @@ static inline int acm_pre_eventchannel_interdomain(domid_t id) return ACM_ACCESS_PERMITTED; } -static inline int acm_pre_dom0_op(struct dom0_op *op, void **ssid) +static inline int acm_pre_domctl(struct xen_domctl *op, void **ssid) { int ret = -EACCES; struct domain *d; switch(op->cmd) { - case DOM0_CREATEDOMAIN: + case XEN_DOMCTL_createdomain: ret = acm_pre_domain_create( current->domain->ssid, op->u.createdomain.ssidref); break; - case DOM0_DESTROYDOMAIN: + case XEN_DOMCTL_destroydomain: if (*ssid != NULL) { printkd("%s: Warning. Overlapping destruction.\n", __func__); return -EACCES; } - d = find_domain_by_id(op->u.destroydomain.domain); + d = find_domain_by_id(op->domain); if (d != NULL) { *ssid = d->ssid; /* save for post destroy when d is gone */ if (*ssid == NULL) { @@ -262,23 +262,23 @@ static inline int acm_pre_dom0_op(struct dom0_op *op, void **ssid) return ret; } -static inline void acm_post_dom0_op(struct dom0_op *op, void **ssid) +static inline void acm_post_domctl(struct xen_domctl *op, void **ssid) { switch(op->cmd) { - case DOM0_CREATEDOMAIN: + case XEN_DOMCTL_createdomain: /* initialialize shared sHype security labels for new domain */ acm_init_domain_ssid( - op->u.createdomain.domain, op->u.createdomain.ssidref); + op->domain, op->u.createdomain.ssidref); acm_post_domain_create( - op->u.createdomain.domain, op->u.createdomain.ssidref); + op->domain, op->u.createdomain.ssidref); break; - case DOM0_DESTROYDOMAIN: + case XEN_DOMCTL_destroydomain: if (*ssid == NULL) { printkd("%s: ERROR. SSID unset.\n", __func__); break; } - acm_post_domain_destroy(*ssid, op->u.destroydomain.domain); + acm_post_domain_destroy(*ssid, op->domain); /* free security ssid for the destroyed domain (also if null policy */ acm_free_domain_ssid((struct acm_ssid_domain *)(*ssid)); *ssid = NULL; @@ -286,14 +286,14 @@ static inline void acm_post_dom0_op(struct dom0_op *op, void **ssid) } } -static inline void acm_fail_dom0_op(struct dom0_op *op, void **ssid) +static inline void acm_fail_domctl(struct xen_domctl *op, void **ssid) { switch(op->cmd) { - case DOM0_CREATEDOMAIN: + case XEN_DOMCTL_createdomain: acm_fail_domain_create( current->domain->ssid, op->u.createdomain.ssidref); break; - case DOM0_DESTROYDOMAIN: + case XEN_DOMCTL_destroydomain: /* we don't handle domain destroy failure but at least free the ssid */ if (*ssid == NULL) { printkd("%s: ERROR. SSID unset.\n", diff --git a/xen/include/asm-ia64/domain.h b/xen/include/asm-ia64/domain.h index c15f9c1915..f7601cfde1 100644 --- a/xen/include/asm-ia64/domain.h +++ b/xen/include/asm-ia64/domain.h @@ -53,7 +53,7 @@ extern unsigned long domain_set_shared_info_va (unsigned long va); extern void domain_cache_flush (struct domain *d, int sync_only); /* Control the shadow mode. */ -extern int shadow_mode_control(struct domain *d, dom0_shadow_control_t *sc); +extern int shadow_mode_control(struct domain *d, xen_domctl_shadow_op_t *sc); /* Cleanly crash the current domain with a message. */ extern void panic_domain(struct pt_regs *, const char *, ...) diff --git a/xen/include/asm-x86/shadow2.h b/xen/include/asm-x86/shadow2.h index c6ee291b2b..d5b56ae16e 100644 --- a/xen/include/asm-x86/shadow2.h +++ b/xen/include/asm-x86/shadow2.h @@ -23,7 +23,7 @@ #ifndef _XEN_SHADOW2_H #define _XEN_SHADOW2_H -#include <public/dom0_ops.h> +#include <public/domctl.h> #include <xen/sched.h> #include <xen/perfc.h> #include <asm/flushtlb.h> @@ -34,14 +34,14 @@ /* We're in one of the shadow modes */ #define SHM2_enable (1U << SHM2_shift) /* Refcounts based on shadow tables instead of guest tables */ -#define SHM2_refcounts (DOM0_SHADOW_ENABLE_REFCOUNT << SHM2_shift) +#define SHM2_refcounts (XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT << SHM2_shift) /* Enable log dirty mode */ -#define SHM2_log_dirty (DOM0_SHADOW_ENABLE_LOG_DIRTY << SHM2_shift) +#define SHM2_log_dirty (XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY << SHM2_shift) /* Xen does p2m translation, not guest */ -#define SHM2_translate (DOM0_SHADOW_ENABLE_TRANSLATE << SHM2_shift) +#define SHM2_translate (XEN_DOMCTL_SHADOW_ENABLE_TRANSLATE << SHM2_shift) /* Xen does not steal address space from the domain for its own booking; * requires VT or similar mechanisms */ -#define SHM2_external (DOM0_SHADOW_ENABLE_EXTERNAL << SHM2_shift) +#define SHM2_external (XEN_DOMCTL_SHADOW_ENABLE_EXTERNAL << SHM2_shift) #define shadow2_mode_enabled(_d) ((_d)->arch.shadow2.mode) #define shadow2_mode_refcounts(_d) ((_d)->arch.shadow2.mode & SHM2_refcounts) @@ -297,9 +297,9 @@ int shadow2_test_enable(struct domain *d); /* Handler for shadow control ops: enabling and disabling shadow modes, * and log-dirty bitmap ops all happen through here. */ -int shadow2_control_op(struct domain *d, - dom0_shadow_control_t *sc, - XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op); +int shadow2_domctl(struct domain *d, + xen_domctl_shadow_op_t *sc, + XEN_GUEST_HANDLE(xen_domctl_t) u_domctl); /* Call when destroying a domain */ void shadow2_teardown(struct domain *d); diff --git a/xen/include/public/acm.h b/xen/include/public/acm.h index b00b84147a..d53bc6bbd5 100644 --- a/xen/include/public/acm.h +++ b/xen/include/public/acm.h @@ -9,7 +9,6 @@ #define _XEN_PUBLIC_ACM_H #include "xen.h" -#include "sched_ctl.h" /* if ACM_DEBUG defined, all hooks should * print a short trace message (comment it out diff --git a/xen/include/public/acm_ops.h b/xen/include/public/acm_ops.h index 7c7a2f99cf..4a1c3b4d35 100644 --- a/xen/include/public/acm_ops.h +++ b/xen/include/public/acm_ops.h @@ -9,7 +9,6 @@ #define __XEN_PUBLIC_ACM_OPS_H__ #include "xen.h" -#include "sched_ctl.h" #include "acm.h" /* diff --git a/xen/include/public/arch-ia64.h b/xen/include/public/arch-ia64.h index 98bda1d241..5ac98469c2 100644 --- a/xen/include/public/arch-ia64.h +++ b/xen/include/public/arch-ia64.h @@ -18,12 +18,15 @@ #define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name) #define XEN_GUEST_HANDLE(name) __guest_handle_ ## name +#define XEN_GUEST_HANDLE_64(name) __guest_handle_ ## name #define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0) #ifdef __XEN_TOOLS__ #define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0) #endif #ifndef __ASSEMBLY__ +typedef uint64_t uint64_aligned_t; + /* Guest handles for primitive C types. */ __DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char); __DEFINE_XEN_GUEST_HANDLE(uint, unsigned int); diff --git a/xen/include/public/arch-powerpc.h b/xen/include/public/arch-powerpc.h index 5172563821..bd979dfb0b 100644 --- a/xen/include/public/arch-powerpc.h +++ b/xen/include/public/arch-powerpc.h @@ -29,6 +29,7 @@ #define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name) #define XEN_GUEST_HANDLE(name) __guest_handle_ ## name +#define XEN_GUEST_HANDLE_64(name) __guest_handle_ ## name #define set_xen_guest_handle(hnd, val) \ do { \ if (sizeof ((hnd).__pad)) \ @@ -41,6 +42,8 @@ #endif #ifndef __ASSEMBLY__ +typedef uint64_t uint64_aligned_t; + /* Guest handles for primitive C types. */ __DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char); __DEFINE_XEN_GUEST_HANDLE(uint, unsigned int); diff --git a/xen/include/public/arch-x86_32.h b/xen/include/public/arch-x86_32.h index 2d717f0cc0..a71fe141bc 100644 --- a/xen/include/public/arch-x86_32.h +++ b/xen/include/public/arch-x86_32.h @@ -27,9 +27,15 @@ #define TRAP_INSTR "int $0x82" #endif - /* Structural guest handles introduced in 0x00030201. */ -#if __XEN_INTERFACE_VERSION__ >= 0x00030201 +#if (defined(__XEN__) || defined(__XEN_TOOLS__)) && !defined(__ASSEMBLY__) +typedef uint64_t __attribute__((aligned(8))) uint64_aligned_t; +#define __DEFINE_XEN_GUEST_HANDLE(name, type) \ + typedef struct { type *p; } \ + __guest_handle_ ## name; \ + typedef struct { union { type *p; uint64_aligned_t q; }; } \ + __guest_handle_64_ ## name +#elif __XEN_INTERFACE_VERSION__ >= 0x00030201 #define __DEFINE_XEN_GUEST_HANDLE(name, type) \ typedef struct { type *p; } __guest_handle_ ## name #else @@ -39,9 +45,15 @@ #define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name) #define XEN_GUEST_HANDLE(name) __guest_handle_ ## name -#define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0) +#define XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name #ifdef __XEN_TOOLS__ #define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0) +#define set_xen_guest_handle(hnd, val) \ + do { if ( sizeof(hnd) == 8 ) *(uint64_t *)&(hnd) = 0; \ + (hnd).p = val; \ + } while ( 0 ) +#else +#define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0) #endif #ifndef __ASSEMBLY__ diff --git a/xen/include/public/arch-x86_64.h b/xen/include/public/arch-x86_64.h index 2891cfa29e..096352e52c 100644 --- a/xen/include/public/arch-x86_64.h +++ b/xen/include/public/arch-x86_64.h @@ -39,12 +39,15 @@ #define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name) #define XEN_GUEST_HANDLE(name) __guest_handle_ ## name +#define XEN_GUEST_HANDLE_64(name) __guest_handle_ ## name #define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0) #ifdef __XEN_TOOLS__ #define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0) #endif #ifndef __ASSEMBLY__ +typedef uint64_t uint64_aligned_t; + /* Guest handles for primitive C types. */ __DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char); __DEFINE_XEN_GUEST_HANDLE(uint, unsigned int); diff --git a/xen/include/public/dom0_ops.h b/xen/include/public/dom0_ops.h index e4787ea886..b03a7ce2ee 100644 --- a/xen/include/public/dom0_ops.h +++ b/xen/include/public/dom0_ops.h @@ -4,133 +4,49 @@ * Process command requests from domain-0 guest OS. * * Copyright (c) 2002-2003, B Dragovic - * Copyright (c) 2002-2004, K Fraser + * Copyright (c) 2002-2006, K Fraser */ - #ifndef __XEN_PUBLIC_DOM0_OPS_H__ #define __XEN_PUBLIC_DOM0_OPS_H__ #include "xen.h" -#include "sched_ctl.h" - -/* - * Make sure you increment the interface version whenever you modify this file! - * This makes sure that old versions of dom0 tools will stop working in a - * well-defined way (rather than crashing the machine, for instance). - * - * Separate kernel from tools as the kernel uses a small subset of the dom0 - * operations and so it is unnecessary to break backward compatibility so - * often. - */ -#define DOM0_TOOLS_INTERFACE_VERSION 0x13000001 -#define DOM0_KERNEL_INTERFACE_VERSION 0x03000001 +#include "platform.h" -#ifdef __XEN_TOOLS__ -#define DOM0_INTERFACE_VERSION DOM0_TOOLS_INTERFACE_VERSION -#else -#define DOM0_INTERFACE_VERSION DOM0_KERNEL_INTERFACE_VERSION +#if __XEN_INTERFACE_VERSION__ >= 0x00030204 +#error "dom0_ops.h is a compatibility interface only" #endif -/************************************************************************/ +#define DOM0_INTERFACE_VERSION XENPF_INTERFACE_VERSION -#define DOM0_GETMEMLIST 2 -struct dom0_getmemlist { - /* IN variables. */ - domid_t domain; - uint64_t max_pfns; - XEN_GUEST_HANDLE(xen_pfn_t) buffer; - /* OUT variables. */ - uint64_t num_pfns; -}; -typedef struct dom0_getmemlist dom0_getmemlist_t; -DEFINE_XEN_GUEST_HANDLE(dom0_getmemlist_t); +#define DOM0_SETTIME XENPF_settime +#define dom0_settime xenpf_settime +#define dom0_settime_t xenpf_settime_t -#define DOM0_SCHEDCTL 6 - /* struct sched_ctl_cmd is from sched-ctl.h */ -typedef struct sched_ctl_cmd dom0_schedctl_t; -DEFINE_XEN_GUEST_HANDLE(dom0_schedctl_t); +#define DOM0_ADD_MEMTYPE XENPF_add_memtype +#define dom0_add_memtype xenpf_add_memtype +#define dom0_add_memtype_t xenpf_add_memtype_t -#define DOM0_ADJUSTDOM 7 -/* struct sched_adjdom_cmd is from sched-ctl.h */ -typedef struct sched_adjdom_cmd dom0_adjustdom_t; -DEFINE_XEN_GUEST_HANDLE(dom0_adjustdom_t); +#define DOM0_DEL_MEMTYPE XENPF_del_memtype +#define dom0_del_memtype xenpf_del_memtype +#define dom0_del_memtype_t xenpf_del_memtype_t -#define DOM0_CREATEDOMAIN 8 -struct dom0_createdomain { - /* IN parameters */ - uint32_t ssidref; - xen_domain_handle_t handle; - /* IN/OUT parameters. */ - /* Identifier for new domain (auto-allocate if zero is specified). */ - domid_t domain; -}; -typedef struct dom0_createdomain dom0_createdomain_t; -DEFINE_XEN_GUEST_HANDLE(dom0_createdomain_t); +#define DOM0_READ_MEMTYPE XENPF_read_memtype +#define dom0_read_memtype xenpf_read_memtype +#define dom0_read_memtype_t xenpf_read_memtype_t -#define DOM0_DESTROYDOMAIN 9 -struct dom0_destroydomain { - /* IN variables. */ - domid_t domain; -}; -typedef struct dom0_destroydomain dom0_destroydomain_t; -DEFINE_XEN_GUEST_HANDLE(dom0_destroydomain_t); - -#define DOM0_PAUSEDOMAIN 10 -struct dom0_pausedomain { - /* IN parameters. */ - domid_t domain; -}; -typedef struct dom0_pausedomain dom0_pausedomain_t; -DEFINE_XEN_GUEST_HANDLE(dom0_pausedomain_t); +#define DOM0_MICROCODE XENPF_microcode_update +#define dom0_microcode xenpf_microcode_update +#define dom0_microcode_t xenpf_microcode_update_t -#define DOM0_UNPAUSEDOMAIN 11 -struct dom0_unpausedomain { - /* IN parameters. */ - domid_t domain; -}; -typedef struct dom0_unpausedomain dom0_unpausedomain_t; -DEFINE_XEN_GUEST_HANDLE(dom0_unpausedomain_t); - -#define DOM0_GETDOMAININFO 12 -struct dom0_getdomaininfo { - /* IN variables. */ - domid_t domain; /* NB. IN/OUT variable. */ - /* OUT variables. */ -#define DOMFLAGS_DYING (1<<0) /* Domain is scheduled to die. */ -#define DOMFLAGS_SHUTDOWN (1<<2) /* The guest OS has shut down. */ -#define DOMFLAGS_PAUSED (1<<3) /* Currently paused by control software. */ -#define DOMFLAGS_BLOCKED (1<<4) /* Currently blocked pending an event. */ -#define DOMFLAGS_RUNNING (1<<5) /* Domain is currently running. */ -#define DOMFLAGS_CPUMASK 255 /* CPU to which this domain is bound. */ -#define DOMFLAGS_CPUSHIFT 8 -#define DOMFLAGS_SHUTDOWNMASK 255 /* DOMFLAGS_SHUTDOWN guest-supplied code. */ -#define DOMFLAGS_SHUTDOWNSHIFT 16 - uint32_t flags; - uint64_t tot_pages; - uint64_t max_pages; - xen_pfn_t shared_info_frame; /* MFN of shared_info struct */ - uint64_t cpu_time; - uint32_t nr_online_vcpus; /* Number of VCPUs currently online. */ - uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */ - uint32_t ssidref; - xen_domain_handle_t handle; -}; -typedef struct dom0_getdomaininfo dom0_getdomaininfo_t; -DEFINE_XEN_GUEST_HANDLE(dom0_getdomaininfo_t); +#define DOM0_PLATFORM_QUIRK XENPF_platform_quirk +#define dom0_platform_quirk xenpf_platform_quirk +#define dom0_platform_quirk_t xenpf_platform_quirk_t -#define DOM0_SETVCPUCONTEXT 13 -struct dom0_setvcpucontext { - /* IN variables. */ - domid_t domain; - uint32_t vcpu; - /* IN/OUT parameters */ - XEN_GUEST_HANDLE(vcpu_guest_context_t) ctxt; -}; -typedef struct dom0_setvcpucontext dom0_setvcpucontext_t; -DEFINE_XEN_GUEST_HANDLE(dom0_setvcpucontext_t); +typedef uint64_t cpumap_t; -#define DOM0_MSR 15 +/* Unsupported legacy operation -- defined for API compatibility. */ +#define DOM0_MSR 15 struct dom0_msr { /* IN variables. */ uint32_t write; @@ -145,361 +61,8 @@ struct dom0_msr { typedef struct dom0_msr dom0_msr_t; DEFINE_XEN_GUEST_HANDLE(dom0_msr_t); -/* - * Set clock such that it would read <secs,nsecs> after 00:00:00 UTC, - * 1 January, 1970 if the current system time was <system_time>. - */ -#define DOM0_SETTIME 17 -struct dom0_settime { - /* IN variables. */ - uint32_t secs; - uint32_t nsecs; - uint64_t system_time; -}; -typedef struct dom0_settime dom0_settime_t; -DEFINE_XEN_GUEST_HANDLE(dom0_settime_t); - -#define DOM0_GETPAGEFRAMEINFO 18 -#define LTAB_SHIFT 28 -#define NOTAB 0 /* normal page */ -#define L1TAB (1<<LTAB_SHIFT) -#define L2TAB (2<<LTAB_SHIFT) -#define L3TAB (3<<LTAB_SHIFT) -#define L4TAB (4<<LTAB_SHIFT) -#define LPINTAB (1<<31) -#define XTAB (0xf<<LTAB_SHIFT) /* invalid page */ -#define LTAB_MASK XTAB -#define LTABTYPE_MASK (0x7<<LTAB_SHIFT) - -struct dom0_getpageframeinfo { - /* IN variables. */ - xen_pfn_t gmfn; /* GMFN to query. */ - domid_t domain; /* To which domain does the frame belong? */ - /* OUT variables. */ - /* Is the page PINNED to a type? */ - uint32_t type; /* see above type defs */ -}; -typedef struct dom0_getpageframeinfo dom0_getpageframeinfo_t; -DEFINE_XEN_GUEST_HANDLE(dom0_getpageframeinfo_t); - -/* - * Read console content from Xen buffer ring. - */ -#define DOM0_READCONSOLE 19 -struct dom0_readconsole { - /* IN variables. */ - uint32_t clear; /* Non-zero -> clear after reading. */ - XEN_GUEST_HANDLE(char) buffer; /* Buffer start */ - /* IN/OUT variables. */ - uint32_t count; /* In: Buffer size; Out: Used buffer size */ -}; -typedef struct dom0_readconsole dom0_readconsole_t; -DEFINE_XEN_GUEST_HANDLE(dom0_readconsole_t); - -/* - * Set which physical cpus a vcpu can execute on. - */ -#define DOM0_SETVCPUAFFINITY 20 -struct dom0_setvcpuaffinity { - /* IN variables. */ - domid_t domain; - uint32_t vcpu; - cpumap_t cpumap; -}; -typedef struct dom0_setvcpuaffinity dom0_setvcpuaffinity_t; -DEFINE_XEN_GUEST_HANDLE(dom0_setvcpuaffinity_t); - -/* Get trace buffers machine base address */ -#define DOM0_TBUFCONTROL 21 -struct dom0_tbufcontrol { - /* IN variables */ -#define DOM0_TBUF_GET_INFO 0 -#define DOM0_TBUF_SET_CPU_MASK 1 -#define DOM0_TBUF_SET_EVT_MASK 2 -#define DOM0_TBUF_SET_SIZE 3 -#define DOM0_TBUF_ENABLE 4 -#define DOM0_TBUF_DISABLE 5 - uint32_t op; - /* IN/OUT variables */ - cpumap_t cpu_mask; - uint32_t evt_mask; - /* OUT variables */ - xen_pfn_t buffer_mfn; - uint32_t size; -}; -typedef struct dom0_tbufcontrol dom0_tbufcontrol_t; -DEFINE_XEN_GUEST_HANDLE(dom0_tbufcontrol_t); - -/* - * Get physical information about the host machine - */ -#define DOM0_PHYSINFO 22 -struct dom0_physinfo { - uint32_t threads_per_core; - uint32_t cores_per_socket; - uint32_t sockets_per_node; - uint32_t nr_nodes; - uint32_t cpu_khz; - uint64_t total_pages; - uint64_t free_pages; - uint64_t scrub_pages; - uint32_t hw_cap[8]; -}; -typedef struct dom0_physinfo dom0_physinfo_t; -DEFINE_XEN_GUEST_HANDLE(dom0_physinfo_t); - -/* - * Get the ID of the current scheduler. - */ -#define DOM0_SCHED_ID 24 -struct dom0_sched_id { - /* OUT variable */ - uint32_t sched_id; -}; -typedef struct dom0_physinfo dom0_sched_id_t; -DEFINE_XEN_GUEST_HANDLE(dom0_sched_id_t); - -/* - * Control shadow pagetables operation - */ -#define DOM0_SHADOW_CONTROL 25 - -/* Disable shadow mode. */ -#define DOM0_SHADOW_CONTROL_OP_OFF 0 - -/* Enable shadow mode (mode contains ORed DOM0_SHADOW_ENABLE_* flags). */ -#define DOM0_SHADOW_CONTROL_OP_ENABLE 32 - -/* Log-dirty bitmap operations. */ - /* Return the bitmap and clean internal copy for next round. */ -#define DOM0_SHADOW_CONTROL_OP_CLEAN 11 - /* Return the bitmap but do not modify internal copy. */ -#define DOM0_SHADOW_CONTROL_OP_PEEK 12 - -/* Memory allocation accessors. */ -#define DOM0_SHADOW_CONTROL_OP_GET_ALLOCATION 30 -#define DOM0_SHADOW_CONTROL_OP_SET_ALLOCATION 31 - -/* Legacy enable operations. */ - /* Equiv. to ENABLE with no mode flags. */ -#define DOM0_SHADOW_CONTROL_OP_ENABLE_TEST 1 - /* Equiv. to ENABLE with mode flag ENABLE_LOG_DIRTY. */ -#define DOM0_SHADOW_CONTROL_OP_ENABLE_LOGDIRTY 2 - /* Equiv. to ENABLE with mode flags ENABLE_REFCOUNT and ENABLE_TRANSLATE. */ -#define DOM0_SHADOW_CONTROL_OP_ENABLE_TRANSLATE 3 - -/* Mode flags for DOM0_SHADOW_CONTROL_OP_ENABLE. */ - /* - * Shadow pagetables are refcounted: guest does not use explicit mmu - * operations nor write-protect its pagetables. - */ -#define DOM0_SHADOW_ENABLE_REFCOUNT (1 << 1) - /* - * Log pages in a bitmap as they are dirtied. - * Used for live relocation to determine which pages must be re-sent. - */ -#define DOM0_SHADOW_ENABLE_LOG_DIRTY (1 << 2) - /* - * Automatically translate GPFNs into MFNs. - */ -#define DOM0_SHADOW_ENABLE_TRANSLATE (1 << 3) - /* - * Xen does not steal virtual address space from the guest. - * Requires HVM support. - */ -#define DOM0_SHADOW_ENABLE_EXTERNAL (1 << 4) - -struct dom0_shadow_control_stats { - uint32_t fault_count; - uint32_t dirty_count; -}; -typedef struct dom0_shadow_control_stats dom0_shadow_control_stats_t; -DEFINE_XEN_GUEST_HANDLE(dom0_shadow_control_stats_t); - -struct dom0_shadow_control { - /* IN variables. */ - domid_t domain; - uint32_t op; /* DOM0_SHADOW_CONTROL_OP_* */ - - /* OP_ENABLE */ - uint32_t mode; /* DOM0_SHADOW_ENABLE_* */ - - /* OP_GET_ALLOCATION / OP_SET_ALLOCATION */ - uint32_t mb; /* Shadow memory allocation in MB */ - - /* OP_PEEK / OP_CLEAN */ - XEN_GUEST_HANDLE(ulong) dirty_bitmap; - uint64_t pages; /* Size of buffer. Updated with actual size. */ - struct dom0_shadow_control_stats stats; -}; -typedef struct dom0_shadow_control dom0_shadow_control_t; -DEFINE_XEN_GUEST_HANDLE(dom0_shadow_control_t); - -#define DOM0_SETDOMAINMAXMEM 28 -struct dom0_setdomainmaxmem { - /* IN variables. */ - domid_t domain; - uint64_t max_memkb; -}; -typedef struct dom0_setdomainmaxmem dom0_setdomainmaxmem_t; -DEFINE_XEN_GUEST_HANDLE(dom0_setdomainmaxmem_t); - -#define DOM0_GETPAGEFRAMEINFO2 29 /* batched interface */ -struct dom0_getpageframeinfo2 { - /* IN variables. */ - domid_t domain; - uint64_t num; - /* IN/OUT variables. */ - XEN_GUEST_HANDLE(ulong) array; -}; -typedef struct dom0_getpageframeinfo2 dom0_getpageframeinfo2_t; -DEFINE_XEN_GUEST_HANDLE(dom0_getpageframeinfo2_t); - -/* - * Request memory range (@mfn, @mfn+@nr_mfns-1) to have type @type. - * On x86, @type is an architecture-defined MTRR memory type. - * On success, returns the MTRR that was used (@reg) and a handle that can - * be passed to DOM0_DEL_MEMTYPE to accurately tear down the new setting. - * (x86-specific). - */ -#define DOM0_ADD_MEMTYPE 31 -struct dom0_add_memtype { - /* IN variables. */ - xen_pfn_t mfn; - uint64_t nr_mfns; - uint32_t type; - /* OUT variables. */ - uint32_t handle; - uint32_t reg; -}; -typedef struct dom0_add_memtype dom0_add_memtype_t; -DEFINE_XEN_GUEST_HANDLE(dom0_add_memtype_t); - -/* - * Tear down an existing memory-range type. If @handle is remembered then it - * should be passed in to accurately tear down the correct setting (in case - * of overlapping memory regions with differing types). If it is not known - * then @handle should be set to zero. In all cases @reg must be set. - * (x86-specific). - */ -#define DOM0_DEL_MEMTYPE 32 -struct dom0_del_memtype { - /* IN variables. */ - uint32_t handle; - uint32_t reg; -}; -typedef struct dom0_del_memtype dom0_del_memtype_t; -DEFINE_XEN_GUEST_HANDLE(dom0_del_memtype_t); - -/* Read current type of an MTRR (x86-specific). */ -#define DOM0_READ_MEMTYPE 33 -struct dom0_read_memtype { - /* IN variables. */ - uint32_t reg; - /* OUT variables. */ - xen_pfn_t mfn; - uint64_t nr_mfns; - uint32_t type; -}; -typedef struct dom0_read_memtype dom0_read_memtype_t; -DEFINE_XEN_GUEST_HANDLE(dom0_read_memtype_t); - -/* Interface for controlling Xen software performance counters. */ -#define DOM0_PERFCCONTROL 34 -/* Sub-operations: */ -#define DOM0_PERFCCONTROL_OP_RESET 1 /* Reset all counters to zero. */ -#define DOM0_PERFCCONTROL_OP_QUERY 2 /* Get perfctr information. */ -struct dom0_perfc_desc { - char name[80]; /* name of perf counter */ - uint32_t nr_vals; /* number of values for this counter */ -}; -typedef struct dom0_perfc_desc dom0_perfc_desc_t; -DEFINE_XEN_GUEST_HANDLE(dom0_perfc_desc_t); -typedef uint32_t dom0_perfc_val_t; -DEFINE_XEN_GUEST_HANDLE(dom0_perfc_val_t); - -struct dom0_perfccontrol { - /* IN variables. */ - uint32_t op; /* DOM0_PERFCCONTROL_OP_??? */ - /* OUT variables. */ - uint32_t nr_counters; /* number of counters description */ - uint32_t nr_vals; /* number of values */ - XEN_GUEST_HANDLE(dom0_perfc_desc_t) desc; /* counter information (or NULL) */ - XEN_GUEST_HANDLE(dom0_perfc_val_t) val; /* counter values (or NULL) */ -}; -typedef struct dom0_perfccontrol dom0_perfccontrol_t; -DEFINE_XEN_GUEST_HANDLE(dom0_perfccontrol_t); - -#define DOM0_MICROCODE 35 -struct dom0_microcode { - /* IN variables. */ - XEN_GUEST_HANDLE(void) data; /* Pointer to microcode data */ - uint32_t length; /* Length of microcode data. */ -}; -typedef struct dom0_microcode dom0_microcode_t; -DEFINE_XEN_GUEST_HANDLE(dom0_microcode_t); - -#define DOM0_IOPORT_PERMISSION 36 -struct dom0_ioport_permission { - domid_t domain; /* domain to be affected */ - uint32_t first_port; /* first port int range */ - uint32_t nr_ports; /* size of port range */ - uint8_t allow_access; /* allow or deny access to range? */ -}; -typedef struct dom0_ioport_permission dom0_ioport_permission_t; -DEFINE_XEN_GUEST_HANDLE(dom0_ioport_permission_t); - -#define DOM0_GETVCPUCONTEXT 37 -struct dom0_getvcpucontext { - /* IN variables. */ - domid_t domain; /* domain to be affected */ - uint32_t vcpu; /* vcpu # */ - /* OUT variables. */ - XEN_GUEST_HANDLE(vcpu_guest_context_t) ctxt; -}; -typedef struct dom0_getvcpucontext dom0_getvcpucontext_t; -DEFINE_XEN_GUEST_HANDLE(dom0_getvcpucontext_t); - -#define DOM0_GETVCPUINFO 43 -struct dom0_getvcpuinfo { - /* IN variables. */ - domid_t domain; /* domain to be affected */ - uint32_t vcpu; /* vcpu # */ - /* OUT variables. */ - uint8_t online; /* currently online (not hotplugged)? */ - uint8_t blocked; /* blocked waiting for an event? */ - uint8_t running; /* currently scheduled on its CPU? */ - uint64_t cpu_time; /* total cpu time consumed (ns) */ - uint32_t cpu; /* current mapping */ - cpumap_t cpumap; /* allowable mapping */ -}; -typedef struct dom0_getvcpuinfo dom0_getvcpuinfo_t; -DEFINE_XEN_GUEST_HANDLE(dom0_getvcpuinfo_t); - -#define DOM0_GETDOMAININFOLIST 38 -struct dom0_getdomaininfolist { - /* IN variables. */ - domid_t first_domain; - uint32_t max_domains; - XEN_GUEST_HANDLE(dom0_getdomaininfo_t) buffer; - /* OUT variables. */ - uint32_t num_domains; -}; -typedef struct dom0_getdomaininfolist dom0_getdomaininfolist_t; -DEFINE_XEN_GUEST_HANDLE(dom0_getdomaininfolist_t); - -#define DOM0_PLATFORM_QUIRK 39 -#define QUIRK_NOIRQBALANCING 1 /* Do not restrict IO-APIC RTE targets */ -#define QUIRK_IOAPIC_BAD_REGSEL 2 /* IO-APIC REGSEL forgets its value */ -#define QUIRK_IOAPIC_GOOD_REGSEL 3 /* IO-APIC REGSEL behaves properly */ -struct dom0_platform_quirk { - /* IN variables. */ - uint32_t quirk_id; -}; -typedef struct dom0_platform_quirk dom0_platform_quirk_t; -DEFINE_XEN_GUEST_HANDLE(dom0_platform_quirk_t); - -#define DOM0_PHYSICAL_MEMORY_MAP 40 /* Unimplemented from 3.0.3 onwards */ +/* Unsupported legacy operation -- defined for API compatibility. */ +#define DOM0_PHYSICAL_MEMORY_MAP 40 struct dom0_memory_map_entry { uint64_t start, end; uint32_t flags; /* reserved */ @@ -508,135 +71,18 @@ struct dom0_memory_map_entry { typedef struct dom0_memory_map_entry dom0_memory_map_entry_t; DEFINE_XEN_GUEST_HANDLE(dom0_memory_map_entry_t); -struct dom0_physical_memory_map { - /* IN variables. */ - uint32_t max_map_entries; - /* OUT variables. */ - uint32_t nr_map_entries; - XEN_GUEST_HANDLE(dom0_memory_map_entry_t) memory_map; -}; -typedef struct dom0_physical_memory_map dom0_physical_memory_map_t; -DEFINE_XEN_GUEST_HANDLE(dom0_physical_memory_map_t); - -#define DOM0_MAX_VCPUS 41 -struct dom0_max_vcpus { - domid_t domain; /* domain to be affected */ - uint32_t max; /* maximum number of vcpus */ -}; -typedef struct dom0_max_vcpus dom0_max_vcpus_t; -DEFINE_XEN_GUEST_HANDLE(dom0_max_vcpus_t); - -#define DOM0_SETDOMAINHANDLE 44 -struct dom0_setdomainhandle { - domid_t domain; - xen_domain_handle_t handle; -}; -typedef struct dom0_setdomainhandle dom0_setdomainhandle_t; -DEFINE_XEN_GUEST_HANDLE(dom0_setdomainhandle_t); - -#define DOM0_SETDEBUGGING 45 -struct dom0_setdebugging { - domid_t domain; - uint8_t enable; -}; -typedef struct dom0_setdebugging dom0_setdebugging_t; -DEFINE_XEN_GUEST_HANDLE(dom0_setdebugging_t); - -#define DOM0_IRQ_PERMISSION 46 -struct dom0_irq_permission { - domid_t domain; /* domain to be affected */ - uint8_t pirq; - uint8_t allow_access; /* flag to specify enable/disable of IRQ access */ -}; -typedef struct dom0_irq_permission dom0_irq_permission_t; -DEFINE_XEN_GUEST_HANDLE(dom0_irq_permission_t); - -#define DOM0_IOMEM_PERMISSION 47 -struct dom0_iomem_permission { - domid_t domain; /* domain to be affected */ - xen_pfn_t first_mfn; /* first page (physical page number) in range */ - uint64_t nr_mfns; /* number of pages in range (>0) */ - uint8_t allow_access; /* allow (!0) or deny (0) access to range? */ -}; -typedef struct dom0_iomem_permission dom0_iomem_permission_t; -DEFINE_XEN_GUEST_HANDLE(dom0_iomem_permission_t); - -#define DOM0_HYPERCALL_INIT 48 -struct dom0_hypercall_init { - domid_t domain; /* domain to be affected */ - xen_pfn_t gmfn; /* GMFN to be initialised */ -}; -typedef struct dom0_hypercall_init dom0_hypercall_init_t; -DEFINE_XEN_GUEST_HANDLE(dom0_hypercall_init_t); - -#define DOM0_DOMAIN_SETUP 49 -#define _XEN_DOMAINSETUP_hvm_guest 0 -#define XEN_DOMAINSETUP_hvm_guest (1UL<<_XEN_DOMAINSETUP_hvm_guest) -#define _XEN_DOMAINSETUP_query 1 /* Get parameters (for save) */ -#define XEN_DOMAINSETUP_query (1UL<<_XEN_DOMAINSETUP_query) -typedef struct dom0_domain_setup { - domid_t domain; /* domain to be affected */ - unsigned long flags; /* XEN_DOMAINSETUP_* */ -#ifdef __ia64__ - unsigned long bp; /* mpaddr of boot param area */ - unsigned long maxmem; /* Highest memory address for MDT. */ - unsigned long xsi_va; /* Xen shared_info area virtual address. */ - unsigned int hypercall_imm; /* Break imm for Xen hypercalls. */ -#endif -} dom0_domain_setup_t; -DEFINE_XEN_GUEST_HANDLE(dom0_domain_setup_t); - -#define DOM0_SETTIMEOFFSET 50 -struct dom0_settimeoffset { - domid_t domain; - int32_t time_offset_seconds; /* applied to domain wallclock time */ -}; -typedef struct dom0_settimeoffset dom0_settimeoffset_t; -DEFINE_XEN_GUEST_HANDLE(dom0_settimeoffset_t); - struct dom0_op { uint32_t cmd; uint32_t interface_version; /* DOM0_INTERFACE_VERSION */ union { - struct dom0_createdomain createdomain; - struct dom0_pausedomain pausedomain; - struct dom0_unpausedomain unpausedomain; - struct dom0_destroydomain destroydomain; - struct dom0_getmemlist getmemlist; - struct sched_ctl_cmd schedctl; - struct sched_adjdom_cmd adjustdom; - struct dom0_setvcpucontext setvcpucontext; - struct dom0_getdomaininfo getdomaininfo; - struct dom0_getpageframeinfo getpageframeinfo; struct dom0_msr msr; struct dom0_settime settime; - struct dom0_readconsole readconsole; - struct dom0_setvcpuaffinity setvcpuaffinity; - struct dom0_tbufcontrol tbufcontrol; - struct dom0_physinfo physinfo; - struct dom0_sched_id sched_id; - struct dom0_shadow_control shadow_control; - struct dom0_setdomainmaxmem setdomainmaxmem; - struct dom0_getpageframeinfo2 getpageframeinfo2; struct dom0_add_memtype add_memtype; struct dom0_del_memtype del_memtype; struct dom0_read_memtype read_memtype; - struct dom0_perfccontrol perfccontrol; struct dom0_microcode microcode; - struct dom0_ioport_permission ioport_permission; - struct dom0_getvcpucontext getvcpucontext; - struct dom0_getvcpuinfo getvcpuinfo; - struct dom0_getdomaininfolist getdomaininfolist; struct dom0_platform_quirk platform_quirk; - struct dom0_physical_memory_map physical_memory_map; - struct dom0_max_vcpus max_vcpus; - struct dom0_setdomainhandle setdomainhandle; - struct dom0_setdebugging setdebugging; - struct dom0_irq_permission irq_permission; - struct dom0_iomem_permission iomem_permission; - struct dom0_hypercall_init hypercall_init; - struct dom0_domain_setup domain_setup; - struct dom0_settimeoffset settimeoffset; + struct dom0_memory_map_entry physical_memory_map; uint8_t pad[128]; } u; }; diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h new file mode 100644 index 0000000000..1739ebf823 --- /dev/null +++ b/xen/include/public/domctl.h @@ -0,0 +1,393 @@ +/****************************************************************************** + * domctl.h + * + * Domain management operations. For use by node control stack. + * + * Copyright (c) 2002-2003, B Dragovic + * Copyright (c) 2002-2006, K Fraser + */ + +#ifndef __XEN_PUBLIC_DOMCTL_H__ +#define __XEN_PUBLIC_DOMCTL_H__ + +#if !defined(__XEN__) && !defined(__XEN_TOOLS__) +#error "domctl operations are intended for use by node control tools only" +#endif + +#include "xen.h" + +#define XEN_DOMCTL_INTERFACE_VERSION 0x00000001 + +#define uint64_t uint64_aligned_t + +struct xenctl_cpumap { + XEN_GUEST_HANDLE_64(uint8_t) bitmap; + uint32_t nr_cpus; +}; + +/* + * NB. xen_domctl.domain is an IN/OUT parameter for this operation. + * If it is specified as zero, an id is auto-allocated and returned. + */ +#define XEN_DOMCTL_createdomain 1 +struct xen_domctl_createdomain { + /* IN parameters */ + uint32_t ssidref; + xen_domain_handle_t handle; +}; +typedef struct xen_domctl_createdomain xen_domctl_createdomain_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_createdomain_t); + +#define XEN_DOMCTL_destroydomain 2 +#define XEN_DOMCTL_pausedomain 3 +#define XEN_DOMCTL_unpausedomain 4 + +#define XEN_DOMCTL_getdomaininfo 5 +struct xen_domctl_getdomaininfo { + /* OUT variables. */ + domid_t domain; /* Also echoed in domctl.domain */ +#define DOMFLAGS_DYING (1<<0) /* Domain is scheduled to die. */ +#define DOMFLAGS_SHUTDOWN (1<<2) /* The guest OS has shut down. */ +#define DOMFLAGS_PAUSED (1<<3) /* Currently paused by control software. */ +#define DOMFLAGS_BLOCKED (1<<4) /* Currently blocked pending an event. */ +#define DOMFLAGS_RUNNING (1<<5) /* Domain is currently running. */ +#define DOMFLAGS_CPUMASK 255 /* CPU to which this domain is bound. */ +#define DOMFLAGS_CPUSHIFT 8 +#define DOMFLAGS_SHUTDOWNMASK 255 /* DOMFLAGS_SHUTDOWN guest-supplied code. */ +#define DOMFLAGS_SHUTDOWNSHIFT 16 + uint32_t flags; + uint64_t tot_pages; + uint64_t max_pages; + uint64_t shared_info_frame; /* MFN of shared_info struct */ + uint64_t cpu_time; + uint32_t nr_online_vcpus; /* Number of VCPUs currently online. */ + uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */ + uint32_t ssidref; + xen_domain_handle_t handle; +}; +typedef struct xen_domctl_getdomaininfo xen_domctl_getdomaininfo_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_getdomaininfo_t); + + +#define XEN_DOMCTL_getmemlist 6 +struct xen_domctl_getmemlist { + /* IN variables. */ + uint64_t max_pfns; + XEN_GUEST_HANDLE_64(ulong) buffer; + /* OUT variables. */ + uint64_t num_pfns; +}; +typedef struct xen_domctl_getmemlist xen_domctl_getmemlist_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_getmemlist_t); + + +#define XEN_DOMCTL_getpageframeinfo 7 + +#define XEN_DOMCTL_PFINFO_LTAB_SHIFT 28 +#define XEN_DOMCTL_PFINFO_NOTAB (0x0<<28) +#define XEN_DOMCTL_PFINFO_L1TAB (0x1<<28) +#define XEN_DOMCTL_PFINFO_L2TAB (0x2<<28) +#define XEN_DOMCTL_PFINFO_L3TAB (0x3<<28) +#define XEN_DOMCTL_PFINFO_L4TAB (0x4<<28) +#define XEN_DOMCTL_PFINFO_LTABTYPE_MASK (0x7<<28) +#define XEN_DOMCTL_PFINFO_LPINTAB (0x1<<31) +#define XEN_DOMCTL_PFINFO_XTAB (0xf<<28) /* invalid page */ +#define XEN_DOMCTL_PFINFO_LTAB_MASK (0xf<<28) + +struct xen_domctl_getpageframeinfo { + /* IN variables. */ + uint64_t gmfn; /* GMFN to query */ + /* OUT variables. */ + /* Is the page PINNED to a type? */ + uint32_t type; /* see above type defs */ +}; +typedef struct xen_domctl_getpageframeinfo xen_domctl_getpageframeinfo_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_getpageframeinfo_t); + + +#define XEN_DOMCTL_getpageframeinfo2 8 +struct xen_domctl_getpageframeinfo2 { + /* IN variables. */ + uint64_t num; + /* IN/OUT variables. */ + XEN_GUEST_HANDLE_64(ulong) array; +}; +typedef struct xen_domctl_getpageframeinfo2 xen_domctl_getpageframeinfo2_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_getpageframeinfo2_t); + + +/* + * Control shadow pagetables operation + */ +#define XEN_DOMCTL_shadow_op 10 + +/* Disable shadow mode. */ +#define XEN_DOMCTL_SHADOW_OP_OFF 0 + +/* Enable shadow mode (mode contains ORed XEN_DOMCTL_SHADOW_ENABLE_* flags). */ +#define XEN_DOMCTL_SHADOW_OP_ENABLE 32 + +/* Log-dirty bitmap operations. */ + /* Return the bitmap and clean internal copy for next round. */ +#define XEN_DOMCTL_SHADOW_OP_CLEAN 11 + /* Return the bitmap but do not modify internal copy. */ +#define XEN_DOMCTL_SHADOW_OP_PEEK 12 + +/* Memory allocation accessors. */ +#define XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION 30 +#define XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION 31 + +/* Legacy enable operations. */ + /* Equiv. to ENABLE with no mode flags. */ +#define XEN_DOMCTL_SHADOW_OP_ENABLE_TEST 1 + /* Equiv. to ENABLE with mode flag ENABLE_LOG_DIRTY. */ +#define XEN_DOMCTL_SHADOW_OP_ENABLE_LOGDIRTY 2 + /* Equiv. to ENABLE with mode flags ENABLE_REFCOUNT and ENABLE_TRANSLATE. */ +#define XEN_DOMCTL_SHADOW_OP_ENABLE_TRANSLATE 3 + +/* Mode flags for XEN_DOMCTL_SHADOW_OP_ENABLE. */ + /* + * Shadow pagetables are refcounted: guest does not use explicit mmu + * operations nor write-protect its pagetables. + */ +#define XEN_DOMCTL_SHADOW_ENABLE_REFCOUNT (1 << 1) + /* + * Log pages in a bitmap as they are dirtied. + * Used for live relocation to determine which pages must be re-sent. + */ +#define XEN_DOMCTL_SHADOW_ENABLE_LOG_DIRTY (1 << 2) + /* + * Automatically translate GPFNs into MFNs. + */ +#define XEN_DOMCTL_SHADOW_ENABLE_TRANSLATE (1 << 3) + /* + * Xen does not steal virtual address space from the guest. + * Requires HVM support. + */ +#define XEN_DOMCTL_SHADOW_ENABLE_EXTERNAL (1 << 4) + +struct xen_domctl_shadow_op_stats { + uint32_t fault_count; + uint32_t dirty_count; +}; +typedef struct xen_domctl_shadow_op_stats xen_domctl_shadow_op_stats_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_shadow_op_stats_t); + +struct xen_domctl_shadow_op { + /* IN variables. */ + uint32_t op; /* XEN_DOMCTL_SHADOW_OP_* */ + + /* OP_ENABLE */ + uint32_t mode; /* XEN_DOMCTL_SHADOW_ENABLE_* */ + + /* OP_GET_ALLOCATION / OP_SET_ALLOCATION */ + uint32_t mb; /* Shadow memory allocation in MB */ + + /* OP_PEEK / OP_CLEAN */ + XEN_GUEST_HANDLE_64(ulong) dirty_bitmap; + uint64_t pages; /* Size of buffer. Updated with actual size. */ + struct xen_domctl_shadow_op_stats stats; +}; +typedef struct xen_domctl_shadow_op xen_domctl_shadow_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_shadow_op_t); + + +#define XEN_DOMCTL_max_mem 11 +struct xen_domctl_max_mem { + /* IN variables. */ + uint64_t max_memkb; +}; +typedef struct xen_domctl_max_mem xen_domctl_max_mem_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_mem_t); + + +#define XEN_DOMCTL_setvcpucontext 12 +#define XEN_DOMCTL_getvcpucontext 13 +struct xen_domctl_vcpucontext { + uint32_t vcpu; /* IN */ + XEN_GUEST_HANDLE_64(vcpu_guest_context_t) ctxt; /* IN/OUT */ +}; +typedef struct xen_domctl_vcpucontext xen_domctl_vcpucontext_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpucontext_t); + + +#define XEN_DOMCTL_getvcpuinfo 14 +struct xen_domctl_getvcpuinfo { + /* IN variables. */ + uint32_t vcpu; + /* OUT variables. */ + uint8_t online; /* currently online (not hotplugged)? */ + uint8_t blocked; /* blocked waiting for an event? */ + uint8_t running; /* currently scheduled on its CPU? */ + uint64_t cpu_time; /* total cpu time consumed (ns) */ + uint32_t cpu; /* current mapping */ +}; +typedef struct xen_domctl_getvcpuinfo xen_domctl_getvcpuinfo_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_getvcpuinfo_t); + + +/* Get/set which physical cpus a vcpu can execute on. */ +#define XEN_DOMCTL_setvcpuaffinity 9 +#define XEN_DOMCTL_getvcpuaffinity 25 +struct xen_domctl_vcpuaffinity { + uint32_t vcpu; /* IN */ + struct xenctl_cpumap cpumap; /* IN/OUT */ +}; +typedef struct xen_domctl_vcpuaffinity xen_domctl_vcpuaffinity_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_vcpuaffinity_t); + + +#define XEN_DOMCTL_max_vcpus 15 +struct xen_domctl_max_vcpus { + uint32_t max; /* maximum number of vcpus */ +}; +typedef struct xen_domctl_max_vcpus xen_domctl_max_vcpus_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_vcpus_t); + + +#define XEN_DOMCTL_scheduler_op 16 +/* Scheduler types. */ +#define XEN_SCHEDULER_SEDF 4 +#define XEN_SCHEDULER_CREDIT 5 +/* Set or get info? */ +#define XEN_DOMCTL_SCHEDOP_putinfo 0 +#define XEN_DOMCTL_SCHEDOP_getinfo 1 +struct xen_domctl_scheduler_op { + uint32_t sched_id; /* XEN_SCHEDULER_* */ + uint32_t cmd; /* XEN_DOMCTL_SCHEDOP_* */ + union { + struct xen_domctl_sched_sedf { + uint64_t period; + uint64_t slice; + uint64_t latency; + uint32_t extratime; + uint32_t weight; + } sedf; + struct xen_domctl_sched_credit { + uint16_t weight; + uint16_t cap; + } credit; + } u; +}; +typedef struct xen_domctl_scheduler_op xen_domctl_scheduler_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_scheduler_op_t); + + +#define XEN_DOMCTL_setdomainhandle 17 +struct xen_domctl_setdomainhandle { + xen_domain_handle_t handle; +}; +typedef struct xen_domctl_setdomainhandle xen_domctl_setdomainhandle_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_setdomainhandle_t); + + +#define XEN_DOMCTL_setdebugging 18 +struct xen_domctl_setdebugging { + uint8_t enable; +}; +typedef struct xen_domctl_setdebugging xen_domctl_setdebugging_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_setdebugging_t); + + +#define XEN_DOMCTL_irq_permission 19 +struct xen_domctl_irq_permission { + uint8_t pirq; + uint8_t allow_access; /* flag to specify enable/disable of IRQ access */ +}; +typedef struct xen_domctl_irq_permission xen_domctl_irq_permission_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_irq_permission_t); + + +#define XEN_DOMCTL_iomem_permission 20 +struct xen_domctl_iomem_permission { + uint64_t first_mfn; /* first page (physical page number) in range */ + uint64_t nr_mfns; /* number of pages in range (>0) */ + uint8_t allow_access; /* allow (!0) or deny (0) access to range? */ +}; +typedef struct xen_domctl_iomem_permission xen_domctl_iomem_permission_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_iomem_permission_t); + + +#define XEN_DOMCTL_ioport_permission 21 +struct xen_domctl_ioport_permission { + uint32_t first_port; /* first port int range */ + uint32_t nr_ports; /* size of port range */ + uint8_t allow_access; /* allow or deny access to range? */ +}; +typedef struct xen_domctl_ioport_permission xen_domctl_ioport_permission_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_ioport_permission_t); + +#define XEN_DOMCTL_hypercall_init 22 +struct xen_domctl_hypercall_init { + uint64_t gmfn; /* GMFN to be initialised */ +}; +typedef struct xen_domctl_hypercall_init xen_domctl_hypercall_init_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_hypercall_init_t); + +#define XEN_DOMCTL_arch_setup 23 +#define _XEN_DOMAINSETUP_hvm_guest 0 +#define XEN_DOMAINSETUP_hvm_guest (1UL<<_XEN_DOMAINSETUP_hvm_guest) +#define _XEN_DOMAINSETUP_query 1 /* Get parameters (for save) */ +#define XEN_DOMAINSETUP_query (1UL<<_XEN_DOMAINSETUP_query) +typedef struct xen_domctl_arch_setup { + uint64_t flags; /* XEN_DOMAINSETUP_* */ +#ifdef __ia64__ + uint64_t bp; /* mpaddr of boot param area */ + uint64_t maxmem; /* Highest memory address for MDT. */ + uint64_t xsi_va; /* Xen shared_info area virtual address. */ + uint32_t hypercall_imm; /* Break imm for Xen hypercalls. */ +#endif +} xen_domctl_arch_setup_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_arch_setup_t); + +#define XEN_DOMCTL_settimeoffset 24 +struct xen_domctl_settimeoffset { + int32_t time_offset_seconds; /* applied to domain wallclock time */ +}; +typedef struct xen_domctl_settimeoffset xen_domctl_settimeoffset_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_settimeoffset_t); + +struct xen_domctl { + uint32_t cmd; + uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */ + domid_t domain; + union { + struct xen_domctl_createdomain createdomain; + struct xen_domctl_getdomaininfo getdomaininfo; + struct xen_domctl_getmemlist getmemlist; + struct xen_domctl_getpageframeinfo getpageframeinfo; + struct xen_domctl_getpageframeinfo2 getpageframeinfo2; + struct xen_domctl_vcpuaffinity vcpuaffinity; + struct xen_domctl_shadow_op shadow_op; + struct xen_domctl_max_mem max_mem; + struct xen_domctl_vcpucontext vcpucontext; + struct xen_domctl_getvcpuinfo getvcpuinfo; + struct xen_domctl_max_vcpus max_vcpus; + struct xen_domctl_scheduler_op scheduler_op; + struct xen_domctl_setdomainhandle setdomainhandle; + struct xen_domctl_setdebugging setdebugging; + struct xen_domctl_irq_permission irq_permission; + struct xen_domctl_iomem_permission iomem_permission; + struct xen_domctl_ioport_permission ioport_permission; + struct xen_domctl_hypercall_init hypercall_init; + struct xen_domctl_arch_setup arch_setup; + struct xen_domctl_settimeoffset settimeoffset; + uint8_t pad[128]; + } u; +}; +typedef struct xen_domctl xen_domctl_t; +DEFINE_XEN_GUEST_HANDLE(xen_domctl_t); + +#undef uint64_t + +#endif /* __XEN_PUBLIC_DOMCTL_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/platform.h b/xen/include/public/platform.h new file mode 100644 index 0000000000..46e9160915 --- /dev/null +++ b/xen/include/public/platform.h @@ -0,0 +1,125 @@ +/****************************************************************************** + * platform.h + * + * Hardware platform operations. Intended for use by domain-0 kernel. + * + * Copyright (c) 2002-2006, K Fraser + */ + +#ifndef __XEN_PUBLIC_PLATFORM_H__ +#define __XEN_PUBLIC_PLATFORM_H__ + +#include "xen.h" + +#define XENPF_INTERFACE_VERSION 0x03000001 + +/* + * Set clock such that it would read <secs,nsecs> after 00:00:00 UTC, + * 1 January, 1970 if the current system time was <system_time>. + */ +#define XENPF_settime 17 +struct xenpf_settime { + /* IN variables. */ + uint32_t secs; + uint32_t nsecs; + uint64_t system_time; +}; +typedef struct xenpf_settime xenpf_settime_t; +DEFINE_XEN_GUEST_HANDLE(xenpf_settime_t); + +/* + * Request memory range (@mfn, @mfn+@nr_mfns-1) to have type @type. + * On x86, @type is an architecture-defined MTRR memory type. + * On success, returns the MTRR that was used (@reg) and a handle that can + * be passed to XENPF_DEL_MEMTYPE to accurately tear down the new setting. + * (x86-specific). + */ +#define XENPF_add_memtype 31 +struct xenpf_add_memtype { + /* IN variables. */ + xen_pfn_t mfn; + uint64_t nr_mfns; + uint32_t type; + /* OUT variables. */ + uint32_t handle; + uint32_t reg; +}; +typedef struct xenpf_add_memtype xenpf_add_memtype_t; +DEFINE_XEN_GUEST_HANDLE(xenpf_add_memtype_t); + +/* + * Tear down an existing memory-range type. If @handle is remembered then it + * should be passed in to accurately tear down the correct setting (in case + * of overlapping memory regions with differing types). If it is not known + * then @handle should be set to zero. In all cases @reg must be set. + * (x86-specific). + */ +#define XENPF_del_memtype 32 +struct xenpf_del_memtype { + /* IN variables. */ + uint32_t handle; + uint32_t reg; +}; +typedef struct xenpf_del_memtype xenpf_del_memtype_t; +DEFINE_XEN_GUEST_HANDLE(xenpf_del_memtype_t); + +/* Read current type of an MTRR (x86-specific). */ +#define XENPF_read_memtype 33 +struct xenpf_read_memtype { + /* IN variables. */ + uint32_t reg; + /* OUT variables. */ + xen_pfn_t mfn; + uint64_t nr_mfns; + uint32_t type; +}; +typedef struct xenpf_read_memtype xenpf_read_memtype_t; +DEFINE_XEN_GUEST_HANDLE(xenpf_read_memtype_t); + +#define XENPF_microcode_update 35 +struct xenpf_microcode_update { + /* IN variables. */ + XEN_GUEST_HANDLE(void) data; /* Pointer to microcode data */ + uint32_t length; /* Length of microcode data. */ +}; +typedef struct xenpf_microcode_update xenpf_microcode_update_t; +DEFINE_XEN_GUEST_HANDLE(xenpf_microcode_update_t); + +#define XENPF_platform_quirk 39 +#define QUIRK_NOIRQBALANCING 1 /* Do not restrict IO-APIC RTE targets */ +#define QUIRK_IOAPIC_BAD_REGSEL 2 /* IO-APIC REGSEL forgets its value */ +#define QUIRK_IOAPIC_GOOD_REGSEL 3 /* IO-APIC REGSEL behaves properly */ +struct xenpf_platform_quirk { + /* IN variables. */ + uint32_t quirk_id; +}; +typedef struct xenpf_platform_quirk xenpf_platform_quirk_t; +DEFINE_XEN_GUEST_HANDLE(xenpf_platform_quirk_t); + +struct xen_platform_op { + uint32_t cmd; + uint32_t interface_version; /* XENPF_INTERFACE_VERSION */ + union { + struct xenpf_settime settime; + struct xenpf_add_memtype add_memtype; + struct xenpf_del_memtype del_memtype; + struct xenpf_read_memtype read_memtype; + struct xenpf_microcode_update microcode; + struct xenpf_platform_quirk platform_quirk; + uint8_t pad[128]; + } u; +}; +typedef struct xen_platform_op xen_platform_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_platform_op_t); + +#endif /* __XEN_PUBLIC_PLATFORM_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/sched_ctl.h b/xen/include/public/sched_ctl.h deleted file mode 100644 index d8523f09e1..0000000000 --- a/xen/include/public/sched_ctl.h +++ /dev/null @@ -1,56 +0,0 @@ -/****************************************************************************** - * Generic scheduler control interface. - * - * Mark Williamson, (C) 2004 Intel Research Cambridge - */ - -#ifndef __XEN_PUBLIC_SCHED_CTL_H__ -#define __XEN_PUBLIC_SCHED_CTL_H__ - -/* Scheduler types. */ -#define SCHED_SEDF 4 -#define SCHED_CREDIT 5 - -/* Set or get info? */ -#define SCHED_INFO_PUT 0 -#define SCHED_INFO_GET 1 - -/* - * Generic scheduler control command - used to adjust system-wide scheduler - * parameters - */ -struct sched_ctl_cmd { - uint32_t sched_id; - uint32_t direction; -}; - -struct sched_adjdom_cmd { - uint32_t sched_id; - uint32_t direction; - domid_t domain; - union { - struct sedf_adjdom { - uint64_t period; - uint64_t slice; - uint64_t latency; - uint32_t extratime; - uint32_t weight; - } sedf; - struct sched_credit_adjdom { - uint16_t weight; - uint16_t cap; - } credit; - } u; -}; - -#endif /* __XEN_PUBLIC_SCHED_CTL_H__ */ - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h new file mode 100644 index 0000000000..a739012825 --- /dev/null +++ b/xen/include/public/sysctl.h @@ -0,0 +1,155 @@ +/****************************************************************************** + * sysctl.h + * + * System management operations. For use by node control stack. + * + * Copyright (c) 2002-2006, K Fraser + */ + +#ifndef __XEN_PUBLIC_SYSCTL_H__ +#define __XEN_PUBLIC_SYSCTL_H__ + +#if !defined(__XEN__) && !defined(__XEN_TOOLS__) +#error "sysctl operations are intended for use by node control tools only" +#endif + +#include "xen.h" +#include "domctl.h" + +#define XEN_SYSCTL_INTERFACE_VERSION 0x00000001 + +#define uint64_t uint64_aligned_t + +/* + * Read console content from Xen buffer ring. + */ +#define XEN_SYSCTL_readconsole 1 +struct xen_sysctl_readconsole { + /* IN variables. */ + uint32_t clear; /* Non-zero -> clear after reading. */ + XEN_GUEST_HANDLE_64(char) buffer; /* Buffer start */ + /* IN/OUT variables. */ + uint32_t count; /* In: Buffer size; Out: Used buffer size */ +}; +typedef struct xen_sysctl_readconsole xen_sysctl_readconsole_t; +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_readconsole_t); + +/* Get trace buffers machine base address */ +#define XEN_SYSCTL_tbuf_op 2 +struct xen_sysctl_tbuf_op { + /* IN variables */ +#define XEN_SYSCTL_TBUFOP_get_info 0 +#define XEN_SYSCTL_TBUFOP_set_cpu_mask 1 +#define XEN_SYSCTL_TBUFOP_set_evt_mask 2 +#define XEN_SYSCTL_TBUFOP_set_size 3 +#define XEN_SYSCTL_TBUFOP_enable 4 +#define XEN_SYSCTL_TBUFOP_disable 5 + uint32_t cmd; + /* IN/OUT variables */ + struct xenctl_cpumap cpu_mask; + uint32_t evt_mask; + /* OUT variables */ + uint64_t buffer_mfn; + uint32_t size; +}; +typedef struct xen_sysctl_tbuf_op xen_sysctl_tbuf_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_tbuf_op_t); + +/* + * Get physical information about the host machine + */ +#define XEN_SYSCTL_physinfo 3 +struct xen_sysctl_physinfo { + uint32_t threads_per_core; + uint32_t cores_per_socket; + uint32_t sockets_per_node; + uint32_t nr_nodes; + uint32_t cpu_khz; + uint64_t total_pages; + uint64_t free_pages; + uint64_t scrub_pages; + uint32_t hw_cap[8]; +}; +typedef struct xen_sysctl_physinfo xen_sysctl_physinfo_t; +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_physinfo_t); + +/* + * Get the ID of the current scheduler. + */ +#define XEN_SYSCTL_sched_id 4 +struct xen_sysctl_sched_id { + /* OUT variable */ + uint32_t sched_id; +}; +typedef struct xen_sysctl_sched_id xen_sysctl_sched_id_t; +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_sched_id_t); + +/* Interface for controlling Xen software performance counters. */ +#define XEN_SYSCTL_perfc_op 5 +/* Sub-operations: */ +#define XEN_SYSCTL_PERFCOP_reset 1 /* Reset all counters to zero. */ +#define XEN_SYSCTL_PERFCOP_query 2 /* Get perfctr information. */ +struct xen_sysctl_perfc_desc { + char name[80]; /* name of perf counter */ + uint32_t nr_vals; /* number of values for this counter */ +}; +typedef struct xen_sysctl_perfc_desc xen_sysctl_perfc_desc_t; +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_perfc_desc_t); +typedef uint32_t xen_sysctl_perfc_val_t; +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_perfc_val_t); + +struct xen_sysctl_perfc_op { + /* IN variables. */ + uint32_t cmd; /* XEN_SYSCTL_PERFCOP_??? */ + /* OUT variables. */ + uint32_t nr_counters; /* number of counters description */ + uint32_t nr_vals; /* number of values */ + /* counter information (or NULL) */ + XEN_GUEST_HANDLE_64(xen_sysctl_perfc_desc_t) desc; + /* counter values (or NULL) */ + XEN_GUEST_HANDLE_64(xen_sysctl_perfc_val_t) val; +}; +typedef struct xen_sysctl_perfc_op xen_sysctl_perfc_op_t; +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_perfc_op_t); + +#define XEN_SYSCTL_getdomaininfolist 6 +struct xen_sysctl_getdomaininfolist { + /* IN variables. */ + domid_t first_domain; + uint32_t max_domains; + XEN_GUEST_HANDLE_64(xen_domctl_getdomaininfo_t) buffer; + /* OUT variables. */ + uint32_t num_domains; +}; +typedef struct xen_sysctl_getdomaininfolist xen_sysctl_getdomaininfolist_t; +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_getdomaininfolist_t); + +struct xen_sysctl { + uint32_t cmd; + uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */ + union { + struct xen_sysctl_readconsole readconsole; + struct xen_sysctl_tbuf_op tbuf_op; + struct xen_sysctl_physinfo physinfo; + struct xen_sysctl_sched_id sched_id; + struct xen_sysctl_perfc_op perfc_op; + struct xen_sysctl_getdomaininfolist getdomaininfolist; + uint8_t pad[128]; + } u; +}; +typedef struct xen_sysctl xen_sysctl_t; +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_t); + +#undef uint64_t + +#endif /* __XEN_PUBLIC_SYSCTL_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/xen-compat.h b/xen/include/public/xen-compat.h index 72ae7c659c..89f7bd487a 100644 --- a/xen/include/public/xen-compat.h +++ b/xen/include/public/xen-compat.h @@ -9,7 +9,7 @@ #ifndef __XEN_PUBLIC_XEN_COMPAT_H__ #define __XEN_PUBLIC_XEN_COMPAT_H__ -#define __XEN_LATEST_INTERFACE_VERSION__ 0x00030203 +#define __XEN_LATEST_INTERFACE_VERSION__ 0x00030204 #if defined(__XEN__) || defined(__XEN_TOOLS__) /* Xen is built with matching headers and implements the latest interface. */ diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index b06f215174..eb4bfcb6f9 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -34,7 +34,7 @@ #define __HYPERVISOR_set_callbacks 4 #define __HYPERVISOR_fpu_taskswitch 5 #define __HYPERVISOR_sched_op_compat 6 /* compat since 0x00030101 */ -#define __HYPERVISOR_dom0_op 7 +#define __HYPERVISOR_platform_op 7 #define __HYPERVISOR_set_debugreg 8 #define __HYPERVISOR_get_debugreg 9 #define __HYPERVISOR_update_descriptor 10 @@ -61,6 +61,8 @@ #define __HYPERVISOR_event_channel_op 32 #define __HYPERVISOR_physdev_op 33 #define __HYPERVISOR_hvm_op 34 +#define __HYPERVISOR_sysctl 35 +#define __HYPERVISOR_domctl 36 /* Architecture-specific hypercall definitions. */ #define __HYPERVISOR_arch_0 48 @@ -90,6 +92,11 @@ #define __HYPERVISOR_physdev_op __HYPERVISOR_physdev_op_compat #endif +/* New platform_op hypercall introduced in 0x00030204. */ +#if __XEN_INTERFACE_VERSION__ < 0x00030204 +#define __HYPERVISOR_dom0_op __HYPERVISOR_platform_op +#endif + /* * VIRTUAL INTERRUPTS * @@ -530,14 +537,17 @@ typedef struct dom0_vga_console_info { uint8_t rsvd_size; } dom0_vga_console_info_t; -typedef uint64_t cpumap_t; - typedef uint8_t xen_domain_handle_t[16]; /* Turn a plain number into a C unsigned long constant. */ #define __mk_unsigned_long(x) x ## UL #define mk_unsigned_long(x) __mk_unsigned_long(x) +DEFINE_XEN_GUEST_HANDLE(uint8_t); +DEFINE_XEN_GUEST_HANDLE(uint16_t); +DEFINE_XEN_GUEST_HANDLE(uint32_t); +DEFINE_XEN_GUEST_HANDLE(uint64_t); + #else /* __ASSEMBLY__ */ /* In assembly code we cannot use C numeric constant suffixes. */ diff --git a/xen/include/xen/cpumask.h b/xen/include/xen/cpumask.h index 0188570955..997efb1d45 100644 --- a/xen/include/xen/cpumask.h +++ b/xen/include/xen/cpumask.h @@ -379,4 +379,11 @@ extern cpumask_t cpu_present_map; #define for_each_online_cpu(cpu) for_each_cpu_mask((cpu), cpu_online_map) #define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map) +/* Copy to/from cpumap provided by control tools. */ +struct xenctl_cpumap; +void cpumask_to_xenctl_cpumap( + struct xenctl_cpumap *enctl_cpumap, cpumask_t *cpumask); +void xenctl_cpumap_to_cpumask( + cpumask_t *cpumask, struct xenctl_cpumap *enctl_cpumap); + #endif /* __XEN_CPUMASK_H */ diff --git a/xen/include/xen/hypercall.h b/xen/include/xen/hypercall.h index 5635fa1961..16cde7b738 100644 --- a/xen/include/xen/hypercall.h +++ b/xen/include/xen/hypercall.h @@ -9,7 +9,9 @@ #include <xen/types.h> #include <xen/time.h> #include <public/xen.h> -#include <public/dom0_ops.h> +#include <public/domctl.h> +#include <public/sysctl.h> +#include <public/platform.h> #include <public/acm_ops.h> #include <public/event_channel.h> #include <asm/hypercall.h> @@ -29,8 +31,16 @@ do_sched_op( XEN_GUEST_HANDLE(void) arg); extern long -do_dom0_op( - XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op); +do_domctl( + XEN_GUEST_HANDLE(xen_domctl_t) u_domctl); + +extern long +do_sysctl( + XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl); + +extern long +do_platform_op( + XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op); extern long do_memory_op( diff --git a/xen/include/xen/sched-if.h b/xen/include/xen/sched-if.h index 78f61a7b17..4cfed1cbb8 100644 --- a/xen/include/xen/sched-if.h +++ b/xen/include/xen/sched-if.h @@ -73,9 +73,8 @@ struct scheduler { struct task_slice (*do_schedule) (s_time_t); - int (*control) (struct sched_ctl_cmd *); - int (*adjdom) (struct domain *, - struct sched_adjdom_cmd *); + int (*adjust) (struct domain *, + struct xen_domctl_scheduler_op *); void (*dump_settings) (void); void (*dump_cpu_state) (int); }; diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index b32f1616c6..fb98daeecc 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -7,7 +7,7 @@ #include <xen/spinlock.h> #include <xen/smp.h> #include <public/xen.h> -#include <public/dom0_ops.h> +#include <public/domctl.h> #include <public/vcpu.h> #include <xen/time.h> #include <xen/timer.h> @@ -243,7 +243,7 @@ extern int construct_dom0( unsigned long image_start, unsigned long image_len, unsigned long initrd_start, unsigned long initrd_len, char *cmdline); -extern int set_info_guest(struct domain *d, dom0_setvcpucontext_t *); +extern int set_info_guest(struct domain *d, xen_domctl_vcpucontext_t *); struct domain *find_domain_by_id(domid_t dom); extern void domain_destroy(struct domain *d); @@ -282,8 +282,7 @@ void scheduler_init(void); void schedulers_start(void); int sched_init_vcpu(struct vcpu *); void sched_destroy_domain(struct domain *); -long sched_ctl(struct sched_ctl_cmd *); -long sched_adjdom(struct sched_adjdom_cmd *); +long sched_adjust(struct domain *, struct xen_domctl_scheduler_op *); int sched_id(void); void vcpu_wake(struct vcpu *d); void vcpu_sleep_nosync(struct vcpu *d); diff --git a/xen/include/xen/trace.h b/xen/include/xen/trace.h index a3e6b55654..4f3649a394 100644 --- a/xen/include/xen/trace.h +++ b/xen/include/xen/trace.h @@ -16,15 +16,13 @@ * * Access to the trace buffers is via a dom0 hypervisor op and analysis of * trace buffer contents can then be performed using a userland tool. - * - * See also common/trace.c and the dom0 op in include/public/dom0_ops.h */ #ifndef __XEN_TRACE_H__ #define __XEN_TRACE_H__ #include <xen/config.h> -#include <public/dom0_ops.h> +#include <public/sysctl.h> #include <public/trace.h> extern int tb_init_done; @@ -33,7 +31,7 @@ extern int tb_init_done; void init_trace_bufs(void); /* used to retrieve the physical address of the trace buffers */ -int tb_control(dom0_tbufcontrol_t *tbc); +int tb_control(struct xen_sysctl_tbuf_op *tbc); void trace(u32 event, unsigned long d1, unsigned long d2, unsigned long d3, unsigned long d4, unsigned long d5); |