git: b0165dc4539f - main - x86/xen: fix HVM guest hypercall page setup

From: Roger Pau Monné <royger_at_FreeBSD.org>
Date: Tue, 16 Jan 2024 17:52:17 UTC
The branch main has been updated by royger:

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

commit b0165dc4539fdfc84351a719b58850e4e7a6cbb6
Author:     Roger Pau Monné <royger@FreeBSD.org>
AuthorDate: 2024-01-16 15:32:56 +0000
Commit:     Roger Pau Monné <royger@FreeBSD.org>
CommitDate: 2024-01-16 17:50:54 +0000

    x86/xen: fix HVM guest hypercall page setup
    
    c7368ccb6801 didn't take into account that vm_guest will also get setup by
    generic identify CPU code, and hence by the time xen_hvm_init() gets called
    vm_guest will always be set if running as a Xen guest, either by the PVH entry
    point code, or by generic CPU identification.
    
    xen_hvm_init() and xen_hvm_init_hypercall_stubs() were relying on xen_domain()
    returning false when running as an HVM guest, and used that into order to
    figure out whether hypercall page needed to be populated.
    
    Get rid of such assumptions and simplify the code since legacy PVH is no
    longer supported.
    
    This fixes booting FreeBSD as a Xen HVM guest.
    
    Fixes: c7368ccb6801 ('xen: remove xen_domain_type enum/variable')
    Sponsored by: Cloud Software Group
---
 sys/x86/xen/hvm.c | 35 +++++++++--------------------------
 1 file changed, 9 insertions(+), 26 deletions(-)

diff --git a/sys/x86/xen/hvm.c b/sys/x86/xen/hvm.c
index e096559711a3..b8125e230b6f 100644
--- a/sys/x86/xen/hvm.c
+++ b/sys/x86/xen/hvm.c
@@ -155,25 +155,14 @@ xen_hvm_init_hypercall_stubs(enum xen_hvm_init_type init_type)
 {
 	uint32_t regs[4];
 
-	/* Legacy PVH will get here without the cpuid leaf being set. */
-	if (xen_cpuid_base == 0)
-		xen_cpuid_base = xen_hvm_cpuid_base();
+	if (xen_cpuid_base != 0)
+		/* Already setup. */
+		goto out;
+
+	xen_cpuid_base = xen_hvm_cpuid_base();
 	if (xen_cpuid_base == 0)
 		return (ENXIO);
 
-	if (xen_domain() && init_type == XEN_HVM_INIT_LATE) {
-		/*
-		 * If the domain type is already set we can assume that the
-		 * hypercall page has been populated too, so just print the
-		 * version (and apply any quirks) and exit.
-		 */
-		hypervisor_version();
-		return 0;
-	}
-
-	if (init_type == XEN_HVM_INIT_LATE)
-		hypervisor_version();
-
 	/*
 	 * Find the hypercall pages.
 	 */
@@ -185,6 +174,8 @@ xen_hvm_init_hypercall_stubs(enum xen_hvm_init_type init_type)
 	    ? (vm_paddr_t)((uintptr_t)&hypercall_page - KERNBASE)
 	    : vtophys(&hypercall_page));
 
+out:
+	hypervisor_version();
 	return (0);
 }
 
@@ -334,7 +325,8 @@ xen_hvm_init(enum xen_hvm_init_type init_type)
 	int error;
 	int i;
 
-	if (init_type == XEN_HVM_INIT_CANCELLED_SUSPEND)
+	if (!xen_domain() ||
+	    init_type == XEN_HVM_INIT_CANCELLED_SUSPEND)
 		return;
 
 	error = xen_hvm_init_hypercall_stubs(init_type);
@@ -344,15 +336,6 @@ xen_hvm_init(enum xen_hvm_init_type init_type)
 		if (error != 0)
 			return;
 
-		/*
-		 * If the Xen domain type is not set at this point
-		 * it means we are inside a (PV)HVM guest, because
-		 * for PVH the guest type is set much earlier
-		 * (see hammer_time_xen).
-		 */
-		if (!xen_domain())
-			vm_guest = VM_GUEST_XEN;
-
 		setup_xen_features();
 #ifdef SMP
 		cpu_ops = xen_hvm_cpu_ops;