ia64/xen-unstable
changeset 3327:6b1aa25ff284
bitkeeper revision 1.1159.1.504 (41cc93b0yD09pgWkeLlUepCAam5oFA)
Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-2.0-testing.bk
into labyrinth.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-unstable.bk
Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-2.0-testing.bk
into labyrinth.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-unstable.bk
author | iap10@labyrinth.cl.cam.ac.uk |
---|---|
date | Fri Dec 24 22:09:52 2004 +0000 (2004-12-24) |
parents | c8def7019487 f36de623daa0 |
children | 39a7a74fd6f9 |
files | .rootkeys tools/libxc/Makefile tools/libxc/plan9a.out.h tools/libxc/xc.h tools/libxc/xc_plan9_build.c tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/XendDomainInfo.py |
line diff
1.1 --- a/.rootkeys Thu Dec 23 14:06:12 2004 +0000 1.2 +++ b/.rootkeys Fri Dec 24 22:09:52 2004 +0000 1.3 @@ -329,6 +329,7 @@ 40ee75a93cqxHp6MiYXxxwR5j2_8QQ tools/exa 1.4 41090ec8Pj_bkgCBpg2W7WfmNkumEA tools/examples/xmexample1 1.5 40cf2937oKlROYOJTN8GWwWM5AmjBg tools/examples/xmexample2 1.6 3fbba6dbDfYvJSsw9500b4SZyUhxjQ tools/libxc/Makefile 1.7 +41cc934abX-QLXJXW_clV_wRjM0zYg tools/libxc/plan9a.out.h 1.8 3fbba6dc1uU7U3IFeF6A-XEOYF2MkQ tools/libxc/rpm.spec 1.9 3fbba6dcrNxtygEcgJYAJJ1gCQqfsA tools/libxc/xc.h 1.10 40589968oCfoUlXd460CjVAkBE8IBA tools/libxc/xc_atropos.c 1.11 @@ -343,6 +344,7 @@ 3fbba6dbl267zZOAVHYLOdLCdhcZMw tools/lib 1.12 3fbba6db7li3FJiABYtCmuGxOJxEGw tools/libxc/xc_linux_save.c 1.13 3fbba6db7WnnJr0KFrIFrqNlSKvFYg tools/libxc/xc_misc.c 1.14 4051bce6CHAsYh8P5t2OHDtRWOP9og tools/libxc/xc_physdev.c 1.15 +41cc934aO1m6NxEh_8eDr9bJIMoLFA tools/libxc/xc_plan9_build.c 1.16 3fbba6dctWRWlFJkYb6hdix2X4WMuw tools/libxc/xc_private.c 1.17 3fbba6dcbVrG2hPzEzwdeV_UC8kydQ tools/libxc/xc_private.h 1.18 40589968UQFnJeOMn8UIFLbXBuwXjw tools/libxc/xc_rrobin.c
2.1 --- a/tools/libxc/Makefile Thu Dec 23 14:06:12 2004 +0000 2.2 +++ b/tools/libxc/Makefile Fri Dec 24 22:09:52 2004 +0000 2.3 @@ -18,6 +18,7 @@ SRCS += xc_domain.c 2.4 SRCS += xc_evtchn.c 2.5 SRCS += xc_io.c 2.6 SRCS += xc_linux_build.c 2.7 +SRCS += xc_plan9_build.c 2.8 SRCS += xc_linux_restore.c 2.9 SRCS += xc_linux_save.c 2.10 SRCS += xc_misc.c
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/tools/libxc/plan9a.out.h Fri Dec 24 22:09:52 2004 +0000 3.3 @@ -0,0 +1,28 @@ 3.4 + 3.5 +typedef struct Exec 3.6 +{ 3.7 + long magic; /* magic number */ 3.8 + long text; /* size of text segment */ 3.9 + long data; /* size of initialized data */ 3.10 + long bss; /* size of uninitialized data */ 3.11 + long syms; /* size of symbol table */ 3.12 + long entry; /* entry point */ 3.13 + long spsz; /* size of pc/sp offset table */ 3.14 + long pcsz; /* size of pc/line number table */ 3.15 +} Exec; 3.16 + 3.17 +#define _MAGIC(b) ((((4*b)+0)*b)+7) 3.18 +#define A_MAGIC _MAGIC(8) /* 68020 */ 3.19 +#define I_MAGIC _MAGIC(11) /* intel 386 */ 3.20 +#define J_MAGIC _MAGIC(12) /* intel 960 */ 3.21 +#define K_MAGIC _MAGIC(13) /* sparc */ 3.22 +#define V_MAGIC _MAGIC(16) /* mips 3000 */ 3.23 +#define X_MAGIC _MAGIC(17) /* att dsp 3210 */ 3.24 +#define M_MAGIC _MAGIC(18) /* mips 4000 */ 3.25 +#define D_MAGIC _MAGIC(19) /* amd 29000 */ 3.26 +#define E_MAGIC _MAGIC(20) /* arm 7-something */ 3.27 +#define Q_MAGIC _MAGIC(21) /* powerpc */ 3.28 +#define N_MAGIC _MAGIC(22) /* mips 4000 LE */ 3.29 +#define L_MAGIC _MAGIC(23) /* dec alpha */ 3.30 +#define P_MAGIC _MAGIC(24) /* mips 3000 LE */ 3.31 +
4.1 --- a/tools/libxc/xc.h Thu Dec 23 14:06:12 2004 +0000 4.2 +++ b/tools/libxc/xc.h Fri Dec 24 22:09:52 2004 +0000 4.3 @@ -97,6 +97,14 @@ int xc_linux_build(int xc_handle, 4.4 unsigned int control_evtchn, 4.5 unsigned long flags); 4.6 4.7 +int 4.8 +xc_plan9_build (int xc_handle, 4.9 + u32 domid, 4.10 + const char *image_name, 4.11 + const char *cmdline, 4.12 + unsigned int control_evtchn, 4.13 + unsigned long flags); 4.14 + 4.15 int xc_bvtsched_global_set(int xc_handle, 4.16 unsigned long ctx_allow); 4.17
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/tools/libxc/xc_plan9_build.c Fri Dec 24 22:09:52 2004 +0000 5.3 @@ -0,0 +1,744 @@ 5.4 +/****************************************************************************** 5.5 + * xc_plan9_build.c 5.6 + * derived from xc_linux_build.c 5.7 + */ 5.8 + 5.9 +#include "xc_private.h" 5.10 + 5.11 +#include <zlib.h> 5.12 + 5.13 +#define DEBUG 1 5.14 +#ifdef DEBUG 5.15 +#define DPRINTF(x) printf x; fflush(stdout); 5.16 +#else 5.17 +#define DPRINTF(x) 5.18 +#endif 5.19 + 5.20 +#include "plan9a.out.h" 5.21 + 5.22 +/* really TOS which means stack starts at 0x2000, and uses page 1*/ 5.23 +#define STACKPAGE 2 5.24 +struct Exec header, origheader; 5.25 + 5.26 +typedef struct page { 5.27 + char data[PAGE_SIZE]; 5.28 +} PAGE; 5.29 + 5.30 + 5.31 +int 5.32 +memcpy_toguest(int xc_handle, u32 dom, void *v, int size, 5.33 + unsigned long *page_array, unsigned int to_page) 5.34 +{ 5.35 + int ret; 5.36 + unsigned char *cp = v; 5.37 + unsigned int whichpage; 5.38 + unsigned char *vaddr; 5.39 + 5.40 +// DPRINTF(("memcpy_to_guest: to_page 0x%x, count %d\n", to_page, size)); 5.41 + for (ret = 0, whichpage = to_page; size > 0; 5.42 + whichpage++, size -= PAGE_SIZE, cp += PAGE_SIZE) { 5.43 + 5.44 + // DPRINTF (("map_pfn_writeable(%p, 0x%lx)\n", pm_handle, 5.45 +// page_array[whichpage])); 5.46 + vaddr = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 5.47 + PROT_READ | PROT_WRITE, 5.48 + page_array[whichpage]); 5.49 + // DPRINTF (("vaddr is %p\n", vaddr)); 5.50 + if (vaddr == NULL) { 5.51 + ret = -1; 5.52 + ERROR("Couldn't map guest memory"); 5.53 + goto out; 5.54 + } 5.55 + // DPRINTF (("copy %p to %p, count 0x%x\n", cp, vaddr, 4096)); 5.56 + memcpy(vaddr, cp, 4096); 5.57 + munmap(vaddr, PAGE_SIZE); 5.58 + // DPRINTF (("Did %ud'th pages\n", whichpage)); 5.59 + } 5.60 + out: 5.61 + return ret; 5.62 +} 5.63 + 5.64 +/* this is a function which can go away. It dumps a hunk of 5.65 + * guest pages to a file (/tmp/dumpit); handy for debugging 5.66 + * your image builder. 5.67 + * Xen guys, nuke this if you wish. 5.68 + */ 5.69 +void 5.70 +dumpit(int xc_handle, u32 dom, 5.71 + int start_page, int tot, unsigned long *page_array) 5.72 +{ 5.73 + int i, ofd; 5.74 + unsigned char *vaddr; 5.75 + 5.76 + ofd = open("/tmp/dumpit", O_RDWR); 5.77 + for (i = start_page; i < tot; i++) { 5.78 + vaddr = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 5.79 + PROT_READ | PROT_WRITE, 5.80 + page_array[i]); 5.81 + if (!vaddr) { 5.82 + fprintf(stderr, "Page %d\n", i); 5.83 + perror("shit"); 5.84 + read(0, &i, 1); 5.85 + return; 5.86 + } 5.87 + write(ofd, vaddr, 4096); 5.88 + munmap(vaddr, PAGE_SIZE); 5.89 + } 5.90 +} 5.91 +int 5.92 +blah(char *b) 5.93 +{ 5.94 + fprintf(stderr, "Error in xc_plan9_build!\n"); 5.95 + perror(b); 5.96 + return errno; 5.97 +} 5.98 + 5.99 +/* swap bytes. For plan 9 headers */ 5.100 +void 5.101 +swabby(unsigned long *s, char *name) 5.102 +{ 5.103 + unsigned long it; 5.104 + it = ((*s & 0xff000000) >> 24) | ((*s & 0xff0000) >> 8) | 5.105 + ((*s & 0xff00) << 8) | ((*s & 0xff) << 24); 5.106 + DPRINTF(("Item %s is 0x%lx\n", name, it)); 5.107 + *s = it; 5.108 +} 5.109 + 5.110 +void 5.111 +plan9header(Exec * header) 5.112 +{ 5.113 + /* header is big-endian */ 5.114 + swabby(&header->magic, "magic"); 5.115 + swabby(&header->text, "text"); 5.116 + swabby(&header->data, "data"); 5.117 + swabby(&header->bss, "bss"); 5.118 + swabby(&header->syms, "syms"); 5.119 + swabby(&header->entry, "entry"); 5.120 + swabby(&header->spsz, "spsz"); 5.121 + swabby(&header->pcsz, "pcsz"); 5.122 + 5.123 +} 5.124 + 5.125 +static int 5.126 + loadp9image(gzFile kernel_gfd, int xc_handle, u32 dom, 5.127 + unsigned long *page_array, 5.128 + unsigned long tot_pages, unsigned long *virt_load_addr, 5.129 + unsigned long *ksize, unsigned long *symtab_addr, 5.130 + unsigned long *symtab_len, 5.131 + unsigned long *first_data_page, unsigned long *pdb_page); 5.132 + 5.133 +#define P9ROUND (P9SIZE / 8) 5.134 + 5.135 +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) 5.136 +#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) 5.137 + 5.138 +static long 5.139 +get_tot_pages(int xc_handle, u32 domid) 5.140 +{ 5.141 + dom0_op_t op; 5.142 + op.cmd = DOM0_GETDOMAININFO; 5.143 + op.u.getdomaininfo.domain = (domid_t) domid; 5.144 + op.u.getdomaininfo.ctxt = NULL; 5.145 + return (do_dom0_op(xc_handle, &op) < 0) ? 5.146 + -1 : op.u.getdomaininfo.tot_pages; 5.147 +} 5.148 + 5.149 +static int 5.150 +get_pfn_list(int xc_handle, 5.151 + u32 domid, unsigned long *pfn_buf, unsigned long max_pfns) 5.152 +{ 5.153 + dom0_op_t op; 5.154 + int ret; 5.155 + op.cmd = DOM0_GETMEMLIST; 5.156 + op.u.getmemlist.domain = (domid_t) domid; 5.157 + op.u.getmemlist.max_pfns = max_pfns; 5.158 + op.u.getmemlist.buffer = pfn_buf; 5.159 + 5.160 + if (mlock(pfn_buf, max_pfns * sizeof (unsigned long)) != 0) 5.161 + return -1; 5.162 + 5.163 + ret = do_dom0_op(xc_handle, &op); 5.164 + 5.165 + (void) munlock(pfn_buf, max_pfns * sizeof (unsigned long)); 5.166 + 5.167 +#if 0 5.168 +#ifdef DEBUG 5.169 + DPRINTF(("Ret for get_pfn_list is %d\n", ret)); 5.170 + if (ret >= 0) { 5.171 + int i, j; 5.172 + for (i = 0; i < op.u.getmemlist.num_pfns; i += 16) { 5.173 + fprintf(stderr, "0x%x: ", i); 5.174 + for (j = 0; j < 16; j++) 5.175 + fprintf(stderr, "0x%lx ", pfn_buf[i + j]); 5.176 + fprintf(stderr, "\n"); 5.177 + } 5.178 + } 5.179 +#endif 5.180 +#endif 5.181 + return (ret < 0) ? -1 : op.u.getmemlist.num_pfns; 5.182 +} 5.183 + 5.184 +static int 5.185 +setup_guestos(int xc_handle, 5.186 + u32 dom, 5.187 + gzFile kernel_gfd, 5.188 + unsigned long tot_pages, 5.189 + unsigned long *virt_startinfo_addr, 5.190 + unsigned long *virt_load_addr, 5.191 + full_execution_context_t * ctxt, 5.192 + const char *cmdline, 5.193 + unsigned long shared_info_frame, 5.194 + unsigned int control_evtchn, 5.195 + int flags) 5.196 +{ 5.197 + l1_pgentry_t *vl1e = NULL; 5.198 + l2_pgentry_t *vl2tab = NULL, *vl2e = NULL; 5.199 + unsigned long *cpage_array = NULL; 5.200 + unsigned long *pte_array = NULL; 5.201 + unsigned long l2tab; 5.202 + unsigned long l1tab; 5.203 + unsigned long count; 5.204 + unsigned long symtab_addr = 0, symtab_len = 0; 5.205 + start_info_t *start_info; 5.206 + shared_info_t *shared_info; 5.207 + unsigned long ksize; 5.208 + mmu_t *mmu = NULL; 5.209 + int i; 5.210 + unsigned long first_page_after_kernel, 5.211 + first_data_page, 5.212 + page_array_page; 5.213 + unsigned long cpu0pdb, cpu0pte, cpu0ptelast; 5.214 + unsigned long /*last_pfn, */ tot_pte_pages; 5.215 + 5.216 + DPRINTF(("tot pages is %ld\n", tot_pages)); 5.217 + if ((cpage_array = malloc(tot_pages * sizeof (unsigned long))) == NULL) { 5.218 + PERROR("Could not allocate cpage array"); 5.219 + goto error_out; 5.220 + } 5.221 + 5.222 + if (get_pfn_list(xc_handle, dom, cpage_array, tot_pages) != tot_pages) { 5.223 + PERROR("Could not get the page frame list"); 5.224 + goto error_out; 5.225 + } 5.226 + 5.227 + for (i = 0; i < 64; i++) 5.228 + DPRINTF(("First %d page is 0x%lx\n", i, cpage_array[i])); 5.229 + 5.230 + tot_pte_pages = tot_pages >> 10; 5.231 + DPRINTF(("Page range is 0 to 0x%lx, which requires 0x%lx pte pages\n", 5.232 + tot_pte_pages, tot_pte_pages)); 5.233 + 5.234 + if (loadp9image(kernel_gfd, xc_handle, dom, cpage_array, tot_pages, 5.235 + virt_load_addr, &ksize, &symtab_addr, &symtab_len, 5.236 + &first_data_page, &first_page_after_kernel)) 5.237 + goto error_out; 5.238 + DPRINTF(("First data page is 0x%lx\n", first_data_page)); 5.239 + DPRINTF(("First page after kernel is 0x%lx\n", 5.240 + first_page_after_kernel)); 5.241 + 5.242 + /* 5.243 + NEED TO INCREMENT first page after kernel by: 5.244 + + 1 (pdb) 5.245 + + tot_pte_pages (pte) 5.246 + + tot_pte_pages (page_array) 5.247 + */ 5.248 + /* SO, have to copy the first kernel pages pfns right into the 5.249 + * page_array, then do identity maps for the rest. 5.250 + */ 5.251 + DPRINTF(("mapped kernel pages\n")); 5.252 + 5.253 + /* now loop over all ptes and store into the page_array, so as 5.254 + * to get the identity map. 5.255 + */ 5.256 + if ((pte_array = 5.257 + malloc(tot_pte_pages * 1024 * sizeof (unsigned long))) == NULL) { 5.258 + PERROR("Could not allocate pte array"); 5.259 + goto error_out; 5.260 + } 5.261 + 5.262 + /* plan 9 on startup expects a "l2" (xen parlance) at 0x2000, 5.263 + * this "l2" should have one PTE pointer for a va of 0x80000000. 5.264 + * and an l1 (PTEs to you) at 0x3000. (physical). 5.265 + * the PTEs should map the first 4M of memory. 5.266 + */ 5.267 + /* get a physical address for the L2. This means take the PFN and 5.268 + * shift left. 5.269 + */ 5.270 + /* this terminology is plan 9 terminology. 5.271 + * pdb is essentially the Xen L2. 'Page Directory Block'? 5.272 + * I need to ask JMK. 5.273 + * cpupte is the pte array. 5.274 + * Plan 9 counts on these being set up for cpu0. 5.275 + * SO: cpu0pdb (Xen L2) 5.276 + * and cpupte (Xen L1) 5.277 + */ 5.278 + /* cpu0pdb is right after kernel */ 5.279 + cpu0pdb = first_page_after_kernel; 5.280 + /* cpu0pte comes right after cpu0pdb */ 5.281 + cpu0pte = cpu0pdb + 1; 5.282 + /* number of the past cpu0pte page */ 5.283 + cpu0ptelast = cpu0pte + tot_pte_pages - 1; 5.284 + /* first page of the page array (mfn) */ 5.285 + page_array_page = cpu0ptelast + 1; 5.286 + 5.287 + DPRINTF(("cpu0pdb 0x%lx, cpu0pte 0x%lx cpu0ptelast 0x%lx\n", cpu0pdb, 5.288 + cpu0pte, cpu0ptelast)); 5.289 + l2tab = cpage_array[cpu0pdb] << PAGE_SHIFT; 5.290 + DPRINTF(("l2tab 0x%lx\n", l2tab)); 5.291 + ctxt->pt_base = l2tab; 5.292 + 5.293 + /* get a physical address for the L1. This means take the PFN and 5.294 + * shift left. 5.295 + */ 5.296 + l1tab = cpage_array[cpu0pte] << PAGE_SHIFT; 5.297 + DPRINTF(("l1tab 0x%lx\n", l1tab)); 5.298 + if ((mmu = init_mmu_updates(xc_handle, dom)) == NULL) 5.299 + goto error_out; 5.300 + DPRINTF(("now map in l2tab\n")); 5.301 + 5.302 + /* Initialise the page tables. */ 5.303 + /* mmap in the l2tab */ 5.304 + if ((vl2tab = xc_map_foreign_range(xc_handle, dom, 5.305 + PAGE_SIZE, PROT_READ | PROT_WRITE, 5.306 + l2tab >> PAGE_SHIFT)) == NULL) 5.307 + goto error_out; 5.308 + DPRINTF(("vl2tab 0x%p\n", vl2tab)); 5.309 + /* now we have the cpu0pdb for the kernel, starting at 0x2000, 5.310 + * so we can plug in the physical pointer to the 0x3000 pte 5.311 + */ 5.312 + /* zero it */ 5.313 + memset(vl2tab, 0, PAGE_SIZE); 5.314 + /* get a pointer in the l2tab for the virt_load_addr */ 5.315 + DPRINTF(("&vl2tab[l2_table_offset(*virt_load_addr)] is 0x%p[0x%lx]\n", 5.316 + &vl2tab[l2_table_offset(*virt_load_addr)], 5.317 + l2_table_offset(*virt_load_addr))); 5.318 + 5.319 + vl2e = &vl2tab[l2_table_offset(*virt_load_addr)]; 5.320 + 5.321 + /* OK, for all the available PTE, set the PTE pointer up */ 5.322 + DPRINTF(("For i = %ld to %ld ...\n", cpu0pte, cpu0ptelast)); 5.323 + for (i = cpu0pte; i <= cpu0ptelast; i++) { 5.324 + DPRINTF(("Index %d Set %p to 0x%lx\n", i, vl2e, 5.325 + (cpage_array[i] << PAGE_SHIFT) | L2_PROT)); 5.326 + *vl2e++ = (cpage_array[i] << PAGE_SHIFT) | L2_PROT; 5.327 + } 5.328 + 5.329 + /* unmap it ... */ 5.330 + munmap(vl2tab, PAGE_SIZE); 5.331 + 5.332 + /* for the pages from virt_load_pointer to the end of this 5.333 + * set of PTEs, map in the PFN for that VA 5.334 + */ 5.335 + for (vl1e = (l1_pgentry_t *) pte_array, count = 0; 5.336 + count < tot_pte_pages * 1024; count++, vl1e++) { 5.337 + 5.338 + *vl1e = cpage_array[count]; 5.339 + if (!cpage_array[count]) 5.340 + continue; 5.341 + /* set in the PFN for this entry */ 5.342 + *vl1e = (cpage_array[count] << PAGE_SHIFT) | L1_PROT; 5.343 +/* 5.344 + DPRINTF (("vl1e # %d 0x%lx gets 0x%lx\n", 5.345 + count, vl1e, *vl1e)); 5.346 +*/ 5.347 + if ((count >= cpu0pdb) && (count <= cpu0ptelast)) { 5.348 + //DPRINTF((" Fix up page %d as it is in pte ville: ", count)); 5.349 + *vl1e &= ~_PAGE_RW; 5.350 + DPRINTF(("0x%lx\n", *vl1e)); 5.351 + } 5.352 + if ((count >= (0x100000 >> 12)) 5.353 + && (count < (first_data_page >> 12))) { 5.354 + //DPRINTF((" Fix up page %d as it is in text ", count)); 5.355 + *vl1e &= ~_PAGE_RW; 5.356 + //DPRINTF (("0x%lx\n", *vl1e)); 5.357 + } 5.358 + } 5.359 + /* special thing. Pre-map the shared info page */ 5.360 + vl1e = &pte_array[2]; 5.361 + *vl1e = (shared_info_frame << PAGE_SHIFT) | L1_PROT; 5.362 + DPRINTF(("v1l1 %p, has value 0x%lx\n", vl1e, *(unsigned long *) vl1e)); 5.363 + /* another special thing. VA 80005000 has to point to 80006000 */ 5.364 + /* this is a Plan 9 thing -- the 'mach' pointer */ 5.365 + /* 80005000 is the mach pointer per-cpu, and the actual 5.366 + * mach pointers are 80006000, 80007000 etc. 5.367 + */ 5.368 + vl1e = &pte_array[5]; 5.369 + *vl1e = (cpage_array[6] << PAGE_SHIFT) | L1_PROT; 5.370 + 5.371 + /* OK, it's all set up, copy it in */ 5.372 + memcpy_toguest(xc_handle, dom, pte_array, 5.373 + (tot_pte_pages * 1024 * sizeof (unsigned long) /**/), 5.374 + cpage_array, cpu0pte); 5.375 + 5.376 + /* We really need to have the vl1tab unmapped or the add_mmu_update 5.377 + * below will fail bigtime. 5.378 + */ 5.379 + /* Xen guys: remember my errors on domain exit? Something I'm doing 5.380 + * wrong in here? We never did find out ... 5.381 + */ 5.382 + /* get rid of the entries we can not use ... */ 5.383 + memcpy_toguest(xc_handle, dom, cpage_array, 5.384 + (tot_pte_pages * 1024 * sizeof (unsigned long) /**/), 5.385 + cpage_array, page_array_page); 5.386 + /* last chance to dump all of memory */ 5.387 + // dumpit(xc_handle, dom, 0 /*0x100000>>12*/, tot_pages, cpage_array) ; 5.388 + /* 5.389 + * Pin down l2tab addr as page dir page - causes hypervisor to provide 5.390 + * correct protection for the page 5.391 + */ 5.392 + if (add_mmu_update(xc_handle, mmu, 5.393 + l2tab | MMU_EXTENDED_COMMAND, MMUEXT_PIN_L2_TABLE)) 5.394 + goto error_out; 5.395 + 5.396 + for (count = 0; count < tot_pages; count++) { 5.397 +/* 5.398 + DPRINTF (("add_mmu_update(0x%x, 0x%x, 0x%x, %d)\n", xc_handle, mmu, 5.399 + (cpage_array[count] 5.400 + << PAGE_SHIFT) | 5.401 + MMU_MACHPHYS_UPDATE, 5.402 + count)); 5.403 +*/ 5.404 + if (add_mmu_update(xc_handle, mmu, 5.405 + (cpage_array[count] << PAGE_SHIFT) | 5.406 + MMU_MACHPHYS_UPDATE, count)) 5.407 + goto error_out; 5.408 + //DPRINTF(("Do the next one\n")); 5.409 + } 5.410 +/* 5.411 + */ 5.412 + 5.413 + //dumpit(pm_handle, 3, 4, page_array); 5.414 + /* put the virt_startinfo_addr at KZERO */ 5.415 + /* just hard-code for now */ 5.416 + *virt_startinfo_addr = 0x80000000; 5.417 + 5.418 + DPRINTF(("virt_startinfo_addr = 0x%lx\n", *virt_startinfo_addr)); 5.419 + start_info = xc_map_foreign_range(xc_handle, dom, 5.420 + PAGE_SIZE, PROT_READ | PROT_WRITE, 5.421 + cpage_array[0]); 5.422 + DPRINTF(("startinfo = 0x%p\n", start_info)); 5.423 + DPRINTF(("shared_info_frame is %lx\n", shared_info_frame)); 5.424 + memset(start_info, 0, sizeof (*start_info)); 5.425 + start_info->pt_base = 0x80000000 | cpu0pdb << PAGE_SHIFT; 5.426 + start_info->mfn_list = 0x80000000 | (page_array_page) << PAGE_SHIFT; 5.427 + DPRINTF(("mfn_list 0x%lx\n", start_info->mfn_list)); 5.428 + start_info->mod_start = 0; 5.429 + start_info->mod_len = 0; 5.430 + start_info->nr_pages = tot_pte_pages * 1024; 5.431 + start_info->nr_pt_frames = tot_pte_pages + 1; 5.432 + start_info->shared_info = shared_info_frame; 5.433 + start_info->flags = 0; 5.434 + DPRINTF((" control event channel is %d\n", control_evtchn)); 5.435 + start_info->domain_controller_evtchn = control_evtchn; 5.436 + strncpy(start_info->cmd_line, cmdline, MAX_CMDLINE); 5.437 + start_info->cmd_line[MAX_CMDLINE - 1] = '\0'; 5.438 + munmap(start_info, PAGE_SIZE); 5.439 + 5.440 + DPRINTF(("done setting up start_info\n")); 5.441 + DPRINTF(("shared_info_frame = 0x%lx\n", shared_info_frame)); 5.442 + /* shared_info page starts its life empty. */ 5.443 + 5.444 + shared_info = xc_map_foreign_range(xc_handle, dom, 5.445 + PAGE_SIZE, PROT_READ | PROT_WRITE, 5.446 + shared_info_frame); 5.447 + memset(shared_info, 0, PAGE_SIZE); 5.448 + /* Mask all upcalls... */ 5.449 + DPRINTF(("mask all upcalls\n")); 5.450 + for (i = 0; i < MAX_VIRT_CPUS; i++) 5.451 + shared_info->vcpu_data[i].evtchn_upcall_mask = 1; 5.452 + munmap(shared_info, PAGE_SIZE); 5.453 + 5.454 + /* Send the page update requests down to the hypervisor. */ 5.455 + DPRINTF(("send page update reqs down.\n")); 5.456 + if (finish_mmu_updates(xc_handle, mmu)) 5.457 + goto error_out; 5.458 + 5.459 + //DPRINTF (("call dumpit.\n")); 5.460 + //dumpit(pm_handle, 0x100000>>12, tot_pages, page_array) ; 5.461 + //dumpit (pm_handle, 2, 0x100, page_array); 5.462 + free(mmu); 5.463 + 5.464 + /* we don't bother freeing anything at this point -- 5.465 + * we're exiting and it is pointless 5.466 + */ 5.467 + return 0; 5.468 + 5.469 + error_out: 5.470 + /* oh well we still free some things -- I oughtta nuke this */ 5.471 + if (mmu != NULL) 5.472 + free(mmu); 5.473 + ; 5.474 + return -1; 5.475 +} 5.476 + 5.477 +int 5.478 +xc_plan9_build(int xc_handle, 5.479 + u32 domid, 5.480 + const char *image_name, 5.481 + const char *cmdline, 5.482 + unsigned int control_evtchn, unsigned long flags) 5.483 +{ 5.484 + dom0_op_t launch_op, op; 5.485 + unsigned long load_addr; 5.486 + long tot_pages; 5.487 + int kernel_fd = -1; 5.488 + gzFile kernel_gfd = NULL; 5.489 + int rc, i; 5.490 + full_execution_context_t st_ctxt, *ctxt = &st_ctxt; 5.491 + unsigned long virt_startinfo_addr; 5.492 + 5.493 + if ((tot_pages = get_tot_pages(xc_handle, domid)) < 0) { 5.494 + PERROR("Could not find total pages for domain"); 5.495 + return 1; 5.496 + } 5.497 + DPRINTF(("get_tot_pages returns %ld pages\n", tot_pages)); 5.498 + 5.499 + kernel_fd = open(image_name, O_RDONLY); 5.500 + if (kernel_fd < 0) { 5.501 + PERROR("Could not open kernel image"); 5.502 + return 1; 5.503 + } 5.504 + 5.505 + if ((kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL) { 5.506 + PERROR("Could not allocate decompression state for state file"); 5.507 + close(kernel_fd); 5.508 + return 1; 5.509 + } 5.510 + 5.511 + DPRINTF(("get_tot_pages returns %ld pages\n", tot_pages)); 5.512 + if (mlock(&st_ctxt, sizeof (st_ctxt))) { 5.513 + PERROR("Unable to mlock ctxt"); 5.514 + return 1; 5.515 + } 5.516 + 5.517 + op.cmd = DOM0_GETDOMAININFO; 5.518 + op.u.getdomaininfo.domain = (domid_t) domid; 5.519 + op.u.getdomaininfo.ctxt = ctxt; 5.520 + if ((do_dom0_op(xc_handle, &op) < 0) || 5.521 + ((u32) op.u.getdomaininfo.domain != domid)) { 5.522 + PERROR("Could not get info on domain"); 5.523 + goto error_out; 5.524 + } 5.525 + DPRINTF(("get_tot_pages returns %ld pages\n", tot_pages)); 5.526 + 5.527 + if (!(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) 5.528 + || (op.u.getdomaininfo.ctxt->pt_base != 0)) { 5.529 + ERROR("Domain is already constructed"); 5.530 + goto error_out; 5.531 + } 5.532 + 5.533 + DPRINTF(("get_tot_pages returns %ld pages\n", tot_pages)); 5.534 + if (setup_guestos(xc_handle, domid, kernel_gfd, tot_pages, 5.535 + &virt_startinfo_addr, 5.536 + &load_addr, &st_ctxt, cmdline, 5.537 + op.u.getdomaininfo.shared_info_frame, 5.538 + control_evtchn, flags) < 0) { 5.539 + ERROR("Error constructing guest OS"); 5.540 + goto error_out; 5.541 + } 5.542 + 5.543 + /* leave the leak in here for now 5.544 + if ( kernel_fd >= 0 ) 5.545 + close(kernel_fd); 5.546 + if( kernel_gfd ) 5.547 + gzclose(kernel_gfd); 5.548 + */ 5.549 + ctxt->flags = 0; 5.550 + 5.551 + /* 5.552 + * Initial register values: 5.553 + * DS,ES,FS,GS = FLAT_GUESTOS_DS 5.554 + * CS:EIP = FLAT_GUESTOS_CS:start_pc 5.555 + * SS:ESP = FLAT_GUESTOS_DS:start_stack 5.556 + * ESI = start_info 5.557 + * [EAX,EBX,ECX,EDX,EDI,EBP are zero] 5.558 + * EFLAGS = IF | 2 (bit 1 is reserved and should always be 1) 5.559 + */ 5.560 + ctxt->cpu_ctxt.ds = FLAT_GUESTOS_DS; 5.561 + ctxt->cpu_ctxt.es = FLAT_GUESTOS_DS; 5.562 + ctxt->cpu_ctxt.fs = FLAT_GUESTOS_DS; 5.563 + ctxt->cpu_ctxt.gs = FLAT_GUESTOS_DS; 5.564 + ctxt->cpu_ctxt.ss = FLAT_GUESTOS_DS; 5.565 + ctxt->cpu_ctxt.cs = FLAT_GUESTOS_CS; 5.566 + ctxt->cpu_ctxt.eip = load_addr; 5.567 + ctxt->cpu_ctxt.eip = 0x80100020; 5.568 + /* put stack at top of second page */ 5.569 + ctxt->cpu_ctxt.esp = 0x80000000 + (STACKPAGE << PAGE_SHIFT); 5.570 + 5.571 + /* why is this set? */ 5.572 + ctxt->cpu_ctxt.esi = ctxt->cpu_ctxt.esp; 5.573 + ctxt->cpu_ctxt.eflags = (1 << 9) | (1 << 2); 5.574 + 5.575 + /* FPU is set up to default initial state. */ 5.576 + memset(ctxt->fpu_ctxt, 0, sizeof (ctxt->fpu_ctxt)); 5.577 + 5.578 + /* Virtual IDT is empty at start-of-day. */ 5.579 + for (i = 0; i < 256; i++) { 5.580 + ctxt->trap_ctxt[i].vector = i; 5.581 + ctxt->trap_ctxt[i].cs = FLAT_GUESTOS_CS; 5.582 + } 5.583 + ctxt->fast_trap_idx = 0; 5.584 + 5.585 + /* No LDT. */ 5.586 + ctxt->ldt_ents = 0; 5.587 + 5.588 + /* Use the default Xen-provided GDT. */ 5.589 + ctxt->gdt_ents = 0; 5.590 + 5.591 + /* Ring 1 stack is the initial stack. */ 5.592 + /* put stack at top of second page */ 5.593 + ctxt->guestos_ss = FLAT_GUESTOS_DS; 5.594 + ctxt->guestos_esp = ctxt->cpu_ctxt.esp; 5.595 + 5.596 + /* No debugging. */ 5.597 + memset(ctxt->debugreg, 0, sizeof (ctxt->debugreg)); 5.598 + 5.599 + /* No callback handlers. */ 5.600 + ctxt->event_callback_cs = FLAT_GUESTOS_CS; 5.601 + ctxt->event_callback_eip = 0; 5.602 + ctxt->failsafe_callback_cs = FLAT_GUESTOS_CS; 5.603 + ctxt->failsafe_callback_eip = 0; 5.604 + 5.605 + memset(&launch_op, 0, sizeof (launch_op)); 5.606 + 5.607 + launch_op.u.builddomain.domain = (domid_t) domid; 5.608 + // launch_op.u.builddomain.num_vifs = 1; 5.609 + launch_op.u.builddomain.ctxt = ctxt; 5.610 + launch_op.cmd = DOM0_BUILDDOMAIN; 5.611 + rc = do_dom0_op(xc_handle, &launch_op); 5.612 + 5.613 + fprintf(stderr, "RC is %d\n", rc); 5.614 + return rc; 5.615 + 5.616 + error_out: 5.617 + if (kernel_fd >= 0) 5.618 + close(kernel_fd); 5.619 + if (kernel_gfd) 5.620 + gzclose(kernel_gfd); 5.621 + 5.622 + return -1; 5.623 +} 5.624 + 5.625 +/* 5.626 + * Plan 9 memory layout (initial) 5.627 + * ---------------- 5.628 + * | info from xen| @0 5.629 + * ---------------- 5.630 + * | stack | 5.631 + * ----------------<--- page 2 5.632 + * | empty | 5.633 + * ---------------<---- page 5 MACHADDR (always points to machp[cpuno] 5.634 + * | aliased | 5.635 + * ---------------<----- page 6 CPU0MACH 5.636 + * | CPU0MACH | 5.637 + * ---------------- 5.638 + * | empty | 5.639 + * ---------------- *virt_load_addr = ehdr.e_entry (0x80100000) 5.640 + * | kernel | 5.641 + * | | 5.642 + * ---------------- <----- page aligned boundary. 5.643 + * | data | 5.644 + * | | 5.645 + * ---------------- 5.646 + * | bss | 5.647 + * ----------------<--- end of kernel (page aligned) 5.648 + * | PMD cpu0pdb | 5.649 + * ----------------<--- page +1 5.650 + * | PTE cpu0pte | 5.651 + * ----------------<--- page (tot_pte_pages)/1024 5.652 + * | page_array | 5.653 + * ---------------- <--- page (tot_pte_pages)/1024 5.654 + * | empty to TOM | 5.655 + * ---------------- 5.656 + */ 5.657 + 5.658 +static int 5.659 +loadp9image(gzFile kernel_gfd, int xc_handle, u32 dom, 5.660 + unsigned long *page_array, 5.661 + unsigned long tot_pages, unsigned long *virt_load_addr, 5.662 + unsigned long *ksize, unsigned long *symtab_addr, 5.663 + unsigned long *symtab_len, 5.664 + unsigned long *first_data_page, unsigned long *pdb_page) 5.665 +{ 5.666 + unsigned long datapage; 5.667 + Exec ehdr; 5.668 + 5.669 + char *p; 5.670 + unsigned long maxva; 5.671 + int curpos, ret; 5.672 + PAGE *image = 0; 5.673 + unsigned long image_tot_pages = 0; 5.674 + unsigned long textround; 5.675 + 5.676 + ret = -1; 5.677 + 5.678 + p = NULL; 5.679 + maxva = 0; 5.680 + 5.681 + if (gzread(kernel_gfd, &ehdr, sizeof (Exec)) != sizeof (Exec)) { 5.682 + PERROR("Error reading kernel image P9 header."); 5.683 + goto out; 5.684 + } 5.685 + 5.686 + plan9header(&ehdr); 5.687 + curpos = sizeof (Exec); 5.688 + 5.689 + if (ehdr.magic != I_MAGIC) { 5.690 + PERROR("Image does not have an P9 header."); 5.691 + goto out; 5.692 + } 5.693 + 5.694 + textround = ((ehdr.text + 0x20 + 4095) >> 12) << 12; 5.695 + *first_data_page = 0x100000 + textround; 5.696 + DPRINTF(("ehrd.text is 0x%lx, textround is 0x%lx\n", 5.697 + ehdr.text, textround)); 5.698 + 5.699 + image_tot_pages = 5.700 + (textround + ehdr.data + ehdr.bss + PAGE_SIZE - 1) >> PAGE_SHIFT; 5.701 + DPRINTF(("tot pages is %ld\n", image_tot_pages)); 5.702 + 5.703 + *virt_load_addr = 0x80100000; 5.704 + 5.705 + if ((*virt_load_addr & (PAGE_SIZE - 1)) != 0) { 5.706 + ERROR("We can only deal with page-aligned load addresses"); 5.707 + goto out; 5.708 + } 5.709 + 5.710 + if ((*virt_load_addr + (image_tot_pages << PAGE_SHIFT)) > 5.711 + HYPERVISOR_VIRT_START) { 5.712 + ERROR("Cannot map all domain memory without hitting Xen space"); 5.713 + goto out; 5.714 + } 5.715 + 5.716 + /* just malloc an image that is image_tot_pages in size. Then read in 5.717 + * the image -- text, data, -- to page-rounded alignments. 5.718 + * then copy into xen . 5.719 + * this gets BSS zeroed for free 5.720 + */ 5.721 + DPRINTF(("Allocate %ld bytes\n", image_tot_pages * sizeof (*image))); 5.722 + image = calloc(image_tot_pages, sizeof (*image)); 5.723 + if (!image) 5.724 + return blah("alloc data"); 5.725 + /* text starts at 0x20, after the header, just like Unix long ago */ 5.726 + if (gzread(kernel_gfd, &image[0].data[sizeof (Exec)], ehdr.text) < 5.727 + ehdr.text) 5.728 + return blah("read text"); 5.729 + DPRINTF(("READ TEXT %ld bytes\n", ehdr.text)); 5.730 + datapage = ((ehdr.text + sizeof (Exec)) / PAGE_SIZE) + 1; 5.731 + if (gzread(kernel_gfd, image[datapage].data, ehdr.data) < ehdr.data) 5.732 + return blah("read data"); 5.733 + DPRINTF(("READ DATA %ld bytes\n", ehdr.data)); 5.734 + 5.735 + /* nice contig stuff */ 5.736 + /* oops need to start at 0x100000 */ 5.737 + 5.738 + ret = memcpy_toguest(xc_handle, dom, 5.739 + image, image_tot_pages * 4096, page_array, 0x100); 5.740 + DPRINTF(("done copying kernel to guest memory\n")); 5.741 + 5.742 + out: 5.743 + if (image) 5.744 + free(image); 5.745 + *pdb_page = image_tot_pages + (0x100000 >> PAGE_SHIFT); 5.746 + return ret; 5.747 +}
6.1 --- a/tools/python/xen/lowlevel/xc/xc.c Thu Dec 23 14:06:12 2004 +0000 6.2 +++ b/tools/python/xen/lowlevel/xc/xc.c Fri Dec 24 22:09:52 2004 +0000 6.3 @@ -366,6 +366,33 @@ static PyObject *pyxc_linux_build(PyObje 6.4 return zero; 6.5 } 6.6 6.7 +static PyObject *pyxc_plan9_build(PyObject *self, 6.8 + PyObject *args, 6.9 + PyObject *kwds) 6.10 +{ 6.11 + XcObject *xc = (XcObject *)self; 6.12 + 6.13 + u32 dom; 6.14 + char *image, *ramdisk = NULL, *cmdline = ""; 6.15 + int control_evtchn, flags = 0; 6.16 + 6.17 + static char *kwd_list[] = { "dom", "control_evtchn", 6.18 + "image", "ramdisk", "cmdline", "flags", 6.19 + NULL }; 6.20 + 6.21 + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|ssi", kwd_list, 6.22 + &dom, &control_evtchn, 6.23 + &image, &ramdisk, &cmdline, &flags) ) 6.24 + return NULL; 6.25 + 6.26 + if ( xc_plan9_build(xc->xc_handle, dom, image, 6.27 + cmdline, control_evtchn, flags) != 0 ) 6.28 + return PyErr_SetFromErrno(xc_error); 6.29 + 6.30 + Py_INCREF(zero); 6.31 + return zero; 6.32 +} 6.33 + 6.34 static PyObject *pyxc_bvtsched_global_set(PyObject *self, 6.35 PyObject *args, 6.36 PyObject *kwds) 6.37 @@ -889,6 +916,14 @@ static PyMethodDef pyxc_methods[] = { 6.38 " state_file [str]: Name of state file. Must not currently exist.\n" 6.39 " progress [int, 1]: Bool - display a running progress indication?\n\n" 6.40 "Returns: [int] 0 on success; -1 on error.\n" }, 6.41 + { "plan9_build", 6.42 + (PyCFunction)pyxc_plan9_build, 6.43 + METH_VARARGS | METH_KEYWORDS, "\n" 6.44 + "Build a new Plan 9 guest OS.\n" 6.45 + " dom [long]: Identifier of domain to build into.\n" 6.46 + " image [str]: Name of kernel image file. May be gzipped.\n" 6.47 + " cmdline [str, n/a]: Kernel parameters, if any.\n\n" 6.48 + "Returns: [int] 0 on success; -1 on error.\n" }, 6.49 6.50 { "linux_restore", 6.51 (PyCFunction)pyxc_linux_restore,
7.1 --- a/tools/python/xen/xend/XendDomainInfo.py Thu Dec 23 14:06:12 2004 +0000 7.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Fri Dec 24 22:09:52 2004 +0000 7.3 @@ -1065,6 +1065,34 @@ def vm_image_linux(vm, image): 7.4 vm.create_domain("linux", kernel, ramdisk, cmdline) 7.5 return vm 7.6 7.7 +def vm_image_plan9(vm, image): 7.8 + """Create a VM for a Plan 9 image. 7.9 + 7.10 + name vm name 7.11 + memory vm memory 7.12 + image image config 7.13 + 7.14 + returns vm 7.15 + """ 7.16 + #todo: Same as for linux. Is that right? If so can unify them. 7.17 + kernel = sxp.child_value(image, "kernel") 7.18 + cmdline = "" 7.19 + ip = sxp.child_value(image, "ip", "dhcp") 7.20 + if ip: 7.21 + cmdline += "ip=" + ip 7.22 + root = sxp.child_value(image, "root") 7.23 + if root: 7.24 + cmdline += "root=" + root 7.25 + args = sxp.child_value(image, "args") 7.26 + if args: 7.27 + cmdline += " " + args 7.28 + ramdisk = sxp.child_value(image, "ramdisk", '') 7.29 + vifs = vm.config_devices("vif") 7.30 + vm.create_domain("plan9", kernel, ramdisk, cmdline) 7.31 + return vm 7.32 + 7.33 + 7.34 + 7.35 def vm_dev_vif(vm, val, index, change=0): 7.36 """Create a virtual network interface (vif). 7.37 7.38 @@ -1186,6 +1214,7 @@ def vm_field_maxmem(vm, config, val, ind 7.39 7.40 # Register image handlers. 7.41 add_image_handler('linux', vm_image_linux) 7.42 +add_image_handler('plan9', vm_image_plan9) 7.43 7.44 # Register device handlers. 7.45 add_device_handler('vif', vm_dev_vif)