From patchwork Thu Oct 24 03:45:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= X-Patchwork-Id: 11208241 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8C04A1920 for ; Thu, 24 Oct 2019 03:47:21 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 673002166E for ; Thu, 24 Oct 2019 03:47:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="G9WBXuaR" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 673002166E Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=invisiblethingslab.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iNU3t-0003fY-79; Thu, 24 Oct 2019 03:45:21 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iNU3s-0003fO-AJ for xen-devel@lists.xenproject.org; Thu, 24 Oct 2019 03:45:20 +0000 X-Inumbo-ID: b07bc210-f610-11e9-beca-bc764e2007e4 Received: from new2-smtp.messagingengine.com (unknown [66.111.4.224]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id b07bc210-f610-11e9-beca-bc764e2007e4; Thu, 24 Oct 2019 03:45:15 +0000 (UTC) Received: from compute7.internal (compute7.nyi.internal [10.202.2.47]) by mailnew.nyi.internal (Postfix) with ESMTP id 29D34708B; Wed, 23 Oct 2019 23:45:15 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute7.internal (MEProxy); Wed, 23 Oct 2019 23:45:15 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm1; bh=Rnf1HlA5KdCns/sgMtkx8jI7lpGa2YVdg56M8DgBw kM=; b=G9WBXuaRcqtifHlZUdiJbMKYcp39rPr89G1QUIVwDdILbf/6oxUD6UUVw CtBhz42tqDs/rJ+W0MP7Isrxd8xJmoYbseGdKpChmj+QCZihkUGBeCLoqMvoQ8pr 2koYt9sRcd2RJ9/tqInHD3IczzD0fnLSE2h/ua0s/G6I66sZ+AdmW+ZYXDd/sBx6 iruOuVCAGn2LdDSfCv9vnf5NUL2w70BRA8mDq2Oi7mtvIvnO3sa9qH9rvLm+dM8I t9esZUz3fUvQ5jP9I7CFzO3BXDjOJ2tAAZu39zX0clwSChtQQUVOcNP0RGXwpYDa IhpfTPHNgZNg2cl1e1irq/CDNeBTA== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedufedrledtgdejvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgjfhggtgfgsehtkeertdertdejnecuhfhrohhmpeforghrvghk ucforghrtgiihihkohifshhkihdqifpkrhgvtghkihcuoehmrghrmhgrrhgvkhesihhnvh hishhisghlvghthhhinhhgshhlrggsrdgtohhmqeenucfkphepledurdeihedrfeegrdef feenucfrrghrrghmpehmrghilhhfrhhomhepmhgrrhhmrghrvghksehinhhvihhsihgslh gvthhhihhnghhslhgrsgdrtghomhenucevlhhushhtvghrufhiiigvpedt X-ME-Proxy: Received: from localhost.localdomain (ip5b412221.dynamic.kabel-deutschland.de [91.65.34.33]) by mail.messagingengine.com (Postfix) with ESMTPA id 930C880066; Wed, 23 Oct 2019 23:45:13 -0400 (EDT) From: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= To: xen-devel@lists.xenproject.org Date: Thu, 24 Oct 2019 05:45:04 +0200 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Subject: [Xen-devel] [PATCH v4 2/3] xen/efi: optionally call SetVirtualAddressMap() X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Stefano Stabellini , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , =?utf-8?q?Marek_Marczykowski-G?= =?utf-8?q?=C3=B3recki?= , Tim Deegan , Julien Grall , Jan Beulich Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Some UEFI implementations are not happy about lack of SetVirtualAddressMap() call. Likely abuse the address map change notification to do things beyond the necessary ConvertPointer() calls. Specifically, wihtout the SetVirtualAddressMap() call, some access EfiBootServices{Code,Data}, or even totally unmapped areas. Example crash of GetVariable() call on Thinkpad W540: Xen call trace: [<0000000000000080>] 0000000000000080 [<8c2b0398e0000daa>] 8c2b0398e0000daa Pagetable walk from ffffffff858483a1: L4[0x1ff] = 0000000000000000 ffffffffffffffff **************************************** Panic on CPU 0: FATAL PAGE FAULT [error_code=0002] Faulting linear address: ffffffff858483a1 **************************************** Fix this by calling SetVirtualAddressMap() runtime service, giving it 1:1 map for areas marked as needed during runtime. The address space in which EFI runtime services are called is unchanged, but UEFI view of it may be. Since it's fairly late in Xen 4.13 development cycle, disable it by default and hide behind EXPERT. Signed-off-by: Marek Marczykowski-Górecki Reviewed-by: Jan Beulich --- Changes in v2: - call SetVirtualAddressMap() before adjusting efi pointers; especially efi_memmap at this point still needs to use physical address, not a directmap one Changes in v3: - clarify impact (or rather: lack of it) on kexec, drop !KEXEC dependency. Changes in v4: - update commit message - adjust comment - rename config option to add EFI_ prefix --- xen/common/Kconfig | 10 ++++++++++ xen/common/efi/boot.c | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/xen/common/Kconfig b/xen/common/Kconfig index 16829f6..549a7d5 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -88,6 +88,16 @@ config KEXEC If unsure, say Y. +config EFI_SET_VIRTUAL_ADDRESS_MAP + bool "EFI: call SetVirtualAddressMap()" if EXPERT = "y" + ---help--- + Call EFI SetVirtualAddressMap() runtime service to setup memory map for + further runtime services. According to UEFI spec, it isn't strictly + necessary, but many UEFI implementations misbehave when this call is + missing. + + If unsure, say N. + config XENOPROF def_bool y prompt "Xen Oprofile Support" if EXPERT = "y" diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c index cddf3de..9debc5b 100644 --- a/xen/common/efi/boot.c +++ b/xen/common/efi/boot.c @@ -1056,11 +1056,17 @@ static void __init efi_set_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop, UINTN gop efi_arch_video_init(gop, info_size, mode_info); } +#define INVALID_VIRTUAL_ADDRESS (0xBAAADUL << \ + (EFI_PAGE_SHIFT + BITS_PER_LONG - 32)) + static void __init efi_exit_boot(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) { EFI_STATUS status; UINTN info_size = 0, map_key; bool retry; +#ifdef CONFIG_EFI_SET_VIRTUAL_ADDRESS_MAP + unsigned int i; +#endif efi_bs->GetMemoryMap(&info_size, NULL, &map_key, &efi_mdesc_size, &mdesc_ver); @@ -1094,6 +1100,26 @@ static void __init efi_exit_boot(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *Syste if ( EFI_ERROR(status) ) PrintErrMesg(L"Cannot exit boot services", status); +#ifdef CONFIG_EFI_SET_VIRTUAL_ADDRESS_MAP + for ( i = 0; i < efi_memmap_size; i += efi_mdesc_size ) + { + EFI_MEMORY_DESCRIPTOR *desc = efi_memmap + i; + + if ( desc->Attribute & EFI_MEMORY_RUNTIME ) + desc->VirtualStart = desc->PhysicalStart; + else + desc->VirtualStart = INVALID_VIRTUAL_ADDRESS; + } + status = efi_rs->SetVirtualAddressMap(efi_memmap_size, efi_mdesc_size, + mdesc_ver, efi_memmap); + if ( status != EFI_SUCCESS ) + { + printk(XENLOG_ERR "EFI: SetVirtualAddressMap() failed (%#lx), disabling runtime services\n", + status); + __clear_bit(EFI_RS, &efi_flags); + } +#endif + /* Adjust pointers into EFI. */ efi_ct = (void *)efi_ct + DIRECTMAP_VIRT_START; efi_memmap = (void *)efi_memmap + DIRECTMAP_VIRT_START; @@ -1460,8 +1486,6 @@ static bool __init rt_range_valid(unsigned long smfn, unsigned long emfn) return true; } -#define INVALID_VIRTUAL_ADDRESS (0xBAAADUL << \ - (EFI_PAGE_SHIFT + BITS_PER_LONG - 32)) void __init efi_init_memory(void) { @@ -1576,7 +1600,10 @@ void __init efi_init_memory(void) return; } - /* Set up 1:1 page tables to do runtime calls in "physical" mode. */ + /* + * Set up 1:1 page tables for runtime calls. See SetVirtualAddressMap() in + * efi_exit_boot(). + */ efi_l4_pgtable = alloc_xen_pagetable(); BUG_ON(!efi_l4_pgtable); clear_page(efi_l4_pgtable);