Index: sys/x86/xen/pv.c =================================================================== --- sys/x86/xen/pv.c +++ sys/x86/xen/pv.c @@ -76,6 +76,7 @@ #include #include +#include #include #include @@ -117,6 +118,35 @@ /*-------------------------------- Xen PV init -------------------------------*/ +static int +isxen(void) +{ + u_int regs[4]; + + /* + * The full code for identifying which hypervisor we're running under + * is in sys/x86/x86/identcpu.c and runs later in the boot process; + * this is sufficient to distinguish Xen PVH booting from non-Xen PVH + * and skip some very early Xen-specific code in the non-Xen case. + */ + do_cpuid(0x40000000, regs); + if (regs[1] == XEN_CPUID_SIGNATURE_EBX && + regs[2] == XEN_CPUID_SIGNATURE_ECX && + regs[3] == XEN_CPUID_SIGNATURE_EDX) + return (1); + else + return (0); +} + +#define CRASH(...) do { \ + if (isxen()) { \ + xc_printf(__VA_ARGS__); \ + HYPERVISOR_shutdown(SHUTDOWN_crash); \ + } else { \ + halt(); \ + } \ +} while (0) + uint64_t hammer_time_xen(vm_paddr_t start_info_paddr) { @@ -126,21 +156,20 @@ char *kenv; int rc; - xen_domain_type = XEN_HVM_DOMAIN; - vm_guest = VM_GUEST_XEN; - - rc = xen_hvm_init_hypercall_stubs(XEN_HVM_INIT_EARLY); - if (rc) { - xc_printf("ERROR: failed to initialize hypercall page: %d\n", - rc); - HYPERVISOR_shutdown(SHUTDOWN_crash); + if (isxen()) { + xen_domain_type = XEN_HVM_DOMAIN; + vm_guest = VM_GUEST_XEN; + rc = xen_hvm_init_hypercall_stubs(XEN_HVM_INIT_EARLY); + if (rc) { + CRASH("ERROR: failed to initialize hypercall page: %d\n", + rc); + } } start_info = (struct hvm_start_info *)(start_info_paddr + KERNBASE); if (start_info->magic != XEN_HVM_START_MAGIC_VALUE) { - xc_printf("Unknown magic value in start_info struct: %#x\n", + CRASH("Unknown magic value in start_info struct: %#x\n", start_info->magic); - HYPERVISOR_shutdown(SHUTDOWN_crash); } /* @@ -164,9 +193,8 @@ unsigned int i; if (start_info->nr_modules == 0) { - xc_printf( + CRASH( "ERROR: modlist_paddr != 0 but nr_modules == 0\n"); - HYPERVISOR_shutdown(SHUTDOWN_crash); } mod = (struct hvm_modlist_entry *) (start_info->modlist_paddr + KERNBASE); @@ -175,16 +203,16 @@ PAGE_SIZE), physfree); } - xatp.domid = DOMID_SELF; - xatp.idx = 0; - xatp.space = XENMAPSPACE_shared_info; - xatp.gpfn = atop(physfree); - if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) { - xc_printf("ERROR: failed to setup shared_info page\n"); - HYPERVISOR_shutdown(SHUTDOWN_crash); + if (isxen()) { + xatp.domid = DOMID_SELF; + xatp.idx = 0; + xatp.space = XENMAPSPACE_shared_info; + xatp.gpfn = atop(physfree); + if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) + CRASH("ERROR: failed to setup shared_info page\n"); + HYPERVISOR_shared_info = (shared_info_t *)(physfree + KERNBASE); + physfree += PAGE_SIZE; } - HYPERVISOR_shared_info = (shared_info_t *)(physfree + KERNBASE); - physfree += PAGE_SIZE; /* * Init a static kenv using a free page. The contents will be filled @@ -245,7 +273,7 @@ value = option; option = strsep(&value, "="); - if (kern_setenv(option, value) != 0) + if (kern_setenv(option, value) != 0 && isxen()) xc_printf("unable to add kenv %s=%s\n", option, value); option = value + strlen(value) + 1; } @@ -269,7 +297,8 @@ if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || ehdr->e_version > 1) { - xc_printf("Unable to load ELF symtab: invalid symbol table\n"); + if (isxen()) + xc_printf("Unable to load ELF symtab: invalid symbol table\n"); return; } @@ -290,7 +319,8 @@ } if (ksymtab == 0 || kstrtab == 0) - xc_printf( + if (isxen()) + xc_printf( "Unable to load ELF symtab: could not find symtab or strtab\n"); } #endif @@ -320,8 +350,7 @@ if ((header->flags & XENHEADER_HAS_MODULEP_OFFSET) != XENHEADER_HAS_MODULEP_OFFSET) { - xc_printf("Unable to load module metadata\n"); - HYPERVISOR_shutdown(SHUTDOWN_crash); + CRASH("Unable to load module metadata\n"); } preload_metadata = (caddr_t)(mod[0].paddr + @@ -331,8 +360,7 @@ if (kmdp == NULL) kmdp = preload_search_by_type("elf64 kernel"); if (kmdp == NULL) { - xc_printf("Unable to find kernel\n"); - HYPERVISOR_shutdown(SHUTDOWN_crash); + CRASH("Unable to find kernel\n"); } /* @@ -353,8 +381,7 @@ if (kmdp == NULL) kmdp = preload_search_by_type("elf64 kernel"); if (kmdp == NULL) { - xc_printf("Unable to find kernel\n"); - HYPERVISOR_shutdown(SHUTDOWN_crash); + CRASH("Unable to find kernel\n"); } metadata = MD_FETCH(kmdp, MODINFOMD_MODULEP, vm_paddr_t); @@ -436,9 +463,8 @@ set_xen_guest_handle(memmap.buffer, xen_smap); rc = HYPERVISOR_memory_op(XENMEM_memory_map, &memmap); if (rc) { - xc_printf("ERROR: unable to fetch Xen E820 memory map: %d\n", + CRASH("ERROR: unable to fetch Xen E820 memory map: %d\n", rc); - HYPERVISOR_shutdown(SHUTDOWN_crash); } size = memmap.nr_entries * sizeof(xen_smap[0]);