ia64/xen-unstable

annotate xen/arch/ia64/xen/xensetup.c @ 9770:ced37bea0647

[IA64] FPH enabling + cleanup

Move contents of switch_to macro from xensystem.h to context_switch function.
Initialize FPU on all processors. FPH is always enabled in Xen.
Speed up context-switch (a little bit!) by not enabling/disabling FPH.
Cleanup (unused function/variablesi/fields, debug printf...)
vmx_ia64_switch_to removed (was unused).

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
author awilliam@xenbuild.aw
date Tue Apr 25 22:35:41 2006 -0600 (2006-04-25)
parents ae0d41bd3bba
children ddcd9c267612
rev   line source
djm@6458 1 /******************************************************************************
djm@6458 2 * xensetup.c
djm@6458 3 * Copyright (c) 2004-2005 Hewlett-Packard Co
djm@6458 4 * Dan Magenheimer <dan.magenheimer@hp.com>
djm@6458 5 */
djm@6458 6
djm@6458 7 #include <xen/config.h>
djm@6458 8 #include <xen/lib.h>
djm@6458 9 #include <xen/errno.h>
djm@6458 10 //#include <xen/spinlock.h>
djm@6458 11 #include <xen/multiboot.h>
djm@6458 12 #include <xen/sched.h>
djm@6458 13 #include <xen/mm.h>
djm@6723 14 #include <public/version.h>
kaf24@9117 15 #include <xen/gdbstub.h>
djm@6458 16 #include <xen/compile.h>
awilliam@9005 17 #include <xen/console.h>
djm@6458 18 #include <xen/serial.h>
djm@6458 19 #include <xen/trace.h>
djm@6458 20 #include <asm/meminit.h>
djm@6458 21 #include <asm/page.h>
djm@6458 22 #include <asm/setup.h>
djm@6458 23 #include <xen/string.h>
djm@8475 24 #include <asm/vmx.h>
awilliam@9005 25 #include <linux/efi.h>
djm@6458 26
awilliam@9495 27 /* Be sure the struct shared_info fits on a page because it is mapped in
awilliam@9495 28 domain. */
awilliam@9495 29 #if SHARED_INFO_SIZE > PAGE_SIZE
awilliam@9495 30 #error "struct shared_info does not not fit in PAGE_SIZE"
awilliam@9495 31 #endif
awilliam@9495 32
djm@6458 33 unsigned long xenheap_phys_end;
djm@6458 34
djm@6458 35 char saved_command_line[COMMAND_LINE_SIZE];
awilliam@9270 36 char dom0_command_line[COMMAND_LINE_SIZE];
djm@6458 37
kaf24@8552 38 struct vcpu *idle_vcpu[NR_CPUS];
djm@6458 39
djm@6458 40 cpumask_t cpu_present_map;
djm@6458 41
djm@6458 42 extern unsigned long domain0_ready;
djm@6458 43
djm@6458 44 int find_max_pfn (unsigned long, unsigned long, void *);
djm@6458 45 void start_of_day(void);
djm@6458 46
awilliam@9005 47 /* FIXME: which header these declarations should be there ? */
awilliam@9005 48 extern long is_platform_hp_ski(void);
awilliam@9005 49 extern void early_setup_arch(char **);
awilliam@9005 50 extern void late_setup_arch(char **);
awilliam@9005 51 extern void hpsim_serial_init(void);
awilliam@9005 52 extern void alloc_dom0(void);
awilliam@9005 53 extern void setup_per_cpu_areas(void);
awilliam@9005 54 extern void mem_init(void);
awilliam@9005 55 extern void init_IRQ(void);
awilliam@9005 56
djm@6458 57 /* opt_nosmp: If true, secondary processors are ignored. */
djm@6458 58 static int opt_nosmp = 0;
djm@6458 59 boolean_param("nosmp", opt_nosmp);
djm@6458 60
djm@6458 61 /* maxcpus: maximum number of CPUs to activate. */
djm@6458 62 static unsigned int max_cpus = NR_CPUS;
djm@6458 63 integer_param("maxcpus", max_cpus);
djm@6458 64
djm@6458 65 /*
djm@6458 66 * opt_xenheap_megabytes: Size of Xen heap in megabytes, including:
djm@6458 67 * xen image
djm@6458 68 * bootmap bits
djm@6458 69 * xen heap
djm@6458 70 * Note: To allow xenheap size configurable, the prerequisite is
djm@6458 71 * to configure elilo allowing relocation defaultly. Then since
djm@6458 72 * elilo chooses 256M as alignment when relocating, alignment issue
djm@6458 73 * on IPF can be addressed.
djm@6458 74 */
djm@6458 75 unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
djm@6458 76 unsigned long xenheap_size = XENHEAP_DEFAULT_SIZE;
djm@6458 77 extern long running_on_sim;
djm@6458 78 unsigned long xen_pstart;
djm@6458 79
djm@6458 80 static int
djm@6458 81 xen_count_pages(u64 start, u64 end, void *arg)
djm@6458 82 {
djm@6458 83 unsigned long *count = arg;
djm@6458 84
djm@6458 85 /* FIXME: do we need consider difference between DMA-usable memory and
djm@6458 86 * normal memory? Seems that HV has no requirement to operate DMA which
djm@6458 87 * is owned by Dom0? */
djm@6458 88 *count += (end - start) >> PAGE_SHIFT;
djm@6458 89 return 0;
djm@6458 90 }
djm@6458 91
djm@6458 92 /* Find first hole after trunk for xen image */
djm@6458 93 static int
djm@6458 94 xen_find_first_hole(u64 start, u64 end, void *arg)
djm@6458 95 {
djm@6458 96 unsigned long *first_hole = arg;
djm@6458 97
djm@6458 98 if ((*first_hole) == 0) {
djm@6458 99 if ((start <= KERNEL_START) && (KERNEL_START < end))
djm@6458 100 *first_hole = __pa(end);
djm@6458 101 }
djm@6458 102
djm@6458 103 return 0;
djm@6458 104 }
djm@6458 105
djm@6458 106 static void __init do_initcalls(void)
djm@6458 107 {
djm@6458 108 initcall_t *call;
djm@6458 109 for ( call = &__initcall_start; call < &__initcall_end; call++ )
djm@6458 110 (*call)();
djm@6458 111 }
djm@6458 112
djm@6458 113 /*
djm@6458 114 * IPF loader only supports one commaind line currently, for
djm@6458 115 * both xen and guest kernel. This function provides pre-parse
djm@6458 116 * to mixed command line, to split it into two parts.
djm@6458 117 *
djm@6458 118 * User should split the parameters by "--", with strings after
djm@6458 119 * spliter for guest kernel. Missing "--" means whole line belongs
djm@6458 120 * to guest. Example:
djm@6458 121 * "com2=57600,8n1 console=com2 -- console=ttyS1 console=tty
djm@6458 122 * root=/dev/sda3 ro"
djm@6458 123 */
djm@6458 124 static char null[4] = { 0 };
djm@6458 125
djm@6458 126 void early_cmdline_parse(char **cmdline_p)
djm@6458 127 {
djm@6458 128 char *guest_cmd;
awilliam@9270 129 static const char * const split = "--";
djm@6458 130
djm@6458 131 if (*cmdline_p == NULL) {
djm@6458 132 *cmdline_p = &null[0];
djm@6458 133 saved_command_line[0] = '\0';
awilliam@9270 134 dom0_command_line[0] = '\0';
djm@6458 135 return;
djm@6458 136 }
djm@6458 137
djm@6458 138 guest_cmd = strstr(*cmdline_p, split);
djm@6458 139 /* If no spliter, whole line is for guest */
djm@6458 140 if (guest_cmd == NULL) {
djm@6458 141 guest_cmd = *cmdline_p;
djm@6458 142 *cmdline_p = &null[0];
djm@6458 143 } else {
djm@6458 144 *guest_cmd = '\0'; /* Split boot parameters for xen and guest */
djm@6458 145 guest_cmd += strlen(split);
djm@6458 146 while (*guest_cmd == ' ') guest_cmd++;
djm@6458 147 }
djm@6458 148
awilliam@9270 149 strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE);
awilliam@9270 150 strlcpy(dom0_command_line, guest_cmd, COMMAND_LINE_SIZE);
djm@6458 151 return;
djm@6458 152 }
djm@6458 153
djm@6458 154 struct ns16550_defaults ns16550_com1 = {
djm@6458 155 .baud = BAUD_AUTO,
djm@6458 156 .data_bits = 8,
djm@6458 157 .parity = 'n',
djm@6458 158 .stop_bits = 1
djm@6458 159 };
djm@6458 160
djm@6458 161 struct ns16550_defaults ns16550_com2 = {
djm@6458 162 .baud = BAUD_AUTO,
djm@6458 163 .data_bits = 8,
djm@6458 164 .parity = 'n',
djm@6458 165 .stop_bits = 1
djm@6458 166 };
djm@6458 167
awilliam@9750 168 /* efi_print: print efi table at boot */
awilliam@9750 169 static int opt_efi_print = 0;
awilliam@9750 170 boolean_param("efi_print", opt_efi_print);
awilliam@9750 171
awilliam@9750 172 /* print EFI memory map: */
awilliam@9750 173 static void
awilliam@9750 174 efi_print(void)
awilliam@9750 175 {
awilliam@9750 176 void *efi_map_start, *efi_map_end;
awilliam@9750 177 u64 efi_desc_size;
awilliam@9750 178
awilliam@9750 179 efi_memory_desc_t *md;
awilliam@9750 180 void *p;
awilliam@9750 181 int i;
awilliam@9750 182
awilliam@9750 183 if (!opt_efi_print)
awilliam@9750 184 return;
awilliam@9750 185
awilliam@9750 186 efi_map_start = __va(ia64_boot_param->efi_memmap);
awilliam@9750 187 efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
awilliam@9750 188 efi_desc_size = ia64_boot_param->efi_memdesc_size;
awilliam@9750 189
awilliam@9750 190 for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) {
awilliam@9750 191 md = p;
awilliam@9750 192 printk("mem%02u: type=%u, attr=0x%lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
awilliam@9750 193 i, md->type, md->attribute, md->phys_addr,
awilliam@9750 194 md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
awilliam@9750 195 md->num_pages >> (20 - EFI_PAGE_SHIFT));
awilliam@9750 196 }
awilliam@9750 197 }
awilliam@9750 198
djm@6458 199 void start_kernel(void)
djm@6458 200 {
djm@6458 201 unsigned char *cmdline;
djm@6458 202 void *heap_start;
awilliam@9005 203 unsigned long nr_pages, firsthole_start;
djm@7735 204 unsigned long dom0_memory_start, dom0_memory_size;
djm@7735 205 unsigned long dom0_initrd_start, dom0_initrd_size;
djm@6458 206 unsigned long initial_images_start, initial_images_end;
kaf24@8552 207 struct domain *idle_domain;
awilliam@9314 208 #ifdef CONFIG_SMP
awilliam@9314 209 int i;
awilliam@9314 210 #endif
djm@6458 211
djm@6458 212 running_on_sim = is_platform_hp_ski();
djm@6458 213 /* Kernel may be relocated by EFI loader */
djm@6458 214 xen_pstart = ia64_tpa(KERNEL_START);
djm@6458 215
awilliam@9005 216 early_setup_arch((char **) &cmdline);
djm@6458 217
djm@6458 218 /* We initialise the serial devices very early so we can get debugging. */
djm@6458 219 if (running_on_sim) hpsim_serial_init();
djm@6458 220 else {
djm@6458 221 ns16550_init(0, &ns16550_com1);
djm@6458 222 /* Also init com2 for Tiger4. */
djm@6458 223 ns16550_com2.io_base = 0x2f8;
djm@6458 224 ns16550_com2.irq = 3;
djm@6458 225 ns16550_init(1, &ns16550_com2);
djm@6458 226 }
djm@6458 227 serial_init_preirq();
djm@6458 228
djm@6458 229 init_console();
djm@6458 230 set_printk_prefix("(XEN) ");
djm@6458 231
djm@6458 232 /* xenheap should be in same TR-covered range with xen image */
djm@6458 233 xenheap_phys_end = xen_pstart + xenheap_size;
djm@6458 234 printk("xen image pstart: 0x%lx, xenheap pend: 0x%lx\n",
djm@6458 235 xen_pstart, xenheap_phys_end);
djm@6458 236
djm@6458 237 /* Find next hole */
djm@6458 238 firsthole_start = 0;
djm@6458 239 efi_memmap_walk(xen_find_first_hole, &firsthole_start);
djm@6458 240
djm@8373 241 if (running_on_sim || ia64_boot_param->domain_start == 0
djm@7735 242 || ia64_boot_param->domain_size == 0) {
djm@7735 243 /* This is possible only with the old elilo, which does not support
djm@7735 244 a vmm. Fix now, and continue without initrd. */
djm@7735 245 printk ("Your elilo is not Xen-aware. Bootparams fixed\n");
djm@7735 246 ia64_boot_param->domain_start = ia64_boot_param->initrd_start;
djm@7735 247 ia64_boot_param->domain_size = ia64_boot_param->initrd_size;
djm@7735 248 ia64_boot_param->initrd_start = 0;
djm@7735 249 ia64_boot_param->initrd_size = 0;
djm@7735 250 }
djm@7735 251
djm@6458 252 initial_images_start = xenheap_phys_end;
djm@7735 253 initial_images_end = initial_images_start +
djm@7735 254 PAGE_ALIGN(ia64_boot_param->domain_size);
djm@7735 255
djm@7735 256 /* also reserve space for initrd */
djm@7735 257 if (ia64_boot_param->initrd_start && ia64_boot_param->initrd_size)
djm@7735 258 initial_images_end += PAGE_ALIGN(ia64_boot_param->initrd_size);
djm@7735 259 else {
djm@7735 260 /* sanity cleanup */
djm@7735 261 ia64_boot_param->initrd_size = 0;
djm@7735 262 ia64_boot_param->initrd_start = 0;
djm@7735 263 }
djm@7735 264
djm@6458 265
djm@6458 266 /* Later may find another memory trunk, even away from xen image... */
djm@6458 267 if (initial_images_end > firsthole_start) {
djm@6458 268 printk("Not enough memory to stash the DOM0 kernel image.\n");
djm@6458 269 printk("First hole:0x%lx, relocation end: 0x%lx\n",
djm@6458 270 firsthole_start, initial_images_end);
djm@6458 271 for ( ; ; );
djm@6458 272 }
djm@6458 273
djm@6458 274 /* This copy is time consuming, but elilo may load Dom0 image
djm@6458 275 * within xenheap range */
djm@7735 276 printk("ready to move Dom0 to 0x%lx with len %lx...", initial_images_start,
djm@7735 277 ia64_boot_param->domain_size);
djm@7735 278
djm@6458 279 memmove(__va(initial_images_start),
djm@7735 280 __va(ia64_boot_param->domain_start),
djm@7735 281 ia64_boot_param->domain_size);
djm@7735 282 // ia64_boot_param->domain_start = initial_images_start;
djm@7735 283
djm@7735 284 printk("ready to move initrd to 0x%lx with len %lx...",
djm@7735 285 initial_images_start+PAGE_ALIGN(ia64_boot_param->domain_size),
djm@7735 286 ia64_boot_param->initrd_size);
djm@7735 287 memmove(__va(initial_images_start+PAGE_ALIGN(ia64_boot_param->domain_size)),
djm@7735 288
djm@6458 289 __va(ia64_boot_param->initrd_start),
djm@6458 290 ia64_boot_param->initrd_size);
djm@6458 291 printk("Done\n");
djm@6458 292
djm@6458 293 /* first find highest page frame number */
djm@6458 294 max_page = 0;
djm@6458 295 efi_memmap_walk(find_max_pfn, &max_page);
djm@6458 296 printf("find_memory: efi_memmap_walk returns max_page=%lx\n",max_page);
awilliam@9758 297 #ifndef CONFIG_XEN_IA64_DOM0_VP
djm@8374 298 /* this is a bad hack. see dom_fw.c creation of EFI map for dom0 */
djm@8374 299 max_page = (GRANULEROUNDDOWN(max_page << PAGE_SHIFT)
djm@8374 300 - IA64_GRANULE_SIZE) >> PAGE_SHIFT;
djm@8374 301 printf("find_memory: last granule reserved for dom0; xen max_page=%lx\n",
djm@8374 302 max_page);
awilliam@9758 303 #endif
awilliam@9750 304 efi_print();
djm@6458 305
djm@6458 306 heap_start = memguard_init(ia64_imva(&_end));
awilliam@9005 307 printf("Before heap_start: %p\n", heap_start);
djm@6458 308 heap_start = __va(init_boot_allocator(__pa(heap_start)));
awilliam@9005 309 printf("After heap_start: %p\n", heap_start);
djm@6458 310
djm@6458 311 reserve_memory();
djm@6458 312
djm@6458 313 efi_memmap_walk(filter_rsvd_memory, init_boot_pages);
djm@6458 314 efi_memmap_walk(xen_count_pages, &nr_pages);
djm@6458 315
djm@6458 316 printk("System RAM: %luMB (%lukB)\n",
djm@6458 317 nr_pages >> (20 - PAGE_SHIFT),
djm@6458 318 nr_pages << (PAGE_SHIFT - 10));
djm@6458 319
djm@6458 320 init_frametable();
djm@6458 321
djm@6458 322 alloc_dom0();
djm@6458 323
djm@6458 324 end_boot_allocator();
djm@6458 325
djm@6458 326 init_xenheap_pages(__pa(heap_start), xenheap_phys_end);
djm@6458 327 printk("Xen heap: %luMB (%lukB)\n",
djm@6458 328 (xenheap_phys_end-__pa(heap_start)) >> 20,
djm@6458 329 (xenheap_phys_end-__pa(heap_start)) >> 10);
djm@6458 330
kaf24@8552 331 printk("About to call scheduler_init()\n");
kaf24@8552 332 scheduler_init();
kaf24@8552 333 idle_vcpu[0] = (struct vcpu*) ia64_r13;
kaf24@8611 334 idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
kaf24@8552 335 BUG_ON(idle_domain == NULL);
kaf24@8552 336
awilliam@9005 337 late_setup_arch((char **) &cmdline);
djm@6458 338 setup_per_cpu_areas();
djm@6458 339 mem_init();
djm@6458 340
djm@6458 341 local_irq_disable();
djm@7332 342 init_IRQ ();
djm@6466 343 printk("About to call init_xen_time()\n");
djm@6458 344 init_xen_time(); /* initialise the time */
kaf24@8586 345 printk("About to call timer_init()\n");
kaf24@8586 346 timer_init();
djm@6458 347
djm@7928 348 #ifdef CONFIG_XEN_CONSOLE_INPUT /* CONFIG_SERIAL_8250_CONSOLE=n in dom0! */
djm@7928 349 initialize_keytable();
djm@7928 350 serial_init_postirq();
djm@7928 351 #endif
djm@7928 352
djm@6458 353 #ifdef CONFIG_SMP
djm@6458 354 if ( opt_nosmp )
djm@6458 355 {
djm@6458 356 max_cpus = 0;
djm@6458 357 smp_num_siblings = 1;
djm@6458 358 //boot_cpu_data.x86_num_cores = 1;
djm@6458 359 }
djm@6458 360
awilliam@9495 361 /* A vcpu is created for the idle domain on every physical cpu.
awilliam@9495 362 Limit the number of cpus to the maximum number of vcpus. */
awilliam@9495 363 if (max_cpus > MAX_VIRT_CPUS)
awilliam@9495 364 max_cpus = MAX_VIRT_CPUS;
awilliam@9495 365
djm@6458 366 smp_prepare_cpus(max_cpus);
awilliam@9495 367
djm@6458 368 /* We aren't hotplug-capable yet. */
djm@6458 369 for_each_cpu ( i )
djm@6458 370 cpu_set(i, cpu_present_map);
djm@6458 371
djm@7332 372 /* Enable IRQ to receive IPI (needed for ITC sync). */
djm@7332 373 local_irq_enable();
djm@7332 374
djm@6458 375 printk("num_online_cpus=%d, max_cpus=%d\n",num_online_cpus(),max_cpus);
djm@6458 376 for_each_present_cpu ( i )
djm@6458 377 {
djm@6458 378 if ( num_online_cpus() >= max_cpus )
djm@6458 379 break;
djm@6458 380 if ( !cpu_online(i) ) {
djm@6458 381 __cpu_up(i);
djm@6458 382 }
djm@6458 383 }
djm@6458 384
djm@7332 385 local_irq_disable();
djm@7332 386
djm@6458 387 printk("Brought up %ld CPUs\n", (long)num_online_cpus());
djm@6458 388 smp_cpus_done(max_cpus);
djm@6458 389 #endif
djm@6458 390
kaf24@9117 391 initialise_gdb(); /* could be moved earlier */
kaf24@9117 392
djm@6458 393 do_initcalls();
djm@6458 394 printk("About to call sort_main_extable()\n");
djm@6458 395 sort_main_extable();
djm@6458 396
djm@6458 397
awilliam@9685 398 init_rid_allocator ();
awilliam@9685 399
djm@6458 400 /* Create initial domain 0. */
kaf24@8611 401 printk("About to call domain_create()\n");
kaf24@8611 402 dom0 = domain_create(0, 0);
kaf24@8552 403
djm@6458 404 if ( dom0 == NULL )
djm@6458 405 panic("Error creating domain 0\n");
djm@6458 406
djm@6458 407 set_bit(_DOMF_privileged, &dom0->domain_flags);
djm@6458 408
djm@6458 409 /*
djm@6458 410 * We're going to setup domain0 using the module(s) that we stashed safely
djm@6458 411 * above our heap. The second module, if present, is an initrd ramdisk.
djm@6458 412 */
djm@7735 413 printk("About to call construct_dom0()\n");
awilliam@9005 414 dom0_memory_start = (unsigned long) __va(initial_images_start);
djm@7735 415 dom0_memory_size = ia64_boot_param->domain_size;
awilliam@9005 416 dom0_initrd_start = (unsigned long) __va(initial_images_start +
djm@7735 417 PAGE_ALIGN(ia64_boot_param->domain_size));
djm@7735 418 dom0_initrd_size = ia64_boot_param->initrd_size;
djm@7735 419
djm@7735 420 if ( construct_dom0(dom0, dom0_memory_start, dom0_memory_size,
djm@7735 421 dom0_initrd_start,dom0_initrd_size,
djm@7735 422 0) != 0)
djm@6458 423 panic("Could not set up DOM0 guest OS\n");
djm@7332 424
djm@7332 425 /* PIN domain0 on CPU 0. */
kaf24@8511 426 dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0);
djm@7332 427
djm@6458 428 if (!running_on_sim) // slow on ski and pages are pre-initialized to zero
djm@6458 429 scrub_heap_pages();
djm@6458 430
djm@6458 431 printk("About to call init_trace_bufs()\n");
djm@6458 432 init_trace_bufs();
djm@6458 433
djm@6458 434 /* Give up the VGA console if DOM0 is configured to grab it. */
djm@7928 435 #ifdef CONFIG_XEN_CONSOLE_INPUT /* CONFIG_SERIAL_8250_CONSOLE=n in dom0! */
djm@6458 436 console_endboot(cmdline && strstr(cmdline, "tty0"));
djm@6458 437 #endif
djm@6458 438
djm@7332 439 domain0_ready = 1;
djm@7332 440
djm@7332 441 local_irq_enable();
djm@7332 442
kaf24@8552 443 printf("About to call schedulers_start dom0=%p, idle_dom=%p\n",
kaf24@8552 444 dom0, &idle_domain);
djm@7332 445 schedulers_start();
djm@7332 446
djm@6458 447 domain_unpause_by_systemcontroller(dom0);
djm@7332 448
djm@6458 449 printk("About to call startup_cpu_idle_loop()\n");
djm@6458 450 startup_cpu_idle_loop();
djm@6458 451 }
djm@6723 452
djm@6797 453 void arch_get_xen_caps(xen_capabilities_info_t info)
djm@6723 454 {
djm@6797 455 char *p=info;
djm@6723 456
djm@8475 457 p += sprintf(p,"xen-%d.%d-ia64 ", XEN_VERSION, XEN_SUBVERSION);
djm@6723 458
djm@8475 459 if (vmx_enabled)
djm@8475 460 p += sprintf(p,"hvm-%d.%d-ia64 ", XEN_VERSION, XEN_SUBVERSION);
djm@6723 461
djm@6797 462 *(p-1) = 0;
djm@6723 463
djm@6797 464 BUG_ON((p-info)>sizeof(xen_capabilities_info_t));
djm@6797 465
djm@6723 466 }
djm@6723 467