aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Pau Monné <royger@FreeBSD.org>2024-02-02 10:20:33 +0000
committerRoger Pau Monné <royger@FreeBSD.org>2024-02-22 10:08:05 +0000
commit5d62aba742ace4f020be5d5e843cf0f89024930b (patch)
tree94273b851ef200338191d0b01232eb8d6cc4b08f
parent9a687d1fe3af460cdc39c3ed08d1e33cc99b8141 (diff)
downloadsrc-5d62aba742ace4f020be5d5e843cf0f89024930b.tar.gz
src-5d62aba742ace4f020be5d5e843cf0f89024930b.zip
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
-rw-r--r--sys/x86/xen/hvm.c43
-rw-r--r--sys/x86/xen/pv.c14
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.