git: 5d62aba742ac - main - x86/xen: move shared page setup to early init handler

From: Roger Pau Monné <royger_at_FreeBSD.org>
Date: Thu, 22 Feb 2024 10:31:24 UTC
The branch main has been updated by royger:

URL: https://cgit.FreeBSD.org/src/commit/?id=5d62aba742ace4f020be5d5e843cf0f89024930b

commit 5d62aba742ace4f020be5d5e843cf0f89024930b
Author:     Roger Pau Monné <royger@FreeBSD.org>
AuthorDate: 2024-02-02 10:20:33 +0000
Commit:     Roger Pau Monné <royger@FreeBSD.org>
CommitDate: 2024-02-22 10:08:05 +0000

    x86/xen: move shared page setup to early init handler
    
    As done with the hypercall page, move the setup fo the shared info page into
    the newly introduced helper, which the aim of having a single helper and call
    site used by both HVM and PV in order to setup the basic Xen environment.
    
    Sponsored by: Cloud Software Group
    Reviewed by: markj
    Differential revision: https://reviews.freebsd.org/D43933
---
 sys/x86/xen/hvm.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 sys/x86/xen/pv.c  | 14 --------------
 2 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/sys/x86/xen/hvm.c b/sys/x86/xen/hvm.c
index 9d9a64dd29ea..9dc9360d719c 100644
--- a/sys/x86/xen/hvm.c
+++ b/sys/x86/xen/hvm.c
@@ -210,11 +210,48 @@ early_init_vtop(void *addr)
 	    );
 }
 
+static int
+map_shared_info(void)
+{
+	/*
+	 * TODO shared info page should be mapped in an unpopulated (IOW:
+	 * non-RAM) address.  But finding one at this point in boot is
+	 * complicated, hence re-use a RAM address for the time being.  This
+	 * sadly causes super-page shattering in the second stage translation
+	 * page tables.
+	 */
+	static union {
+		shared_info_t shared_info;
+		uint8_t raw[PAGE_SIZE];
+	} shared_page __attribute__((aligned(PAGE_SIZE)));
+	static struct xen_add_to_physmap xatp = {
+	    .domid = DOMID_SELF,
+	    .space = XENMAPSPACE_shared_info,
+	};
+	int rc;
+
+	_Static_assert(sizeof(shared_page) == PAGE_SIZE,
+	    "invalid Xen shared_info struct size");
+
+	if (xatp.gpfn == 0)
+		xatp.gpfn = atop(early_init_vtop(&shared_page.shared_info));
+
+	rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
+	if (rc != 0) {
+		xc_printf("cannot map shared info page: %d\n", rc);
+		HYPERVISOR_shared_info = NULL;
+	} else if (HYPERVISOR_shared_info == NULL)
+		HYPERVISOR_shared_info = &shared_page.shared_info;
+
+	return (rc);
+}
+
 /* Early initialization when running as a Xen guest. */
 void
 xen_early_init(void)
 {
 	uint32_t regs[4];
+	int rc;
 
 	xen_cpuid_base = xen_hvm_cpuid_base();
 	if (xen_cpuid_base == 0)
@@ -230,6 +267,12 @@ xen_early_init(void)
 	}
 
 	wrmsr(regs[1], early_init_vtop(&hypercall_page));
+
+	rc = map_shared_info();
+	if (rc != 0) {
+		vm_guest = VM_GUEST_VM;
+		return;
+	}
 }
 
 static void
diff --git a/sys/x86/xen/pv.c b/sys/x86/xen/pv.c
index 3c22d9e5cf6f..515e5c58d304 100644
--- a/sys/x86/xen/pv.c
+++ b/sys/x86/xen/pv.c
@@ -159,7 +159,6 @@ uint64_t
 hammer_time_xen(vm_paddr_t start_info_paddr)
 {
 	struct hvm_modlist_entry *mod;
-	struct xen_add_to_physmap xatp;
 	uint64_t physfree;
 	char *kenv;
 
@@ -210,19 +209,6 @@ hammer_time_xen(vm_paddr_t start_info_paddr)
 			    PAGE_SIZE), physfree);
 	}
 
-	if (isxen()) {
-		xatp.domid = DOMID_SELF;
-		xatp.idx = 0;
-		xatp.space = XENMAPSPACE_shared_info;
-		xatp.gpfn = atop(physfree);
-		if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) {
-			xc_printf("ERROR: failed to setup shared_info page\n");
-			HYPERVISOR_shutdown(SHUTDOWN_crash);
-		}
-		HYPERVISOR_shared_info = (shared_info_t *)(physfree + KERNBASE);
-		physfree += PAGE_SIZE;
-	}
-
 	/*
 	 * Init a static kenv using a free page. The contents will be filled
 	 * from the parse_preload_data hook.