ia64/xen-unstable

annotate xen/arch/x86/setup.c @ 13754:9578ae319874

Clean up arch_get_xen_caps() to not use sprintf().
Based on a patch from Christoph Egger <Christoph.Egger@amd.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author Keir Fraser <keir@xensource.com>
date Tue Jan 30 16:23:43 2007 +0000 (2007-01-30)
parents 647c06ba0b49
children 7d3bb465e938
rev   line source
kaf24@1452 1 #include <xen/config.h>
kaf24@1452 2 #include <xen/init.h>
kaf24@1452 3 #include <xen/lib.h>
kaf24@1452 4 #include <xen/sched.h>
cl349@5247 5 #include <xen/domain.h>
kaf24@1452 6 #include <xen/serial.h>
kaf24@1506 7 #include <xen/softirq.h>
kaf24@1452 8 #include <xen/acpi.h>
kaf24@3338 9 #include <xen/console.h>
iap10@4287 10 #include <xen/serial.h>
kaf24@3338 11 #include <xen/trace.h>
kaf24@3338 12 #include <xen/multiboot.h>
kaf24@5356 13 #include <xen/domain_page.h>
kfraser@10890 14 #include <xen/version.h>
kaf24@9117 15 #include <xen/gdbstub.h>
kaf24@9818 16 #include <xen/percpu.h>
kfraser@11296 17 #include <xen/hypercall.h>
kfraser@11601 18 #include <xen/keyhandler.h>
kfraser@11971 19 #include <xen/numa.h>
kaf24@13662 20 #include <xen/rcupdate.h>
iap10@6721 21 #include <public/version.h>
ack@13291 22 #ifdef CONFIG_COMPAT
ack@13291 23 #include <compat/platform.h>
ack@13291 24 #include <compat/xen.h>
ack@13291 25 #endif
kaf24@1452 26 #include <asm/bitops.h>
kaf24@1452 27 #include <asm/smp.h>
kaf24@1452 28 #include <asm/processor.h>
kaf24@1452 29 #include <asm/mpspec.h>
kaf24@1452 30 #include <asm/apic.h>
kaf24@1452 31 #include <asm/desc.h>
kaf24@3338 32 #include <asm/shadow.h>
kaf24@3344 33 #include <asm/e820.h>
kaf24@5536 34 #include <acm/acm_hooks.h>
ian@12677 35 #include <xen/kexec.h>
kaf24@3338 36
kaf24@5157 37 extern void dmi_scan_machine(void);
kaf24@5211 38 extern void generic_apic_probe(void);
kfraser@11971 39 extern void numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn);
kaf24@5157 40
kaf24@3338 41 /*
kaf24@3338 42 * opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
kaf24@8726 43 * page_info table and allocation bitmap.
kaf24@3338 44 */
kaf24@3338 45 static unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
kaf24@4950 46 #if defined(CONFIG_X86_64)
kaf24@3338 47 integer_param("xenheap_megabytes", opt_xenheap_megabytes);
kaf24@3354 48 #endif
kaf24@1452 49
kaf24@5146 50 /* opt_nosmp: If true, secondary processors are ignored. */
kaf24@5900 51 static int opt_nosmp = 0;
kaf24@5146 52 boolean_param("nosmp", opt_nosmp);
kaf24@5146 53
kaf24@5146 54 /* maxcpus: maximum number of CPUs to activate. */
kaf24@5146 55 static unsigned int max_cpus = NR_CPUS;
shand@11156 56 integer_param("maxcpus", max_cpus);
kaf24@5146 57
kaf24@3334 58 /* opt_watchdog: If true, run a watchdog NMI on each processor. */
kaf24@3334 59 static int opt_watchdog = 0;
kaf24@3334 60 boolean_param("watchdog", opt_watchdog);
kaf24@3334 61
kaf24@4850 62 /* **** Linux config option: propagated to domain0. */
kaf24@4850 63 /* "acpi=off": Sisables both ACPI table parsing and interpreter. */
kaf24@4850 64 /* "acpi=force": Override the disable blacklist. */
kaf24@4850 65 /* "acpi=strict": Disables out-of-spec workarounds. */
kaf24@4850 66 /* "acpi=ht": Limit ACPI just to boot-time to enable HT. */
kaf24@4850 67 /* "acpi=noirq": Disables ACPI interrupt routing. */
kaf24@4850 68 static void parse_acpi_param(char *s);
kaf24@4850 69 custom_param("acpi", parse_acpi_param);
kaf24@4850 70
kaf24@4850 71 /* **** Linux config option: propagated to domain0. */
kaf24@4850 72 /* acpi_skip_timer_override: Skip IRQ0 overrides. */
kaf24@4850 73 extern int acpi_skip_timer_override;
kaf24@4850 74 boolean_param("acpi_skip_timer_override", acpi_skip_timer_override);
kaf24@4850 75
kaf24@4850 76 /* **** Linux config option: propagated to domain0. */
kaf24@4850 77 /* noapic: Disable IOAPIC setup. */
kaf24@4850 78 extern int skip_ioapic_setup;
kaf24@4850 79 boolean_param("noapic", skip_ioapic_setup);
kaf24@4850 80
kaf24@3594 81 int early_boot = 1;
kaf24@3594 82
kaf24@5146 83 cpumask_t cpu_present_map;
kaf24@5146 84
kaf24@5003 85 /* Limits of Xen heap, used to initialise the allocator. */
kaf24@5003 86 unsigned long xenheap_phys_start, xenheap_phys_end;
kaf24@3338 87
kaf24@2298 88 extern void arch_init_memory(void);
kaf24@1589 89 extern void init_IRQ(void);
kaf24@1589 90 extern void trap_init(void);
kaf24@5604 91 extern void early_time_init(void);
kaf24@5167 92 extern void early_cpu_init(void);
kaf24@1589 93
kaf24@8533 94 struct tss_struct init_tss[NR_CPUS];
kaf24@8533 95
kaf24@5011 96 extern unsigned long cpu0_stack[];
kaf24@5011 97
kaf24@5214 98 struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
kaf24@1452 99
kaf24@5237 100 #if CONFIG_PAGING_LEVELS > 2
kaf24@1670 101 unsigned long mmu_cr4_features = X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE;
kaf24@1670 102 #else
kaf24@5593 103 unsigned long mmu_cr4_features = X86_CR4_PSE;
kaf24@1670 104 #endif
kaf24@1452 105 EXPORT_SYMBOL(mmu_cr4_features);
kaf24@1452 106
kaf24@4818 107 int acpi_disabled;
kaf24@1452 108
kaf24@4850 109 int acpi_force;
kaf24@4850 110 char acpi_param[10] = "";
kaf24@4850 111 static void parse_acpi_param(char *s)
kaf24@4850 112 {
kaf24@4850 113 /* Save the parameter so it can be propagated to domain0. */
kfraser@13689 114 safe_strcpy(acpi_param, s);
kaf24@4850 115
kaf24@4850 116 /* Interpret the parameter for use within Xen. */
kaf24@4850 117 if ( !strcmp(s, "off") )
kaf24@4850 118 {
kaf24@4850 119 disable_acpi();
kaf24@4850 120 }
kaf24@4850 121 else if ( !strcmp(s, "force") )
kaf24@4850 122 {
kaf24@4850 123 acpi_force = 1;
kaf24@4850 124 acpi_ht = 1;
kaf24@4850 125 acpi_disabled = 0;
kaf24@4850 126 }
kaf24@4850 127 else if ( !strcmp(s, "strict") )
kaf24@4850 128 {
kaf24@4850 129 acpi_strict = 1;
kaf24@4850 130 }
kaf24@4850 131 else if ( !strcmp(s, "ht") )
kaf24@4850 132 {
kaf24@4850 133 if ( !acpi_force )
kaf24@4850 134 disable_acpi();
kaf24@4850 135 acpi_ht = 1;
kaf24@4850 136 }
kaf24@4850 137 else if ( !strcmp(s, "noirq") )
kaf24@4850 138 {
kaf24@4850 139 acpi_noirq_set();
kaf24@4850 140 }
kaf24@4850 141 }
kaf24@4850 142
kaf24@1452 143 static void __init do_initcalls(void)
kaf24@1452 144 {
kaf24@1452 145 initcall_t *call;
kaf24@1452 146 for ( call = &__initcall_start; call < &__initcall_end; call++ )
kaf24@1452 147 (*call)();
kaf24@1452 148 }
kaf24@1452 149
kaf24@8459 150 #define EARLY_FAIL() for ( ; ; ) __asm__ __volatile__ ( "hlt" )
kaf24@8459 151
kaf24@8459 152 static struct e820entry e820_raw[E820MAX];
kaf24@8459 153
kaf24@9067 154 static unsigned long initial_images_start, initial_images_end;
kaf24@9067 155
kaf24@9067 156 unsigned long initial_images_nrpages(void)
kaf24@9067 157 {
kaf24@9067 158 unsigned long s = initial_images_start + PAGE_SIZE - 1;
kaf24@9067 159 unsigned long e = initial_images_end;
kaf24@9067 160 return ((e >> PAGE_SHIFT) - (s >> PAGE_SHIFT));
kaf24@9067 161 }
kaf24@9067 162
kaf24@9067 163 void discard_initial_images(void)
kaf24@9067 164 {
kaf24@9067 165 init_domheap_pages(initial_images_start, initial_images_end);
kaf24@9067 166 }
kaf24@9067 167
kaf24@9818 168 extern char __per_cpu_start[], __per_cpu_data_end[], __per_cpu_end[];
kaf24@9818 169
kfraser@11241 170 static void __init percpu_init_areas(void)
kaf24@9818 171 {
kaf24@9818 172 unsigned int i, data_size = __per_cpu_data_end - __per_cpu_start;
kaf24@9818 173
kaf24@9818 174 BUG_ON(data_size > PERCPU_SIZE);
kaf24@9818 175
kfraser@11241 176 for_each_cpu ( i )
kfraser@11241 177 {
kfraser@11241 178 memguard_unguard_range(__per_cpu_start + (i << PERCPU_SHIFT),
kfraser@11241 179 1 << PERCPU_SHIFT);
kfraser@11241 180 if ( i != 0 )
kfraser@11241 181 memcpy(__per_cpu_start + (i << PERCPU_SHIFT),
kfraser@11241 182 __per_cpu_start,
kfraser@11241 183 data_size);
kfraser@11241 184 }
kaf24@9818 185 }
kaf24@9818 186
kfraser@11241 187 static void __init percpu_guard_areas(void)
kfraser@11241 188 {
kfraser@11241 189 memguard_guard_range(__per_cpu_start, __per_cpu_end - __per_cpu_start);
kfraser@11241 190 }
kfraser@11241 191
kfraser@11241 192 static void __init percpu_free_unused_areas(void)
kaf24@9818 193 {
kaf24@9818 194 unsigned int i, first_unused;
kaf24@9818 195
kaf24@9818 196 /* Find first unused CPU number. */
kaf24@9818 197 for ( i = 0; i < NR_CPUS; i++ )
kaf24@9818 198 if ( !cpu_online(i) )
kaf24@9818 199 break;
kaf24@9818 200 first_unused = i;
kaf24@9818 201
kaf24@9818 202 /* Check that there are no holes in cpu_online_map. */
kaf24@9818 203 for ( ; i < NR_CPUS; i++ )
kaf24@9818 204 BUG_ON(cpu_online(i));
kaf24@9818 205
kfraser@11241 206 #ifndef MEMORY_GUARD
kaf24@9818 207 init_xenheap_pages(__pa(__per_cpu_start) + (first_unused << PERCPU_SHIFT),
kaf24@9818 208 __pa(__per_cpu_end));
kfraser@11241 209 #endif
kaf24@9818 210 }
kaf24@9818 211
kfraser@11881 212 /* Fetch acm policy module from multiboot modules. */
kfraser@11881 213 static void extract_acm_policy(
kfraser@11881 214 multiboot_info_t *mbi,
kfraser@11881 215 unsigned int *initrdidx,
kfraser@11881 216 char **_policy_start,
kfraser@11881 217 unsigned long *_policy_len)
kfraser@11881 218 {
kfraser@11881 219 int i;
kfraser@11881 220 module_t *mod = (module_t *)__va(mbi->mods_addr);
kfraser@11881 221 unsigned long start, policy_len;
kfraser@11881 222 char *policy_start;
kfraser@11881 223
kfraser@11881 224 /*
kfraser@11881 225 * Try all modules and see whichever could be the binary policy.
kfraser@11881 226 * Adjust the initrdidx if module[1] is the binary policy.
kfraser@11881 227 */
kfraser@11881 228 for ( i = mbi->mods_count-1; i >= 1; i-- )
kfraser@11881 229 {
kfraser@11881 230 start = initial_images_start + (mod[i].mod_start-mod[0].mod_start);
kfraser@11881 231 #if defined(__i386__)
kfraser@11881 232 policy_start = (char *)start;
kfraser@11881 233 #elif defined(__x86_64__)
kfraser@11881 234 policy_start = __va(start);
kfraser@11881 235 #endif
kfraser@11881 236 policy_len = mod[i].mod_end - mod[i].mod_start;
kfraser@11881 237 if ( acm_is_policy(policy_start, policy_len) )
kfraser@11881 238 {
kfraser@11881 239 printk("Policy len 0x%lx, start at %p - module %d.\n",
kfraser@11881 240 policy_len, policy_start, i);
kfraser@11881 241 *_policy_start = policy_start;
kfraser@11881 242 *_policy_len = policy_len;
kfraser@11881 243 if ( i == 1 )
kfraser@11881 244 *initrdidx = (mbi->mods_count > 2) ? 2 : 0;
kfraser@11881 245 break;
kfraser@11881 246 }
kfraser@11881 247 }
kfraser@11881 248 }
kfraser@11881 249
kfraser@11241 250 static void __init init_idle_domain(void)
kfraser@11240 251 {
kfraser@11240 252 struct domain *idle_domain;
kfraser@11240 253
kfraser@11240 254 /* Domain creation requires that scheduler structures are initialised. */
kfraser@11240 255 scheduler_init();
kfraser@11240 256
kfraser@12210 257 idle_domain = domain_create(IDLE_DOMAIN_ID, 0);
kfraser@11240 258 if ( (idle_domain == NULL) || (alloc_vcpu(idle_domain, 0, 0) == NULL) )
kfraser@11240 259 BUG();
kfraser@11240 260
kfraser@11240 261 set_current(idle_domain->vcpu[0]);
kfraser@11240 262 idle_vcpu[0] = this_cpu(curr_vcpu) = current;
kfraser@11240 263
kfraser@11240 264 setup_idle_pagetable();
kfraser@11240 265 }
kfraser@11240 266
kfraser@11971 267 static void srat_detect_node(int cpu)
kfraser@11971 268 {
kfraser@11998 269 unsigned node;
kfraser@11998 270 u8 apicid = x86_cpu_to_apicid[cpu];
kfraser@11971 271
kfraser@11998 272 node = apicid_to_node[apicid];
kfraser@11998 273 if ( node == NUMA_NO_NODE )
kfraser@11998 274 node = 0;
kfraser@11998 275 numa_set_node(cpu, node);
kfraser@11971 276
kfraser@11998 277 if ( acpi_numa > 0 )
kfraser@11998 278 printk(KERN_INFO "CPU %d APIC %d -> Node %d\n", cpu, apicid, node);
kfraser@11971 279 }
kfraser@11971 280
ian@12681 281 void __init move_memory(unsigned long dst,
ian@12677 282 unsigned long src_start, unsigned long src_end)
ian@12677 283 {
ian@12677 284 #if defined(CONFIG_X86_32)
ian@12681 285 memmove((void *)dst, /* use low mapping */
ian@12677 286 (void *)src_start, /* use low mapping */
ian@12677 287 src_end - src_start);
ian@12677 288 #elif defined(CONFIG_X86_64)
ian@12677 289 memmove(__va(dst),
ian@12677 290 __va(src_start),
ian@12677 291 src_end - src_start);
ian@12677 292 #endif
ian@12677 293 }
ian@12677 294
kaf24@8463 295 void __init __start_xen(multiboot_info_t *mbi)
kaf24@1452 296 {
kaf24@9823 297 char __cmdline[] = "", *cmdline = __cmdline;
kaf24@8457 298 unsigned long _initrd_start = 0, _initrd_len = 0;
kaf24@8457 299 unsigned int initrdidx = 1;
kfraser@11881 300 char *_policy_start = NULL;
kfraser@11881 301 unsigned long _policy_len = 0;
kaf24@8457 302 module_t *mod = (module_t *)__va(mbi->mods_addr);
kaf24@6111 303 unsigned long nr_pages, modules_length;
kaf24@8726 304 paddr_t s, e;
kaf24@8402 305 int i, e820_warn = 0, e820_raw_nr = 0, bytes = 0;
kaf24@5776 306 struct ns16550_defaults ns16550 = {
kaf24@5776 307 .data_bits = 8,
kaf24@5776 308 .parity = 'n',
kaf24@5776 309 .stop_bits = 1
kaf24@5776 310 };
kaf24@3338 311
kfraser@12853 312 extern void early_page_fault(void);
kfraser@12853 313 set_intr_gate(TRAP_page_fault, &early_page_fault);
kfraser@12853 314
kaf24@3338 315 /* Parse the command-line options. */
kaf24@3344 316 if ( (mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0) )
kaf24@9823 317 cmdline = __va(mbi->cmdline);
kaf24@9823 318 cmdline_parse(cmdline);
kaf24@3338 319
kaf24@8534 320 set_current((struct vcpu *)0xfffff000); /* debug sanity */
kfraser@11240 321 idle_vcpu[0] = current;
kaf24@8534 322 set_processor_id(0); /* needed early, for smp_processor_id() */
kaf24@3338 323
kaf24@5146 324 smp_prepare_boot_cpu();
kaf24@5146 325
kaf24@3338 326 /* We initialise the serial devices very early so we can get debugging. */
kaf24@5776 327 ns16550.io_base = 0x3f8;
kaf24@5776 328 ns16550.irq = 4;
kaf24@5776 329 ns16550_init(0, &ns16550);
kaf24@5776 330 ns16550.io_base = 0x2f8;
kaf24@5776 331 ns16550.irq = 3;
kaf24@5776 332 ns16550_init(1, &ns16550);
kaf24@5195 333 serial_init_preirq();
kaf24@3338 334
kaf24@3338 335 init_console();
kaf24@3338 336
kfraser@11947 337 printk("Command line: %s\n", cmdline);
kaf24@9823 338
kaf24@3344 339 /* Check that we have at least one Multiboot module. */
kaf24@3344 340 if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
kaf24@3338 341 {
kaf24@5542 342 printk("FATAL ERROR: dom0 kernel not specified."
kaf24@5542 343 " Check bootloader configuration.\n");
kaf24@5011 344 EARLY_FAIL();
kaf24@5011 345 }
kaf24@5011 346
kaf24@5011 347 if ( ((unsigned long)cpu0_stack & (STACK_SIZE-1)) != 0 )
kaf24@5011 348 {
kaf24@5011 349 printk("FATAL ERROR: Misaligned CPU0 stack.\n");
kaf24@5011 350 EARLY_FAIL();
kaf24@3338 351 }
kaf24@3338 352
kfraser@11618 353 /*
kfraser@11618 354 * Since there are some stubs getting built on the stacks which use
kfraser@11618 355 * direct calls/jumps, the heap must be confined to the lower 2G so
kfraser@11618 356 * that those branches can reach their targets.
kfraser@11618 357 */
kfraser@11618 358 if ( opt_xenheap_megabytes > 2048 )
kfraser@11618 359 opt_xenheap_megabytes = 2048;
kaf24@3338 360 xenheap_phys_end = opt_xenheap_megabytes << 20;
kaf24@3338 361
kaf24@3344 362 if ( mbi->flags & MBI_MEMMAP )
kaf24@3344 363 {
kaf24@3344 364 while ( bytes < mbi->mmap_length )
kaf24@3344 365 {
kaf24@3344 366 memory_map_t *map = __va(mbi->mmap_addr + bytes);
kaf24@8402 367
kaf24@8402 368 /*
kaf24@8403 369 * This is a gross workaround for a BIOS bug. Some bootloaders do
kaf24@8402 370 * not write e820 map entries into pre-zeroed memory. This is
kaf24@8402 371 * okay if the BIOS fills in all fields of the map entry, but
kaf24@8402 372 * some broken BIOSes do not bother to write the high word of
kaf24@8402 373 * the length field if the length is smaller than 4GB. We
kaf24@8402 374 * detect and fix this by flagging sections below 4GB that
kaf24@8403 375 * appear to be larger than 4GB in size.
kaf24@8402 376 */
kaf24@8403 377 if ( (map->base_addr_high == 0) && (map->length_high != 0) )
kaf24@8402 378 {
kaf24@8402 379 e820_warn = 1;
kaf24@8402 380 map->length_high = 0;
kaf24@8402 381 }
kaf24@8402 382
kaf24@3344 383 e820_raw[e820_raw_nr].addr =
kaf24@3344 384 ((u64)map->base_addr_high << 32) | (u64)map->base_addr_low;
kaf24@3344 385 e820_raw[e820_raw_nr].size =
kaf24@3344 386 ((u64)map->length_high << 32) | (u64)map->length_low;
kaf24@3344 387 e820_raw[e820_raw_nr].type =
kfraser@12226 388 (map->type > E820_NVS) ? E820_RESERVED : map->type;
kaf24@3344 389 e820_raw_nr++;
kaf24@8402 390
kaf24@3344 391 bytes += map->size + 4;
kaf24@3344 392 }
kaf24@3344 393 }
kaf24@3344 394 else if ( mbi->flags & MBI_MEMLIMITS )
kaf24@3344 395 {
kaf24@3344 396 e820_raw[0].addr = 0;
kaf24@3344 397 e820_raw[0].size = mbi->mem_lower << 10;
kaf24@3344 398 e820_raw[0].type = E820_RAM;
kaf24@3354 399 e820_raw[1].addr = 0x100000;
kaf24@3354 400 e820_raw[1].size = mbi->mem_upper << 10;
kaf24@3354 401 e820_raw[1].type = E820_RAM;
kaf24@3344 402 e820_raw_nr = 2;
kaf24@3344 403 }
kaf24@3344 404 else
kaf24@3344 405 {
kaf24@3344 406 printk("FATAL ERROR: Bootloader provided no memory information.\n");
kaf24@3344 407 for ( ; ; ) ;
kaf24@3344 408 }
kaf24@3344 409
kaf24@8402 410 if ( e820_warn )
kaf24@8402 411 printk("WARNING: Buggy e820 map detected and fixed "
kaf24@8402 412 "(truncated length fields).\n");
kaf24@8402 413
kaf24@13427 414 /* Ensure that all E820 RAM regions are page-aligned and -sized. */
kaf24@13427 415 for ( i = 0; i < e820_raw_nr; i++ )
kaf24@13427 416 {
kaf24@13427 417 uint64_t s, e;
kaf24@13427 418 if ( e820_raw[i].type != E820_RAM )
kaf24@13427 419 continue;
kaf24@13427 420 s = PFN_UP(e820_raw[i].addr);
kaf24@13427 421 e = PFN_DOWN(e820_raw[i].addr + e820_raw[i].size);
kaf24@13427 422 e820_raw[i].size = 0; /* discarded later */
kaf24@13427 423 if ( s < e )
kaf24@13427 424 {
kaf24@13427 425 e820_raw[i].addr = s << PAGE_SHIFT;
kaf24@13427 426 e820_raw[i].size = (e - s) << PAGE_SHIFT;
kaf24@13427 427 }
kaf24@13427 428 }
kaf24@13427 429
kaf24@13427 430 /* Sanitise the raw E820 map to produce a final clean version. */
kaf24@4950 431 max_page = init_e820(e820_raw, &e820_raw_nr);
kaf24@3338 432
kaf24@6111 433 modules_length = mod[mbi->mods_count-1].mod_end - mod[0].mod_start;
kaf24@3338 434
kaf24@6111 435 /* Find a large enough RAM extent to stash the DOM0 modules. */
kaf24@6111 436 for ( i = 0; ; i++ )
kaf24@3338 437 {
kaf24@6111 438 if ( i == e820.nr_map )
kaf24@6111 439 {
kaf24@6111 440 printk("Not enough memory to stash the DOM0 kernel image.\n");
kaf24@6111 441 for ( ; ; ) ;
kaf24@6111 442 }
kaf24@13427 443
kaf24@6134 444 if ( (e820.map[i].type == E820_RAM) &&
kaf24@6134 445 (e820.map[i].size >= modules_length) &&
kaf24@6134 446 ((e820.map[i].addr + e820.map[i].size) >=
kaf24@6134 447 (xenheap_phys_end + modules_length)) )
kaf24@6134 448 break;
kaf24@3338 449 }
kaf24@6111 450
kaf24@6134 451 /* Stash as near as possible to the beginning of the RAM extent. */
kaf24@6134 452 initial_images_start = e820.map[i].addr;
kaf24@6134 453 if ( initial_images_start < xenheap_phys_end )
kaf24@6134 454 initial_images_start = xenheap_phys_end;
kaf24@6134 455 initial_images_end = initial_images_start + modules_length;
kaf24@6134 456
ian@12677 457 move_memory(initial_images_start,
ian@12677 458 mod[0].mod_start, mod[mbi->mods_count-1].mod_end);
kaf24@3338 459
kaf24@3354 460 /* Initialise boot-time allocator with all RAM situated after modules. */
kaf24@5003 461 xenheap_phys_start = init_boot_allocator(__pa(&_end));
kaf24@6111 462 nr_pages = 0;
kaf24@3354 463 for ( i = 0; i < e820.nr_map; i++ )
kaf24@3354 464 {
kaf24@3354 465 if ( e820.map[i].type != E820_RAM )
kaf24@3354 466 continue;
kaf24@6111 467
kaf24@3354 468 nr_pages += e820.map[i].size >> PAGE_SHIFT;
kaf24@6111 469
kaf24@6111 470 /* Initialise boot heap, skipping Xen heap and dom0 modules. */
kaf24@6111 471 s = e820.map[i].addr;
kaf24@6111 472 e = s + e820.map[i].size;
kaf24@6111 473 if ( s < xenheap_phys_end )
kaf24@6111 474 s = xenheap_phys_end;
kaf24@6111 475 if ( (s < initial_images_end) && (e > initial_images_start) )
kaf24@6111 476 s = initial_images_end;
kaf24@6111 477 init_boot_pages(s, e);
kaf24@6111 478
kaf24@5003 479 #if defined (CONFIG_X86_64)
kaf24@5003 480 /*
kaf24@5003 481 * x86/64 maps all registered RAM. Points to note:
kaf24@9783 482 * 1. The initial pagetable already maps low 1GB, so skip that.
kaf24@5003 483 * 2. We must map *only* RAM areas, taking care to avoid I/O holes.
kaf24@5003 484 * Failure to do this can cause coherency problems and deadlocks
kaf24@5003 485 * due to cache-attribute mismatches (e.g., AMD/AGP Linux bug).
kaf24@5003 486 */
kaf24@5003 487 {
kaf24@5004 488 /* Calculate page-frame range, discarding partial frames. */
kaf24@5004 489 unsigned long start, end;
kaf24@9783 490 unsigned long init_mapped = 1UL << (30 - PAGE_SHIFT); /* 1GB */
kaf24@5005 491 start = PFN_UP(e820.map[i].addr);
kaf24@5005 492 end = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
kaf24@9800 493 /* Clip the range to exclude what the bootstrapper initialised. */
kaf24@9783 494 if ( start < init_mapped )
kaf24@9783 495 start = init_mapped;
kaf24@13427 496 if ( end <= start )
kaf24@13427 497 continue;
kaf24@5004 498 /* Request the mapping. */
kaf24@5003 499 map_pages_to_xen(
kaf24@5004 500 PAGE_OFFSET + (start << PAGE_SHIFT),
kaf24@5004 501 start, end-start, PAGE_HYPERVISOR);
kaf24@5003 502 }
kaf24@5003 503 #endif
kaf24@3354 504 }
kaf24@3354 505
ian@13421 506 if ( kexec_crash_area.size > 0 && kexec_crash_area.start > 0)
ian@12681 507 {
ian@12677 508 unsigned long kdump_start, kdump_size, k;
ian@12677 509
ian@12681 510 /* Mark images pages as free for now. */
ian@12677 511
ian@12677 512 init_boot_pages(initial_images_start, initial_images_end);
ian@12677 513
ian@12713 514 kdump_start = kexec_crash_area.start;
ian@12713 515 kdump_size = kexec_crash_area.size;
ian@12677 516
ian@12681 517 printk("Kdump: %luMB (%lukB) at 0x%lx\n",
ian@12677 518 kdump_size >> 20,
ian@12677 519 kdump_size >> 10,
ian@12677 520 kdump_start);
ian@12677 521
ian@12681 522 if ( (kdump_start & ~PAGE_MASK) || (kdump_size & ~PAGE_MASK) )
ian@12677 523 panic("Kdump parameters not page aligned\n");
ian@12677 524
ian@12677 525 kdump_start >>= PAGE_SHIFT;
ian@12677 526 kdump_size >>= PAGE_SHIFT;
ian@12677 527
kfraser@12853 528 /* Allocate pages for Kdump memory area. */
ian@12677 529
ian@12677 530 k = alloc_boot_pages_at(kdump_size, kdump_start);
ian@12681 531 if ( k != kdump_start )
ian@12677 532 panic("Unable to reserve Kdump memory\n");
ian@12677 533
kfraser@12853 534 /* Allocate pages for relocated initial images. */
ian@12677 535
ian@12677 536 k = ((initial_images_end - initial_images_start) & ~PAGE_MASK) ? 1 : 0;
ian@12677 537 k += (initial_images_end - initial_images_start) >> PAGE_SHIFT;
ian@12677 538
ian@12677 539 k = alloc_boot_pages(k, 1);
kfraser@12853 540 if ( k == 0 )
ian@12677 541 panic("Unable to allocate initial images memory\n");
ian@12677 542
ian@12677 543 move_memory(k << PAGE_SHIFT, initial_images_start, initial_images_end);
ian@12677 544
ian@12677 545 initial_images_end -= initial_images_start;
ian@12677 546 initial_images_start = k << PAGE_SHIFT;
ian@12677 547 initial_images_end += initial_images_start;
ian@12681 548 }
ian@12677 549
kaf24@5003 550 memguard_init();
kfraser@11241 551 percpu_guard_areas();
kaf24@4950 552
ian@12681 553 printk("System RAM: %luMB (%lukB)\n",
kaf24@3354 554 nr_pages >> (20 - PAGE_SHIFT),
kaf24@3354 555 nr_pages << (PAGE_SHIFT - 10));
kaf24@7220 556 total_pages = nr_pages;
kaf24@3354 557
kfraser@11296 558 /* Sanity check for unwanted bloat of certain hypercall structures. */
kfraser@11296 559 BUILD_BUG_ON(sizeof(((struct xen_platform_op *)0)->u) !=
kfraser@11296 560 sizeof(((struct xen_platform_op *)0)->u.pad));
kfraser@11296 561 BUILD_BUG_ON(sizeof(((struct xen_domctl *)0)->u) !=
kfraser@11296 562 sizeof(((struct xen_domctl *)0)->u.pad));
kfraser@11296 563 BUILD_BUG_ON(sizeof(((struct xen_sysctl *)0)->u) !=
kfraser@11296 564 sizeof(((struct xen_sysctl *)0)->u.pad));
kaf24@7388 565
kaf24@9878 566 BUILD_BUG_ON(sizeof(start_info_t) > PAGE_SIZE);
kaf24@9878 567 BUILD_BUG_ON(sizeof(shared_info_t) > PAGE_SIZE);
ack@13292 568 BUILD_BUG_ON(sizeof(struct vcpu_info) != 64);
kaf24@7744 569
ack@13291 570 #ifdef CONFIG_COMPAT
ack@13291 571 BUILD_BUG_ON(sizeof(((struct compat_platform_op *)0)->u) !=
ack@13291 572 sizeof(((struct compat_platform_op *)0)->u.pad));
ack@13291 573 BUILD_BUG_ON(sizeof(start_info_compat_t) > PAGE_SIZE);
ack@13292 574 BUILD_BUG_ON(sizeof(struct compat_vcpu_info) != 64);
ack@13291 575 #endif
ack@13291 576
kfraser@10492 577 /* Check definitions in public headers match internal defs. */
kaf24@9878 578 BUILD_BUG_ON(__HYPERVISOR_VIRT_START != HYPERVISOR_VIRT_START);
kaf24@8521 579 #ifdef HYPERVISOR_VIRT_END
kaf24@9878 580 BUILD_BUG_ON(__HYPERVISOR_VIRT_END != HYPERVISOR_VIRT_END);
kaf24@8521 581 #endif
kfraser@10492 582 BUILD_BUG_ON(MACH2PHYS_VIRT_START != RO_MPT_VIRT_START);
kfraser@10492 583 BUILD_BUG_ON(MACH2PHYS_VIRT_END != RO_MPT_VIRT_END);
kaf24@8521 584
kaf24@3354 585 init_frametable();
kaf24@3338 586
kfraser@11971 587 acpi_boot_table_init();
kfraser@11971 588
kfraser@11971 589 acpi_numa_init();
kfraser@11971 590
kfraser@11971 591 numa_initmem_init(0, max_page);
kfraser@11971 592
kaf24@3354 593 end_boot_allocator();
kaf24@3354 594
kaf24@6111 595 /* Initialise the Xen heap, skipping RAM holes. */
kaf24@6111 596 nr_pages = 0;
kaf24@6111 597 for ( i = 0; i < e820.nr_map; i++ )
kaf24@6111 598 {
kaf24@6111 599 if ( e820.map[i].type != E820_RAM )
kaf24@6111 600 continue;
kaf24@6111 601
kaf24@6111 602 s = e820.map[i].addr;
kaf24@6111 603 e = s + e820.map[i].size;
kaf24@6111 604 if ( s < xenheap_phys_start )
kaf24@6111 605 s = xenheap_phys_start;
kaf24@6111 606 if ( e > xenheap_phys_end )
kaf24@6111 607 e = xenheap_phys_end;
kaf24@6111 608
kaf24@6111 609 if ( s < e )
kaf24@6111 610 {
kaf24@6111 611 nr_pages += (e - s) >> PAGE_SHIFT;
kaf24@6111 612 init_xenheap_pages(s, e);
kaf24@6111 613 }
kaf24@6111 614 }
kaf24@6111 615
kaf24@6111 616 printk("Xen heap: %luMB (%lukB)\n",
kaf24@6111 617 nr_pages >> (20 - PAGE_SHIFT),
kaf24@6111 618 nr_pages << (PAGE_SHIFT - 10));
kaf24@3338 619
kaf24@3594 620 early_boot = 0;
kaf24@3338 621
kaf24@8459 622 early_cpu_init();
kaf24@8459 623
kaf24@8459 624 paging_init();
kaf24@8459 625
kaf24@8459 626 /* Unmap the first page of CPU0's stack. */
kaf24@8459 627 memguard_guard_stack(cpu0_stack);
kaf24@8459 628
kaf24@8459 629 open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);
kaf24@8459 630
kaf24@8459 631 if ( opt_watchdog )
kaf24@8459 632 nmi_watchdog = NMI_LOCAL_APIC;
kaf24@8459 633
kaf24@8459 634 sort_exception_tables();
kaf24@8459 635
kaf24@8459 636 find_smp_config();
kaf24@8459 637
kaf24@8459 638 smp_alloc_memory();
kaf24@8459 639
kaf24@8459 640 dmi_scan_machine();
kaf24@8459 641
kaf24@8459 642 generic_apic_probe();
kaf24@8459 643
kaf24@8459 644 acpi_boot_init();
kaf24@8459 645
kfraser@11971 646 init_cpu_to_node();
kfraser@11971 647
kfraser@11241 648 if ( smp_found_config )
kaf24@8459 649 get_smp_config();
kaf24@8459 650
kaf24@8459 651 init_apic_mappings();
kaf24@8459 652
kaf24@8459 653 init_IRQ();
kaf24@8459 654
kfraser@11241 655 percpu_init_areas();
kfraser@11241 656
kfraser@11240 657 init_idle_domain();
kfraser@11240 658
kaf24@8459 659 trap_init();
kaf24@8459 660
kaf24@13662 661 rcu_init();
kaf24@13662 662
kaf24@8586 663 timer_init();
kaf24@8459 664
kaf24@8459 665 early_time_init();
kaf24@8459 666
kaf24@8459 667 arch_init_memory();
kaf24@8459 668
kaf24@8459 669 identify_cpu(&boot_cpu_data);
kaf24@8459 670 if ( cpu_has_fxsr )
kaf24@8459 671 set_in_cr4(X86_CR4_OSFXSR);
kaf24@8459 672 if ( cpu_has_xmm )
kaf24@8459 673 set_in_cr4(X86_CR4_OSXMMEXCPT);
kaf24@8459 674
kaf24@8459 675 if ( opt_nosmp )
kaf24@8459 676 max_cpus = 0;
kaf24@8459 677
kaf24@8459 678 smp_prepare_cpus(max_cpus);
kaf24@8459 679
kaf24@8459 680 /*
kaf24@8459 681 * Initialise higher-level timer functions. We do this fairly late
kaf24@8459 682 * (post-SMP) because the time bases and scale factors need to be updated
kaf24@8459 683 * regularly, and SMP initialisation can cause a long delay with
kaf24@8459 684 * interrupts not yet enabled.
kaf24@8459 685 */
kaf24@8459 686 init_xen_time();
kaf24@8459 687
kaf24@8459 688 initialize_keytable();
kaf24@8459 689
kaf24@8459 690 serial_init_postirq();
kaf24@8459 691
kaf24@8459 692 BUG_ON(!local_irq_is_enabled());
kaf24@8459 693
kaf24@8459 694 for_each_present_cpu ( i )
kaf24@8459 695 {
kaf24@8459 696 if ( num_online_cpus() >= max_cpus )
kaf24@8459 697 break;
kaf24@8459 698 if ( !cpu_online(i) )
kaf24@13662 699 {
kaf24@13662 700 rcu_online_cpu(i);
kaf24@8459 701 __cpu_up(i);
kaf24@13662 702 }
kfraser@11971 703
kfraser@11998 704 /* Set up cpu_to_node[]. */
kfraser@11971 705 srat_detect_node(i);
kfraser@11998 706 /* Set up node_to_cpumask based on cpu_to_node[]. */
kfraser@11971 707 numa_add_cpu(i);
kaf24@8459 708 }
kaf24@8459 709
kaf24@8459 710 printk("Brought up %ld CPUs\n", (long)num_online_cpus());
kaf24@8459 711 smp_cpus_done(max_cpus);
kaf24@8459 712
kaf24@9818 713 percpu_free_unused_areas();
kaf24@9818 714
kaf24@9117 715 initialise_gdb(); /* could be moved earlier */
kaf24@9117 716
kaf24@8459 717 do_initcalls();
kaf24@8459 718
kaf24@8459 719 schedulers_start();
kaf24@8459 720
kaf24@8594 721 if ( opt_watchdog )
kaf24@8594 722 watchdog_enable();
kaf24@8459 723
kfraser@11881 724 /* Extract policy from multiboot. */
kfraser@11881 725 extract_acm_policy(mbi, &initrdidx, &_policy_start, &_policy_len);
kfraser@11881 726
kaf24@8459 727 /* initialize access control security module */
kfraser@11881 728 acm_init(_policy_start, _policy_len);
kaf24@8459 729
kaf24@8459 730 /* Create initial domain 0. */
kfraser@12210 731 dom0 = domain_create(0, 0);
kfraser@10655 732 if ( (dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL) )
kaf24@8459 733 panic("Error creating domain 0\n");
kaf24@8459 734
kfraser@12210 735 dom0->is_privileged = 1;
kfraser@12210 736
kfraser@12210 737 /* Post-create hook sets security label. */
kaf24@8459 738 acm_post_domain0_create(dom0->domain_id);
kaf24@8459 739
kaf24@8459 740 /* Grab the DOM0 command line. */
kaf24@8459 741 cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
kaf24@8459 742 if ( cmdline != NULL )
kaf24@8459 743 {
kaf24@8459 744 static char dom0_cmdline[MAX_GUEST_CMDLINE];
kaf24@8459 745
kaf24@8459 746 /* Skip past the image name and copy to a local buffer. */
kaf24@8459 747 while ( *cmdline == ' ' ) cmdline++;
kaf24@8459 748 if ( (cmdline = strchr(cmdline, ' ')) != NULL )
kaf24@8459 749 {
kaf24@8459 750 while ( *cmdline == ' ' ) cmdline++;
kfraser@13689 751 safe_strcpy(dom0_cmdline, cmdline);
kaf24@8459 752 }
kaf24@8459 753
kaf24@8459 754 /* Append any extra parameters. */
kfraser@13691 755 if ( skip_ioapic_setup && !strstr(dom0_cmdline, "noapic") )
kfraser@13691 756 safe_strcat(dom0_cmdline, " noapic");
kaf24@8459 757 if ( acpi_skip_timer_override &&
kfraser@13691 758 !strstr(dom0_cmdline, "acpi_skip_timer_override") )
kfraser@13691 759 safe_strcat(dom0_cmdline, " acpi_skip_timer_override");
kfraser@13691 760 if ( (strlen(acpi_param) != 0) && !strstr(dom0_cmdline, "acpi=") )
kaf24@8459 761 {
kfraser@13691 762 safe_strcat(dom0_cmdline, " acpi=");
kfraser@13691 763 safe_strcat(dom0_cmdline, acpi_param);
kaf24@8459 764 }
kfraser@13691 765
kfraser@13691 766 cmdline = dom0_cmdline;
kaf24@8459 767 }
kaf24@8459 768
kaf24@8459 769 if ( (initrdidx > 0) && (initrdidx < mbi->mods_count) )
kaf24@8459 770 {
kaf24@8459 771 _initrd_start = initial_images_start +
kaf24@8459 772 (mod[initrdidx].mod_start - mod[0].mod_start);
kaf24@8459 773 _initrd_len = mod[initrdidx].mod_end - mod[initrdidx].mod_start;
kaf24@8459 774 }
kaf24@8459 775
kaf24@8459 776 /*
kaf24@8459 777 * We're going to setup domain0 using the module(s) that we stashed safely
kaf24@8459 778 * above our heap. The second module, if present, is an initrd ramdisk.
kaf24@8459 779 */
kaf24@8459 780 if ( construct_dom0(dom0,
kaf24@8459 781 initial_images_start,
kaf24@8459 782 mod[0].mod_end-mod[0].mod_start,
kaf24@8459 783 _initrd_start,
kaf24@8459 784 _initrd_len,
kaf24@8459 785 cmdline) != 0)
kaf24@8459 786 panic("Could not set up DOM0 guest OS\n");
kaf24@8459 787
kaf24@8459 788 /* Scrub RAM that is still free and so may go to an unprivileged domain. */
kaf24@8459 789 scrub_heap_pages();
kaf24@8459 790
kaf24@8459 791 init_trace_bufs();
kaf24@8459 792
kaf24@10502 793 console_endboot();
kaf24@8459 794
kaf24@8459 795 /* Hide UART from DOM0 if we're using it */
kaf24@8459 796 serial_endboot();
kaf24@8459 797
kaf24@8459 798 domain_unpause_by_systemcontroller(dom0);
kaf24@8459 799
kaf24@8459 800 startup_cpu_idle_loop();
kaf24@8459 801 }
kaf24@8459 802
kaf24@6725 803 void arch_get_xen_caps(xen_capabilities_info_t info)
iap10@6721 804 {
kfraser@10890 805 int major = xen_major_version();
kfraser@10890 806 int minor = xen_minor_version();
keir@13754 807 char s[32];
keir@13754 808
keir@13754 809 info[0] = '\0';
iap10@6721 810
kaf24@6725 811 #if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE)
kaf24@6725 812
keir@13754 813 snprintf(s, sizeof(s), "xen-%d.%d-x86_32 ", major, minor);
keir@13754 814 safe_strcat(info, s);
keir@13754 815 if ( hvm_enabled )
keir@13754 816 {
keir@13754 817 snprintf(s, sizeof(s), "hvm-%d.%d-x86_32 ", major, minor);
keir@13754 818 safe_strcat(info, s);
kfraser@13685 819 }
kaf24@6725 820
kaf24@6725 821 #elif defined(CONFIG_X86_32) && defined(CONFIG_X86_PAE)
kaf24@6725 822
keir@13754 823 snprintf(s, sizeof(s), "xen-%d.%d-x86_32p ", major, minor);
keir@13754 824 safe_strcat(info, s);
kaf24@6725 825 if ( hvm_enabled )
iap10@6721 826 {
keir@13754 827 snprintf(s, sizeof(s), "hvm-%d.%d-x86_32 ", major, minor);
keir@13754 828 safe_strcat(info, s);
keir@13754 829 snprintf(s, sizeof(s), "hvm-%d.%d-x86_32p ", major, minor);
keir@13754 830 safe_strcat(info, s);
iap10@6721 831 }
iap10@6721 832
kaf24@6725 833 #elif defined(CONFIG_X86_64)
iap10@6721 834
keir@13754 835 snprintf(s, sizeof(s), "xen-%d.%d-x86_64 ", major, minor);
keir@13754 836 safe_strcat(info, s);
ack@13288 837 #ifdef CONFIG_COMPAT
keir@13754 838 snprintf(s, sizeof(s), "xen-%d.%d-x86_32p ", major, minor);
keir@13754 839 safe_strcat(info, s);
ack@13288 840 #endif
kaf24@6725 841 if ( hvm_enabled )
iap10@6721 842 {
keir@13754 843 snprintf(s, sizeof(s), "hvm-%d.%d-x86_32 ", major, minor);
keir@13754 844 safe_strcat(info, s);
keir@13754 845 snprintf(s, sizeof(s), "hvm-%d.%d-x86_32p ", major, minor);
keir@13754 846 safe_strcat(info, s);
keir@13754 847 snprintf(s, sizeof(s), "hvm-%d.%d-x86_64 ", major, minor);
keir@13754 848 safe_strcat(info, s);
iap10@6721 849 }
kaf24@6725 850
iap10@6721 851 #endif
iap10@6721 852 }
iap10@6721 853
kaf24@3914 854 /*
kaf24@3914 855 * Local variables:
kaf24@3914 856 * mode: C
kaf24@3914 857 * c-set-style: "BSD"
kaf24@3914 858 * c-basic-offset: 4
kaf24@3914 859 * tab-width: 4
kaf24@3914 860 * indent-tabs-mode: nil
kaf24@3988 861 * End:
kaf24@3914 862 */