From patchwork Sat Oct 12 14:36:09 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: 11186797 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 06A4F17EE for ; Sat, 12 Oct 2019 14:38:02 +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 D6A2E2089C for ; Sat, 12 Oct 2019 14:38:01 +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="L0PZjdmO" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D6A2E2089C 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 1iJIVX-0000YQ-LR; Sat, 12 Oct 2019 14:36:35 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iJIVW-0000Y8-Bv for xen-devel@lists.xenproject.org; Sat, 12 Oct 2019 14:36:34 +0000 X-Inumbo-ID: adbfc236-ecfd-11e9-bbab-bc764e2007e4 Received: from new1-smtp.messagingengine.com (unknown [66.111.4.221]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id adbfc236-ecfd-11e9-bbab-bc764e2007e4; Sat, 12 Oct 2019 14:36:29 +0000 (UTC) Received: from compute7.internal (compute7.nyi.internal [10.202.2.47]) by mailnew.nyi.internal (Postfix) with ESMTP id 93BB25916; Sat, 12 Oct 2019 10:36:29 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute7.internal (MEProxy); Sat, 12 Oct 2019 10:36:29 -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=2tq+EVixw2b0GMKGNXgcN3F/3xwOoxlJnB+6cPiUc fY=; b=L0PZjdmOEq9VoeoAAD5bKWKzcQqI/EdCaEh7iXKU6TcsULet/uZbpFGbN GHJW3IM6FOXEURI0FOjEE4gSHISUZAPUL75qhelqzayod+cEHlH6ViTk/R50bCWj 9i4mYoIiMbtFWgwf96p5Whht4NZIOnSXhQmcCDQvv8aGBvdQ4H0EqXKfdJC4pRBr PBMoB1++tVXEBN7yBr9gpUO11Ft8CwXJZ1Kt8nimW/Fj/MaZjwGMytALxrJsw3T9 XR8kbDVLMZrspZLFOLulnf+uhcJZv0aBBibkZM47EssnGglfaTgG5kgTWCHKT0fQ HyPpNLygqiQuLg9G59+SsBn3blvCw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedufedrieejgdejlecutefuodetggdotefrodftvf 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 0F367D6005D; Sat, 12 Oct 2019 10:36:27 -0400 (EDT) From: =?utf-8?q?Marek_Marczykowski-G=C3=B3recki?= To: xen-devel@lists.xenproject.org Date: Sat, 12 Oct 2019 16:36:09 +0200 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Subject: [Xen-devel] [PATCH v2 2/2] 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 running in 1:1 addressing, but really virtual address space. Specifically, 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. SetVirtualAddressMap() can be called only once, hence it's incompatible with kexec. For this reason, make it an optional feature, depending on !KEXEC. And to not inflate number of supported configurations, hide it behind EXPERT. Signed-off-by: Marek Marczykowski-Górecki --- 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 --- xen/common/Kconfig | 13 +++++++++++++ xen/common/efi/boot.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/xen/common/Kconfig b/xen/common/Kconfig index 16829f6..fe98f8a 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -88,6 +88,19 @@ config KEXEC If unsure, say Y. +config SET_VIRTUAL_ADDRESS_MAP + bool "EFI: call SetVirtualAddressMap()" if EXPERT = "y" + default n + depends on !KEXEC + ---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. On the other hand, this call can be made only once, which makes + it incompatible with kexec (kexec-ing this Xen from other Xen or Linux). + + If unsuser, 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..6eaabd4 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_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_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) {