diff --git a/sys/x86/include/xen/xen-os.h b/sys/x86/include/xen/xen-os.h --- a/sys/x86/include/xen/xen-os.h +++ b/sys/x86/include/xen/xen-os.h @@ -96,6 +96,9 @@ bool xen_has_iommu_maps(void); +/* (Very) early initialization. */ +void xen_early_init(void); + #endif /* !__ASSEMBLY__ */ #endif /* _MACHINE_X86_XEN_XEN_OS_H_ */ diff --git a/sys/x86/xen/hvm.c b/sys/x86/xen/hvm.c --- a/sys/x86/xen/hvm.c +++ b/sys/x86/xen/hvm.c @@ -41,8 +41,10 @@ #include +#include #include #include +#include #include #include @@ -184,6 +186,52 @@ return (0); } +/* + * Translate linear to physical address when still running on the bootloader + * created page-tables. + */ +static vm_paddr_t +early_init_vtop(void *addr) +{ + + /* + * Using a KASSERT won't print anything, as this is before console + * initialization. + */ + if (__predict_false((uintptr_t)addr < KERNBASE)) { + xc_printf("invalid linear address: %#lx\n", (uintptr_t)addr); + halt(); + } + + return ((uintptr_t)addr - KERNBASE +#ifdef __amd64__ + + kernphys - KERNLOAD +#endif + ); +} + +/* Early initialization when running as a Xen guest. */ +void +xen_early_init(void) +{ + uint32_t regs[4]; + + xen_cpuid_base = xen_hvm_cpuid_base(); + if (xen_cpuid_base == 0) + return; + + /* Find the hypercall pages. */ + do_cpuid(xen_cpuid_base + 2, regs); + if (regs[0] != 1) { + xc_printf("Invalid number of hypercall pages %u\n", + regs[0]); + vm_guest = VM_GUEST_VM; + return; + } + + wrmsr(regs[1], early_init_vtop(&hypercall_page)); +} + static void xen_hvm_init_shared_info_page(void) { diff --git a/sys/x86/xen/pv.c b/sys/x86/xen/pv.c --- a/sys/x86/xen/pv.c +++ b/sys/x86/xen/pv.c @@ -162,14 +162,13 @@ struct xen_add_to_physmap xatp; uint64_t physfree; char *kenv; - int rc; if (isxen()) { 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); + xen_early_init(); + if (xen_cpuid_base == 0) { + xc_printf( + "ERROR: failed to initialize hypercall page\n"); HYPERVISOR_shutdown(SHUTDOWN_crash); } }