From patchwork Fri Jan 20 11:33:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Woodhouse X-Patchwork-Id: 13109629 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 51668C05027 for ; Fri, 20 Jan 2023 11:33:52 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.481693.746767 (Exim 4.92) (envelope-from ) id 1pIpeD-0005zq-Ok; Fri, 20 Jan 2023 11:33:29 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 481693.746767; Fri, 20 Jan 2023 11:33:29 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pIpeD-0005zj-Lz; Fri, 20 Jan 2023 11:33:29 +0000 Received: by outflank-mailman (input) for mailman id 481693; Fri, 20 Jan 2023 11:33:28 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1pIpe9-0005zd-9l for xen-devel@lists.xenproject.org; Fri, 20 Jan 2023 11:33:28 +0000 Received: from casper.infradead.org (casper.infradead.org [2001:8b0:10b:1236::1]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 3ed5fe8e-98b6-11ed-91b6-6bf2151ebd3b; Fri, 20 Jan 2023 12:33:23 +0100 (CET) Received: from [2001:8b0:10b:5::bb3] (helo=u3832b3a9db3152.infradead.org) by casper.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pIpe3-001ttS-Vy; Fri, 20 Jan 2023 11:33:20 +0000 X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 3ed5fe8e-98b6-11ed-91b6-6bf2151ebd3b DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=MIME-Version:Content-Type:Date:Cc:To: From:Subject:Message-ID:Sender:Reply-To:Content-Transfer-Encoding:Content-ID: Content-Description:In-Reply-To:References; bh=FPmMJJucX/DY1S9Sm3Up0z7xbAoQFdvYkviGDi2uMMs=; b=naiS7fk8gxacUZ3x4HlaciIzLf XKqAH7AVLuriO6KopMrb+IwHuBvdaA5BMj3oqXseffvUXZofXK3ZI892h/OA77G3KPbVKcxStmlpm 3YmPaEQQHJfao3h5dWXMtZpamyr/yOqF31QTFDqDXq4pp0Zwj9wH2kUlMzJ8WDVf7MzopLfkEWRQ7 EgKWSyVfjdisarVKmMlYdpxgWR4pLKwsO3mmaweeHoZ95GY6PHXIwgtkulGCxqzotLfwpIvLXjqg1 VoSfCBZouWaL3nGBlkYa1WOYRcppmCOWd5/6wixlvDF51RraYNAfiERzzHhMwGlmdbzRX+PB0M2WR SRLCvh+Q==; Message-ID: Subject: [SeaBIOS PATCH] xen: require Xen info structure at 0x1000 to detect Xen From: David Woodhouse To: seabios , xen-devel , qemu-devel Cc: paul Date: Fri, 20 Jan 2023 11:33:19 +0000 User-Agent: Evolution 3.44.4-0ubuntu1 MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html From: David Woodhouse When running under Xen, hvmloader places a table at 0x1000 with the e820 information and BIOS tables. If this isn't present, SeaBIOS will currently panic. We now have support for running Xen guests natively in QEMU/KVM, which boots SeaBIOS directly instead of via hvmloader, and does not provide the same structure. As it happens, this doesn't matter on first boot. because although we set PlatformRunningOn to PF_QEMU|PF_XEN, reading it back again still gives zero. Presumably because in true Xen, this is all already RAM. But in QEMU with a faithfully-emulated PAM config in the host bridge, it's still in ROM mode at this point so we don't see what we've just written. On reboot, however, the region *is* set to RAM mode and we do see the updated value of PlatformRunningOn, do manage to remember that we've detected Xen in CPUID, and hit the panic. It's not trivial to detect QEMU vs. real Xen at the time xen_preinit() runs, because it's so early. We can't even make a XENVER_extraversion hypercall to look for hints, because we haven't set up the hypercall page (and don't have an allocator to give us a page in which to do so). So just make Xen detection contingent on the info structure being present. If it wasn't, we were going to panic anyway. That leaves us taking the standard QEMU init path for Xen guests in native QEMU, which is just fine. Untested on actual Xen but ObviouslyCorrectâ„¢. Signed-off-by: David Woodhouse Tested-by: Paul Durrant Reviewed-by: Paul Durrant --- src/fw/xen.c | 45 ++++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/src/fw/xen.c b/src/fw/xen.c index a215b9e..00e4b0c 100644 --- a/src/fw/xen.c +++ b/src/fw/xen.c @@ -40,16 +40,25 @@ struct xen_seabios_info { u32 e820_nr; } PACKED; -static void validate_info(struct xen_seabios_info *t) +static struct xen_seabios_info *validate_info(void) { - if ( memcmp(t->signature, "XenHVMSeaBIOS", 14) ) - panic("Bad Xen info signature\n"); + struct xen_seabios_info *t = (void *)INFO_PHYSICAL_ADDRESS; - if ( t->length < sizeof(struct xen_seabios_info) ) - panic("Bad Xen info length\n"); + if ( memcmp(t->signature, "XenHVMSeaBIOS", 14) ) { + dprintf(1, "Bad Xen info signature\n"); + return NULL; + } + + if ( t->length < sizeof(struct xen_seabios_info) ) { + dprintf(1, "Bad Xen info length\n"); + return NULL; + } - if (checksum(t, t->length) != 0) - panic("Bad Xen info checksum\n"); + if (checksum(t, t->length) != 0) { + dprintf(1, "Bad Xen info checksum\n"); + return NULL; + } + return t; } void xen_preinit(void) @@ -86,7 +95,10 @@ void xen_preinit(void) dprintf(1, "No Xen hypervisor found.\n"); return; } - PlatformRunningOn = PF_QEMU|PF_XEN; + if (validate_info()) + PlatformRunningOn = PF_QEMU|PF_XEN; + else + dprintf(1, "Not enabling Xen support due to lack of Xen info\n"); } static int hypercall_xen_version( int cmd, void *arg) @@ -122,10 +134,14 @@ void xen_hypercall_setup(void) void xen_biostable_setup(void) { - struct xen_seabios_info *info = (void *)INFO_PHYSICAL_ADDRESS; - void **tables = (void*)info->tables; + struct xen_seabios_info *info = validate_info(); + void **tables; int i; + if (!info) + panic("Xen info corrupted\n"); + + tables = (void*)info->tables; dprintf(1, "xen: copy BIOS tables...\n"); for (i=0; itables_nr; i++) copy_table(tables[i]); @@ -136,12 +152,15 @@ void xen_biostable_setup(void) void xen_ramsize_preinit(void) { int i; - struct xen_seabios_info *info = (void *)INFO_PHYSICAL_ADDRESS; - struct e820entry *e820 = (struct e820entry *)info->e820; - validate_info(info); + struct xen_seabios_info *info = validate_info(); + struct e820entry *e820; + + if (!info) + panic("Xen info corrupted\n"); dprintf(1, "xen: copy e820...\n"); + e820 = (struct e820entry *)info->e820; for (i = 0; i < info->e820_nr; i++) { struct e820entry *e = &e820[i]; e820_add(e->start, e->size, e->type);