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
This commit is contained in:
Roger Pau Monné 2024-02-02 11:20:33 +01:00
parent 9a687d1fe3
commit 5d62aba742
2 changed files with 43 additions and 14 deletions

View file

@ -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

View file

@ -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.