From nobody Tue Oct 18 06:03:15 2022 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Ms3FH654Lz4g8FN; Tue, 18 Oct 2022 06:03:15 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Ms3FH5Br6z3cMc; Tue, 18 Oct 2022 06:03:15 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1666072995; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Zqo3EnHSs8h11gRpQnZXkxt2AoFRQC6AcIM+9t+N/6I=; b=ha8Eite8HlR0wYnGMKtbbdpptrs1lvpHR4x7nQkPZhaeOBmKiMMbROXbistDAX9tUH3/EJ vMrMsCTTkcZaUxPOyLw0znCEDF/q3u1HWNdTLBNlcsei1h1RiQuAUvvTT+Q/35r2n1sykz KXPIs3qOusL7XZNqlJV0JTeL10FLF695E0DZUI2+3q8dga+wsVvfBsiSBMfL0CGbcN4v+o 9jHwUL45QCK+mTwyeeBexMrv4GLrHG6Xm4iO1qBiYSPq5ubn6FlcuBWRRzLD6Fo4nZo/go wWMCC15zGnxIXBdnMOH2JdN4o9yjuYheNv2kRhAXWmj9H221iKZaTUepZXOVKQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Ms3FH479vz15BP; Tue, 18 Oct 2022 06:03:15 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 29I63FsX097513; Tue, 18 Oct 2022 06:03:15 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 29I63FLX097512; Tue, 18 Oct 2022 06:03:15 GMT (envelope-from git) Date: Tue, 18 Oct 2022 06:03:15 GMT Message-Id: <202210180603.29I63FLX097512@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Colin Percival Subject: git: a8ea1540640f - main - x86: Distinguish Xen from non-Xen PVH boots List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: cperciva X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: a8ea1540640f154844f12a0b24d0e272b6e39ca9 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1666072995; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Zqo3EnHSs8h11gRpQnZXkxt2AoFRQC6AcIM+9t+N/6I=; b=PSv+z+6dR/cthCnZ8eGRLMATf+L90VwEM5Uf+qm499thnxnyuWDh/wehfYk2G+qhJT+1b2 rP8QJwbFnILIxRo+CkW+u3rhp9YdaGQVznMc6Ts/TfjMISKidMWvP98Ox4D1Q8O94rJUKh Ko+cvBUaDGEc2UIlKTPhETbwJAevxDXR4rzajnzbrsFQVKfMEbZ8E0zjIFoBwBGg0srEPS CrZ68wfhuD3r57SxI0ZxC20K2rxkYxKDgRsIgnoEpx4VbhqgtxKgkCDU9fVWPpvfhpdij7 scYJ0pQ94na6ij13UdDuVyFESAJGgKEgg0dqMqiihVjxviTCAcmmztWNcmoy6A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1666072995; a=rsa-sha256; cv=none; b=Vmqu298UqNGoEVtz4gH/PnGpiNgMTzC6yrLna5K9zmpd2kro2AkIMCigqcqpSG3oqGmQs0 Opz+TqyPO1UAgmQZLJXlTYwGSseZlyVca4jgRTRO+qEwfKHYooHo3Q3tKILFMsC6IrIUPR IkCheWf8gvr3HoXbcLIKXY9XNDOXZHBz9++EYQisCNzQN2IdUDPS2T85qKQ294mlfaJVMQ 4AJFoz0lVpv1uPX8UQJVj4beVKW/7n6Ux6rZxFQ5nnIU2JVqHgrSKrr12CVuGhcFB0HlH9 mvf0+99ow3qCZ7h5YhwNBWso4ioMfjpBiAijiEDWRd/cm1WHRJZcjPSG6LRnNg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by cperciva: URL: https://cgit.FreeBSD.org/src/commit/?id=a8ea1540640f154844f12a0b24d0e272b6e39ca9 commit a8ea1540640f154844f12a0b24d0e272b6e39ca9 Author: Colin Percival AuthorDate: 2022-07-13 00:46:04 +0000 Commit: Colin Percival CommitDate: 2022-10-18 06:02:22 +0000 x86: Distinguish Xen from non-Xen PVH boots The PVH boot protocol, introduced by Xen, is now used by some non-Xen platforms (e.g. the Firecracker VM) as well. In order to accommodate these, we use CPUID to detect Xen and only perform Xen-specific setup when running on that platform. The "isxen" function duplicates some work done by identcpu.c later in the boot process; but we need it here since this is the very first C code which runs when PVH booting (even before hammer_time). In many places the existing code had xc_printf(...); HYPERVISOR_shutdown(SHUTDOWN_crash); making use of Xen functionality to print a message and shut down; in the places where this idiom can be reached in the non-xen case, we replace it idiom with a CRASH(...) macro which calls those in the Xen case and halts in the non-Xen case. Reviewed by: royger Sponsored by: https://www.patreon.com/cperciva Differential Revision: https://reviews.freebsd.org/D35801 --- sys/x86/xen/pv.c | 92 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 24 deletions(-) diff --git a/sys/x86/xen/pv.c b/sys/x86/xen/pv.c index 845c2d7222eb..b81423a1be88 100644 --- a/sys/x86/xen/pv.c +++ b/sys/x86/xen/pv.c @@ -76,6 +76,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -117,6 +118,44 @@ static struct hvm_start_info *start_info; /*-------------------------------- Xen PV init -------------------------------*/ +static int +isxen(void) +{ + static int xen = -1; + uint32_t base; + u_int regs[4]; + + if (xen != -1) + return (xen); + + /* + * The full code for identifying which hypervisor we're running under + * is in sys/x86/x86/identcpu.c and runs later in the boot process; + * this is sufficient to distinguish Xen PVH booting from non-Xen PVH + * and skip some very early Xen-specific code in the non-Xen case. + */ + xen = 0; + for (base = 0x40000000; base < 0x40010000; base += 0x100) { + do_cpuid(base, regs); + if (regs[1] == XEN_CPUID_SIGNATURE_EBX && + regs[2] == XEN_CPUID_SIGNATURE_ECX && + regs[3] == XEN_CPUID_SIGNATURE_EDX) { + xen = 1; + break; + } + } + return (xen); +} + +#define CRASH(...) do { \ + if (isxen()) { \ + xc_printf(__VA_ARGS__); \ + HYPERVISOR_shutdown(SHUTDOWN_crash); \ + } else { \ + halt(); \ + } \ +} while (0) + uint64_t hammer_time_xen(vm_paddr_t start_info_paddr) { @@ -126,21 +165,21 @@ hammer_time_xen(vm_paddr_t start_info_paddr) char *kenv; int rc; - xen_domain_type = XEN_HVM_DOMAIN; - vm_guest = VM_GUEST_XEN; - - rc = xen_hvm_init_hypercall_stubs(XEN_HVM_INIT_EARLY); - if (rc) { - xc_printf("ERROR: failed to initialize hypercall page: %d\n", - rc); - HYPERVISOR_shutdown(SHUTDOWN_crash); + if (isxen()) { + xen_domain_type = XEN_HVM_DOMAIN; + vm_guest = VM_GUEST_XEN; + rc = xen_hvm_init_hypercall_stubs(XEN_HVM_INIT_EARLY); + if (rc) { + xc_printf("ERROR: failed to initialize hypercall page: %d\n", + rc); + HYPERVISOR_shutdown(SHUTDOWN_crash); + } } start_info = (struct hvm_start_info *)(start_info_paddr + KERNBASE); if (start_info->magic != XEN_HVM_START_MAGIC_VALUE) { - xc_printf("Unknown magic value in start_info struct: %#x\n", + CRASH("Unknown magic value in start_info struct: %#x\n", start_info->magic); - HYPERVISOR_shutdown(SHUTDOWN_crash); } /* @@ -164,9 +203,8 @@ hammer_time_xen(vm_paddr_t start_info_paddr) unsigned int i; if (start_info->nr_modules == 0) { - xc_printf( + CRASH( "ERROR: modlist_paddr != 0 but nr_modules == 0\n"); - HYPERVISOR_shutdown(SHUTDOWN_crash); } mod = (struct hvm_modlist_entry *) (start_info->modlist_paddr + KERNBASE); @@ -175,16 +213,18 @@ hammer_time_xen(vm_paddr_t start_info_paddr) PAGE_SIZE), physfree); } - 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); + 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; } - HYPERVISOR_shared_info = (shared_info_t *)(physfree + KERNBASE); - physfree += PAGE_SIZE; /* * Init a static kenv using a free page. The contents will be filled @@ -245,7 +285,7 @@ xen_pvh_set_env(char *env, bool (*filter)(const char *)) value = option; option = strsep(&value, "="); - if (kern_setenv(option, value) != 0) + if (kern_setenv(option, value) != 0 && isxen()) xc_printf("unable to add kenv %s=%s\n", option, value); option = value + strlen(value) + 1; } @@ -269,7 +309,8 @@ xen_pvh_parse_symtab(void) if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) || ehdr->e_ident[EI_CLASS] != ELF_TARG_CLASS || ehdr->e_version > 1) { - xc_printf("Unable to load ELF symtab: invalid symbol table\n"); + if (isxen()) + xc_printf("Unable to load ELF symtab: invalid symbol table\n"); return; } @@ -289,7 +330,7 @@ xen_pvh_parse_symtab(void) break; } - if (ksymtab == 0 || kstrtab == 0) + if ((ksymtab == 0 || kstrtab == 0) && isxen()) xc_printf( "Unable to load ELF symtab: could not find symtab or strtab\n"); } @@ -432,6 +473,9 @@ xen_pvh_parse_memmap(caddr_t kmdp, vm_paddr_t *physmap, int *physmap_idx) u_int32_t size; int rc; + /* We should only reach here if we're running under Xen. */ + KASSERT(isxen(), ("xen_pvh_parse_memmap reached when !Xen")); + /* Fetch the E820 map from Xen */ memmap.nr_entries = MAX_E820_ENTRIES; set_xen_guest_handle(memmap.buffer, xen_smap);