x86/xen: introduce a Xen early init function
Start by moving the hyeprcall setup to such function. The aim is to have a function that does all the required Xen early initialization for both HVM and PVH, instead of having it scattered across different paths. Sponsored by: Cloud Software Group Reviewed by: markj Differential revision: https://reviews.freebsd.org/D43932
This commit is contained in:
parent
848e2719af
commit
9a687d1fe3
|
@ -96,6 +96,9 @@ xen_pv_nics_disabled(void)
|
|||
|
||||
bool xen_has_iommu_maps(void);
|
||||
|
||||
/* (Very) early initialization. */
|
||||
void xen_early_init(void);
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _MACHINE_X86_XEN_XEN_OS_H_ */
|
||||
|
|
|
@ -41,8 +41,10 @@
|
|||
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
||||
#include <machine/_inttypes.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/smp.h>
|
||||
|
||||
#include <x86/apicreg.h>
|
||||
|
@ -184,6 +186,52 @@ out:
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -162,14 +162,13 @@ hammer_time_xen(vm_paddr_t start_info_paddr)
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue