debuggers.hg

view tools/libxc/xc_dom_boot.c @ 21067:b4a1832a916f

Update Xen version to 4.0.0-rc6
author Keir Fraser <keir.fraser@citrix.com>
date Tue Mar 09 18:18:05 2010 +0000 (2010-03-09)
parents 5333e6497af6
children 3ffdb094c2c0
line source
1 /*
2 * Xen domain builder -- xen booter.
3 *
4 * This is the code which actually boots a fresh
5 * prepared domain image as xen guest domain.
6 *
7 * ==> this is the only domain builder code piece
8 * where xen hypercalls are allowed <==
9 *
10 * This code is licenced under the GPL.
11 * written 2006 by Gerd Hoffmann <kraxel@suse.de>.
12 *
13 */
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <inttypes.h>
18 #include <zlib.h>
20 #include "xg_private.h"
21 #include "xc_dom.h"
22 #include <xen/hvm/params.h>
24 /* ------------------------------------------------------------------------ */
26 static int setup_hypercall_page(struct xc_dom_image *dom)
27 {
28 DECLARE_DOMCTL;
29 xen_pfn_t pfn;
30 int rc;
32 if ( dom->parms.virt_hypercall == -1 )
33 return 0;
34 pfn = (dom->parms.virt_hypercall - dom->parms.virt_base)
35 >> XC_DOM_PAGE_SHIFT(dom);
37 xc_dom_printf("%s: vaddr=0x%" PRIx64 " pfn=0x%" PRIpfn "\n", __FUNCTION__,
38 dom->parms.virt_hypercall, pfn);
39 domctl.cmd = XEN_DOMCTL_hypercall_init;
40 domctl.domain = dom->guest_domid;
41 domctl.u.hypercall_init.gmfn = xc_dom_p2m_guest(dom, pfn);
42 rc = do_domctl(dom->guest_xc, &domctl);
43 if ( rc != 0 )
44 xc_dom_panic(XC_INTERNAL_ERROR, "%s: HYPERCALL_INIT failed (rc=%d)\n",
45 __FUNCTION__, rc);
46 return rc;
47 }
49 static int launch_vm(int xc, domid_t domid, void *ctxt)
50 {
51 DECLARE_DOMCTL;
52 int rc;
54 xc_dom_printf("%s: called, ctxt=%p\n", __FUNCTION__, ctxt);
55 memset(&domctl, 0, sizeof(domctl));
56 domctl.cmd = XEN_DOMCTL_setvcpucontext;
57 domctl.domain = domid;
58 domctl.u.vcpucontext.vcpu = 0;
59 set_xen_guest_handle(domctl.u.vcpucontext.ctxt, ctxt);
60 rc = do_domctl(xc, &domctl);
61 if ( rc != 0 )
62 xc_dom_panic(XC_INTERNAL_ERROR,
63 "%s: SETVCPUCONTEXT failed (rc=%d)\n", __FUNCTION__, rc);
64 return rc;
65 }
67 static int clear_page(struct xc_dom_image *dom, xen_pfn_t pfn)
68 {
69 xen_pfn_t dst;
70 int rc;
72 if ( pfn == 0 )
73 return 0;
75 dst = xc_dom_p2m_host(dom, pfn);
76 xc_dom_printf("%s: pfn 0x%" PRIpfn ", mfn 0x%" PRIpfn "\n",
77 __FUNCTION__, pfn, dst);
78 rc = xc_clear_domain_page(dom->guest_xc, dom->guest_domid, dst);
79 if ( rc != 0 )
80 xc_dom_panic(XC_INTERNAL_ERROR,
81 "%s: xc_clear_domain_page failed (pfn 0x%" PRIpfn
82 ", rc=%d)\n", __FUNCTION__, pfn, rc);
83 return rc;
84 }
87 /* ------------------------------------------------------------------------ */
89 int xc_dom_compat_check(struct xc_dom_image *dom)
90 {
91 xen_capabilities_info_t xen_caps;
92 char *item, *ptr;
93 int match, found = 0;
95 strncpy(xen_caps, dom->xen_caps, XEN_CAPABILITIES_INFO_LEN - 1);
96 xen_caps[XEN_CAPABILITIES_INFO_LEN - 1] = '\0';
98 for ( item = strtok_r(xen_caps, " ", &ptr);
99 item != NULL ; item = strtok_r(NULL, " ", &ptr) )
100 {
101 match = !strcmp(dom->guest_type, item);
102 xc_dom_printf("%s: supported guest type: %s%s\n", __FUNCTION__,
103 item, match ? " <= matches" : "");
104 if ( match )
105 found++;
106 }
107 if ( !found )
108 xc_dom_panic(XC_INVALID_KERNEL,
109 "%s: guest type %s not supported by xen kernel, sorry\n",
110 __FUNCTION__, dom->guest_type);
112 return found;
113 }
115 int xc_dom_boot_xen_init(struct xc_dom_image *dom, int xc, domid_t domid)
116 {
117 dom->guest_xc = xc;
118 dom->guest_domid = domid;
120 dom->xen_version = xc_version(dom->guest_xc, XENVER_version, NULL);
121 if ( xc_version(xc, XENVER_capabilities, &dom->xen_caps) < 0 )
122 {
123 xc_dom_panic(XC_INTERNAL_ERROR, "can't get xen capabilities");
124 return -1;
125 }
126 xc_dom_printf("%s: ver %d.%d, caps %s\n", __FUNCTION__,
127 dom->xen_version >> 16, dom->xen_version & 0xff,
128 dom->xen_caps);
129 return 0;
130 }
132 int xc_dom_boot_mem_init(struct xc_dom_image *dom)
133 {
134 long rc;
136 xc_dom_printf("%s: called\n", __FUNCTION__);
138 rc = arch_setup_meminit(dom);
139 if ( rc != 0 )
140 {
141 xc_dom_panic(XC_OUT_OF_MEMORY,
142 "%s: can't allocate low memory for domain\n",
143 __FUNCTION__);
144 return rc;
145 }
147 return 0;
148 }
150 void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn,
151 xen_pfn_t count)
152 {
153 int page_shift = XC_DOM_PAGE_SHIFT(dom);
154 privcmd_mmap_entry_t *entries;
155 void *ptr;
156 int i;
157 int err;
159 entries = xc_dom_malloc(dom, count * sizeof(privcmd_mmap_entry_t));
160 if ( entries == NULL )
161 {
162 xc_dom_panic(XC_INTERNAL_ERROR,
163 "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn
164 " [malloc]\n", __FUNCTION__, pfn, count);
165 return NULL;
166 }
168 for ( i = 0; i < count; i++ )
169 entries[i].mfn = xc_dom_p2m_host(dom, pfn + i);
171 ptr = xc_map_foreign_ranges(dom->guest_xc, dom->guest_domid,
172 count << page_shift, PROT_READ | PROT_WRITE, 1 << page_shift,
173 entries, count);
174 if ( ptr == NULL )
175 {
176 err = errno;
177 xc_dom_panic(XC_INTERNAL_ERROR,
178 "%s: failed to mmap domU pages 0x%" PRIpfn "+0x%" PRIpfn
179 " [mmap, errno=%i (%s)]\n", __FUNCTION__, pfn, count,
180 err, strerror(err));
181 return NULL;
182 }
184 return ptr;
185 }
187 int xc_dom_boot_image(struct xc_dom_image *dom)
188 {
189 DECLARE_DOMCTL;
190 vcpu_guest_context_any_t ctxt;
191 int rc;
193 xc_dom_printf("%s: called\n", __FUNCTION__);
195 /* misc ia64 stuff*/
196 if ( (rc = arch_setup_bootearly(dom)) != 0 )
197 return rc;
199 /* collect some info */
200 domctl.cmd = XEN_DOMCTL_getdomaininfo;
201 domctl.domain = dom->guest_domid;
202 rc = do_domctl(dom->guest_xc, &domctl);
203 if ( rc != 0 )
204 {
205 xc_dom_panic(XC_INTERNAL_ERROR,
206 "%s: getdomaininfo failed (rc=%d)\n", __FUNCTION__, rc);
207 return rc;
208 }
209 if ( domctl.domain != dom->guest_domid )
210 {
211 xc_dom_panic(XC_INTERNAL_ERROR,
212 "%s: Huh? domid mismatch (%d != %d)\n", __FUNCTION__,
213 domctl.domain, dom->guest_domid);
214 return -1;
215 }
216 dom->shared_info_mfn = domctl.u.getdomaininfo.shared_info_frame;
218 /* sanity checks */
219 if ( !xc_dom_compat_check(dom) )
220 return -1;
222 /* initial mm setup */
223 if ( (rc = xc_dom_update_guest_p2m(dom)) != 0 )
224 return rc;
225 if ( dom->arch_hooks->setup_pgtables )
226 if ( (rc = dom->arch_hooks->setup_pgtables(dom)) != 0 )
227 return rc;
229 if ( (rc = clear_page(dom, dom->console_pfn)) != 0 )
230 return rc;
231 if ( (rc = clear_page(dom, dom->xenstore_pfn)) != 0 )
232 return rc;
234 /* start info page */
235 if ( dom->arch_hooks->start_info )
236 dom->arch_hooks->start_info(dom);
238 /* hypercall page */
239 if ( (rc = setup_hypercall_page(dom)) != 0 )
240 return rc;
241 xc_dom_log_memory_footprint(dom);
243 /* misc x86 stuff */
244 if ( (rc = arch_setup_bootlate(dom)) != 0 )
245 return rc;
247 /* let the vm run */
248 memset(&ctxt, 0, sizeof(ctxt));
249 if ( (rc = dom->arch_hooks->vcpu(dom, &ctxt)) != 0 )
250 return rc;
251 xc_dom_unmap_all(dom);
252 rc = launch_vm(dom->guest_xc, dom->guest_domid, &ctxt);
254 return rc;
255 }
257 /*
258 * Local variables:
259 * mode: C
260 * c-set-style: "BSD"
261 * c-basic-offset: 4
262 * tab-width: 4
263 * indent-tabs-mode: nil
264 * End:
265 */