ia64/xen-unstable

changeset 172:9713c0d10ee7

bitkeeper revision 1.38 (3e4d2343mb2iLy2GxQFBASfFtfoNkQ)

Merge labyrinth.cl.cam.ac.uk:/usr/groups/xeno/BK/xeno
into labyrinth.cl.cam.ac.uk:/local/scratch/kaf24/xeno-net
author kaf24@labyrinth.cl.cam.ac.uk
date Fri Feb 14 17:11:31 2003 +0000 (2003-02-14)
parents cf76e69e6979 3f8ad6ef593d
children 5669423b1d2a
files .rootkeys tools/domain_builder/Makefile tools/domain_builder/README tools/domain_builder/dom0_defs.h tools/domain_builder/dom0_ops.h tools/domain_builder/dom_builder.c tools/domain_builder/dom_kill.c tools/domain_builder/hypervisor_defs.h tools/domain_builder/mem_defs.h tools/domain_builder/newdom tools/domain_builder/vifinit
line diff
     1.1 --- a/.rootkeys	Fri Feb 14 16:56:44 2003 +0000
     1.2 +++ b/.rootkeys	Fri Feb 14 17:11:31 2003 +0000
     1.3 @@ -1,6 +1,16 @@
     1.4  3ddb6b0bKlMz_dz-M59a1mkUa1lASw BitKeeper/etc/config
     1.5  3ddb6b0buTaC5zg1_a8FoAR9FWi_mw BitKeeper/etc/ignore
     1.6  3ddb79c9_hgSp-gsQm8HqWM_9W3B_A BitKeeper/etc/logging_ok
     1.7 +3e4d00468-FN2VDeEHo96zxrMHK_mA tools/domain_builder/Makefile
     1.8 +3e4d0046SPau_y0sw2WLJz8QkqNoRA tools/domain_builder/README
     1.9 +3e4d0046bbdH0GsI9J_1Eb4ZQHfIiQ tools/domain_builder/dom0_defs.h
    1.10 +3e4d0046RgYCfGOw6qGz_7kYLMV2Vw tools/domain_builder/dom0_ops.h
    1.11 +3e4d0046ouLij_CMN_j7-dUHZIBI_A tools/domain_builder/dom_builder.c
    1.12 +3e4d0046EKs06fY0CWDEgZQcn7DYUg tools/domain_builder/dom_kill.c
    1.13 +3e4d0046aPbGiRTtdWxqY5b3ytWurA tools/domain_builder/hypervisor_defs.h
    1.14 +3e4d00468aE86IfyjfrJwYoxzM7pAw tools/domain_builder/mem_defs.h
    1.15 +3e4d0046VHhXwFuG5FK34AVxqd5A_A tools/domain_builder/newdom
    1.16 +3e4d0046IBzDIeaMbQB-e2QB2ahbig tools/domain_builder/vifinit
    1.17  3ddb79bcbOVHh38VJzc97-JEGD4dJQ xen-2.4.16/Makefile
    1.18  3ddb79bcCa2VbsMp7mWKlhgwLQUQGA xen-2.4.16/README
    1.19  3ddb79bcWnTwYsQRWl_PaneJfa6p0w xen-2.4.16/Rules.mk
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/tools/domain_builder/Makefile	Fri Feb 14 17:11:31 2003 +0000
     2.3 @@ -0,0 +1,17 @@
     2.4 +CC = gcc
     2.5 +BUILDER = domain_builder
     2.6 +KILL = kill_domain
     2.7 +
     2.8 +all: dom_builder.o dom_kill.o
     2.9 +	$(CC) -o $(BUILDER) dom_builder.o
    2.10 +	$(CC) -o $(KILL) dom_kill.o
    2.11 +
    2.12 +dom_builder.o: dom_builder.c dom0_defs.h dom0_ops.h hypervisor_defs.h mem_defs.h
    2.13 +	$(CC) -c dom_builder.c 
    2.14 +
    2.15 +dom_kill.o: dom_kill.c dom0_ops.h dom0_defs.h
    2.16 +	$(CC) -c dom_kill.c 
    2.17 +
    2.18 +clean:
    2.19 +	$(RM) *.o domain_builder kill_domain
    2.20 +
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/domain_builder/README	Fri Feb 14 17:11:31 2003 +0000
     3.3 @@ -0,0 +1,29 @@
     3.4 +A couple of simple steps to get you going:
     3.5 +
     3.6 +1. do make (suitable Makefile is in the source dir)
     3.7 +2. copy over andy's vifinit script to local dir
     3.8 +3. copy over xenolinux guestos image (NB. image needs to be uncompressed, so
     3.9 +if the only image you have is image.gz do gunzip image.gz before doing 
    3.10 +anything further)
    3.11 +4. add executable permissions to newdom and vifint
    3.12 +5. edit newdom script and change it as it suits you
    3.13 +
    3.14 +newdom script takes guestos image file name as first parameter and newdom id
    3.15 +as second parameter, eg.:
    3.16 +
    3.17 +./newdom xenolinux 1
    3.18 +
    3.19 +should initiate building of dom1 with the image contained in file named 
    3.20 +xenolinux in local dir.
    3.21 +
    3.22 +in general, domain_builder application takes three parameters: requested 
    3.23 +memory in kb, guestos image file name and number of vifs to be created, eg.
    3.24 +
    3.25 +./domain_builder 16000 xenolinux 1
    3.26 +
    3.27 +would build domX reserving 16MB mem, creating 1 vif and using os image stored
    3.28 +as xenolinux in local dir.
    3.29 +
    3.30 +happy booting!
    3.31 +
    3.32 +boris
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/domain_builder/dom0_defs.h	Fri Feb 14 17:11:31 2003 +0000
     4.3 @@ -0,0 +1,8 @@
     4.4 +#define PROC_XENO_ROOT  "xeno"
     4.5 +#define PROC_CMD        "dom0_cmd"
     4.6 +#define PROC_DOM_PREFIX "dom"
     4.7 +#define PROC_DOM_MEM    "mem"
     4.8 +#define PROC_DOM_DATA   "new_dom_data"
     4.9 +
    4.10 +#define MAX_PATH        256
    4.11 +
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tools/domain_builder/dom0_ops.h	Fri Feb 14 17:11:31 2003 +0000
     5.3 @@ -0,0 +1,80 @@
     5.4 +/******************************************************************************
     5.5 + * dom0_ops.h
     5.6 + * 
     5.7 + * Process command requests from domain-0 guest OS.
     5.8 + * 
     5.9 + * Copyright (c) 2002, K A Fraser, B Dragovic
    5.10 + */
    5.11 +
    5.12 +#define DOM0_NEWDOMAIN   0
    5.13 +#define DOM0_KILLDOMAIN  1
    5.14 +#define DOM0_GETMEMLIST  2
    5.15 +#define DOM0_STARTDOM    4
    5.16 +#define MAP_DOM_MEM      6 /* Not passed down to Xen */
    5.17 +#define DO_PGUPDATES     7 /* Not passed down to Xen */
    5.18 +#define MAX_CMD          8
    5.19 +
    5.20 +#define MAX_CMD_LEN     256
    5.21 +
    5.22 +typedef struct dom0_newdomain_st
    5.23 +{
    5.24 +    unsigned int domain;
    5.25 +    unsigned int memory_kb;
    5.26 +    unsigned int num_vifs;  // temporary
    5.27 +    unsigned long pg_head;  // return parameter
    5.28 +} dom0_newdomain_t;
    5.29 +
    5.30 +typedef struct dom0_killdomain_st
    5.31 +{
    5.32 +    unsigned int domain;
    5.33 +} dom0_killdomain_t;
    5.34 +
    5.35 +typedef struct dom0_getmemlist_st
    5.36 +{
    5.37 +    unsigned long start_pfn;
    5.38 +    unsigned long num_pfns;
    5.39 +    void *buffer;
    5.40 +} dom0_getmemlist_t;
    5.41 +
    5.42 +/* This is entirely processed by XenoLinux */
    5.43 +typedef struct dom_mem 
    5.44 +{
    5.45 +    unsigned int domain;
    5.46 +    unsigned long vaddr;
    5.47 +    unsigned long start_pfn;
    5.48 +    int tot_pages;
    5.49 +} dom_mem_t;
    5.50 +
    5.51 +/* This is entirely processed by XenoLinux */
    5.52 +typedef struct dom_pgupdate
    5.53 +{
    5.54 +    unsigned long pgt_update_arr;
    5.55 +    unsigned long num_pgt_updates;
    5.56 +} dom_pgupdate_t;
    5.57 +
    5.58 +typedef struct domain_launch
    5.59 +{
    5.60 +    unsigned int domain;
    5.61 +    unsigned long l2_pgt_addr;
    5.62 +    unsigned long virt_load_addr;
    5.63 +    unsigned long virt_shinfo_addr;
    5.64 +    unsigned long virt_startinfo_addr;
    5.65 +    unsigned int num_vifs;
    5.66 +    char cmd_line[MAX_CMD_LEN];
    5.67 +} dom_meminfo_t;
    5.68 +
    5.69 +typedef struct dom0_op_st
    5.70 +{
    5.71 +    unsigned long cmd;
    5.72 +    union
    5.73 +    {
    5.74 +        dom0_newdomain_t newdomain;
    5.75 +        dom0_killdomain_t killdomain;
    5.76 +        dom0_getmemlist_t getmemlist;
    5.77 +        dom_mem_t dommem;
    5.78 +        dom_pgupdate_t pgupdate;
    5.79 +        dom_meminfo_t meminfo;
    5.80 +    }
    5.81 +    u;
    5.82 +} dom0_op_t;
    5.83 +
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/domain_builder/dom_builder.c	Fri Feb 14 17:11:31 2003 +0000
     6.3 @@ -0,0 +1,470 @@
     6.4 +/* 
     6.5 + * XenoDomainBuilder, copyright (c) Boris Dragovic, bd240@cl.cam.ac.uk
     6.6 + * This code is released under terms and conditions of GNU GPL :).
     6.7 + * Usage: <executable> <mem_kb> <os image> <num_vifs> 
     6.8 + */
     6.9 +
    6.10 +#include <unistd.h>
    6.11 +#include <stdio.h>
    6.12 +#include <errno.h>
    6.13 +#include <fcntl.h>
    6.14 +#include <sys/mman.h>
    6.15 +#include <sys/types.h>
    6.16 +#include <sys/stat.h>
    6.17 +
    6.18 +#include "hypervisor_defs.h"
    6.19 +#include "dom0_ops.h"
    6.20 +#include "dom0_defs.h"
    6.21 +#include "mem_defs.h"
    6.22 +
    6.23 +#define PERR_STRING "Xeno Domain Builder"
    6.24 +
    6.25 +#define GUEST_SIG   "XenoGues"
    6.26 +#define SIG_LEN    8
    6.27 +
    6.28 +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED)
    6.29 +#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED|_PAGE_DIRTY)
    6.30 +
    6.31 +/* Round _n up to nearest multiple of _m. */
    6.32 +#define ROUND_UP(_n,_m) (((_n) + (_m) - 1) / (_m))
    6.33 +
    6.34 +/* standardized error reporting function */
    6.35 +static void dberr(char *msg)
    6.36 +{
    6.37 +    printf("%s: %s\n", PERR_STRING, msg);
    6.38 +}
    6.39 +
    6.40 +/* status reporting function */
    6.41 +static void dbstatus(char * msg)
    6.42 +{
    6.43 +    printf("Domain Builder: %s\n", msg);
    6.44 +}
    6.45 +
    6.46 +/* clean up domain's memory allocations */
    6.47 +static void dom_mem_cleanup(dom_mem_t * dom_mem)
    6.48 +{
    6.49 +    char mem_path[MAX_PATH];
    6.50 +    int mem_fd;
    6.51 +
    6.52 +    /* open the domain's /proc mem interface */
    6.53 +    sprintf(mem_path, "%s%s%s%s%d%s%s", "/proc/", PROC_XENO_ROOT, "/", 
    6.54 +        PROC_DOM_PREFIX, dom_mem->domain, "/", PROC_DOM_MEM);
    6.55 +
    6.56 +    mem_fd = open(mem_path, O_WRONLY);
    6.57 +    if(mem_fd < 0){
    6.58 +        perror(PERR_STRING);
    6.59 +    }
    6.60 +
    6.61 +	if(write(mem_fd, (dom_mem_t *)dom_mem, sizeof(dom_mem_t)) < 0){
    6.62 +		dbstatus("Error unmapping domain's memory.\n");
    6.63 +	}
    6.64 +
    6.65 +    close(mem_fd);
    6.66 +}
    6.67 +
    6.68 +/* ask dom0 to export domains memory through /proc */
    6.69 +static int setup_dom_memmap(unsigned long pfn, int pages, int dom)
    6.70 +{
    6.71 +    char cmd_path[MAX_PATH];
    6.72 +    dom0_op_t dop;
    6.73 +    int cmd_fd;
    6.74 +
    6.75 +    dop.cmd = MAP_DOM_MEM;
    6.76 +    dop.u.dommem.start_pfn = pfn;
    6.77 +    dop.u.dommem.tot_pages = pages;
    6.78 +    dop.u.dommem.domain = dom;
    6.79 +
    6.80 +    /* open the /proc command interface */
    6.81 +    sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
    6.82 +    cmd_fd = open(cmd_path, O_WRONLY);
    6.83 +    if(cmd_fd < 0){
    6.84 +        perror(PERR_STRING);
    6.85 +        return -1;
    6.86 +    }
    6.87 +
    6.88 +    write(cmd_fd, &dop, sizeof(dom0_op_t));
    6.89 +    close(cmd_fd);
    6.90 +
    6.91 +    return 0;
    6.92 +}
    6.93 +      
    6.94 +/* request the actual mapping from dom0 */
    6.95 +static unsigned long get_vaddr(unsigned int dom)
    6.96 +{
    6.97 +    char mem_path[MAX_PATH];
    6.98 +	unsigned long addr;
    6.99 +    int mem_fd;
   6.100 +
   6.101 +    /* open the domain's /proc mem interface */
   6.102 +    sprintf(mem_path, "%s%s%s%s%d%s%s", "/proc/", PROC_XENO_ROOT, "/", 
   6.103 +                    PROC_DOM_PREFIX, dom, "/", PROC_DOM_MEM);
   6.104 +
   6.105 +    mem_fd = open(mem_path, O_RDONLY);
   6.106 +    if(mem_fd < 0){
   6.107 +        perror(PERR_STRING);
   6.108 +        return 0;
   6.109 +    }
   6.110 +
   6.111 +    /* get virtual address of mapped region */
   6.112 +	read(mem_fd, &addr, sizeof(addr));
   6.113 +	
   6.114 +    close(mem_fd);
   6.115 +
   6.116 +    return addr;
   6.117 +}
   6.118 +
   6.119 +static int map_dom_mem(unsigned long pfn, int pages, int dom, 
   6.120 +    dom_mem_t * dom_mem)
   6.121 +{
   6.122 +
   6.123 +    if(setup_dom_memmap(pfn, pages, dom)){
   6.124 +        perror(PERR_STRING);
   6.125 +        return -1;
   6.126 +    }
   6.127 +
   6.128 +    dom_mem->domain = dom;
   6.129 +    dom_mem->start_pfn = pfn;
   6.130 +    dom_mem->tot_pages = pages;
   6.131 +    if((dom_mem->vaddr = get_vaddr(dom)) == 0){
   6.132 +        dberr("Error mapping dom memory.");
   6.133 +        return -1;
   6.134 +    }
   6.135 +    
   6.136 +    return 0;
   6.137 +}
   6.138 +
   6.139 +/* create new domain */
   6.140 +static dom0_newdomain_t * create_new_domain(long req_mem)
   6.141 +{
   6.142 +    dom0_newdomain_t * dom_data;
   6.143 +    char cmd_path[MAX_PATH];
   6.144 +    char dom_id_path[MAX_PATH];
   6.145 +    dom0_op_t dop;
   6.146 +    int cmd_fd;
   6.147 +    int id_fd;
   6.148 +
   6.149 +    /* open the /proc command interface */
   6.150 +    sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
   6.151 +    cmd_fd = open(cmd_path, O_WRONLY);
   6.152 +    if(cmd_fd < 0){
   6.153 +        perror(PERR_STRING);
   6.154 +        return 0;
   6.155 +    }
   6.156 +
   6.157 +    dop.cmd = DOM0_NEWDOMAIN;
   6.158 +    dop.u.newdomain.memory_kb = req_mem;
   6.159 +
   6.160 +    write(cmd_fd, &dop, sizeof(dom0_op_t));
   6.161 +    close(cmd_fd);
   6.162 +
   6.163 +    sprintf(dom_id_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", 
   6.164 +        PROC_DOM_DATA);
   6.165 +    while((id_fd = open(dom_id_path, O_RDONLY)) < 0){}
   6.166 +    dom_data = (dom0_newdomain_t *)malloc(sizeof(dom0_newdomain_t));
   6.167 +    read(id_fd, dom_data, sizeof(dom0_newdomain_t));
   6.168 +    close(id_fd);
   6.169 +    
   6.170 +    sprintf(cmd_path, "Reserved %ld kbytes memory and assigned id %d to the"
   6.171 +                    "new domain.", req_mem, dom_data->domain);
   6.172 +    dbstatus(cmd_path);
   6.173 +
   6.174 +    return dom_data;
   6.175 +}    
   6.176 +
   6.177 +/* open kernel image and do some sanity checks */
   6.178 +static int do_kernel_chcks(char *image, long dom_size, 
   6.179 +    unsigned long * load_addr, size_t * ksize)
   6.180 +{
   6.181 +    char signature[8];
   6.182 +    char status[MAX_PATH];
   6.183 +    struct stat stat;
   6.184 +    int fd;
   6.185 +    int ret; 
   6.186 +    
   6.187 +    fd = open(image, O_RDONLY);
   6.188 +    if(fd < 0){
   6.189 +        perror(PERR_STRING);
   6.190 +        ret = -1;    
   6.191 +        goto out;
   6.192 +    }
   6.193 +
   6.194 +    if(fstat(fd, &stat) < 0){
   6.195 +        perror(PERR_STRING);
   6.196 +        ret = -1;
   6.197 +		close(fd);
   6.198 +        goto out;
   6.199 +    }
   6.200 +
   6.201 +    if(stat.st_size > (dom_size << 10)){
   6.202 +        sprintf(status, "Kernel image size %ld larger than requested "
   6.203 +            "domain size %ld\n Terminated.\n", stat.st_size, dom_size);
   6.204 +        dberr(status);
   6.205 +        ret = -1;
   6.206 +		close(fd);
   6.207 +        goto out;
   6.208 +    }
   6.209 +    *ksize = stat.st_size - SIG_LEN;
   6.210 +    
   6.211 +    read(fd, signature, SIG_LEN);
   6.212 +    if(strncmp(signature, GUEST_SIG, SIG_LEN)){
   6.213 +        dberr("Kernel image does not contain required signature. "
   6.214 +		"Terminating.\n");
   6.215 +        ret = -1;
   6.216 +		close(fd);
   6.217 +        goto out;
   6.218 +    }
   6.219 +
   6.220 +    read(fd, load_addr, sizeof(unsigned long));
   6.221 +
   6.222 +    sprintf(status, "Kernel image %s valid, kernel virtual load address %lx", 
   6.223 +        image, *load_addr);
   6.224 +    dbstatus(status);
   6.225 +
   6.226 +    ret = fd;
   6.227 +
   6.228 +out:    
   6.229 +    return ret;
   6.230 +}
   6.231 +
   6.232 +/* this is the main guestos setup function,
   6.233 + * returnes domain descriptor structure to be used when launching
   6.234 + * the domain by hypervisor to do some last minute initialization.
   6.235 + * page table initialization is done by making a list of page table
   6.236 + * requests that are handeled by the hypervisor in the ordinary
   6.237 + * manner. this way, many potentially messy things are avoided...
   6.238 + */ 
   6.239 +#define PAGE_TO_VADDR(_pfn) ((void *)(dom_mem->vaddr + ((_pfn) * PAGE_SIZE)))
   6.240 +static dom_meminfo_t *setup_guestos(int dom, int kernel_fd, 
   6.241 +    unsigned long virt_load_addr, size_t ksize, dom_mem_t *dom_mem)
   6.242 +{
   6.243 +    dom_meminfo_t *meminfo;
   6.244 +    unsigned long *page_array;
   6.245 +    page_update_request_t *pgt_updates;
   6.246 +    dom_mem_t mem_map;
   6.247 +    dom_meminfo_t *ret = NULL;
   6.248 +    int alloc_index, num_pt_pages;
   6.249 +    unsigned long l2tab;
   6.250 +    unsigned long l1tab = 0;
   6.251 +    unsigned long num_pgt_updates = 0;
   6.252 +    unsigned long count, pt_start;
   6.253 +    dom0_op_t pgupdate_req;
   6.254 +    char cmd_path[MAX_PATH];
   6.255 +    int cmd_fd;
   6.256 +
   6.257 +    meminfo     = (dom_meminfo_t *)malloc(sizeof(dom_meminfo_t));
   6.258 +    page_array  = (unsigned long *)dom_mem->vaddr;
   6.259 +    pgt_updates = (page_update_request_t *)dom_mem->vaddr;
   6.260 +    alloc_index = dom_mem->tot_pages - 1;
   6.261 +
   6.262 +    /* Count bottom-level PTs, rounding up. Include one PTE for shared info. */
   6.263 +    num_pt_pages = ROUND_UP(l1_table_offset(virt_load_addr) +
   6.264 +                            dom_mem->tot_pages + 1, 1024);
   6.265 +    /* We must also count the page directory. */
   6.266 +    num_pt_pages++;
   6.267 +
   6.268 +    /* Index of first PT page. */
   6.269 +    pt_start = dom_mem->tot_pages - num_pt_pages;
   6.270 +
   6.271 +    /* first allocate page for page dir. allocation goes backwards from the
   6.272 +     * end of the allocated physical address space.
   6.273 +     */
   6.274 +    l2tab = *(page_array + alloc_index) << PAGE_SHIFT; 
   6.275 +    memset(PAGE_TO_VADDR(alloc_index), 0, PAGE_SIZE);
   6.276 +    alloc_index--;
   6.277 +    meminfo->l2_pgt_addr = l2tab;
   6.278 +    meminfo->virt_shinfo_addr = virt_load_addr + nr_2_page(dom_mem->tot_pages);
   6.279 +
   6.280 +    /* pin down l2tab addr as page dir page - causes hypervisor to provide
   6.281 +     * correct protection for the page
   6.282 +     */ 
   6.283 +    pgt_updates->ptr = l2tab | PGREQ_EXTENDED_COMMAND;
   6.284 +    pgt_updates->val = PGEXT_PIN_L2_TABLE;
   6.285 +    pgt_updates++;
   6.286 +    num_pgt_updates++;
   6.287 +
   6.288 +    /* Initialise the page tables. */
   6.289 +    l2tab += l2_table_offset(virt_load_addr) * sizeof(l2_pgentry_t);
   6.290 +    for ( count = 0; count < dom_mem->tot_pages; count++ )
   6.291 +    {    
   6.292 +        if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) ) 
   6.293 +        {
   6.294 +            l1tab = *(page_array + alloc_index) << PAGE_SHIFT;
   6.295 +            memset(PAGE_TO_VADDR(alloc_index), 0, PAGE_SIZE);
   6.296 +            alloc_index--;
   6.297 +			
   6.298 +            l1tab += l1_table_offset(virt_load_addr + nr_2_page(count)) 
   6.299 +                * sizeof(l1_pgentry_t);
   6.300 +
   6.301 +            /* make apropriate entry in the page directory */
   6.302 +            pgt_updates->ptr = l2tab;
   6.303 +            pgt_updates->val = l1tab | L2_PROT;
   6.304 +            pgt_updates++;
   6.305 +            num_pgt_updates++;
   6.306 +            l2tab += sizeof(l2_pgentry_t);
   6.307 +        }
   6.308 +		
   6.309 +        if ( count < pt_start )
   6.310 +        {
   6.311 +            pgt_updates->ptr = l1tab;
   6.312 +            pgt_updates->val = (*(page_array + count) << PAGE_SHIFT) | L1_PROT;
   6.313 +            pgt_updates++;
   6.314 +            num_pgt_updates++;
   6.315 +            l1tab += sizeof(l1_pgentry_t);
   6.316 +        }
   6.317 +        else
   6.318 +        {
   6.319 +            pgt_updates->ptr = l1tab;
   6.320 +            pgt_updates->val = 
   6.321 +		((*(page_array + count) << PAGE_SHIFT) | L1_PROT) & ~_PAGE_RW;
   6.322 +            pgt_updates++;
   6.323 +            num_pgt_updates++;
   6.324 +            l1tab += sizeof(l1_pgentry_t);
   6.325 +        }
   6.326 +
   6.327 +        pgt_updates->ptr = 
   6.328 +	    (*(page_array + count) << PAGE_SHIFT) | PGREQ_MPT_UPDATE;
   6.329 +        pgt_updates->val = count;
   6.330 +        pgt_updates++;
   6.331 +        num_pgt_updates++;
   6.332 +    }
   6.333 +
   6.334 +    meminfo->virt_startinfo_addr = virt_load_addr + nr_2_page(alloc_index - 1);
   6.335 +    meminfo->domain = dom;
   6.336 +
   6.337 +    /*
   6.338 +     * Send the page update requests down to the hypervisor.
   6.339 +     * NB. We must do this before loading the guest OS image!
   6.340 +     */
   6.341 +    sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
   6.342 +    if ( (cmd_fd = open(cmd_path, O_WRONLY)) < 0 ) goto out;
   6.343 +    pgupdate_req.cmd = DO_PGUPDATES;
   6.344 +    pgupdate_req.u.pgupdate.pgt_update_arr  = (unsigned long)dom_mem->vaddr;
   6.345 +    pgupdate_req.u.pgupdate.num_pgt_updates = num_pgt_updates;
   6.346 +    write(cmd_fd, &pgupdate_req, sizeof(dom0_op_t));
   6.347 +    close(cmd_fd);
   6.348 +
   6.349 +    /* Load the guest OS image. */
   6.350 +    if(!(read(kernel_fd, (char *)dom_mem->vaddr, ksize) > 0)){
   6.351 +        dberr("Error reading kernel image, could not"
   6.352 +              " read the whole image. Terminating.\n");
   6.353 +        goto out;
   6.354 +    }
   6.355 +
   6.356 +    ret = meminfo;
   6.357 +out:
   6.358 +
   6.359 +    return ret;
   6.360 +}
   6.361 +
   6.362 +static int launch_domain(dom_meminfo_t  * meminfo)
   6.363 +{
   6.364 +    char cmd_path[MAX_PATH];
   6.365 +    dom0_op_t dop;
   6.366 +    int cmd_fd;
   6.367 +
   6.368 +    sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
   6.369 +    cmd_fd = open(cmd_path, O_WRONLY);
   6.370 +    if(cmd_fd < 0){
   6.371 +        perror(PERR_STRING);
   6.372 +        return -1;
   6.373 +    }
   6.374 +
   6.375 +    dop.cmd = DOM0_STARTDOM;
   6.376 +    memcpy(&dop.u.meminfo, meminfo, sizeof(dom_meminfo_t));
   6.377 +    write(cmd_fd, &dop, sizeof(dom0_op_t));
   6.378 +
   6.379 +    dbstatus("Launched the new domain!");
   6.380 +
   6.381 +    close(cmd_fd);
   6.382 +}
   6.383 +
   6.384 +int main(int argc, char **argv)
   6.385 +{
   6.386 +
   6.387 +    dom0_newdomain_t * dom_data;
   6.388 +    dom_mem_t dom_os_image;
   6.389 +    dom_mem_t dom_pgt; 
   6.390 +    dom_meminfo_t * meminfo;
   6.391 +    size_t ksize;
   6.392 +    unsigned long load_addr;
   6.393 +    char status[1024];
   6.394 +    int kernel_fd;
   6.395 +    int count;
   6.396 +    int cmd_len;
   6.397 +    int ret = 0;
   6.398 +
   6.399 +	unsigned long addr;
   6.400 +
   6.401 +    if(argc < 4){
   6.402 +        dberr("Usage: dom_builder <kbytes_mem> <image> <num_vifs> "
   6.403 +                        "<boot_params>\n");
   6.404 +        ret = -1;
   6.405 +        goto out;
   6.406 +    }
   6.407 +
   6.408 +    /* create new domain and set up all the neccessary mappings */
   6.409 +
   6.410 +    kernel_fd = do_kernel_chcks(argv[2], atol(argv[1]), &load_addr, &ksize);
   6.411 +    if(kernel_fd < 0){
   6.412 +        ret = -1;
   6.413 +        goto out;
   6.414 +    }
   6.415 +
   6.416 +    /* request the creation of new domain */
   6.417 +    dom_data = create_new_domain(atol(argv[1]));
   6.418 +    if(dom_data == 0){
   6.419 +        ret = -1;
   6.420 +        goto out;
   6.421 +    }
   6.422 +
   6.423 +    /* map domain's memory */
   6.424 +    if(map_dom_mem(dom_data->pg_head, dom_data->memory_kb >> (PAGE_SHIFT - 10), 
   6.425 +        dom_data->domain, &dom_os_image)){
   6.426 +        ret = -1;
   6.427 +        goto out;
   6.428 +    }
   6.429 +
   6.430 +    /* the following code does the actual domain building */
   6.431 +    meminfo = setup_guestos(dom_data->domain, kernel_fd, load_addr, ksize, 
   6.432 +        &dom_os_image);
   6.433 +    if(meminfo == NULL){
   6.434 +		printf("Domain Builder: debug: meminfo NULL\n");
   6.435 +        ret = -1;
   6.436 +        dom_mem_cleanup(&dom_os_image);
   6.437 +        goto out;
   6.438 +    }
   6.439 +
   6.440 +    dom_mem_cleanup(&dom_os_image);
   6.441 +
   6.442 +    meminfo->virt_load_addr = load_addr;
   6.443 +    meminfo->num_vifs = atoi(argv[3]);
   6.444 +    meminfo->cmd_line[0] = '\0';
   6.445 +    cmd_len = 0;
   6.446 +    for(count = 4; count < argc; count++){
   6.447 +        if(cmd_len + strlen(argv[count]) > MAX_CMD_LEN - 1){
   6.448 +            dberr("Size of image boot params too big!\n");
   6.449 +            break;
   6.450 +        }
   6.451 +        strcat(meminfo->cmd_line, argv[count]);
   6.452 +        strcat(meminfo->cmd_line, " ");
   6.453 +        cmd_len += strlen(argv[count] + 1);
   6.454 +    }
   6.455 +
   6.456 +    sprintf(status, 
   6.457 +	    "About to launch new domain %d with folowing parameters:\n"
   6.458 +	    " * page table base: %lx \n * load address: %lx \n"
   6.459 +	    " * shared info address: %lx \n * start info address: %lx \n"
   6.460 +	    " * number of vifs: %d \n * cmd line: %s \n", meminfo->domain, 
   6.461 +	    meminfo->l2_pgt_addr, meminfo->virt_load_addr, 
   6.462 +	    meminfo->virt_shinfo_addr, meminfo->virt_startinfo_addr, 
   6.463 +	    meminfo->num_vifs, meminfo->cmd_line);
   6.464 +    dbstatus(status);
   6.465 +    
   6.466 +    /* and launch the domain */
   6.467 +    if(launch_domain(meminfo) != 0)
   6.468 +	ret = -1;
   6.469 +
   6.470 +    free(meminfo);
   6.471 +out:
   6.472 +    return ret;
   6.473 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/tools/domain_builder/dom_kill.c	Fri Feb 14 17:11:31 2003 +0000
     7.3 @@ -0,0 +1,55 @@
     7.4 +/* 
     7.5 + * A very(!) simple program to kill a domain. (c) Boris Dragovic
     7.6 + * Usage: <executable> <mem_kb> <os image> <num_vifs> 
     7.7 + */
     7.8 +
     7.9 +#include <unistd.h>
    7.10 +#include <stdio.h>
    7.11 +#include <errno.h>
    7.12 +#include <fcntl.h>
    7.13 +#include <sys/stat.h>
    7.14 +#include <sys/types.h>
    7.15 +
    7.16 +#include "dom0_ops.h"
    7.17 +#include "dom0_defs.h"
    7.18 +
    7.19 +#define PERR_STRING "Xen Domain Killer"
    7.20 +
    7.21 +static int do_kill_domain(int dom_id)
    7.22 +{
    7.23 +    char cmd_path[MAX_PATH];
    7.24 +    dom0_op_t dop;
    7.25 +    int cmd_fd;
    7.26 +
    7.27 +    dop.cmd = DOM0_KILLDOMAIN;
    7.28 +    dop.u.killdomain.domain = dom_id;
    7.29 +
    7.30 +    /* open the /proc command interface */
    7.31 +    sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
    7.32 +    cmd_fd = open(cmd_path, O_WRONLY);
    7.33 +    if(cmd_fd < 0){
    7.34 +        perror(PERR_STRING);
    7.35 +        return -1;
    7.36 +    }
    7.37 +
    7.38 +    write(cmd_fd, &dop, sizeof(dom0_op_t));
    7.39 +    close(cmd_fd);
    7.40 +
    7.41 +    return 0;
    7.42 +}
    7.43 +
    7.44 +int main(int argc, char **argv)
    7.45 +{
    7.46 +    int ret;
    7.47 +
    7.48 +    if(argc < 2){
    7.49 +        printf("Usage: kill_domain <domain_id>\n");
    7.50 +        ret = -1;
    7.51 +        goto out;
    7.52 +    }
    7.53 +
    7.54 +    ret = do_kill_domain(atoi(argv[1]));
    7.55 +
    7.56 +out:
    7.57 +    return ret;
    7.58 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/tools/domain_builder/hypervisor_defs.h	Fri Feb 14 17:11:31 2003 +0000
     8.3 @@ -0,0 +1,36 @@
     8.4 +/******************************************************************************
     8.5 + * hypervisor_defs.h
     8.6 + * 
     8.7 + * This needs to be kept in sync with Xen's pagetable update interface!
     8.8 + * 
     8.9 + * Copyright (c) 2002-2003, Keir Fraser & Boris Dragovic 
    8.10 + */
    8.11 +
    8.12 +/* taken from include/hypervisor-ifs/hypervisor-if.h */
    8.13 +typedef struct
    8.14 +{
    8.15 +/*
    8.16 + * PGREQ_XXX: specified in least-significant bits of 'ptr' field. All requests 
    8.17 + * specify relevent PTE or PT address in 'ptr'. Normal requests specify update 
    8.18 + * value in 'value'. Extended requests specify command in least 8 bits of 
    8.19 + * 'value'.
    8.20 + */
    8.21 +    unsigned long ptr, val; /* *ptr = val */
    8.22 +} page_update_request_t;
    8.23 +
    8.24 +/* A normal page-table update request. */
    8.25 +#define PGREQ_NORMAL           0
    8.26 +#define PGREQ_MPT_UPDATE 1
    8.27 +/* An extended command. */
    8.28 +#define PGREQ_EXTENDED_COMMAND 2
    8.29 +/* Announce a new top-level page table. */
    8.30 +#define PGEXT_PIN_L1_TABLE      0
    8.31 +#define PGEXT_PIN_L2_TABLE      1
    8.32 +#define PGEXT_PIN_L3_TABLE      2
    8.33 +#define PGEXT_PIN_L4_TABLE      3
    8.34 +#define PGEXT_UNPIN_TABLE       4
    8.35 +#define PGEXT_NEW_BASEPTR       5
    8.36 +#define PGEXT_TLB_FLUSH         6
    8.37 +#define PGEXT_INVLPG            7
    8.38 +#define PGEXT_CMD_MASK        255
    8.39 +#define PGEXT_CMD_SHIFT         8
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/tools/domain_builder/mem_defs.h	Fri Feb 14 17:11:31 2003 +0000
     9.3 @@ -0,0 +1,45 @@
     9.4 +/*
     9.5 + * memory related definitions needed for userspace domain builder dom0 application. these _need_ to
     9.6 + * be kept in sync with the kernel .h files they were copied over from or something horrible will
     9.7 + * happen. remmember: god kills a kitten every time you forget to keep these in sync.
     9.8 + * 
     9.9 + * KAF: Boris, these constants are all fixed by x86 hardware. So the kittens are safe for now :-)
    9.10 + * 
    9.11 + * Copyright 2002 by B Dragovic
    9.12 + */
    9.13 +
    9.14 +/* copied over from hypervisor: include/asm-i386/page.h */
    9.15 +
    9.16 +#define _PAGE_PRESENT   0x001
    9.17 +#define _PAGE_RW    0x002
    9.18 +#define _PAGE_USER  0x004
    9.19 +#define _PAGE_PWT   0x008
    9.20 +#define _PAGE_PCD   0x010
    9.21 +#define _PAGE_ACCESSED  0x020
    9.22 +#define _PAGE_DIRTY 0x040
    9.23 +#define _PAGE_PAT       0x080
    9.24 +#define _PAGE_PSE   0x080
    9.25 +#define _PAGE_GLOBAL    0x100
    9.26 +
    9.27 +
    9.28 +#define L1_PAGETABLE_SHIFT       12
    9.29 +#define L2_PAGETABLE_SHIFT       22
    9.30 + 
    9.31 +#define ENTRIES_PER_L1_PAGETABLE 1024
    9.32 +#define ENTRIES_PER_L2_PAGETABLE 1024
    9.33 + 
    9.34 +#define PAGE_SHIFT              L1_PAGETABLE_SHIFT
    9.35 +#define PAGE_SIZE               (1UL << PAGE_SHIFT)
    9.36 +#define PAGE_MASK               (~(PAGE_SIZE-1))
    9.37 +
    9.38 +typedef struct { unsigned long l1_lo; } l1_pgentry_t;
    9.39 +typedef struct { unsigned long l2_lo; } l2_pgentry_t;
    9.40 +
    9.41 +#define l1_table_offset(_a) \
    9.42 +          (((_a) >> L1_PAGETABLE_SHIFT) & (ENTRIES_PER_L1_PAGETABLE - 1))
    9.43 +#define l2_table_offset(_a) \
    9.44 +          ((_a) >> L2_PAGETABLE_SHIFT)
    9.45 +
    9.46 +/* local definitions */
    9.47 +
    9.48 +#define nr_2_page(x) (x << PAGE_SHIFT)
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tools/domain_builder/newdom	Fri Feb 14 17:11:31 2003 +0000
    10.3 @@ -0,0 +1,17 @@
    10.4 +#!/bin/sh
    10.5 +
    10.6 +VIFINIT=./vifinit
    10.7 +DOM_BUILDER=./domain_builder
    10.8 +
    10.9 +DOM=$2
   10.10 +
   10.11 +ADDR=`/sbin/ifconfig eth0 | grep inet.addr | sed -e 's/.*inet addr:\([0-9.]*\) .*/\1/'`
   10.12 +
   10.13 +LO=`echo $ADDR | sed -e 's/[0-9]\+\.[0-9]\+\.[0-9]\+\.\([0-9]\+\)/\1/'`
   10.14 +HI=`echo $ADDR | sed -e 's/\([0-9]\+\.[0-9]\+\.[0-9]\+\)\.[0-9]\+/\1/'`
   10.15 +
   10.16 +NEWADDR=$HI.$[LO+DOM]
   10.17 +
   10.18 +$VIFINIT $DOM $NEWADDR
   10.19 +
   10.20 +$DOM_BUILDER 16000 $1 1
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/tools/domain_builder/vifinit	Fri Feb 14 17:11:31 2003 +0000
    11.3 @@ -0,0 +1,25 @@
    11.4 +#!/bin/bash
    11.5 +#
    11.6 +# vifinit 
    11.7 +#
    11.8 +# This is a silly little script to dump a couple of simple rules down to 
    11.9 +# the hypervisor to assign a full static IP to a given virtual interface.
   11.10 +# 
   11.11 +# Usage is:
   11.12 +#
   11.13 +#   vifinit [vif id] [dotted decimal ip address]
   11.14 +#
   11.15 +if [ $# -ne 2 ] ; 
   11.16 +then
   11.17 +        echo "usage: vifinit [vif id] [dotted decimal ip address]"
   11.18 +        exit
   11.19 +fi
   11.20 +
   11.21 +#outbound rule:
   11.22 +echo "ADD ACCEPT srcaddr=$2 srcaddrmask=255.255.255.255 srcint=$1 dstint=-1 proto=any" > /proc/vfr
   11.23 +
   11.24 +#inbound rule:
   11.25 +echo "ADD ACCEPT dstaddr=$2 dstaddrmask=255.255.255.255 srcint=-4 dstint=$1 proto=any" > /proc/vfr
   11.26 +
   11.27 +#----] done.
   11.28 +