diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-07-12 22:26:07 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-07-12 22:26:07 +0000 |
commit | 6bf073980b8479bae7c94ecd925c4cecef6e5414 (patch) | |
tree | 766f6ff4c90654e80f4f0053822b421c6524f46b /tools | |
parent | 7a68631223523fd53038da61cdf337d3f14c8593 (diff) | |
download | xen-6bf073980b8479bae7c94ecd925c4cecef6e5414.tar.gz xen-6bf073980b8479bae7c94ecd925c4cecef6e5414.tar.bz2 xen-6bf073980b8479bae7c94ecd925c4cecef6e5414.zip |
bitkeeper revision 1.339.1.1 (3f108aff8cNSEyxZFIWHZ-zZtSTT2w)
Many files:
new file
Clean up dom0 proc interfaces. Implemented ioremap and /dev/mem.
.del-dom0_block.c~63815c1974691c1c:
Delete: xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_block.c
.del-sched_ops.c~20807e5c2ed6b51:
Delete: xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/sched_ops.c
.del-xi_list~49abab167156959:
Delete: tools/internal/xi_list
.del-xl_physdisk_proc.c~49451bc26a40fcb2:
Delete: xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c
.del-mmu.h~6bc56547519b6f96:
Delete: xenolinux-2.4.21-sparse/include/asm-xeno/mmu.h
.del-dom0.h~6fb656bb4a0c52e1:
Delete: xenolinux-2.4.21-sparse/include/asm-xeno/dom0.h
.del-dom0_ops.h~fb19960d77217740:
Delete: tools/internal/dom0_ops.h
.del-dom0_ops.h~5c52b016e619bd2d:
Delete: xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_ops.h
.del-dom0_memory.c~c72c6e5f7fd65d38:
Delete: xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_memory.c
.del-direct_map.c~d2fedc686b334f2a:
Delete: xenolinux-2.4.21-sparse/arch/xeno/mm/direct_map.c
direct_map.c:
Rename: xenolinux-2.4.21-sparse/arch/xeno/mm/get_unmapped_area.c -> xenolinux-2.4.21-sparse/arch/xeno/mm/direct_map.c
Diffstat (limited to 'tools')
-rw-r--r-- | tools/control/src/org/xenoserver/control/CommandVbdCreate.java | 4 | ||||
-rw-r--r-- | tools/control/src/org/xenoserver/control/CommandVbdCreatePhysical.java | 4 | ||||
-rw-r--r-- | tools/control/src/org/xenoserver/control/CommandVbdList.java | 2 | ||||
-rw-r--r-- | tools/internal/Makefile | 70 | ||||
-rw-r--r-- | tools/internal/dom0_defs.h | 126 | ||||
-rw-r--r-- | tools/internal/dom0_ops.h | 5 | ||||
-rw-r--r-- | tools/internal/mem_defs.h | 28 | ||||
-rw-r--r-- | tools/internal/xi_build.c | 552 | ||||
-rw-r--r-- | tools/internal/xi_create.c | 96 | ||||
-rw-r--r-- | tools/internal/xi_destroy.c | 88 | ||||
-rwxr-xr-x | tools/internal/xi_list | 46 | ||||
-rw-r--r-- | tools/internal/xi_list.c | 76 | ||||
-rw-r--r-- | tools/internal/xi_phys_grant.c | 67 | ||||
-rw-r--r-- | tools/internal/xi_phys_probe.c | 64 | ||||
-rw-r--r-- | tools/internal/xi_phys_revoke.c | 49 | ||||
-rw-r--r-- | tools/internal/xi_sched_domain.c | 32 | ||||
-rw-r--r-- | tools/internal/xi_sched_global.c | 27 | ||||
-rw-r--r-- | tools/internal/xi_start.c | 70 | ||||
-rw-r--r-- | tools/internal/xi_stop.c | 73 | ||||
-rw-r--r-- | tools/internal/xi_usage.c | 64 | ||||
-rwxr-xr-x | tools/internal/xi_vifinit | 4 |
21 files changed, 772 insertions, 775 deletions
diff --git a/tools/control/src/org/xenoserver/control/CommandVbdCreate.java b/tools/control/src/org/xenoserver/control/CommandVbdCreate.java index 3c1c21aa6c..a1c7c82f15 100644 --- a/tools/control/src/org/xenoserver/control/CommandVbdCreate.java +++ b/tools/control/src/org/xenoserver/control/CommandVbdCreate.java @@ -53,12 +53,12 @@ public class CommandVbdCreate extends Command { String command = vd.dumpForXen(vbd); try { - FileWriter fw = new FileWriter("/proc/xeno/dom0/vhd"); + FileWriter fw = new FileWriter("/proc/xeno/vhd"); fw.write(command); fw.flush(); fw.close(); } catch (IOException e) { - throw new CommandFailedException("Could not write VBD details to /proc/xeno/dom0/vhd", e); + throw new CommandFailedException("Could not write VBD details to /proc/xeno/vhd", e); } return "Created virtual block device " diff --git a/tools/control/src/org/xenoserver/control/CommandVbdCreatePhysical.java b/tools/control/src/org/xenoserver/control/CommandVbdCreatePhysical.java index 2046525529..15b39eab05 100644 --- a/tools/control/src/org/xenoserver/control/CommandVbdCreatePhysical.java +++ b/tools/control/src/org/xenoserver/control/CommandVbdCreatePhysical.java @@ -53,13 +53,13 @@ public class CommandVbdCreatePhysical extends Command { String command = vd.dumpForXen(vbd); try { - FileWriter fw = new FileWriter("/proc/xeno/dom0/vhd"); + FileWriter fw = new FileWriter("/proc/xeno/vhd"); fw.write(command); fw.flush(); fw.close(); } catch (IOException e) { throw new CommandFailedException( - "Could not write VBD details to /proc/xeno/dom0/vhd", + "Could not write VBD details to /proc/xeno/vhd", e); } diff --git a/tools/control/src/org/xenoserver/control/CommandVbdList.java b/tools/control/src/org/xenoserver/control/CommandVbdList.java index e525ee485f..16fd1953c6 100644 --- a/tools/control/src/org/xenoserver/control/CommandVbdList.java +++ b/tools/control/src/org/xenoserver/control/CommandVbdList.java @@ -16,7 +16,7 @@ public class CommandVbdList extends Command { String line; try { - in = new BufferedReader(new FileReader("/proc/xeno/dom0/vhd")); + in = new BufferedReader(new FileReader("/proc/xeno/vhd")); line = in.readLine(); while (line != null) { int domain = -1; diff --git a/tools/internal/Makefile b/tools/internal/Makefile index c39dcf621b..e1b026b199 100644 --- a/tools/internal/Makefile +++ b/tools/internal/Makefile @@ -1,55 +1,27 @@ -CC = gcc -CFLAGS = -Wall -I../../xen/include -I../../xenolinux-2.4.21-sparse/include -XI_CREATE = xi_create -XI_START = xi_start -XI_STOP = xi_stop -XI_DESTROY = xi_destroy -XI_BUILD = xi_build -XI_PHYS_GRANT = xi_phys_grant -XI_PHYS_REVOKE = xi_phys_revoke -XI_PHYS_PROBE = xi_phys_probe - -all: $(XI_CREATE).o $(XI_START).o $(XI_STOP).o $(XI_DESTROY).o $(XI_BUILD).o \ - $(XI_PHYS_GRANT).o $(XI_PHYS_REVOKE).o $(XI_PHYS_PROBE).o - $(CC) -o $(XI_CREATE) $(XI_CREATE).o - $(CC) -o $(XI_BUILD) $(XI_BUILD).o - $(CC) -o $(XI_START) $(XI_START).o - $(CC) -o $(XI_STOP) $(XI_STOP).o - $(CC) -o $(XI_DESTROY) $(XI_DESTROY).o - $(CC) -o $(XI_PHYS_GRANT) $(XI_PHYS_GRANT).o - $(CC) -o $(XI_PHYS_REVOKE) $(XI_PHYS_REVOKE).o - $(CC) -o $(XI_PHYS_PROBE) $(XI_PHYS_PROBE).o - -$(XI_CREATE).o: $(XI_CREATE).c dom0_defs.h dom0_ops.h mem_defs.h - $(CC) $(CFLAGS) -c $(XI_CREATE).c - -internal_domain_build.o: internal_domain_build.c dom0_defs.h dom0_ops.h mem_defs.h - $(CC) $(CFLAGS) -c internal_domain_build.c - -$(XI_START).o: $(XI_START).c dom0_defs.h dom0_ops.h mem_defs.h - $(CC) $(CFLAGS) -c $(XI_START).c - -$(XI_STOP).o: $(XI_STOP).c dom0_defs.h dom0_ops.h mem_defs.h - $(CC) $(CFLAGS) -c $(XI_STOP).c - -$(XI_DESTROY).o: $(XI_DESTROY).c dom0_ops.h dom0_defs.h - $(CC) $(CFLAGS) -c $(XI_DESTROY).c - -$(XI_PHYS_GRANT).o: $(XI_PHYS_GRANT).c - $(CC) $(CFLAGS) -c $(XI_PHYS_GRANT).c - -$(XI_PHYS_REVOKE).o: $(XI_PHYS_REVOKE).c - $(CC) $(CFLAGS) -c $(XI_PHYS_REVOKE).c - -$(XI_PHYS_PROBE).o: $(XI_PHYS_PROBE).c - $(CC) $(CFLAGS) -c $(XI_PHYS_PROBE).c + +CC = gcc +CFLAGS = -Wall -O3 +CFLAGS += -I../../xen/include -I../../xenolinux-2.4.21-sparse/include + +HDRS = $(wildcard *.h) +SRCS = $(wildcard *.c) +OBJS = $(patsubst %.c,%.o,$(SRCS)) + +TARGETS = xi_create xi_start xi_stop xi_destroy xi_build +TARGETS += xi_phys_grant xi_phys_revoke xi_phys_probe xi_list +TARGETS += xi_sched_global xi_sched_domain xi_usage +INSTALL = $(TARGETS) xi_vifinit xi_helper + +all: $(TARGETS) install: all - cp -a xi_list xi_vifinit xi_helper $(XI_CREATE) $(XI_BUILD) $(XI_START) $(XI_STOP) $(XI_DESTROY) $(XI_PHYSDEV_GRANT) $(XI_PHYS_REVOKE) $(XI_PHYS_PROBE).o../../../install/bin - chmod 755 ../../../install/bin/xi_list + cp -a $(INSTALL) ../../../install/bin chmod 755 ../../../install/bin/xi_vifinit chmod 755 ../../../install/bin/xi_helper +clean: + $(RM) *.o *.rpm $(TARGETS) + rpm: all rm -rf staging mkdir staging @@ -58,6 +30,6 @@ rpm: all mv staging/i386/*.rpm . rm -rf staging -clean: - $(RM) *.o *.rpm $(XI_CREATE) $(XI_START) $(XI_STOP) $(XI_DESTROY) $(XI_BUILD) $(XI_PHYS_GRANT) $(XI_PHYS_REVOKE) $(XI_PHYS_PROBE) +%: %.c $(HDRS) Makefile + $(CC) $(CFLAGS) -o $@ $< diff --git a/tools/internal/dom0_defs.h b/tools/internal/dom0_defs.h index e79d85d417..9ef8d0645d 100644 --- a/tools/internal/dom0_defs.h +++ b/tools/internal/dom0_defs.h @@ -1,9 +1,121 @@ -#define PROC_XENO_ROOT "xeno" -#define PROC_CMD "dom0_cmd" -#define PROC_DOM_PREFIX "dom" -#define PROC_DOM_MEM "mem" -#define PROC_DOM_DATA "new_dom_data" -#define PROC_DOMAINS "domains" -#define MAX_PATH 256 +#ifndef __DOM0_DEFS_H__ +#define __DOM0_DEFS_H__ +#include <unistd.h> +#include <stdio.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <string.h> + +#include <asm/types.h> + +#include "mem_defs.h" +#include <asm-xeno/proc_cmd.h> +#include <hypervisor-ifs/hypervisor-if.h> +#include <hypervisor-ifs/dom0_ops.h> + +#define ERROR(_m) \ + fprintf(stderr, "ERROR: %s\n", (_m)) + +#define PERROR(_m) \ + fprintf(stderr, "ERROR: %s (%d = %s)\n", (_m), errno, strerror(errno)) + +static inline int do_privcmd(unsigned int cmd, unsigned long data) +{ + int fd; + + if ( (fd = open("/proc/xeno/privcmd", O_RDWR)) < 0 ) + { + PERROR("Could not open proc interface"); + return -1; + } + + if ( ioctl(fd, cmd, data) < 0 ) + { +#ifndef SILENT_ERRORS_FROM_XEN + PERROR("Error when executing privileged control ioctl"); +#endif + close(fd); + return -1; + } + + close(fd); + return 0; +} + +static inline int xldev_to_physdev(int xldev) +{ + return do_privcmd(IOCTL_PRIVCMD_LINDEV_TO_XENDEV, + (unsigned long)xldev); +} + +static inline int physdev_to_xldev(int physdev) +{ + return do_privcmd(IOCTL_PRIVCMD_XENDEV_TO_LINDEV, + (unsigned long)physdev); +} + +static inline int do_xen_blkmsg(privcmd_blkmsg_t *blkmsg) +{ + return do_privcmd(IOCTL_PRIVCMD_BLKMSG, (unsigned long)blkmsg); +} + +static inline int do_xen_hypercall(privcmd_hypercall_t *hypercall) +{ + return do_privcmd(IOCTL_PRIVCMD_HYPERCALL, (unsigned long)hypercall); +} + +static inline int do_dom0_op(dom0_op_t *op) +{ + int ret = -1; + privcmd_hypercall_t hypercall; + + hypercall.op = __HYPERVISOR_dom0_op; + hypercall.arg[0] = (unsigned long)op; + + if ( mlock(op, sizeof(*op)) != 0 ) + { + PERROR("Could not lock memory for Xen hypercall"); + goto out1; + } + + if ( do_xen_hypercall(&hypercall) < 0 ) + goto out2; + + ret = 0; + + out2: (void)munlock(op, sizeof(*op)); + out1: return ret; +} + +static inline int do_network_op(network_op_t *op) +{ + int ret = -1; + privcmd_hypercall_t hypercall; + + hypercall.op = __HYPERVISOR_network_op; + hypercall.arg[0] = (unsigned long)op; + + if ( mlock(op, sizeof(*op)) != 0 ) + { + PERROR("Could not lock memory for Xen hypercall"); + goto out1; + } + + if ( do_xen_hypercall(&hypercall) < 0 ) + goto out2; + + ret = 0; + + out2: (void)munlock(op, sizeof(*op)); + out1: return ret; +} + +#endif /* __DOM0_DEFS_H__ */ diff --git a/tools/internal/dom0_ops.h b/tools/internal/dom0_ops.h deleted file mode 100644 index 0764f8302b..0000000000 --- a/tools/internal/dom0_ops.h +++ /dev/null @@ -1,5 +0,0 @@ - -#define NO_DOM0_OP_T -#include "../../xen/include/hypervisor-ifs/dom0_ops.h" -#undef NO_DOM0_OP_T -#include "../../xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_ops.h" diff --git a/tools/internal/mem_defs.h b/tools/internal/mem_defs.h index 4ba84ffaee..4361d6766c 100644 --- a/tools/internal/mem_defs.h +++ b/tools/internal/mem_defs.h @@ -1,24 +1,16 @@ -/* - * memory related definitions needed for userspace domain builder dom0 application. these _need_ to - * be kept in sync with the kernel .h files they were copied over from or something horrible will - * happen. remmember: god kills a kitten every time you forget to keep these in sync. - * - * KAF: Boris, these constants are all fixed by x86 hardware. So the kittens are safe for now :-) - * - * Copyright 2002 by B Dragovic - */ -/* copied over from hypervisor: include/asm-i386/page.h */ +#ifndef __MEM_DEFS_H__ +#define __MEM_DEFS_H__ #define _PAGE_PRESENT 0x001 -#define _PAGE_RW 0x002 -#define _PAGE_USER 0x004 -#define _PAGE_PWT 0x008 -#define _PAGE_PCD 0x010 +#define _PAGE_RW 0x002 +#define _PAGE_USER 0x004 +#define _PAGE_PWT 0x008 +#define _PAGE_PCD 0x010 #define _PAGE_ACCESSED 0x020 -#define _PAGE_DIRTY 0x040 +#define _PAGE_DIRTY 0x040 #define _PAGE_PAT 0x080 -#define _PAGE_PSE 0x080 +#define _PAGE_PSE 0x080 #define _PAGE_GLOBAL 0x100 @@ -40,6 +32,4 @@ typedef struct { unsigned long l2_lo; } l2_pgentry_t; #define l2_table_offset(_a) \ ((_a) >> L2_PAGETABLE_SHIFT) -/* local definitions */ - -#define nr_2_page(x) ((x) << PAGE_SHIFT) +#endif /* __MEM_DEFS_H__ */ diff --git a/tools/internal/xi_build.c b/tools/internal/xi_build.c index 805ab22a2a..991666436f 100644 --- a/tools/internal/xi_build.c +++ b/tools/internal/xi_build.c @@ -1,131 +1,95 @@ -/* - * XenoDomainBuilder, copyright (c) Boris Dragovic, bd240@cl.cam.ac.uk - * This code is released under terms and conditions of GNU GPL :). - * Usage: <executable> <mem_kb> <os image> <num_vifs> - */ - -#include <unistd.h> -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <string.h> -#include <stdlib.h> - -#include "asm-xeno/dom0.h" -#include "hypervisor-ifs/hypervisor-if.h" -#include "dom0_ops.h" + +#include "hypervisor-ifs/dom0_ops.h" #include "dom0_defs.h" #include "mem_defs.h" -#define PERR_STRING "Xeno Domain Builder" - #define GUEST_SIG "XenoGues" #define SIG_LEN 8 -/* Watch for precedence when using thses ones... */ -#define PROC_XENO_DOM0_CMD "/proc/" PROC_XENO_ROOT "/" PROC_CMD -#define PROC_XENO_DOMAINS "/proc" PROC_XENO_ROOT "/" PROC_DOMAINS - -/* - * NB. No ring-3 access in initial guestOS pagetables. Note that we allow - * ring-3 privileges in the page directories, so that the guestOS may later - * decide to share a 4MB region with applications. - */ #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) -/* standardized error reporting function */ -static void dberr(char *msg) +static long get_tot_pages(int domain_id) { - printf("%s: %s\n", PERR_STRING, msg); + dom0_op_t op; + op.cmd = DOM0_GETDOMAININFO; + op.u.getdominfo.domain = domain_id; + return (do_dom0_op(&op) < 0) ? -1 : op.u.getdominfo.tot_pages; } -/* status reporting function */ -static void dbstatus(char * msg) +static int get_pfn_list( + int domain_id, unsigned long *pfn_buf, unsigned long max_pfns) { - printf("Domain Builder: %s\n", msg); -} - + dom0_op_t op; + int ret; + op.cmd = DOM0_GETMEMLIST; + op.u.getmemlist.domain = domain_id; + op.u.getmemlist.max_pfns = max_pfns; + op.u.getmemlist.buffer = pfn_buf; + + if ( mlock(pfn_buf, max_pfns * sizeof(unsigned long)) != 0 ) + { + PERROR("Could not lock pfn list buffer"); + return -1; + } -/* clean up domain's memory allocations */ -static void dom_mem_cleanup(dom_mem_t * dom_mem) -{ - int fd; - struct dom0_unmapdommem_args argbuf; - - fd = open("/proc/xeno/dom0_cmd", O_WRONLY); - if(fd < 0){ - perror("openning /proc/xeno/dom0_cmd"); - return; - } - - argbuf.vaddr = dom_mem->vaddr; - argbuf.start_pfn = dom_mem->start_pfn; - argbuf.tot_pages = dom_mem->tot_pages; + ret = do_dom0_op(&op); - if (ioctl(fd, IOCTL_DOM0_UNMAPDOMMEM, &argbuf) < 0) { - dbstatus("Error unmapping domain's memory.\n"); - } + (void)munlock(pfn_buf, max_pfns * sizeof(unsigned long)); - close(fd); + return (ret < 0) ? -1 : op.u.getmemlist.num_pfns; } -static int map_dom_mem(unsigned long pfn, int pages, int dom, - dom_mem_t * dom_mem) +static int send_pgupdates(page_update_request_t *updates, int nr_updates) { - struct dom0_mapdommem_args argbuf; - int fd; - - argbuf.domain = dom; - argbuf.start_pfn = pfn; - argbuf.tot_pages = pages; - - fd = open("/proc/xeno/dom0_cmd", O_RDWR); - if (fd < 0) { - perror("openning /proc/xeno/dom0_cmd"); - return -1; - } - - dom_mem->domain = dom; - dom_mem->start_pfn = pfn; - dom_mem->tot_pages = pages; - dom_mem->vaddr = ioctl(fd, IOCTL_DOM0_MAPDOMMEM, &argbuf); - - if (dom_mem->vaddr == -1) { - perror("mapping domain memory"); - close(fd); - return -1; + int ret = -1; + privcmd_hypercall_t hypercall; + + hypercall.op = __HYPERVISOR_pt_update; + hypercall.arg[0] = (unsigned long)updates; + hypercall.arg[1] = (unsigned long)nr_updates; + + if ( mlock(updates, nr_updates * sizeof(*updates)) != 0 ) + { + PERROR("Could not lock pagetable update array"); + goto out1; } - close(fd); - return 0; + if ( do_xen_hypercall(&hypercall) < 0 ) + goto out2; + + ret = 0; + + out2: (void)munlock(updates, nr_updates * sizeof(*updates)); + out1: return ret; } -/* read the kernel header, extracting the image size and load address. */ +/* Read the kernel header, extracting the image size and load address. */ static int read_kernel_header(int fd, long dom_size, unsigned long * load_addr, size_t * ksize) { char signature[8]; - char status[MAX_PATH]; + char status[1024]; struct stat stat; - if(fstat(fd, &stat) < 0){ - perror(PERR_STRING); + if ( fstat(fd, &stat) < 0 ) + { + PERROR("Cannot stat the kernel image"); return -1; } - if(stat.st_size > (dom_size << 10)){ + if ( (stat.st_size * 2) > (dom_size << 10) ) + { sprintf(status, "Kernel image size %ld larger than requested " "domain size %ld\n Terminated.\n", stat.st_size, dom_size); - dberr(status); + ERROR(status); return -1; } read(fd, signature, SIG_LEN); - if(strncmp(signature, GUEST_SIG, SIG_LEN)){ - dberr("Kernel image does not contain required signature. " + if ( strncmp(signature, GUEST_SIG, SIG_LEN) ) + { + ERROR("Kernel image does not contain required signature. " "Terminating.\n"); return -1; } @@ -137,62 +101,165 @@ static int read_kernel_header(int fd, long dom_size, return 0; } -/* this is the main guestos setup function, - * returnes domain descriptor structure to be used when launching - * the domain by hypervisor to do some last minute initialization. - * page table initialization is done by making a list of page table - * requests that are handeled by the hypervisor in the ordinary - * manner. this way, many potentially messy things are avoided... - */ -#define PAGE_TO_VADDR(_pfn) ((void *)(dom_mem->vaddr + ((_pfn) * PAGE_SIZE))) -static dom_meminfo_t *setup_guestos(int dom, int kernel_fd, int initrd_fd, - unsigned long virt_load_addr, size_t ksize, dom_mem_t *dom_mem) +static int devmem_fd; + +static int init_pfn_mapper(void) +{ + if ( (devmem_fd = open("/dev/mem", O_RDWR)) < 0 ) + { + PERROR("Could not open /dev/mem"); + return -1; + } + return 0; +} + +static void *map_pfn(unsigned long pfn) +{ + void *vaddr = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE, + MAP_SHARED, devmem_fd, pfn << PAGE_SHIFT); + if ( vaddr == MAP_FAILED ) + { + PERROR("Could not mmap a domain pfn using /dev/mem"); + return NULL; + } + return vaddr; +} + +static void unmap_pfn(void *vaddr) +{ + (void)munmap(vaddr, PAGE_SIZE); +} + +static int clear_domain_page(unsigned long pfn) +{ + void *vaddr = map_pfn(pfn); + if ( vaddr == NULL ) + return -1; + memset(vaddr, 0, PAGE_SIZE); + unmap_pfn(vaddr); + return 0; +} + +static int copy_to_domain_page(unsigned long dst_pfn, void *src_page) +{ + void *vaddr = map_pfn(dst_pfn); + if ( vaddr == NULL ) + return -1; + memcpy(vaddr, src_page, PAGE_SIZE); + unmap_pfn(vaddr); + return 0; +} + +static int setup_guestos( + int dom, int kernel_fd, int initrd_fd, unsigned long tot_pages, + unsigned long virt_load_addr, size_t ksize, dom_meminfo_t *meminfo) { - dom_meminfo_t *meminfo = NULL; unsigned long *page_array = NULL; - page_update_request_t *pgt_updates = NULL; + page_update_request_t *pgt_update_arr = NULL, *pgt_updates = NULL; int alloc_index, num_pt_pages; unsigned long l2tab; unsigned long l1tab = 0; unsigned long num_pgt_updates = 0; - unsigned long count, pt_start; - struct dom0_dopgupdates_args pgupdate_req; - int cmd_fd; - int result; - - meminfo = (dom_meminfo_t *)malloc(sizeof(dom_meminfo_t)); - page_array = malloc(dom_mem->tot_pages * 4); - if (!meminfo || !page_array) { - dberr ("Could not allocate memory"); + unsigned long count, pt_start, i, j; + + memset(meminfo, 0, sizeof(*meminfo)); + + if ( init_pfn_mapper() < 0 ) + goto error_out; + + pgt_updates = malloc((tot_pages + 1024) * 3 + * sizeof(page_update_request_t)); + page_array = malloc(tot_pages * sizeof(unsigned long)); + pgt_update_arr = pgt_updates; + if ( (pgt_update_arr == NULL) || (page_array == NULL) ) + { + PERROR("Could not allocate memory"); goto error_out; } - pgt_updates = (page_update_request_t *)dom_mem->vaddr; - alloc_index = dom_mem->tot_pages - 1; - memset(meminfo, 0, sizeof(*meminfo)); + if ( get_pfn_list(dom, page_array, tot_pages) != tot_pages ) + { + PERROR("Could not get the page frame list"); + goto error_out; + } + + /* Load the guest OS image. */ + for ( i = 0; i < ksize; i += PAGE_SIZE ) + { + char page[PAGE_SIZE]; + int size = ((ksize-i) < PAGE_SIZE) ? (ksize-i) : PAGE_SIZE; + if ( read(kernel_fd, page, size) != size ) + { + PERROR("Error reading kernel image, could not" + " read the whole image."); + goto error_out; + } + copy_to_domain_page(page_array[i>>PAGE_SHIFT], page); + } + + /* Load the initial ramdisk image. */ + if ( initrd_fd >= 0 ) + { + struct stat stat; + unsigned long isize; + + if ( fstat(initrd_fd, &stat) < 0 ) + { + PERROR("Could not stat the initrd image"); + goto error_out; + } + isize = stat.st_size; + if ( ((isize + ksize) * 2) > (tot_pages << PAGE_SHIFT) ) + { + ERROR("Kernel + initrd too big to safely fit in domain memory"); + goto error_out; + } - memcpy(page_array, (void *)dom_mem->vaddr, dom_mem->tot_pages * 4); + meminfo->virt_mod_addr = virt_load_addr + i; + meminfo->virt_mod_len = isize; - /* Count bottom-level PTs, rounding up. Include one PTE for shared info. */ + for ( j = 0; j < isize; j += PAGE_SIZE, i += PAGE_SIZE ) + { + char page[PAGE_SIZE]; + int size = ((isize-j) < PAGE_SIZE) ? (isize-j) : PAGE_SIZE; + if ( read(initrd_fd, page, size) != size ) + { + PERROR("Error reading initrd image, could not" + " read the whole image."); + goto error_out; + } + copy_to_domain_page(page_array[i>>PAGE_SHIFT], page); + } + } + + alloc_index = tot_pages - 1; + + /* + * Count bottom-level PTs, rounding up. Include one PTE for shared info. We + * therefore add 1024 because 1 is for shared_info, 1023 is to round up. + */ num_pt_pages = - (l1_table_offset(virt_load_addr) + dom_mem->tot_pages + 1024) / 1024; + (l1_table_offset(virt_load_addr) + tot_pages + 1024) / 1024; /* We must also count the page directory. */ num_pt_pages++; /* Index of first PT page. */ - pt_start = dom_mem->tot_pages - num_pt_pages; + pt_start = tot_pages - num_pt_pages; - /* first allocate page for page dir. allocation goes backwards from the - * end of the allocated physical address space. + /* + * First allocate page for page dir. Allocation goes backwards from the end + * of the allocated physical address space. */ - l2tab = *(page_array + alloc_index) << PAGE_SHIFT; - memset(PAGE_TO_VADDR(alloc_index), 0, PAGE_SIZE); + l2tab = page_array[alloc_index] << PAGE_SHIFT; + if ( clear_domain_page(page_array[alloc_index]) < 0 ) + goto error_out; alloc_index--; meminfo->l2_pgt_addr = l2tab; - meminfo->virt_shinfo_addr = virt_load_addr + nr_2_page(dom_mem->tot_pages); + meminfo->virt_shinfo_addr = virt_load_addr + (tot_pages << PAGE_SHIFT); - /* pin down l2tab addr as page dir page - causes hypervisor to provide + /* + * Pin down l2tab addr as page dir page - causes hypervisor to provide * correct protection for the page */ pgt_updates->ptr = l2tab | PGREQ_EXTENDED_COMMAND; @@ -206,15 +273,16 @@ static dom_meminfo_t *setup_guestos(int dom, int kernel_fd, int initrd_fd, * Xen during final setup. */ l2tab += l2_table_offset(virt_load_addr) * sizeof(l2_pgentry_t); - for ( count = 0; count < (dom_mem->tot_pages + 1); count++ ) + for ( count = 0; count < (tot_pages + 1); count++ ) { if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) ) { - l1tab = *(page_array + alloc_index) << PAGE_SHIFT; - memset(PAGE_TO_VADDR(alloc_index), 0, PAGE_SIZE); + l1tab = page_array[alloc_index] << PAGE_SHIFT; + if ( clear_domain_page(page_array[alloc_index]) < 0 ) + goto error_out; alloc_index--; - l1tab += l1_table_offset(virt_load_addr + nr_2_page(count)) + l1tab += l1_table_offset(virt_load_addr + (count << PAGE_SHIFT)) * sizeof(l1_pgentry_t); /* make apropriate entry in the page directory */ @@ -226,12 +294,14 @@ static dom_meminfo_t *setup_guestos(int dom, int kernel_fd, int initrd_fd, } /* The last PTE we consider is filled in later by Xen. */ - if ( count == dom_mem->tot_pages ) break; + if ( count == tot_pages ) break; + printf("%lu: %08lx\n", count, page_array[count]); + if ( count < pt_start ) { pgt_updates->ptr = l1tab; - pgt_updates->val = (*(page_array + count) << PAGE_SHIFT) | L1_PROT; + pgt_updates->val = (page_array[count] << PAGE_SHIFT) | L1_PROT; pgt_updates++; num_pgt_updates++; l1tab += sizeof(l1_pgentry_t); @@ -240,195 +310,82 @@ static dom_meminfo_t *setup_guestos(int dom, int kernel_fd, int initrd_fd, { pgt_updates->ptr = l1tab; pgt_updates->val = - ((*(page_array + count) << PAGE_SHIFT) | L1_PROT) & ~_PAGE_RW; + ((page_array[count] << PAGE_SHIFT) | L1_PROT) & ~_PAGE_RW; pgt_updates++; num_pgt_updates++; l1tab += sizeof(l1_pgentry_t); } pgt_updates->ptr = - (*(page_array + count) << PAGE_SHIFT) | PGREQ_MPT_UPDATE; + (page_array[count] << PAGE_SHIFT) | PGREQ_MPT_UPDATE; pgt_updates->val = count; pgt_updates++; num_pgt_updates++; } - meminfo->virt_startinfo_addr = virt_load_addr + nr_2_page(alloc_index - 1); - meminfo->domain = dom; - - free(page_array); - - /* - * Send the page update requests down to the hypervisor. - * NB. We must do this before loading the guest OS image! - */ - if ( (cmd_fd = open(PROC_XENO_DOM0_CMD, O_WRONLY)) < 0 ) - { - dberr ("Could not open " PROC_XENO_DOM0_CMD); - goto error_out; - } - - pgupdate_req.pgt_update_arr = (unsigned long)dom_mem->vaddr; - pgupdate_req.num_pgt_updates = num_pgt_updates; - result = ioctl(cmd_fd, IOCTL_DOM0_DOPGUPDATES, &pgupdate_req); - close(cmd_fd); - if (result < 0) { - dberr ("Could not build domain page tables."); - goto error_out; - } - - /* Load the guest OS image. */ - if( read(kernel_fd, (char *)dom_mem->vaddr, ksize) != ksize ) - { - dberr("Error reading kernel image, could not" - " read the whole image."); - goto error_out; - } - - if( initrd_fd >= 0) - { - struct stat stat; - unsigned long isize; - - if(fstat(initrd_fd, &stat) < 0){ - perror(PERR_STRING); - goto error_out; - } - isize = stat.st_size; - - if( read(initrd_fd, ((char *)dom_mem->vaddr)+ksize, isize) != isize ) - { - dberr("Error reading initrd image, could not" - " read the whole image. Terminating."); - goto error_out; - } - - meminfo->virt_mod_addr = virt_load_addr + ksize; - meminfo->virt_mod_len = isize; + printf("XHDHFDHGFGHFGXXX\n"); + sleep(4); - } + meminfo->virt_startinfo_addr = + virt_load_addr + ((alloc_index-1)<<PAGE_SHIFT); + /* Send the page update requests down to the hypervisor. */ + if ( send_pgupdates(pgt_update_arr, num_pgt_updates) < 0 ) + goto error_out; - return meminfo; + free(page_array); + free(pgt_update_arr); + return 0; error_out: - if (meminfo) - free(meminfo); - if (page_array) + if ( page_array == NULL ) free(page_array); - - return NULL; + if ( pgt_update_arr == NULL ) + free(pgt_update_arr); + return -1; } -static int launch_domain(dom_meminfo_t * meminfo) -{ - dom0_op_t dop; - int cmd_fd; - - cmd_fd = open(PROC_XENO_DOM0_CMD, O_WRONLY); - if(cmd_fd < 0){ - perror(PERR_STRING); - return -1; - } - - dop.cmd = DOM0_BUILDDOMAIN; - memcpy(&dop.u.meminfo, meminfo, sizeof(dom_meminfo_t)); - write(cmd_fd, &dop, sizeof(dom0_op_t)); - close(cmd_fd); - - return 0; -} - -static int get_domain_info (int domain_id, - int *pg_head, - int *tot_pages) -{ - FILE *f; - char domains_line[256]; - int read_id; - - f = fopen (PROC_XENO_DOMAINS, "r"); - if (f == NULL) return -1; - - read_id = -1; - while (fgets (domains_line, 256, f) != 0) - { - int trans; - read_id = -1; - trans = sscanf (domains_line, "%d %*d %*d %*d %*d %*d %x %d %*s", &read_id - , pg_head, tot_pages); - if (trans != 3) { - dberr ("format of " PROC_XENO_DOMAINS " changed -- wrong kernel version?"); - read_id = -1; - break; - } - - if (read_id == domain_id) { - break; - } - } - - fclose (f); - - if (read_id == -1) { - errno = ESRCH; - } - - return 0; -} - - int main(int argc, char **argv) { - - dom_mem_t dom_os_image; - dom_meminfo_t * meminfo; + dom0_op_t launch_op; size_t ksize; unsigned long load_addr; + long tot_pages; int kernel_fd, initrd_fd = -1; int count; int cmd_len; int args_start = 4; char initrd_name[1024]; int domain_id; - int pg_head; - int tot_pages; int rc; - /**** this argument parsing code is really _gross_. rewrite me! ****/ - - if(argc < 4) { - dberr("Usage: dom_builder <domain_id> <image> <num_vifs> " - "[<initrd=initrd_name>] <boot_params>\n"); - return -1; + if ( argc < 4 ) + { + fprintf(stderr, "Usage: dom_builder <domain_id> <image> <num_vifs> " + "[<initrd=initrd_name>] <boot_params>\n"); + return 1; } - /* Look up information about the domain */ domain_id = atol(argv[1]); - if ( get_domain_info (domain_id, &pg_head, &tot_pages) != 0 ) + if ( (tot_pages = get_tot_pages(domain_id)) < 0 ) { - perror ("Could not find domain information"); - return -1; + PERROR("Could not find total pages for domain"); + return 1; } - + kernel_fd = open(argv[2], O_RDONLY); - if (kernel_fd < 0) { - perror ("Could not open kernel image"); - return -1; + if ( kernel_fd < 0 ) + { + PERROR("Could not open kernel image"); + return 1; } rc = read_kernel_header(kernel_fd, tot_pages << (PAGE_SHIFT - 10), &load_addr, &ksize); if ( rc < 0 ) - return -1; + return 1; - - /* map domain's memory */ - if ( map_dom_mem(pg_head, tot_pages, - domain_id, &dom_os_image) ) - return -1; - if( (argc > args_start) && (strncmp("initrd=", argv[args_start], 7) == 0) ) { @@ -438,41 +395,40 @@ int main(int argc, char **argv) args_start++; initrd_fd = open(initrd_name, O_RDONLY); - if(initrd_fd < 0){ - perror(PERR_STRING); - return -1; + if ( initrd_fd < 0 ) + { + PERROR("Could not open the initial ramdisk image"); + return 1; } } - /* the following code does the actual domain building */ - meminfo = setup_guestos(domain_id, kernel_fd, initrd_fd, load_addr, - ksize, &dom_os_image); - if (!meminfo) - return -1; + if ( setup_guestos(domain_id, kernel_fd, initrd_fd, tot_pages, + load_addr, ksize, &launch_op.u.meminfo) < 0 ) + return 1; - if (initrd_fd >= 0) + if ( initrd_fd >= 0 ) close(initrd_fd); close(kernel_fd); - /* and unmap the new domain's memory image since we no longer need it */ - dom_mem_cleanup(&dom_os_image); - - meminfo->virt_load_addr = load_addr; - meminfo->num_vifs = atoi(argv[3]); - meminfo->cmd_line[0] = '\0'; + launch_op.u.meminfo.domain = domain_id; + launch_op.u.meminfo.virt_load_addr = load_addr; + launch_op.u.meminfo.num_vifs = atoi(argv[3]); + launch_op.u.meminfo.cmd_line[0] = '\0'; cmd_len = 0; - for(count = args_start; count < argc; count++){ - if(cmd_len + strlen(argv[count]) > MAX_CMD_LEN - 1){ - dberr("Size of image boot params too big!\n"); + for ( count = args_start; count < argc; count++ ) + { + if ( cmd_len + strlen(argv[count]) > MAX_CMD_LEN - 1 ) + { + ERROR("Size of image boot params too big!\n"); break; } - strcat(meminfo->cmd_line, argv[count]); - strcat(meminfo->cmd_line, " "); + strcat(launch_op.u.meminfo.cmd_line, argv[count]); + strcat(launch_op.u.meminfo.cmd_line, " "); cmd_len += strlen(argv[count] + 1); } - /* and launch the domain */ - rc = launch_domain(meminfo); + launch_op.cmd = DOM0_BUILDDOMAIN; + rc = do_dom0_op(&launch_op); - return 0; + return (rc != 0) ? 1 : 0; } diff --git a/tools/internal/xi_create.c b/tools/internal/xi_create.c index ad893285e2..d003979731 100644 --- a/tools/internal/xi_create.c +++ b/tools/internal/xi_create.c @@ -4,90 +4,44 @@ * Usage: <executable> <mem_kb> <os image> <num_vifs> */ -#include <unistd.h> -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <stdlib.h> -#include <sys/ioctl.h> -#include <errno.h> -#include <string.h> - -#include "dom0_ops.h" +#include <hypervisor-ifs/dom0_ops.h> #include "dom0_defs.h" #include "mem_defs.h" -#include "asm-xeno/dom0.h" - -/***********************************************************************/ static char *argv0 = "internal_domain_create"; -static void ERROR (char *message) -{ - fprintf (stderr, "%s: %s\n", argv0, message); - exit (-1); -} - -static void PERROR (char *message) -{ - fprintf (stderr, "%s: %s (%s)\n", argv0, message, strerror(errno)); - exit (-1); -} - -/***********************************************************************/ - static int create_new_domain(long req_mem, char *name) { - char cmd_path[MAX_PATH]; - int cmd_fd; - int dom_id; - struct dom0_createdomain_args argbuf; + int err; + dom0_op_t op; - /* open the /proc command interface */ - sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD); - cmd_fd = open(cmd_path, O_RDWR); - if(cmd_fd < 0){ - PERROR ("Could not open PROC_CMD interface"); - return -1; - } + op.cmd = DOM0_CREATEDOMAIN; + op.u.newdomain.memory_kb = req_mem; + strncpy(op.u.newdomain.name, name, MAX_DOMAIN_NAME); + op.u.newdomain.name[MAX_DOMAIN_NAME-1] = '\0'; - argbuf.kb_mem = req_mem; - argbuf.name = name; - dom_id = ioctl(cmd_fd, IOCTL_DOM0_CREATEDOMAIN, &argbuf); - if (dom_id < 0) { - PERROR("creating new domain"); - } - close(cmd_fd); - return dom_id; -} + err = do_dom0_op(&op); -/***********************************************************************/ + return (err < 0) ? err : op.u.newdomain.domain; +} int main(int argc, char **argv) { - int dom_id; - - if (argv[0] != NULL) - { - argv0 = argv[0]; - } - - if(argc != 3) - { - fprintf (stderr, "Usage: %s <kbytes-mem> <domain-name>\n", argv0); - return -1; - } - - dom_id = create_new_domain(atol(argv[1]), argv[2]); - - if(dom_id < 0) + int dom_id; + + if ( argv[0] != NULL ) + argv0 = argv[0]; + + if ( argc != 3 ) { - return -1; + fprintf(stderr, "Usage: %s <kbytes-mem> <domain-name>\n", argv0); + return 1; } - - fprintf (stdout, "%d\n", dom_id); - return 0; + + dom_id = create_new_domain(atol(argv[1]), argv[2]); + if ( dom_id < 0 ) + return 1; + + printf("%d\n", dom_id); + return 0; } diff --git a/tools/internal/xi_destroy.c b/tools/internal/xi_destroy.c index bffe1d350d..d6b7a09763 100644 --- a/tools/internal/xi_destroy.c +++ b/tools/internal/xi_destroy.c @@ -1,81 +1,43 @@ -/* - * A very(!) simple program to kill a domain. (c) Boris Dragovic - * Usage: <executable> <mem_kb> <os image> <num_vifs> - */ -#include <unistd.h> -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include "dom0_ops.h" +#include "hypervisor-ifs/dom0_ops.h" #include "dom0_defs.h" - -/***********************************************************************/ +#include "mem_defs.h" static char *argv0 = "internal_domain_stop"; -static void ERROR (char *message) -{ - fprintf (stderr, "%s: %s\n", argv0, message); - exit (-1); -} - -static void PERROR (char *message) -{ - fprintf (stderr, "%s: %s (%s)\n", argv0, message, strerror(errno)); - exit (-1); -} - -/***********************************************************************/ - -static int do_kill_domain(int dom_id, int force) +static int kill_domain(int dom_id, int force) { - char cmd_path[MAX_PATH]; - dom0_op_t dop; - int cmd_fd; + int err; + dom0_op_t op; - dop.cmd = DOM0_DESTROYDOMAIN; - dop.u.killdomain.domain = dom_id; - dop.u.killdomain.force = force; + op.cmd = DOM0_DESTROYDOMAIN; + op.u.killdomain.domain = dom_id; + op.u.killdomain.force = force; - /* open the /proc command interface */ - sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD); - cmd_fd = open(cmd_path, O_WRONLY); - if(cmd_fd < 0){ - PERROR ("Count not open PROC_CMD interface"); - } - - write(cmd_fd, &dop, sizeof(dom0_op_t)); - close(cmd_fd); + err = do_dom0_op(&op); - return 0; + return (err < 0) ? -1 : 0; } int main(int argc, char **argv) { - int ret; - - if (argv[0] != NULL) - { - argv0 = argv[0]; - } - - if ( (argc < 2) || (argc > 3) ) + int ret; + + if ( argv[0] != NULL ) + argv0 = argv[0]; + + if ( (argc < 2) || (argc > 3) ) { usage: fprintf(stderr, "Usage: %s [-f] <domain_id>\n", argv0); - fprintf(stderr, " -f: Forces immediate destruction of specified domain\n"); - ret = -1; - goto out; + fprintf(stderr, " -f: Forces immediate destruction of <domain_id>\n"); + return 1; } - - if ( (argc == 3) && strcmp("-f", argv[1]) ) goto usage; - - ret = do_kill_domain(atoi(argv[argc-1]), argc == 3); - -out: - return ret; + + if ( (argc == 3) && strcmp("-f", argv[1]) ) + goto usage; + + ret = kill_domain(atoi(argv[argc-1]), argc == 3); + + return (ret != 0) ? 1 : 0; } diff --git a/tools/internal/xi_list b/tools/internal/xi_list deleted file mode 100755 index e90901818d..0000000000 --- a/tools/internal/xi_list +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash -# -# xi_list -# -# This is a silly little script to dump the currently running domains. -# The output format is a series of space-separate fields for each domain: -# -# 1. Domain id -# 2. Processor -# 3. Has CPU (1 => true, 0 => false) -# 4. State (integer) -# 5. State (RUNNING, INTERRUPTABLE, UNINTERRUPTABLE, WAIT, SUSPENDED, DYING) -# 6. MCU advance -# 7. Total pages -# 8. Name - -INPUT_FILE=/proc/xeno/domains - -awk -f - $INPUT_FILE <<EOF -{ - dom_id = \$1; - - processor = \$2; - - has_cpu = \$3; - - state = "UNKNOWN"; - - if (\$4 == 0) state = "RUNNING"; - if (\$4 == 1) state = "INTERRUPTIBLE"; - if (\$4 == 2) state = "UNINTERRUPTABLE"; - if (\$4 == 4) state = "WAIT"; - if (\$4 == 8) state = "SUSPENDED"; - if (\$4 == 16) state = "DYING"; - - mcu_advance = \$6; - - tot_pages = \$8; - - printf "%d %d %d %d %s %d %d %s", dom_id, processor, has_cpu, \$4, state, mcu_advance, tot_pages, \$9; - for (i = 10; i < NF; i ++) { - printf " %s", \$i; - } - printf "\n"; -} -EOF diff --git a/tools/internal/xi_list.c b/tools/internal/xi_list.c new file mode 100644 index 0000000000..ad6b5d3ccc --- /dev/null +++ b/tools/internal/xi_list.c @@ -0,0 +1,76 @@ +/****************************************************************************** + * xi_list.c + * + * This is a silly little program to dump the currently running domains. + * The output format is a series of space-separate fields for each domain: + * + * 1. Domain id + * 2. Processor + * 3. Has CPU (1 => true, 0 => false) + * 4. State (integer) + * 5. State (RUNNING, INTERRUPTIBLE, UNINTERRUPTIBLE, WAIT, SUSPENDED, DYING) + * 6. Pending events (hex value) + * 7. MCU advance + * 8. Total pages + * 9. Name + */ + +/* + * Xen indicates when we've read info on all domains by returning error ESRCH. + * We don't want the helper functiosn to interpret this as a real error! + */ +#define SILENT_ERRORS_FROM_XEN + +#include "hypervisor-ifs/dom0_ops.h" +#include "dom0_defs.h" +#include "mem_defs.h" + +static char *argv0 = "internal_domain_list"; + +static char *statestr(int state) +{ + switch ( state ) + { + case 0: return "RUNNING"; + case 1: return "INTERRUPTIBLE"; + case 2: return "UNINTERRUPTIBLE"; + case 4: return "WAIT"; + case 8: return "SUSPENDED"; + case 16: return "DYING"; + default: return "UNKNOWN"; + } + return NULL; +} + +int main(int argc, char **argv) +{ + dom0_op_t op; + + if ( argv[0] != NULL ) + argv0 = argv[0]; + + if ( argc != 1 ) + { + fprintf(stderr, "Usage: %s\n", argv0); + return 1; + } + + op.cmd = DOM0_GETDOMAININFO; + op.u.getdominfo.domain = 0; + while ( do_dom0_op(&op) >= 0 ) + { + printf("%8d %2d %1d %2d %s %08x %8ld %8d %s\n", + op.u.getdominfo.domain, + op.u.getdominfo.processor, + op.u.getdominfo.has_cpu, + op.u.getdominfo.state, + statestr(op.u.getdominfo.state), + op.u.getdominfo.hyp_events, + op.u.getdominfo.mcu_advance, + op.u.getdominfo.tot_pages, + op.u.getdominfo.name); + op.u.getdominfo.domain++; + } + + return 0; +} diff --git a/tools/internal/xi_phys_grant.c b/tools/internal/xi_phys_grant.c index 368414f4f5..05630e2429 100644 --- a/tools/internal/xi_phys_grant.c +++ b/tools/internal/xi_phys_grant.c @@ -1,50 +1,43 @@ -#define _GNU_SOURCE -#include <unistd.h> -#include <stdio.h> -#include <errno.h> -#include <sys/fcntl.h> -#include <string.h> -#include <stdlib.h> -#include "hypervisor-ifs/block.h" +#define _GNU_SOURCE +#include "dom0_defs.h" int main(int argc, char *argv[]) { - xp_disk_t buf; - int fd; - char *strbuf; + privcmd_blkmsg_t blkmsg; + xp_disk_t xpd; - if (argc != 7) { - fprintf(stderr, - "Usage: xi_physdev_grant <r/rw> <domain> <device> <start sector> <n_sectors> <partition>\n"); + if ( argc != 7 ) + { + fprintf(stderr, "Usage: xi_physdev_grant <r/rw> <domain> " + "<device> <start sector> <n_sectors> <partition>\n"); return 1; } - buf.mode = 0; - if (argv[1][0] == 'r') - buf.mode |= 1; - else if (argv[1][0] == 'w') - buf.mode |= 2; - if (argv[1][1] == 'r') - buf.mode |= 1; - else if (argv[1][1] == 'w') - buf.mode |= 2; - - buf.device = atol(argv[3]); - buf.start_sect = atol(argv[4]); - buf.n_sectors = atol(argv[5]); - buf.partition = atol(argv[6]); - - asprintf(&strbuf, "/proc/xeno/dom%s/phd", argv[2]); - fd = open(strbuf, O_WRONLY); - if (fd < 0) { - fprintf(stderr, "Can\'t open %s: %s.\n", strbuf, strerror(errno)); - return 1; + xpd.mode = 0; + if ( strchr(argv[1], 'r') ) + xpd.mode |= PHYSDISK_MODE_R; + if ( strchr(argv[1], 'w') ) + xpd.mode |= PHYSDISK_MODE_W; + + xpd.domain = atol(argv[2]); + xpd.device = xldev_to_physdev(atol(argv[3])); + xpd.start_sect = atol(argv[4]); + xpd.n_sectors = atol(argv[5]); + xpd.partition = atol(argv[6]); + + if ( xpd.device == 0 ) + { + ERROR("Unrecognised device"); + return 1; } - free(strbuf); - write(fd, &buf, sizeof(buf)); - close(fd); + blkmsg.op = XEN_BLOCK_PHYSDEV_GRANT; + blkmsg.buf = &xpd; + blkmsg.buf_size = sizeof(xpd); + + if ( do_xen_blkmsg(&blkmsg) < 0 ) + return 1; return 0; } diff --git a/tools/internal/xi_phys_probe.c b/tools/internal/xi_phys_probe.c index a3dfd8952b..a933e11276 100644 --- a/tools/internal/xi_phys_probe.c +++ b/tools/internal/xi_phys_probe.c @@ -1,50 +1,46 @@ -#define _GNU_SOURCE -#include <stdio.h> -#include <sys/fcntl.h> -#include <errno.h> -#include <unistd.h> -#include <string.h> -#include <stdlib.h> -#include "hypervisor-ifs/block.h" +#define _GNU_SOURCE +#include "dom0_defs.h" int main(int argc, char *argv[]) { + privcmd_blkmsg_t blkmsg; physdisk_probebuf_t buf; - int fd; - int x; - char *strbuf; + int i; - if (argc != 2) { + if ( argc != 2 ) + { fprintf(stderr, "Usage: xi_phys_probe <domain_nr>\n"); return 1; } - asprintf(&strbuf, "/proc/xeno/dom%s/phd", argv[1]); - fd = open(strbuf, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "Can\'t open %s: %s.\n", strbuf, strerror(errno)); - return 1; - } - free(strbuf); - memset(&buf, 0, sizeof(buf)); - buf.n_aces = PHYSDISK_MAX_ACES_PER_REQUEST; + do { - buf.n_aces = PHYSDISK_MAX_ACES_PER_REQUEST; - read(fd, &buf, sizeof(buf)); - if (!buf.n_aces) - break; - - for (x = 0; x < buf.n_aces; x++) { - char read = (buf.entries[x].mode & 1 ? 'r' : ' '); - char write = (buf.entries[x].mode & 2 ? 'w' : ' '); - printf("%x %x %lx %lx %c%c\n", buf.entries[x].device, - buf.entries[x].partition, - buf.entries[x].start_sect, - buf.entries[x].n_sectors, read, write); + buf.domain = atol(argv[1]); + buf.n_aces = PHYSDISK_MAX_ACES_PER_REQUEST; + + blkmsg.op = XEN_BLOCK_PHYSDEV_PROBE; + blkmsg.buf = &buf; + blkmsg.buf_size = sizeof(buf); + + if ( do_xen_blkmsg(&blkmsg) < 0 ) + return 1; + + for ( i = 0; i < buf.n_aces; i++ ) + { + char read = (buf.entries[i].mode & 1 ? 'r' : ' '); + char write = (buf.entries[i].mode & 2 ? 'w' : ' '); + printf("%x %x %lx %lx %c%c\n", + physdev_to_xldev(buf.entries[i].device), + buf.entries[i].partition, + buf.entries[i].start_sect, + buf.entries[i].n_sectors, read, write); } + buf.start_ind += buf.n_aces; - } while (buf.n_aces == PHYSDISK_MAX_ACES_PER_REQUEST); + } + while ( buf.n_aces == PHYSDISK_MAX_ACES_PER_REQUEST ); + return 0; } diff --git a/tools/internal/xi_phys_revoke.c b/tools/internal/xi_phys_revoke.c index c39146e889..b018b03a24 100644 --- a/tools/internal/xi_phys_revoke.c +++ b/tools/internal/xi_phys_revoke.c @@ -1,40 +1,37 @@ -#define _GNU_SOURCE -#include <unistd.h> -#include <errno.h> -#include <stdio.h> -#include <sys/fcntl.h> -#include <string.h> -#include <stdlib.h> -#include "hypervisor-ifs/block.h" +#define _GNU_SOURCE +#include "dom0_defs.h" int main(int argc, char *argv[]) { - xp_disk_t buf; - int fd; - char *strbuf; + privcmd_blkmsg_t blkmsg; + xp_disk_t xpd; - if (argc != 5) { - fprintf(stderr, - "Usage: xi_physdev_revoke <domain> <device> <start sector> <n_sectors>\n"); + if ( argc != 5 ) + { + fprintf(stderr, "Usage: xi_physdev_revoke <domain> " + "<device> <start sector> <n_sectors>\n"); return 1; } - buf.device = atol(argv[2]); - buf.mode = 0; - buf.start_sect = atol(argv[3]); - buf.n_sectors = atol(argv[4]); + xpd.mode = 0; + xpd.domain = atol(argv[1]); + xpd.device = xldev_to_physdev(atol(argv[2])); + xpd.start_sect = atol(argv[3]); + xpd.n_sectors = atol(argv[4]); - asprintf(&strbuf, "/proc/xeno/dom%s/phd", argv[1]); - fd = open(strbuf, O_WRONLY); - if (fd < 0) { - fprintf(stderr, "Can\'t open %s: %s.\n", strbuf, strerror(errno)); - return 1; + if ( xpd.device == 0 ) + { + ERROR("Unrecognised device"); + return 1; } - free(strbuf); - write(fd, &buf, sizeof(buf)); - close(fd); + blkmsg.op = XEN_BLOCK_PHYSDEV_GRANT; + blkmsg.buf = &xpd; + blkmsg.buf_size = sizeof(xpd); + + if ( do_xen_blkmsg(&blkmsg) < 0 ) + return 1; return 0; } diff --git a/tools/internal/xi_sched_domain.c b/tools/internal/xi_sched_domain.c new file mode 100644 index 0000000000..c8d921f890 --- /dev/null +++ b/tools/internal/xi_sched_domain.c @@ -0,0 +1,32 @@ + +#include "hypervisor-ifs/dom0_ops.h" +#include "dom0_defs.h" +#include "mem_defs.h" + +static char *argv0 = "internal_domain_sched_domain"; + +int main(int argc, char **argv) +{ + dom0_op_t op; + + if ( argv[0] != NULL ) + argv0 = argv[0]; + + if ( argc != 6 ) + { + fprintf(stderr, "Usage: %s <domain> <mcu_adv> " + "<warp> <warpl> <warpu>\n", argv0); + return 1; + } + + op.cmd = DOM0_ADJUSTDOM; + op.u.adjustdom.domain = atoi(argv[1]); + op.u.adjustdom.mcu_adv = atol(argv[1]); + op.u.adjustdom.warp = atol(argv[1]); + op.u.adjustdom.warpl = atol(argv[1]); + op.u.adjustdom.warpu = atol(argv[1]); + if ( do_dom0_op(&op) < 0 ) + return 1; + + return 0; +} diff --git a/tools/internal/xi_sched_global.c b/tools/internal/xi_sched_global.c new file mode 100644 index 0000000000..0c07455b9c --- /dev/null +++ b/tools/internal/xi_sched_global.c @@ -0,0 +1,27 @@ + +#include "hypervisor-ifs/dom0_ops.h" +#include "dom0_defs.h" +#include "mem_defs.h" + +static char *argv0 = "internal_domain_sched_global"; + +int main(int argc, char **argv) +{ + dom0_op_t op; + + if ( argv[0] != NULL ) + argv0 = argv[0]; + + if ( argc != 2 ) + { + fprintf(stderr, "Usage: %s <ctxt allowance>\n", argv0); + return 1; + } + + op.cmd = DOM0_BVTCTL; + op.u.bvtctl.ctx_allow = atol(argv[1]); + if ( do_dom0_op(&op) < 0 ) + return 1; + + return 0; +} diff --git a/tools/internal/xi_start.c b/tools/internal/xi_start.c index c6826c4874..b21cc84f9f 100644 --- a/tools/internal/xi_start.c +++ b/tools/internal/xi_start.c @@ -1,77 +1,37 @@ -#include <unistd.h> -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <stdlib.h> -#include <string.h> -#include "dom0_ops.h" +#include "hypervisor-ifs/dom0_ops.h" #include "dom0_defs.h" #include "mem_defs.h" -/***********************************************************************/ - static char *argv0 = "internal_domain_start"; -static void ERROR (char *message) -{ - fprintf (stderr, "%s: %s\n", argv0, message); - exit (-1); -} - -static void PERROR (char *message) -{ - fprintf (stderr, "%s: %s (%s)\n", argv0, message, strerror(errno)); - exit (-1); -} - -/***********************************************************************/ - static int start_domain(int id) { - char cmd_path[MAX_PATH]; - dom0_op_t dop; - int cmd_fd; - - /* Set up the DOM0_STARTDOMAIN command */ - dop.cmd = DOM0_STARTDOMAIN; - dop.u.meminfo.domain = id; + int err; + dom0_op_t op; - /* open the /proc command interface */ - sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD); - cmd_fd = open(cmd_path, O_WRONLY); - if(cmd_fd < 0){ - PERROR ("Count not open PROC_CMD interface"); - } + op.cmd = DOM0_STARTDOMAIN; + op.u.meminfo.domain = id; - /* Issue the command */ - write(cmd_fd, &dop, sizeof(dom0_op_t)); - close(cmd_fd); + err = do_dom0_op(&op); - return 0; + return (err < 0) ? -1 : 0; } -/***********************************************************************/ - int main(int argc, char **argv) { - int rc; + int rc; - if (argv[0] != NULL) - { - argv0 = argv[0]; - } + if ( argv[0] != NULL ) + argv0 = argv[0]; - if(argc != 2) + if ( argc != 2 ) { - fprintf (stderr, "Usage: %s <domain-id>\n", argv0); - return -1; + fprintf(stderr, "Usage: %s <domain-id>\n", argv0); + return 1; } - rc = start_domain(atol(argv[1])); + rc = start_domain(atol(argv[1])); - return rc; + return (rc != 0) ? 1 : 0; } diff --git a/tools/internal/xi_stop.c b/tools/internal/xi_stop.c index 6f2437ca14..5cd732df3a 100644 --- a/tools/internal/xi_stop.c +++ b/tools/internal/xi_stop.c @@ -1,79 +1,36 @@ -#include <unistd.h> -#include <stdio.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <stdlib.h> - -#include "dom0_ops.h" +#include "hypervisor-ifs/dom0_ops.h" #include "dom0_defs.h" #include "mem_defs.h" -/***********************************************************************/ - static char *argv0 = "internal_domain_stop"; -static void ERROR (char *message) -{ - fprintf (stderr, "%s: %s\n", argv0, message); - exit (-1); -} - -static void PERROR (char *message) -{ - fprintf (stderr, "%s: %s (%s)\n", argv0, message, strerror(errno)); - exit (-1); -} - -/***********************************************************************/ - static int stop_domain(int id) { - dom0_newdomain_t * dom_data; - char cmd_path[MAX_PATH]; - char dom_id_path[MAX_PATH]; - dom0_op_t dop; - int cmd_fd; - int id_fd; + int err; + dom0_op_t op; - /* Set up the DOM0_STOPDOMAIN command */ - dop.cmd = DOM0_STOPDOMAIN; - dop.u.meminfo.domain = id; - - /* open the /proc command interface */ - sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD); - cmd_fd = open(cmd_path, O_WRONLY); - if(cmd_fd < 0){ - PERROR ("Count not open PROC_CMD interface"); - } + op.cmd = DOM0_STOPDOMAIN; + op.u.meminfo.domain = id; - /* Issue the command */ - write(cmd_fd, &dop, sizeof(dom0_op_t)); - close(cmd_fd); + err = do_dom0_op(&op); - return 0; + return (err < 0) ? -1 : 0; } -/***********************************************************************/ - int main(int argc, char **argv) { - int rc; + int rc; - if (argv[0] != NULL) - { - argv0 = argv[0]; - } + if ( argv[0] != NULL ) + argv0 = argv[0]; - if(argc != 2) + if ( argc != 2 ) { - fprintf (stderr, "Usage: %s <domain-id>\n", argv0); - return -1; + fprintf(stderr, "Usage: %s <domain-id>\n", argv0); + return 1; } - rc = stop_domain(atol(argv[1])); + rc = stop_domain(atol(argv[1])); - return rc; + return (rc != 0) ? 1 : 0; } diff --git a/tools/internal/xi_usage.c b/tools/internal/xi_usage.c new file mode 100644 index 0000000000..3cd61431e5 --- /dev/null +++ b/tools/internal/xi_usage.c @@ -0,0 +1,64 @@ + +#include "hypervisor-ifs/dom0_ops.h" +#include "dom0_defs.h" +#include "mem_defs.h" + +static char *argv0 = "internal_domain_usage"; + +int main(int argc, char **argv) +{ + dom0_op_t op; + network_op_t netop; + int i, domain, vifs[32]; + + if ( argv[0] != NULL ) + argv0 = argv[0]; + + if ( argc != 2 ) + { + fprintf(stderr, "Usage: %s <domain-id>\n", argv0); + return 1; + } + + domain = atol(argv[1]); + + op.cmd = DOM0_GETDOMAININFO; + op.u.getdominfo.domain = domain; + if ( do_dom0_op(&op) < 0 ) + return 1; + + printf("cpu%d: %lld\n", + op.u.getdominfo.processor, + op.u.getdominfo.cpu_time); + + if ( mlock(vifs, sizeof(vifs)) != 0 ) + { + PERROR("Could not lock memory for network query buffer"); + return 1; + } + + netop.cmd = NETWORK_OP_VIFQUERY; + netop.u.vif_query.domain = domain; + netop.u.vif_query.buf = vifs; + if ( do_network_op(&netop) < 0 ) + return 1; + + for ( i = 1; i <= vifs[0]; i++ ) + { + netop.cmd = NETWORK_OP_VIFGETINFO; + netop.u.vif_getinfo.domain = domain; + netop.u.vif_getinfo.vif = vifs[i]; + if ( do_network_op(&netop) < 0 ) + return 1; + + printf("vif%d: sent %lld bytes (%lld packets) " + "received %lld bytes (%lld packets)\n", + vifs[i], + netop.u.vif_getinfo.total_bytes_sent, + netop.u.vif_getinfo.total_packets_sent, + netop.u.vif_getinfo.total_bytes_received, + netop.u.vif_getinfo.total_packets_received); + } + + return 0; +} diff --git a/tools/internal/xi_vifinit b/tools/internal/xi_vifinit index feac666bb6..0da845984b 100755 --- a/tools/internal/xi_vifinit +++ b/tools/internal/xi_vifinit @@ -16,10 +16,10 @@ then fi #outbound rule: -echo "ADD ACCEPT srcaddr=$3 srcaddrmask=255.255.255.255 srcdom=$1 srcidx=$2 dst=PHYS proto=any" > /proc/vfr +echo "ADD ACCEPT srcaddr=$3 srcaddrmask=255.255.255.255 srcdom=$1 srcidx=$2 dst=PHYS proto=any" > /proc/xeno/vfr #inbound rule: -echo "ADD ACCEPT dstaddr=$3 dstaddrmask=255.255.255.255 src=ANY dstdom=$1 dstidx=$2 proto=any" > /proc/vfr +echo "ADD ACCEPT dstaddr=$3 dstaddrmask=255.255.255.255 src=ANY dstdom=$1 dstidx=$2 proto=any" > /proc/xeno/vfr #----] done. |