Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Jul 2023 08:59:51 GMT
From:      =?utf-8?Q?Roger=20Pau=20Monn=C3=A9?= <royger@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 20fc5bf7df1d - main - xen: move vcpu_info to common, leave hook for setup
Message-ID:  <202307210859.36L8xp7v046378@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
+}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202307210859.36L8xp7v046378>