git: 20fc5bf7df1d - main - xen: move vcpu_info to common, leave hook for setup
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 21 Jul 2023 08:59:51 UTC
The branch main has been updated by royger: URL: https://cgit.FreeBSD.org/src/commit/?id=20fc5bf7df1db698f2651eaa04a3bc71290e1636 commit 20fc5bf7df1db698f2651eaa04a3bc71290e1636 Author: Elliott Mitchell <ehem+freebsd@m5p.com> AuthorDate: 2023-06-08 21:13:17 +0000 Commit: Roger Pau Monné <royger@FreeBSD.org> CommitDate: 2023-07-21 08:59:12 +0000 xen: move vcpu_info to common, leave hook for setup vcpu_info is crucial for the Xen event channel core. Since both the data and setup steps are identical between architectures, move them to the common file. Since there is no cross-architecture method to call a function on every processor during bring-up, simply leave the setup function. The number of vcpu_info structures available on the shared information page varies by architecture. Instead of hard-coding the count use nitems(). Add a warning message for this being used. Switch to XEN_VCPUID() and use Xen's typedefs. panic() on failure since >32 processors is no longer unusual. royger: Specify 64-byte alignment for vcpu_info to try to defend against vcpu_info crossing a page boundary. Add detection for this limit. Reviewed by: royger --- sys/x86/xen/hvm.c | 25 +++---------------------- sys/xen/xen-os.h | 5 +++++ sys/xen/xen_common.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 22 deletions(-) diff --git a/sys/x86/xen/hvm.c b/sys/x86/xen/hvm.c index d59c3901d2d7..38c93bf25998 100644 --- a/sys/x86/xen/hvm.c +++ b/sys/x86/xen/hvm.c @@ -88,8 +88,7 @@ int xen_vector_callback_enabled; bool xen_evtchn_needs_ack; /*------------------------------- Per-CPU Data -------------------------------*/ -DPCPU_DEFINE(struct vcpu_info, vcpu_local_info); -DPCPU_DEFINE(struct vcpu_info *, vcpu_info); +DPCPU_DECLARE(struct vcpu_info *, vcpu_info); /*------------------------------ Sysctl tunables -----------------------------*/ int xen_disable_pv_disks = 0; @@ -416,10 +415,8 @@ SYSINIT(xen_hvm_init, SI_SUB_HYPERVISOR, SI_ORDER_FIRST, xen_hvm_sysinit, NULL); static void xen_hvm_cpu_init(void) { - struct vcpu_register_vcpu_info info; - struct vcpu_info *vcpu_info; uint32_t regs[4]; - int cpu, rc; + int rc; if (!xen_domain()) return; @@ -459,23 +456,7 @@ xen_hvm_cpu_init(void) rc); } - /* - * Set the vCPU info. - * - * NB: the vCPU info for vCPUs < 32 can be fetched from the shared info - * page, but in order to make sure the mapping code is correct always - * attempt to map the vCPU info at a custom place. - */ - vcpu_info = DPCPU_PTR(vcpu_local_info); - cpu = PCPU_GET(vcpu_id); - info.mfn = vtophys(vcpu_info) >> PAGE_SHIFT; - info.offset = vtophys(vcpu_info) - trunc_page(vtophys(vcpu_info)); - - rc = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info); - if (rc != 0) - DPCPU_SET(vcpu_info, &HYPERVISOR_shared_info->vcpu_info[cpu]); - else - DPCPU_SET(vcpu_info, vcpu_info); + xen_setup_vcpu_info(); } SYSINIT(xen_hvm_cpu_init, SI_SUB_INTR, SI_ORDER_FIRST, xen_hvm_cpu_init, NULL); diff --git a/sys/xen/xen-os.h b/sys/xen/xen-os.h index e1d03b7322bc..4919a9fc0702 100644 --- a/sys/xen/xen-os.h +++ b/sys/xen/xen-os.h @@ -44,6 +44,11 @@ #include <xen/hvm.h> #include <contrib/xen/event_channel.h> +/* + * Setup function which needs to be called on each processor by architecture + */ +extern void xen_setup_vcpu_info(void); + static inline vm_paddr_t xen_get_xenstore_mfn(void) { diff --git a/sys/xen/xen_common.c b/sys/xen/xen_common.c index d0f0ecdeed59..95fe00b2ba98 100644 --- a/sys/xen/xen_common.c +++ b/sys/xen/xen_common.c @@ -33,11 +33,16 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> /* required by xen/xen-os.h */ +#include <vm/vm.h> +#include <vm/pmap.h> + #include <machine/atomic.h> /* required by xen/xen-os.h */ #include <xen/xen-os.h> #include <xen/hvm.h> +#include <contrib/xen/vcpu.h> + /*-------------------------------- Global Data -------------------------------*/ enum xen_domain_type xen_domain_type = XEN_NATIVE; @@ -49,3 +54,51 @@ uint32_t hvm_start_flags; /*------------------ Hypervisor Access Shared Memory Regions -----------------*/ shared_info_t *HYPERVISOR_shared_info; + +/*------------------------------- Per-CPU Data -------------------------------*/ +DPCPU_DEFINE(struct vcpu_info *, vcpu_info); + +void +xen_setup_vcpu_info(void) +{ + /* This isn't directly accessed outside this function */ + DPCPU_DEFINE_STATIC(vcpu_info_t, vcpu_local_info) + __attribute__((aligned(64))); + + vcpu_info_t *vcpu_info = DPCPU_PTR(vcpu_local_info); + vcpu_register_vcpu_info_t info = { + .mfn = vtophys(vcpu_info) >> PAGE_SHIFT, + .offset = vtophys(vcpu_info) & PAGE_MASK, + }; + unsigned int cpu = XEN_VCPUID(); + int rc; + + KASSERT(xen_domain(), ("%s(): invoked when not on Xen?", __func__)); + + _Static_assert(sizeof(struct vcpu_info) <= 64, + "struct vcpu_info is larger than supported limit of 64 bytes"); + + /* + * Set the vCPU info. + * + * NB: the vCPU info for some vCPUs can be fetched from the shared info + * page, but in order to make sure the mapping code is correct always + * attempt to map the vCPU info at a custom place. + */ + rc = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info); + if (rc == 0) + DPCPU_SET(vcpu_info, vcpu_info); + else if (cpu < nitems(HYPERVISOR_shared_info->vcpu_info)) { + static bool warned = false; + + DPCPU_SET(vcpu_info, &HYPERVISOR_shared_info->vcpu_info[cpu]); + + if (bootverbose && !warned) { + warned = true; + printf( + "WARNING: Xen vCPU %u failed to setup vcpu_info rc = %d\n", + cpu, rc); + } + } else + panic("Unable to register vCPU %u, rc=%d\n", cpu, rc); +}