direct-io.hg

view tools/libxc/xc_dom_x86.c @ 14350:f3f5f2756d75

x86: Add VGCF_onlien flag to vcpu_guest_context.
Change common Xen code to start all VCPUs (except idle ones)
offline. Change arch code to deal with this.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Mon Mar 12 13:53:43 2007 +0000 (2007-03-12)
parents 7e2f7e8b63d3
children 49ec3725d0c0
line source
1 /*
2 * Xen domain builder -- i386 and x86_64 bits.
3 *
4 * Most architecture-specific code for x86 goes here.
5 * - prepare page tables.
6 * - fill architecture-specific structs.
7 *
8 * This code is licenced under the GPL.
9 * written 2006 by Gerd Hoffmann <kraxel@suse.de>.
10 *
11 */
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <inttypes.h>
17 #include <xen/xen.h>
18 #include <xen/foreign/x86_32.h>
19 #include <xen/foreign/x86_64.h>
20 #include <xen/hvm/hvm_info_table.h>
21 #include <xen/hvm/e820.h>
23 #include "xg_private.h"
24 #include "xc_dom.h"
26 /* ------------------------------------------------------------------------ */
28 #define bits_to_mask(bits) (((xen_vaddr_t)1 << (bits))-1)
29 #define round_down(addr, mask) ((addr) & ~(mask))
30 #define round_up(addr, mask) ((addr) | (mask))
32 static unsigned long
33 nr_page_tables(xen_vaddr_t start, xen_vaddr_t end, unsigned long bits)
34 {
35 xen_vaddr_t mask = bits_to_mask(bits);
36 int tables;
38 if ( bits == 0 )
39 return 0; /* unused */
41 if ( bits == (8 * sizeof(unsigned long)) )
42 {
43 /* must be pgd, need one */
44 start = 0;
45 end = -1;
46 tables = 1;
47 }
48 else
49 {
50 start = round_down(start, mask);
51 end = round_up(end, mask);
52 tables = ((end - start) >> bits) + 1;
53 }
55 xc_dom_printf("%s: 0x%016" PRIx64 "/%ld: 0x%016" PRIx64
56 " -> 0x%016" PRIx64 ", %d table(s)\n",
57 __FUNCTION__, mask, bits, start, end, tables);
58 return tables;
59 }
61 static int count_pgtables(struct xc_dom_image *dom, int pae,
62 int l4_bits, int l3_bits, int l2_bits, int l1_bits)
63 {
64 int pages, extra_pages;
65 xen_vaddr_t try_virt_end;
67 extra_pages = dom->alloc_bootstack ? 1 : 0;
68 extra_pages += dom->extra_pages;
69 extra_pages += 128; /* 512kB padding */
70 pages = extra_pages;
71 for ( ; ; )
72 {
73 try_virt_end = round_up(dom->virt_alloc_end + pages * PAGE_SIZE_X86,
74 bits_to_mask(22)); /* 4MB alignment */
75 dom->pg_l4 =
76 nr_page_tables(dom->parms.virt_base, try_virt_end, l4_bits);
77 dom->pg_l3 =
78 nr_page_tables(dom->parms.virt_base, try_virt_end, l3_bits);
79 dom->pg_l2 =
80 nr_page_tables(dom->parms.virt_base, try_virt_end, l2_bits);
81 dom->pg_l1 =
82 nr_page_tables(dom->parms.virt_base, try_virt_end, l1_bits);
83 if (pae && try_virt_end < 0xc0000000)
84 {
85 xc_dom_printf("%s: PAE: extra l2 page table for l3#3\n",
86 __FUNCTION__);
87 dom->pg_l2++;
88 }
89 dom->pgtables = dom->pg_l4 + dom->pg_l3 + dom->pg_l2 + dom->pg_l1;
90 pages = dom->pgtables + extra_pages;
91 if ( dom->virt_alloc_end + pages * PAGE_SIZE_X86 <= try_virt_end + 1 )
92 break;
93 }
94 dom->virt_pgtab_end = try_virt_end + 1;
95 return 0;
96 }
98 /* ------------------------------------------------------------------------ */
99 /* i386 pagetables */
101 #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
102 #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
103 #define L3_PROT (_PAGE_PRESENT)
105 static int count_pgtables_x86_32(struct xc_dom_image *dom)
106 {
107 return count_pgtables(dom, 0, 0, 0, 32, L2_PAGETABLE_SHIFT_I386);
108 }
110 static int count_pgtables_x86_32_pae(struct xc_dom_image *dom)
111 {
112 return count_pgtables(dom, 1, 0, 32,
113 L3_PAGETABLE_SHIFT_PAE, L2_PAGETABLE_SHIFT_PAE);
114 }
116 #define pfn_to_paddr(pfn) ((xen_paddr_t)(pfn) << PAGE_SHIFT_X86)
118 static int setup_pgtables_x86_32(struct xc_dom_image *dom)
119 {
120 xen_pfn_t l2pfn = dom->pgtables_seg.pfn;
121 xen_pfn_t l1pfn = dom->pgtables_seg.pfn + dom->pg_l2;
122 l2_pgentry_32_t *l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1);
123 l1_pgentry_32_t *l1tab = NULL;
124 unsigned long l2off, l1off;
125 xen_vaddr_t addr;
126 xen_pfn_t pgpfn;
128 for ( addr = dom->parms.virt_base; addr < dom->virt_pgtab_end;
129 addr += PAGE_SIZE_X86 )
130 {
131 if ( l1tab == NULL )
132 {
133 /* get L1 tab, make L2 entry */
134 l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1);
135 l2off = l2_table_offset_i386(addr);
136 l2tab[l2off] =
137 pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT;
138 l1pfn++;
139 }
141 /* make L1 entry */
142 l1off = l1_table_offset_i386(addr);
143 pgpfn = (addr - dom->parms.virt_base) >> PAGE_SHIFT_X86;
144 l1tab[l1off] =
145 pfn_to_paddr(xc_dom_p2m_guest(dom, pgpfn)) | L1_PROT;
146 if ( (addr >= dom->pgtables_seg.vstart) &&
147 (addr < dom->pgtables_seg.vend) )
148 l1tab[l1off] &= ~_PAGE_RW; /* page tables are r/o */
149 if ( l1off == (L1_PAGETABLE_ENTRIES_I386 - 1) )
150 l1tab = NULL;
151 }
152 return 0;
153 }
155 static int setup_pgtables_x86_32_pae(struct xc_dom_image *dom)
156 {
157 xen_pfn_t l3pfn = dom->pgtables_seg.pfn;
158 xen_pfn_t l2pfn = dom->pgtables_seg.pfn + dom->pg_l3;
159 xen_pfn_t l1pfn = dom->pgtables_seg.pfn + dom->pg_l3 + dom->pg_l2;
160 l3_pgentry_64_t *l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1);
161 l2_pgentry_64_t *l2tab = NULL;
162 l1_pgentry_64_t *l1tab = NULL;
163 unsigned long l3off, l2off, l1off;
164 xen_vaddr_t addr;
165 xen_pfn_t pgpfn;
167 for ( addr = dom->parms.virt_base; addr < dom->virt_pgtab_end;
168 addr += PAGE_SIZE_X86 )
169 {
170 if ( l2tab == NULL )
171 {
172 /* get L2 tab, make L3 entry */
173 l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1);
174 l3off = l3_table_offset_pae(addr);
175 l3tab[l3off] =
176 pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT;
177 l2pfn++;
178 }
180 if ( l1tab == NULL )
181 {
182 /* get L1 tab, make L2 entry */
183 l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1);
184 l2off = l2_table_offset_pae(addr);
185 l2tab[l2off] =
186 pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT;
187 if ( l2off == (L2_PAGETABLE_ENTRIES_PAE - 1) )
188 l2tab = NULL;
189 l1pfn++;
190 }
192 /* make L1 entry */
193 l1off = l1_table_offset_pae(addr);
194 pgpfn = (addr - dom->parms.virt_base) >> PAGE_SHIFT_X86;
195 l1tab[l1off] =
196 pfn_to_paddr(xc_dom_p2m_guest(dom, pgpfn)) | L1_PROT;
197 if ( (addr >= dom->pgtables_seg.vstart) &&
198 (addr < dom->pgtables_seg.vend) )
199 l1tab[l1off] &= ~_PAGE_RW; /* page tables are r/o */
200 if ( l1off == (L1_PAGETABLE_ENTRIES_PAE - 1) )
201 l1tab = NULL;
202 }
204 if ( dom->virt_pgtab_end <= 0xc0000000 )
205 {
206 xc_dom_printf("%s: PAE: extra l2 page table for l3#3\n", __FUNCTION__);
207 l3tab[3] = pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT;
208 }
209 return 0;
210 }
212 #undef L1_PROT
213 #undef L2_PROT
214 #undef L3_PROT
216 /* ------------------------------------------------------------------------ */
217 /* x86_64 pagetables */
219 static int count_pgtables_x86_64(struct xc_dom_image *dom)
220 {
221 return count_pgtables(dom, 0,
222 L4_PAGETABLE_SHIFT_X86_64 + 9,
223 L4_PAGETABLE_SHIFT_X86_64,
224 L3_PAGETABLE_SHIFT_X86_64,
225 L2_PAGETABLE_SHIFT_X86_64);
226 }
228 #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
229 #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
230 #define L3_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
231 #define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
233 static int setup_pgtables_x86_64(struct xc_dom_image *dom)
234 {
235 xen_pfn_t l4pfn = dom->pgtables_seg.pfn;
236 xen_pfn_t l3pfn = dom->pgtables_seg.pfn + dom->pg_l4;
237 xen_pfn_t l2pfn = dom->pgtables_seg.pfn + dom->pg_l4 + dom->pg_l3;
238 xen_pfn_t l1pfn =
239 dom->pgtables_seg.pfn + dom->pg_l4 + dom->pg_l3 + dom->pg_l2;
240 l4_pgentry_64_t *l4tab = xc_dom_pfn_to_ptr(dom, l4pfn, 1);
241 l3_pgentry_64_t *l3tab = NULL;
242 l2_pgentry_64_t *l2tab = NULL;
243 l1_pgentry_64_t *l1tab = NULL;
244 uint64_t l4off, l3off, l2off, l1off;
245 uint64_t addr;
246 xen_pfn_t pgpfn;
248 for ( addr = dom->parms.virt_base; addr < dom->virt_pgtab_end;
249 addr += PAGE_SIZE_X86 )
250 {
251 if ( l3tab == NULL )
252 {
253 /* get L3 tab, make L4 entry */
254 l3tab = xc_dom_pfn_to_ptr(dom, l3pfn, 1);
255 l4off = l4_table_offset_x86_64(addr);
256 l4tab[l4off] =
257 pfn_to_paddr(xc_dom_p2m_guest(dom, l3pfn)) | L4_PROT;
258 l3pfn++;
259 }
261 if ( l2tab == NULL )
262 {
263 /* get L2 tab, make L3 entry */
264 l2tab = xc_dom_pfn_to_ptr(dom, l2pfn, 1);
265 l3off = l3_table_offset_x86_64(addr);
266 l3tab[l3off] =
267 pfn_to_paddr(xc_dom_p2m_guest(dom, l2pfn)) | L3_PROT;
268 if ( l3off == (L3_PAGETABLE_ENTRIES_X86_64 - 1) )
269 l3tab = NULL;
270 l2pfn++;
271 }
273 if ( l1tab == NULL )
274 {
275 /* get L1 tab, make L2 entry */
276 l1tab = xc_dom_pfn_to_ptr(dom, l1pfn, 1);
277 l2off = l2_table_offset_x86_64(addr);
278 l2tab[l2off] =
279 pfn_to_paddr(xc_dom_p2m_guest(dom, l1pfn)) | L2_PROT;
280 if ( l2off == (L2_PAGETABLE_ENTRIES_X86_64 - 1) )
281 l2tab = NULL;
282 l1pfn++;
283 }
285 /* make L1 entry */
286 l1off = l1_table_offset_x86_64(addr);
287 pgpfn = (addr - dom->parms.virt_base) >> PAGE_SHIFT_X86;
288 l1tab[l1off] =
289 pfn_to_paddr(xc_dom_p2m_guest(dom, pgpfn)) | L1_PROT;
290 if ( (addr >= dom->pgtables_seg.vstart) &&
291 (addr < dom->pgtables_seg.vend) )
292 l1tab[l1off] &= ~_PAGE_RW; /* page tables are r/o */
293 if ( l1off == (L1_PAGETABLE_ENTRIES_X86_64 - 1) )
294 l1tab = NULL;
295 }
296 return 0;
297 }
299 #undef L1_PROT
300 #undef L2_PROT
301 #undef L3_PROT
302 #undef L4_PROT
304 /* ------------------------------------------------------------------------ */
306 static int alloc_magic_pages(struct xc_dom_image *dom)
307 {
308 size_t p2m_size = dom->total_pages * dom->arch_hooks->sizeof_pfn;
310 /* allocate phys2mach table */
311 if ( xc_dom_alloc_segment(dom, &dom->p2m_seg, "phys2mach", 0, p2m_size) )
312 return -1;
313 dom->p2m_guest = xc_dom_seg_to_ptr(dom, &dom->p2m_seg);
315 /* allocate special pages */
316 dom->start_info_pfn = xc_dom_alloc_page(dom, "start info");
317 dom->xenstore_pfn = xc_dom_alloc_page(dom, "xenstore");
318 dom->console_pfn = xc_dom_alloc_page(dom, "console");
319 if ( xc_dom_feature_translated(dom) )
320 dom->shared_info_pfn = xc_dom_alloc_page(dom, "shared info");
321 dom->alloc_bootstack = 1;
323 return 0;
324 }
326 /* ------------------------------------------------------------------------ */
328 static int start_info_x86_32(struct xc_dom_image *dom)
329 {
330 start_info_x86_32_t *start_info =
331 xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1);
332 xen_pfn_t shinfo =
333 xc_dom_feature_translated(dom) ? dom->shared_info_pfn : dom->
334 shared_info_mfn;
336 xc_dom_printf("%s: called\n", __FUNCTION__);
338 sprintf(start_info->magic, dom->guest_type);
339 start_info->nr_pages = dom->total_pages;
340 start_info->shared_info = shinfo << PAGE_SHIFT_X86;
341 start_info->pt_base = dom->pgtables_seg.vstart;
342 start_info->nr_pt_frames = dom->pgtables;
343 start_info->mfn_list = dom->p2m_seg.vstart;
345 start_info->flags = dom->flags;
346 start_info->store_mfn = xc_dom_p2m_guest(dom, dom->xenstore_pfn);
347 start_info->store_evtchn = dom->xenstore_evtchn;
348 start_info->console.domU.mfn = xc_dom_p2m_guest(dom, dom->console_pfn);
349 start_info->console.domU.evtchn = dom->console_evtchn;
351 if ( dom->ramdisk_blob )
352 {
353 start_info->mod_start = dom->ramdisk_seg.vstart;
354 start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart;
355 }
357 if ( dom->cmdline )
358 {
359 strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE);
360 start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = '\0';
361 }
363 return 0;
364 }
366 static int start_info_x86_64(struct xc_dom_image *dom)
367 {
368 start_info_x86_64_t *start_info =
369 xc_dom_pfn_to_ptr(dom, dom->start_info_pfn, 1);
370 xen_pfn_t shinfo =
371 xc_dom_feature_translated(dom) ? dom->shared_info_pfn : dom->
372 shared_info_mfn;
374 xc_dom_printf("%s: called\n", __FUNCTION__);
376 sprintf(start_info->magic, dom->guest_type);
377 start_info->nr_pages = dom->total_pages;
378 start_info->shared_info = shinfo << PAGE_SHIFT_X86;
379 start_info->pt_base = dom->pgtables_seg.vstart;
380 start_info->nr_pt_frames = dom->pgtables;
381 start_info->mfn_list = dom->p2m_seg.vstart;
383 start_info->flags = dom->flags;
384 start_info->store_mfn = xc_dom_p2m_guest(dom, dom->xenstore_pfn);
385 start_info->store_evtchn = dom->xenstore_evtchn;
386 start_info->console.domU.mfn = xc_dom_p2m_guest(dom, dom->console_pfn);
387 start_info->console.domU.evtchn = dom->console_evtchn;
389 if ( dom->ramdisk_blob )
390 {
391 start_info->mod_start = dom->ramdisk_seg.vstart;
392 start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart;
393 }
395 if ( dom->cmdline )
396 {
397 strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE);
398 start_info->cmd_line[MAX_GUEST_CMDLINE - 1] = '\0';
399 }
401 return 0;
402 }
404 static int shared_info_x86_32(struct xc_dom_image *dom, void *ptr)
405 {
406 shared_info_x86_32_t *shared_info = ptr;
407 int i;
409 xc_dom_printf("%s: called\n", __FUNCTION__);
411 memset(shared_info, 0, sizeof(*shared_info));
412 for ( i = 0; i < MAX_VIRT_CPUS; i++ )
413 shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
414 return 0;
415 }
417 static int shared_info_x86_64(struct xc_dom_image *dom, void *ptr)
418 {
419 shared_info_x86_64_t *shared_info = ptr;
420 int i;
422 xc_dom_printf("%s: called\n", __FUNCTION__);
424 memset(shared_info, 0, sizeof(*shared_info));
425 for ( i = 0; i < MAX_VIRT_CPUS; i++ )
426 shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
427 return 0;
428 }
430 /* ------------------------------------------------------------------------ */
432 static int vcpu_x86_32(struct xc_dom_image *dom, void *ptr)
433 {
434 vcpu_guest_context_x86_32_t *ctxt = ptr;
435 xen_pfn_t cr3_pfn;
437 xc_dom_printf("%s: called\n", __FUNCTION__);
439 /* clear everything */
440 memset(ctxt, 0, sizeof(*ctxt));
442 ctxt->user_regs.ds = FLAT_KERNEL_DS_X86_32;
443 ctxt->user_regs.es = FLAT_KERNEL_DS_X86_32;
444 ctxt->user_regs.fs = FLAT_KERNEL_DS_X86_32;
445 ctxt->user_regs.gs = FLAT_KERNEL_DS_X86_32;
446 ctxt->user_regs.ss = FLAT_KERNEL_SS_X86_32;
447 ctxt->user_regs.cs = FLAT_KERNEL_CS_X86_32;
448 ctxt->user_regs.eip = dom->parms.virt_entry;
449 ctxt->user_regs.esp =
450 dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86;
451 ctxt->user_regs.esi =
452 dom->parms.virt_base + (dom->start_info_pfn) * PAGE_SIZE_X86;
453 ctxt->user_regs.eflags = 1 << 9; /* Interrupt Enable */
455 ctxt->kernel_ss = ctxt->user_regs.ss;
456 ctxt->kernel_sp = ctxt->user_regs.esp;
458 ctxt->flags = VGCF_in_kernel_X86_32 | VGCF_online_X86_32;
459 if ( dom->parms.pae == 2 /* extended_cr3 */ ||
460 dom->parms.pae == 3 /* bimodal */ )
461 ctxt->vm_assist |= (1UL << VMASST_TYPE_pae_extended_cr3);
463 cr3_pfn = xc_dom_p2m_guest(dom, dom->pgtables_seg.pfn);
464 ctxt->ctrlreg[3] = xen_pfn_to_cr3_x86_32(cr3_pfn);
465 xc_dom_printf("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "\n",
466 __FUNCTION__, dom->pgtables_seg.pfn, cr3_pfn);
468 return 0;
469 }
471 static int vcpu_x86_64(struct xc_dom_image *dom, void *ptr)
472 {
473 vcpu_guest_context_x86_64_t *ctxt = ptr;
474 xen_pfn_t cr3_pfn;
476 xc_dom_printf("%s: called\n", __FUNCTION__);
478 /* clear everything */
479 memset(ctxt, 0, sizeof(*ctxt));
481 ctxt->user_regs.ds = FLAT_KERNEL_DS_X86_64;
482 ctxt->user_regs.es = FLAT_KERNEL_DS_X86_64;
483 ctxt->user_regs.fs = FLAT_KERNEL_DS_X86_64;
484 ctxt->user_regs.gs = FLAT_KERNEL_DS_X86_64;
485 ctxt->user_regs.ss = FLAT_KERNEL_SS_X86_64;
486 ctxt->user_regs.cs = FLAT_KERNEL_CS_X86_64;
487 ctxt->user_regs.rip = dom->parms.virt_entry;
488 ctxt->user_regs.rsp =
489 dom->parms.virt_base + (dom->bootstack_pfn + 1) * PAGE_SIZE_X86;
490 ctxt->user_regs.rsi =
491 dom->parms.virt_base + (dom->start_info_pfn) * PAGE_SIZE_X86;
492 ctxt->user_regs.rflags = 1 << 9; /* Interrupt Enable */
494 ctxt->kernel_ss = ctxt->user_regs.ss;
495 ctxt->kernel_sp = ctxt->user_regs.esp;
497 ctxt->flags = VGCF_in_kernel_X86_64 | VGCF_online_X86_64;
498 cr3_pfn = xc_dom_p2m_guest(dom, dom->pgtables_seg.pfn);
499 ctxt->ctrlreg[3] = xen_pfn_to_cr3_x86_64(cr3_pfn);
500 xc_dom_printf("%s: cr3: pfn 0x%" PRIpfn " mfn 0x%" PRIpfn "\n",
501 __FUNCTION__, dom->pgtables_seg.pfn, cr3_pfn);
503 return 0;
504 }
506 /* ------------------------------------------------------------------------ */
508 static struct xc_dom_arch xc_dom_32 = {
509 .guest_type = "xen-3.0-x86_32",
510 .page_shift = PAGE_SHIFT_X86,
511 .sizeof_pfn = 4,
512 .alloc_magic_pages = alloc_magic_pages,
513 .count_pgtables = count_pgtables_x86_32,
514 .setup_pgtables = setup_pgtables_x86_32,
515 .start_info = start_info_x86_32,
516 .shared_info = shared_info_x86_32,
517 .vcpu = vcpu_x86_32,
518 };
519 static struct xc_dom_arch xc_dom_32_pae = {
520 .guest_type = "xen-3.0-x86_32p",
521 .page_shift = PAGE_SHIFT_X86,
522 .sizeof_pfn = 4,
523 .alloc_magic_pages = alloc_magic_pages,
524 .count_pgtables = count_pgtables_x86_32_pae,
525 .setup_pgtables = setup_pgtables_x86_32_pae,
526 .start_info = start_info_x86_32,
527 .shared_info = shared_info_x86_32,
528 .vcpu = vcpu_x86_32,
529 };
531 static struct xc_dom_arch xc_dom_64 = {
532 .guest_type = "xen-3.0-x86_64",
533 .page_shift = PAGE_SHIFT_X86,
534 .sizeof_pfn = 8,
535 .alloc_magic_pages = alloc_magic_pages,
536 .count_pgtables = count_pgtables_x86_64,
537 .setup_pgtables = setup_pgtables_x86_64,
538 .start_info = start_info_x86_64,
539 .shared_info = shared_info_x86_64,
540 .vcpu = vcpu_x86_64,
541 };
543 static void __init register_arch_hooks(void)
544 {
545 xc_dom_register_arch_hooks(&xc_dom_32);
546 xc_dom_register_arch_hooks(&xc_dom_32_pae);
547 xc_dom_register_arch_hooks(&xc_dom_64);
548 }
550 /*
551 * Local variables:
552 * mode: C
553 * c-set-style: "BSD"
554 * c-basic-offset: 4
555 * tab-width: 4
556 * indent-tabs-mode: nil
557 * End:
558 */