From 238daefdd2c366f86e466f552c00cd92d40a31ef Mon Sep 17 00:00:00 2001 From: "smh22@boulderdash.cl.cam.ac.uk" Date: Fri, 14 Feb 2003 14:42:14 +0000 Subject: bitkeeper revision 1.33.1.1 (3e4d0046UBuDSsmiQzTssLuipi89Wg) put domain builder tools and scripts under bk (these are for running under domain 0) --- tools/domain_builder/Makefile | 17 ++ tools/domain_builder/README | 29 ++ tools/domain_builder/dom0_defs.h | 8 + tools/domain_builder/dom0_ops.h | 80 ++++++ tools/domain_builder/dom_builder.c | 485 +++++++++++++++++++++++++++++++++ tools/domain_builder/dom_kill.c | 55 ++++ tools/domain_builder/hypervisor_defs.h | 36 +++ tools/domain_builder/mem_defs.h | 45 +++ tools/domain_builder/newdom | 17 ++ tools/domain_builder/vifinit | 25 ++ 10 files changed, 797 insertions(+) create mode 100644 tools/domain_builder/Makefile create mode 100644 tools/domain_builder/README create mode 100644 tools/domain_builder/dom0_defs.h create mode 100644 tools/domain_builder/dom0_ops.h create mode 100644 tools/domain_builder/dom_builder.c create mode 100644 tools/domain_builder/dom_kill.c create mode 100644 tools/domain_builder/hypervisor_defs.h create mode 100644 tools/domain_builder/mem_defs.h create mode 100644 tools/domain_builder/newdom create mode 100644 tools/domain_builder/vifinit (limited to 'tools') diff --git a/tools/domain_builder/Makefile b/tools/domain_builder/Makefile new file mode 100644 index 0000000000..6707481f1b --- /dev/null +++ b/tools/domain_builder/Makefile @@ -0,0 +1,17 @@ +CC = gcc +BUILDER = domain_builder +KILL = kill_domain + +all: dom_builder.o dom_kill.o + $(CC) -o $(BUILDER) dom_builder.o + $(CC) -o $(KILL) dom_kill.o + +dom_builder.o: dom_builder.c dom0_defs.h dom0_ops.h hypervisor_defs.h mem_defs.h + $(CC) -c dom_builder.c + +dom_kill.o: dom_kill.c dom0_ops.h dom0_defs.h + $(CC) -c dom_kill.c + +clean: + $(RM) *.o domain_builder kill_domain + diff --git a/tools/domain_builder/README b/tools/domain_builder/README new file mode 100644 index 0000000000..7622eada5d --- /dev/null +++ b/tools/domain_builder/README @@ -0,0 +1,29 @@ +A couple of simple steps to get you going: + +1. do make (suitable Makefile is in the source dir) +2. copy over andy's vifinit script to local dir +3. copy over xenolinux guestos image (NB. image needs to be uncompressed, so +if the only image you have is image.gz do gunzip image.gz before doing +anything further) +4. add executable permissions to newdom and vifint +5. edit newdom script and change it as it suits you + +newdom script takes guestos image file name as first parameter and newdom id +as second parameter, eg.: + +./newdom xenolinux 1 + +should initiate building of dom1 with the image contained in file named +xenolinux in local dir. + +in general, domain_builder application takes three parameters: requested +memory in kb, guestos image file name and number of vifs to be created, eg. + +./domain_builder 16000 xenolinux 1 + +would build domX reserving 16MB mem, creating 1 vif and using os image stored +as xenolinux in local dir. + +happy booting! + +boris diff --git a/tools/domain_builder/dom0_defs.h b/tools/domain_builder/dom0_defs.h new file mode 100644 index 0000000000..bba020470f --- /dev/null +++ b/tools/domain_builder/dom0_defs.h @@ -0,0 +1,8 @@ +#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 MAX_PATH 256 + diff --git a/tools/domain_builder/dom0_ops.h b/tools/domain_builder/dom0_ops.h new file mode 100644 index 0000000000..d98ce1b1eb --- /dev/null +++ b/tools/domain_builder/dom0_ops.h @@ -0,0 +1,80 @@ +/****************************************************************************** + * dom0_ops.h + * + * Process command requests from domain-0 guest OS. + * + * Copyright (c) 2002, K A Fraser, B Dragovic + */ + +#define DOM0_NEWDOMAIN 0 +#define DOM0_KILLDOMAIN 1 +#define DOM0_GETMEMLIST 2 +#define DOM0_STARTDOM 4 +#define MAP_DOM_MEM 6 /* Not passed down to Xen */ +#define DO_PGUPDATES 7 /* Not passed down to Xen */ +#define MAX_CMD 8 + +#define MAX_CMD_LEN 256 + +typedef struct dom0_newdomain_st +{ + unsigned int domain; + unsigned int memory_kb; + unsigned int num_vifs; // temporary + unsigned long pg_head; // return parameter +} dom0_newdomain_t; + +typedef struct dom0_killdomain_st +{ + unsigned int domain; +} dom0_killdomain_t; + +typedef struct dom0_getmemlist_st +{ + unsigned long start_pfn; + unsigned long num_pfns; + void *buffer; +} dom0_getmemlist_t; + +/* This is entirely processed by XenoLinux */ +typedef struct dom_mem +{ + unsigned int domain; + unsigned long vaddr; + unsigned long start_pfn; + int tot_pages; +} dom_mem_t; + +/* This is entirely processed by XenoLinux */ +typedef struct dom_pgupdate +{ + unsigned long pgt_update_arr; + unsigned long num_pgt_updates; +} dom_pgupdate_t; + +typedef struct domain_launch +{ + unsigned int domain; + unsigned long l2_pgt_addr; + unsigned long virt_load_addr; + unsigned long virt_shinfo_addr; + unsigned long virt_startinfo_addr; + unsigned int num_vifs; + char cmd_line[MAX_CMD_LEN]; +} dom_meminfo_t; + +typedef struct dom0_op_st +{ + unsigned long cmd; + union + { + dom0_newdomain_t newdomain; + dom0_killdomain_t killdomain; + dom0_getmemlist_t getmemlist; + dom_mem_t dommem; + dom_pgupdate_t pgupdate; + dom_meminfo_t meminfo; + } + u; +} dom0_op_t; + diff --git a/tools/domain_builder/dom_builder.c b/tools/domain_builder/dom_builder.c new file mode 100644 index 0000000000..4e39068686 --- /dev/null +++ b/tools/domain_builder/dom_builder.c @@ -0,0 +1,485 @@ +/* + * XenoDomainBuilder, copyright (c) Boris Dragovic, bd240@cl.cam.ac.uk + * This code is released under terms and conditions of GNU GPL :). + * Usage: + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "hypervisor_defs.h" +#include "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 + +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED) +#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED|_PAGE_DIRTY) + +/* standardized error reporting function */ +static void dberr(char *msg) +{ + printf("%s: %s\n", PERR_STRING, msg); +} + +/* status reporting function */ +static void dbstatus(char * msg) +{ + printf("Domain Builder: %s\n", msg); +} + +/* clean up domain's memory allocations */ +static void dom_mem_cleanup(dom_mem_t * dom_mem) +{ + char mem_path[MAX_PATH]; + int mem_fd; + + /* open the domain's /proc mem interface */ + sprintf(mem_path, "%s%s%s%s%d%s%s", "/proc/", PROC_XENO_ROOT, "/", + PROC_DOM_PREFIX, dom_mem->domain, "/", PROC_DOM_MEM); + + mem_fd = open(mem_path, O_WRONLY); + if(mem_fd < 0){ + perror(PERR_STRING); + } + + if(write(mem_fd, (dom_mem_t *)dom_mem, sizeof(dom_mem_t)) < 0){ + dbstatus("Error unmapping domain's memory.\n"); + } + + close(mem_fd); +} + +/* ask dom0 to export domains memory through /proc */ +static int setup_dom_memmap(unsigned long pfn, int pages, int dom) +{ + char cmd_path[MAX_PATH]; + dom0_op_t dop; + int cmd_fd; + + dop.cmd = MAP_DOM_MEM; + dop.u.dommem.start_pfn = pfn; + dop.u.dommem.tot_pages = pages; + dop.u.dommem.domain = dom; + + /* 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(PERR_STRING); + return -1; + } + + write(cmd_fd, &dop, sizeof(dom0_op_t)); + close(cmd_fd); + + return 0; +} + +/* request the actual mapping from dom0 */ +static unsigned long get_vaddr(unsigned int dom) +{ + char mem_path[MAX_PATH]; + unsigned long addr; + int mem_fd; + + /* open the domain's /proc mem interface */ + sprintf(mem_path, "%s%s%s%s%d%s%s", "/proc/", PROC_XENO_ROOT, "/", + PROC_DOM_PREFIX, dom, "/", PROC_DOM_MEM); + + mem_fd = open(mem_path, O_RDONLY); + if(mem_fd < 0){ + perror(PERR_STRING); + return 0; + } + + /* get virtual address of mapped region */ + read(mem_fd, &addr, sizeof(addr)); + + close(mem_fd); + + return addr; +} + +static int map_dom_mem(unsigned long pfn, int pages, int dom, + dom_mem_t * dom_mem) +{ + + if(setup_dom_memmap(pfn, pages, dom)){ + perror(PERR_STRING); + return -1; + } + + dom_mem->domain = dom; + dom_mem->start_pfn = pfn; + dom_mem->tot_pages = pages; + if((dom_mem->vaddr = get_vaddr(dom)) == 0){ + dberr("Error mapping dom memory."); + return -1; + } + + return 0; +} + +/* create new domain */ +static dom0_newdomain_t * create_new_domain(long req_mem) +{ + 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; + + /* 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(PERR_STRING); + return 0; + } + + dop.cmd = DOM0_NEWDOMAIN; + dop.u.newdomain.memory_kb = req_mem; + + write(cmd_fd, &dop, sizeof(dom0_op_t)); + close(cmd_fd); + + sprintf(dom_id_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", + PROC_DOM_DATA); + while((id_fd = open(dom_id_path, O_RDONLY)) < 0){} + dom_data = (dom0_newdomain_t *)malloc(sizeof(dom0_newdomain_t)); + read(id_fd, dom_data, sizeof(dom0_newdomain_t)); + close(id_fd); + + sprintf(cmd_path, "Reserved %ld kbytes memory and assigned id %d to the" + "new domain.", req_mem, dom_data->domain); + dbstatus(cmd_path); + + return dom_data; +} + +/* open kernel image and do some sanity checks */ +static int do_kernel_chcks(char *image, long dom_size, + unsigned long * load_addr, size_t * ksize) +{ + char signature[8]; + char status[MAX_PATH]; + struct stat stat; + int fd; + int ret; + + fd = open(image, O_RDONLY); + if(fd < 0){ + perror(PERR_STRING); + ret = -1; + goto out; + } + + if(fstat(fd, &stat) < 0){ + perror(PERR_STRING); + ret = -1; + close(fd); + goto out; + } + + if(stat.st_size > (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); + ret = -1; + close(fd); + goto out; + } + *ksize = stat.st_size - SIG_LEN; + + read(fd, signature, SIG_LEN); + if(strncmp(signature, GUEST_SIG, SIG_LEN)){ + dberr("Kernel image does not contain required signature. " + "Terminating.\n"); + ret = -1; + close(fd); + goto out; + } + + read(fd, load_addr, sizeof(unsigned long)); + + sprintf(status, "Kernel image %s valid, kernel virtual load address %lx", + image, *load_addr); + dbstatus(status); + + ret = fd; + +out: + return ret; +} + +/* 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... + */ +static dom_meminfo_t * setup_guestos(int dom, int kernel_fd, + unsigned long virt_load_addr, size_t ksize, dom_mem_t *dom_mem) +{ + dom_meminfo_t * meminfo = (dom_meminfo_t *)malloc(sizeof(dom_meminfo_t)); + unsigned long * page_array = (unsigned long *)(dom_mem->vaddr); + page_update_request_t * pgt_updates = (page_update_request_t *) + (dom_mem->vaddr + ((ksize + (PAGE_SIZE-1)) & PAGE_MASK)); + dom_mem_t mem_map; + dom_meminfo_t * ret = NULL; + int alloc_index = dom_mem->tot_pages - 1, num_pt_pages; + unsigned long l2tab; + unsigned long l1tab = 0; + unsigned long num_pgt_updates = 0; + unsigned long pgt_update_arr = (unsigned long)pgt_updates; + unsigned long count, pt_start; + + /* Count bottom-level PTs. Round up to a whole PT. */ + num_pt_pages = + (l1_table_offset(virt_load_addr) + dom_mem->tot_pages + 1023) / 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; + + /* 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; + alloc_index--; + meminfo->l2_pgt_addr = l2tab; + meminfo->virt_shinfo_addr = virt_load_addr + nr_2_page(dom_mem->tot_pages); + count = ((unsigned long)pgt_updates - (unsigned long)(dom_mem->vaddr)) + >> PAGE_SHIFT; + + /* zero out l2 page */ + if(map_dom_mem(l2tab >> PAGE_SHIFT, 1, dom_mem->domain, &mem_map)){ + dberr("Unable to map l2 page into Domain Builder."); + goto out; + } + memset((void *)mem_map.vaddr, 0, PAGE_SIZE); + dom_mem_cleanup(&mem_map); + + /* pin down l2tab addr as page dir page - causes hypervisor to provide + * correct protection for the page + */ + pgt_updates->ptr = l2tab | PGREQ_EXTENDED_COMMAND; + pgt_updates->val = PGEXT_PIN_L2_TABLE; + pgt_updates++; + num_pgt_updates++; + + /* this loop initializes page tables and does one extra entry + * to be used by the shared info page. shared info is not in + * the domains physical address space and is not owned by the + * domain. + */ + l2tab += l2_table_offset(virt_load_addr) * sizeof(l2_pgentry_t); + for(count = 0; + count < dom_mem->tot_pages + 1; + count++){ + + if(!((unsigned long)l1tab & (PAGE_SIZE-1))){ + l1tab = *(page_array + alloc_index) << PAGE_SHIFT; + alloc_index--; + + /* zero out l1 page */ + if(map_dom_mem(l1tab >> PAGE_SHIFT, 1, dom_mem->domain, &mem_map)){ + dberr("Unable to map l1 page into Domain Builder."); + goto out; + } + memset((void *)mem_map.vaddr, 0, PAGE_SIZE); + dom_mem_cleanup(&mem_map); + + l1tab += l1_table_offset(virt_load_addr + nr_2_page(count)) + * sizeof(l1_pgentry_t); + + /* make apropriate entry in the page directory */ + pgt_updates->ptr = l2tab; + pgt_updates->val = l1tab | L2_PROT; + pgt_updates++; + num_pgt_updates++; + l2tab += sizeof(l2_pgentry_t); + } + + if ( count < pt_start ) + { + pgt_updates->ptr = l1tab; + pgt_updates->val = (*(page_array + count) << PAGE_SHIFT) | L1_PROT; + pgt_updates++; + num_pgt_updates++; + l1tab += sizeof(l1_pgentry_t); + } + else + { + pgt_updates->ptr = l1tab; + pgt_updates->val = + ((*(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; + 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; + + /* copy the guest os image */ + if(!(read(kernel_fd, (char *)dom_mem->vaddr, ksize) > 0)){ + dberr("Error reading kernel image, could not" + " read the whole image. Terminating.\n"); + goto out; + } + + { + dom0_op_t pgupdate_req; + char cmd_path[MAX_PATH]; + int cmd_fd; + + sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD); + if ( (cmd_fd = open(cmd_path, O_WRONLY)) < 0 ) goto out; + + pgupdate_req.cmd = DO_PGUPDATES; + pgupdate_req.u.pgupdate.pgt_update_arr = pgt_update_arr; + pgupdate_req.u.pgupdate.num_pgt_updates = num_pgt_updates; + + write(cmd_fd, &pgupdate_req, sizeof(dom0_op_t)); + close(cmd_fd); + } + + ret = meminfo; +out: + + return ret; +} + +static int launch_domain(dom_meminfo_t * meminfo) +{ + char cmd_path[MAX_PATH]; + dom0_op_t dop; + int cmd_fd; + + 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(PERR_STRING); + return -1; + } + + dop.cmd = DOM0_STARTDOM; + memcpy(&dop.u.meminfo, meminfo, sizeof(dom_meminfo_t)); + write(cmd_fd, &dop, sizeof(dom0_op_t)); + + dbstatus("Launched the new domain!"); + + close(cmd_fd); +} + +int main(int argc, char **argv) +{ + + dom0_newdomain_t * dom_data; + dom_mem_t dom_os_image; + dom_mem_t dom_pgt; + dom_meminfo_t * meminfo; + size_t ksize; + unsigned long load_addr; + char status[1024]; + int kernel_fd; + int count; + int cmd_len; + int ret = 0; + + unsigned long addr; + + if(argc < 4){ + dberr("Usage: dom_builder " + "\n"); + ret = -1; + goto out; + } + + /* create new domain and set up all the neccessary mappings */ + + kernel_fd = do_kernel_chcks(argv[2], atol(argv[1]), &load_addr, &ksize); + if(kernel_fd < 0){ + ret = -1; + goto out; + } + + /* request the creation of new domain */ + dom_data = create_new_domain(atol(argv[1])); + if(dom_data == 0){ + ret = -1; + goto out; + } + + /* map domain's memory */ + if(map_dom_mem(dom_data->pg_head, dom_data->memory_kb >> (PAGE_SHIFT - 10), + dom_data->domain, &dom_os_image)){ + ret = -1; + goto out; + } + + /* the following code does the actual domain building */ + meminfo = setup_guestos(dom_data->domain, kernel_fd, load_addr, ksize, + &dom_os_image); + if(meminfo == NULL){ + printf("Domain Builder: debug: meminfo NULL\n"); + ret = -1; + dom_mem_cleanup(&dom_os_image); + goto out; + } + + dom_mem_cleanup(&dom_os_image); + + meminfo->virt_load_addr = load_addr; + meminfo->num_vifs = atoi(argv[3]); + meminfo->cmd_line[0] = '\0'; + cmd_len = 0; + for(count = 4; count < argc; count++){ + if(cmd_len + strlen(argv[count]) > MAX_CMD_LEN - 1){ + dberr("Size of image boot params too big!\n"); + break; + } + strcat(meminfo->cmd_line, argv[count]); + strcat(meminfo->cmd_line, " "); + cmd_len += strlen(argv[count] + 1); + } + + sprintf(status, + "About to launch new domain %d with folowing parameters:\n" + " * page table base: %lx \n * load address: %lx \n" + " * shared info address: %lx \n * start info address: %lx \n" + " * number of vifs: %d \n * cmd line: %s \n", meminfo->domain, + meminfo->l2_pgt_addr, meminfo->virt_load_addr, + meminfo->virt_shinfo_addr, meminfo->virt_startinfo_addr, + meminfo->num_vifs, meminfo->cmd_line); + dbstatus(status); + + /* and launch the domain */ + if(launch_domain(meminfo) != 0) + ret = -1; + + free(meminfo); +out: + return ret; +} diff --git a/tools/domain_builder/dom_kill.c b/tools/domain_builder/dom_kill.c new file mode 100644 index 0000000000..2b8b0a5097 --- /dev/null +++ b/tools/domain_builder/dom_kill.c @@ -0,0 +1,55 @@ +/* + * A very(!) simple program to kill a domain. (c) Boris Dragovic + * Usage: + */ + +#include +#include +#include +#include +#include +#include + +#include "dom0_ops.h" +#include "dom0_defs.h" + +#define PERR_STRING "Xen Domain Killer" + +static int do_kill_domain(int dom_id) +{ + char cmd_path[MAX_PATH]; + dom0_op_t dop; + int cmd_fd; + + dop.cmd = DOM0_KILLDOMAIN; + dop.u.killdomain.domain = dom_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(PERR_STRING); + return -1; + } + + write(cmd_fd, &dop, sizeof(dom0_op_t)); + close(cmd_fd); + + return 0; +} + +int main(int argc, char **argv) +{ + int ret; + + if(argc < 2){ + printf("Usage: kill_domain \n"); + ret = -1; + goto out; + } + + ret = do_kill_domain(atoi(argv[1])); + +out: + return ret; +} diff --git a/tools/domain_builder/hypervisor_defs.h b/tools/domain_builder/hypervisor_defs.h new file mode 100644 index 0000000000..7d0aba03d7 --- /dev/null +++ b/tools/domain_builder/hypervisor_defs.h @@ -0,0 +1,36 @@ +/****************************************************************************** + * hypervisor_defs.h + * + * This needs to be kept in sync with Xen's pagetable update interface! + * + * Copyright (c) 2002-2003, Keir Fraser & Boris Dragovic + */ + +/* taken from include/hypervisor-ifs/hypervisor-if.h */ +typedef struct +{ +/* + * PGREQ_XXX: specified in least-significant bits of 'ptr' field. All requests + * specify relevent PTE or PT address in 'ptr'. Normal requests specify update + * value in 'value'. Extended requests specify command in least 8 bits of + * 'value'. + */ + unsigned long ptr, val; /* *ptr = val */ +} page_update_request_t; + +/* A normal page-table update request. */ +#define PGREQ_NORMAL 0 +#define PGREQ_MPT_UPDATE 1 +/* An extended command. */ +#define PGREQ_EXTENDED_COMMAND 2 +/* Announce a new top-level page table. */ +#define PGEXT_PIN_L1_TABLE 0 +#define PGEXT_PIN_L2_TABLE 1 +#define PGEXT_PIN_L3_TABLE 2 +#define PGEXT_PIN_L4_TABLE 3 +#define PGEXT_UNPIN_TABLE 4 +#define PGEXT_NEW_BASEPTR 5 +#define PGEXT_TLB_FLUSH 6 +#define PGEXT_INVLPG 7 +#define PGEXT_CMD_MASK 255 +#define PGEXT_CMD_SHIFT 8 diff --git a/tools/domain_builder/mem_defs.h b/tools/domain_builder/mem_defs.h new file mode 100644 index 0000000000..a9a1441d61 --- /dev/null +++ b/tools/domain_builder/mem_defs.h @@ -0,0 +1,45 @@ +/* + * 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 */ + +#define _PAGE_PRESENT 0x001 +#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_PAT 0x080 +#define _PAGE_PSE 0x080 +#define _PAGE_GLOBAL 0x100 + + +#define L1_PAGETABLE_SHIFT 12 +#define L2_PAGETABLE_SHIFT 22 + +#define ENTRIES_PER_L1_PAGETABLE 1024 +#define ENTRIES_PER_L2_PAGETABLE 1024 + +#define PAGE_SHIFT L1_PAGETABLE_SHIFT +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +typedef struct { unsigned long l1_lo; } l1_pgentry_t; +typedef struct { unsigned long l2_lo; } l2_pgentry_t; + +#define l1_table_offset(_a) \ + (((_a) >> L1_PAGETABLE_SHIFT) & (ENTRIES_PER_L1_PAGETABLE - 1)) +#define l2_table_offset(_a) \ + ((_a) >> L2_PAGETABLE_SHIFT) + +/* local definitions */ + +#define nr_2_page(x) (x << PAGE_SHIFT) diff --git a/tools/domain_builder/newdom b/tools/domain_builder/newdom new file mode 100644 index 0000000000..979661ec26 --- /dev/null +++ b/tools/domain_builder/newdom @@ -0,0 +1,17 @@ +#!/bin/sh + +VIFINIT=./vifinit +DOM_BUILDER=./domain_builder + +DOM=$2 + +ADDR=`/sbin/ifconfig eth0 | grep inet.addr | sed -e 's/.*inet addr:\([0-9.]*\) .*/\1/'` + +LO=`echo $ADDR | sed -e 's/[0-9]\+\.[0-9]\+\.[0-9]\+\.\([0-9]\+\)/\1/'` +HI=`echo $ADDR | sed -e 's/\([0-9]\+\.[0-9]\+\.[0-9]\+\)\.[0-9]\+/\1/'` + +NEWADDR=$HI.$[LO+DOM] + +$VIFINIT $DOM $NEWADDR + +$DOM_BUILDER 16000 $1 1 diff --git a/tools/domain_builder/vifinit b/tools/domain_builder/vifinit new file mode 100644 index 0000000000..58b50eaab0 --- /dev/null +++ b/tools/domain_builder/vifinit @@ -0,0 +1,25 @@ +#!/bin/bash +# +# vifinit +# +# This is a silly little script to dump a couple of simple rules down to +# the hypervisor to assign a full static IP to a given virtual interface. +# +# Usage is: +# +# vifinit [vif id] [dotted decimal ip address] +# +if [ $# -ne 2 ] ; +then + echo "usage: vifinit [vif id] [dotted decimal ip address]" + exit +fi + +#outbound rule: +echo "ADD ACCEPT srcaddr=$2 srcaddrmask=255.255.255.255 srcint=$1 dstint=-1 proto=any" > /proc/vfr + +#inbound rule: +echo "ADD ACCEPT dstaddr=$2 dstaddrmask=255.255.255.255 srcint=-4 dstint=$1 proto=any" > /proc/vfr + +#----] done. + -- cgit v1.2.3