git: 9a687d1fe3af - main - x86/xen: introduce a Xen early init function
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 22 Feb 2024 10:31:23 UTC
The branch main has been updated by royger: URL: https://cgit.FreeBSD.org/src/commit/?id=9a687d1fe3af460cdc39c3ed08d1e33cc99b8141 commit 9a687d1fe3af460cdc39c3ed08d1e33cc99b8141 Author: Roger Pau Monné <royger@FreeBSD.org> AuthorDate: 2024-02-02 10:00:31 +0000 Commit: Roger Pau Monné <royger@FreeBSD.org> CommitDate: 2024-02-22 10:08:04 +0000 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 --- sys/x86/include/xen/xen-os.h | 3 +++ sys/x86/xen/hvm.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ sys/x86/xen/pv.c | 9 ++++----- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/sys/x86/include/xen/xen-os.h b/sys/x86/include/xen/xen-os.h index 12942375be43..ec0d4b1ab9f1 100644 --- a/sys/x86/include/xen/xen-os.h +++ b/sys/x86/include/xen/xen-os.h @@ -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_ */ diff --git a/sys/x86/xen/hvm.c b/sys/x86/xen/hvm.c index 6411b790a2be..9d9a64dd29ea 100644 --- a/sys/x86/xen/hvm.c +++ b/sys/x86/xen/hvm.c @@ -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) { diff --git a/sys/x86/xen/pv.c b/sys/x86/xen/pv.c index 75c345ff3a2c..3c22d9e5cf6f 100644 --- a/sys/x86/xen/pv.c +++ b/sys/x86/xen/pv.c @@ -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); } }