From patchwork Sat Feb 2 09:41:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 157330 Delivered-To: patch@linaro.org Received: by 2002:a02:48:0:0:0:0:0 with SMTP id 69csp1509914jaa; Sat, 2 Feb 2019 01:41:42 -0800 (PST) X-Google-Smtp-Source: ALg8bN7z+W10EtygAab1BrnK8KPxizRYKkCKXHBLm4jZLhrLUEDu/1VBFV/XlQl8BEy48fePbtEh X-Received: by 2002:a17:902:6b49:: with SMTP id g9mr42439057plt.98.1549100502221; Sat, 02 Feb 2019 01:41:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549100502; cv=none; d=google.com; s=arc-20160816; b=ijOFdKfB8tVrA8SB9o+Y2KbCcJJcLpnwvELlAvQ60G3ixWd2yIkouUNld7TozY21vf GSzrEgof+F3uQWJ1EHk6U87SeozrFdPU691d+W3/S8a7nqxHIf842sZ5lT0AW04yuVdj qZD/CHtPGT3hjHkPcy/rx+dEV35ROWbgGDQchCUPY0wXONBuY4riLRtugbdk9AzMSk7n zpngs5J9PGHd8316suYxHeUfUbrq7aWWH2lgrjABCS9OpsWFqoBKm6K6CwCQpJCCEiP5 3qQqTVFPjKfSwsB0VTblKCen+eZtNz9hCBMOrlbM0WR2RGCq2ScqIisHOl/ndu9UIQhg NEzw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=tQBUl2UZJ0vfR/KYX3Z1OnD6qvSuR/J3cZ1KmLStMQw=; b=dLONtceJLBAn4vzdsaiAA+g3BwVtmdEg4/5Ksr4QaKl/Khj3PpURdYoogZS2NN72zr bQIpNU/d9HHuMCgRSi0sDi2vH9kvg4Bf6BMgrirqG9vIwDewvJ6S4+ITNxYI6w09rQrT 2JWPzuwxvbAEWdrRk1CGH23hvktkCssWLfPDc4mnE5bwlp0a4LXtWVTHuAYm1nuUonlL aFaKJSvfkD7naHWFv6h0nnUgZYZYrQjQ5AjxYLykcAE4QudGJ5psvpV5r2hgLzPsTvEc 1cGiia5UGI1xRutYpKQtMoNV3mh81pncwwwNCPSFmLaPyBuDKq6zRaq3Iu8DwysW3F/w PwZQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="hBLc/6O/"; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id y10si8686394pgp.348.2019.02.02.01.41.42; Sat, 02 Feb 2019 01:41:42 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="hBLc/6O/"; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727594AbfBBJlk (ORCPT + 3 others); Sat, 2 Feb 2019 04:41:40 -0500 Received: from mail-ed1-f68.google.com ([209.85.208.68]:44262 "EHLO mail-ed1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727627AbfBBJlj (ORCPT ); Sat, 2 Feb 2019 04:41:39 -0500 Received: by mail-ed1-f68.google.com with SMTP id y56so7435168edd.11 for ; Sat, 02 Feb 2019 01:41:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=tQBUl2UZJ0vfR/KYX3Z1OnD6qvSuR/J3cZ1KmLStMQw=; b=hBLc/6O/QY8ijpLk6qYy7tQmvlFjGW9YPnqwanYXgw1mgswBhE7ZzJjwAUG38zOxdS 5yAiGypuQ8Ks8fEg8zGfrguYNTBmpN5lwRbPbfRn9cMAzutBavYdzkrdlHgRVz86LIuA wwuGWvX0yxxs6x2Os2bCXL+F69LaZsymCxNxI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=tQBUl2UZJ0vfR/KYX3Z1OnD6qvSuR/J3cZ1KmLStMQw=; b=EWtE/s4zCe46hxU+4lDzHp/COrUAV/fHR1GNTf5u0VhmijAX1oB5nLWJPGzq/Gp1zZ 4BQrLSu38L4020d5qS+Ok+MpSHNlx9Z8WnDFFKmST8axnD4zK+d4g9IcOsahy6fvoWIS YCMrs67P61IbtCRKAukWsQ3obQAptFMqaTUXmMggmcJdU5EakpPjVlLwMWXxYLBVvZK6 QycOakzIcLawtsEOdlWJKii9CQaupgBkiBqi0tOFzYogybC+GeiRBB6YloeX1Dsok0cp LujcnwOFwzQUFZEGuKC53brqztcB9C3ODVMGy1ZYGA5iLW70VsH0Wqfh0sxIOIKLh0zz KHRA== X-Gm-Message-State: AJcUukduuFA8l7+clqWunSubuXJnp3Zq+oBFtAN7k/h8oB3z8XNOVxY+ WarEvvBfhlovxlhgHqgX5KbF7zok8yWqrg== X-Received: by 2002:a50:a786:: with SMTP id i6mr42297103edc.37.1549100497431; Sat, 02 Feb 2019 01:41:37 -0800 (PST) Received: from mba13.c.hoisthospitality.com ([109.236.135.164]) by smtp.gmail.com with ESMTPSA id l41sm2608824eda.83.2019.02.02.01.41.36 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 02 Feb 2019 01:41:36 -0800 (PST) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, Ingo Molnar , Thomas Gleixner Cc: Ard Biesheuvel , linux-kernel@vger.kernel.org, AKASHI Takahiro , Alexander Graf , Bjorn Andersson , Borislav Petkov , Heinrich Schuchardt , Jeffrey Hugo , Lee Jones , Leif Lindholm , Linus Torvalds , Peter Jones , Peter Zijlstra , Sai Praneeth Prakhya Subject: [PATCH 07/10] efi: arm/arm64: allow SetVirtualAddressMap() to be omitted Date: Sat, 2 Feb 2019 10:41:16 +0100 Message-Id: <20190202094119.13230-8-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190202094119.13230-1-ard.biesheuvel@linaro.org> References: <20190202094119.13230-1-ard.biesheuvel@linaro.org> Sender: linux-efi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org The UEFI spec revision 2.7 errata A section 8.4 has the following to say about the virtual memory runtime services: "This section contains function definitions for the virtual memory support that may be optionally used by an operating system at runtime. If an operating system chooses to make EFI runtime service calls in a virtual addressing mode instead of the flat physical mode, then the operating system must use the services in this section to switch the EFI runtime services from flat physical addressing to virtual addressing." So it is pretty clear that calling SetVirtualAddressMap() is entirely optional, and so there is no point in doing so unless it achieves anything useful for us. This is not the case for 64-bit ARM. The identity mapping used by the firmware is arbitrarily converted into another permutation of userland addresses (i.e., bits [63:48] cleared), and the runtime code could easily deal with the original layout in exactly the same way as it deals with the converted layout. However, due to constraints related to page size differences if the OS is not running with 4k pages, and related to systems that may expose the individual sections of PE/COFF runtime modules as different memory regions, creating the virtual layout is a bit fiddly, and requires us to sort the memory map and reason about adjacent regions with identical memory types etc etc. So the obvious fix is to stop calling SetVirtualAddressMap() altogether on arm64 systems. However, to avoid surprises, which are notoriously hard to diagnose when it comes to OS<->firmware interactions, let's start by making it an opt-out feature, and implement support for the 'efi=novamap' kernel command line parameter on ARM and arm64 systems. (Note that 32-bit ARM generally does require SetVirtualAddressMap() to be used, given that the physical memory map and the kernel virtual address map are not guaranteed to be non-overlapping like on arm64. However, having support for efi=novamap,noruntime on 32-bit ARM, combined with the recently proposed support for earlycon=efifb, is likely to be useful to diagnose boot issues on such systems if they have no accessible serial port) Cc: Alexander Graf Cc: Heinrich Schuchardt Cc: AKASHI Takahiro Cc: Leif Lindholm Tested-by: Jeffrey Hugo Tested-by: Bjorn Andersson Tested-by: Lee Jones Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/arm-stub.c | 5 +++++ drivers/firmware/efi/libstub/efi-stub-helper.c | 10 ++++++++++ drivers/firmware/efi/libstub/efistub.h | 1 + drivers/firmware/efi/libstub/fdt.c | 3 +++ 4 files changed, 19 insertions(+) -- 2.17.1 diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c index eee42d5e25ee..626ec4b4a664 100644 --- a/drivers/firmware/efi/libstub/arm-stub.c +++ b/drivers/firmware/efi/libstub/arm-stub.c @@ -370,6 +370,11 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, paddr = in->phys_addr; size = in->num_pages * EFI_PAGE_SIZE; + if (novamap()) { + in->virt_addr = in->phys_addr; + continue; + } + /* * Make the mapping compatible with 64k pages: this allows * a 4k page size kernel to kexec a 64k page size kernel and diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index 8f2d000bec75..e4610e72b78f 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -31,6 +31,7 @@ static unsigned long __chunk_size = EFI_READ_CHUNK_SIZE; static int __section(.data) __nokaslr; static int __section(.data) __quiet; +static int __section(.data) __novamap; int __pure nokaslr(void) { @@ -40,6 +41,10 @@ int __pure is_quiet(void) { return __quiet; } +int __pure novamap(void) +{ + return __novamap; +} #define EFI_MMAP_NR_SLACK_SLOTS 8 @@ -479,6 +484,11 @@ efi_status_t efi_parse_options(char const *cmdline) __chunk_size = -1UL; } + if (!strncmp(str, "novamap", 7)) { + str += strlen("novamap"); + __novamap = 1; + } + /* Group words together, delimited by "," */ while (*str && *str != ' ' && *str != ',') str++; diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index cefcf6ba3150..1b1dfcaa6fb9 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -27,6 +27,7 @@ extern int __pure nokaslr(void); extern int __pure is_quiet(void); +extern int __pure novamap(void); #define pr_efi(sys_table, msg) do { \ if (!is_quiet()) efi_printk(sys_table, "EFI stub: "msg); \ diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c index 7cfc51935c4b..5440ba17a1c5 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c @@ -318,6 +318,9 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table, if (status == EFI_SUCCESS) { efi_set_virtual_address_map_t *svam; + if (novamap()) + return EFI_SUCCESS; + /* Install the new virtual address map */ svam = sys_table->runtime->set_virtual_address_map; status = svam(runtime_entry_count * desc_size, desc_size,