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:
Roger Pau Monné 2024-02-02 11:00:31 +01:00
parent 848e2719af
commit 9a687d1fe3
3 changed files with 55 additions and 5 deletions

View file

@ -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_ */

View file

@ -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 @@ xen_hvm_init_hypercall_stubs(enum xen_hvm_init_type init_type)
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)
{

View file

@ -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);
}
}