From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id BD327C4360C for ; Thu, 10 Oct 2019 06:37:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 82D3F2067B for ; Thu, 10 Oct 2019 06:37:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="LG6OY8If" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732832AbfJJGhE (ORCPT ); Thu, 10 Oct 2019 02:37:04 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:46108 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727041AbfJJGhD (ORCPT ); Thu, 10 Oct 2019 02:37:03 -0400 Received: by mail-wr1-f67.google.com with SMTP id o18so6217935wrv.13 for ; Wed, 09 Oct 2019 23:37:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=39vL/RjFbpzLu5bkAOs1K86XiNbeAZ4i2GoTlfcf4x4=; b=LG6OY8Ifh2UAofGEue5rrXE+63Iw2DQ4XcKKST6nHpnkTIm+Xi7vYiN9h7p7DhgdGo MetSI9e8ryaSLrYm2j+3toTnDUM1XufXB1rRQ8hzX+ChgU5atdy0v2XTIZy+v+j7N1pT BBRAWQEBjW3nGG4K4RyfL8QaQX7p5UzcdC3kvK50siY0lf6ezCXhioUy7fVNkM7WFsig U1tqB8Ddnvt66XzEbIJ9K9dQCeJKk4AoHEn64Qk3ITT9CWHpiZYThN/hAWwrdfx6K2Rk R5Aj4Ll6e71WIf6oJ0g5fO3DESV3CHMUzmY00XS8Q/9auLi/LY8nOI+llMdnHbVqiWSD DIRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=39vL/RjFbpzLu5bkAOs1K86XiNbeAZ4i2GoTlfcf4x4=; b=VscagPrqGTXXu1DJX9D9M+fDqiuUNcA7gaIZ+nmqlCDqgErE5wxAij1G4JnMCffk5z cgDAjzsUQDzCQFkIQA6ODzIe7TK5Tj15ZNjIb9342ulDZ/hYOsoT5fw7CQCqU5RTZq7o jhgaoD0oID09DPQFbQFBDrgDj7FHfpH3W345TzyXG5OX3TjtHV04lZBkirmYKYP6L+E5 on3EbOmZgtlONnvRHcsTjr3xS7tvFJ/gQOUgjWJwgTk4fXloISkEO9jlwx07gA64uiNX mMvpZuA8qvx4DVdOT7tLt5sAVxIbdjkzmJqfgmqOigNaGCp86XkyWr+DJSozF94/FXAe PeZA== X-Gm-Message-State: APjAAAU9TJtMSO9v3hUFvaTPWJlt+jf+6mv55xJLgnvnYtX33pm4x+7h 6MQFRcTTUzmPMBbT2iGbdeFeTOwEK09qolIjGCHYDQ== X-Google-Smtp-Source: APXvYqz2UpiOk7Jsv91cVM9s0b5LHK+kyw4OAekcJw3qQGAv+2SCCXQz/+vZSOLup3set0dvqH15r8Bymf/YQRUCBkU= X-Received: by 2002:adf:f5c2:: with SMTP id k2mr7212983wrp.0.1570689420029; Wed, 09 Oct 2019 23:37:00 -0700 (PDT) MIME-Version: 1.0 References: <157066227329.1059972.5659620631541203458.stgit@dwillia2-desk3.amr.corp.intel.com> <157066229757.1059972.16873416956816693344.stgit@dwillia2-desk3.amr.corp.intel.com> In-Reply-To: <157066229757.1059972.16873416956816693344.stgit@dwillia2-desk3.amr.corp.intel.com> From: Ard Biesheuvel Date: Thu, 10 Oct 2019 08:36:48 +0200 Message-ID: Subject: Re: [PATCH v6 04/12] efi: Common enable/disable infrastructure for EFI soft reservation To: Dan Williams Cc: Ingo Molnar , Peter Zijlstra , Vishal L Verma , Dave Hansen , "the arch/x86 maintainers" , linux-efi , Linux Kernel Mailing List , ACPI Devel Maling List Content-Type: text/plain; charset="UTF-8" Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org On Thu, 10 Oct 2019 at 01:19, Dan Williams wrote: > > UEFI 2.8 defines an EFI_MEMORY_SP attribute bit to augment the > interpretation of the EFI Memory Types as "reserved for a specific > purpose". > > The proposed Linux behavior for specific purpose memory is that it is > reserved for direct-access (device-dax) by default and not available for > any kernel usage, not even as an OOM fallback. Later, through udev > scripts or another init mechanism, these device-dax claimed ranges can > be reconfigured and hot-added to the available System-RAM with a unique > node identifier. This device-dax management scheme implements "soft" in > the "soft reserved" designation by allowing some or all of the > reservation to be recovered as typical memory. This policy can be > disabled at compile-time with CONFIG_EFI_SOFT_RESERVE=n, or runtime with > efi=nosoftreserve. > > As for this patch, define the common helpers to determine if the > EFI_MEMORY_SP attribute should be honored. The determination needs to be > made early to prevent the kernel from being loaded into soft-reserved > memory, or otherwise allowing early allocations to land there. Follow-on > changes are needed per architecture to leverage these helpers in their > respective mem-init paths. > > Cc: Ard Biesheuvel > Signed-off-by: Dan Williams Reviewed-by: Ard Biesheuvel > --- > Documentation/admin-guide/kernel-parameters.txt | 9 ++++++++- > drivers/firmware/efi/Kconfig | 21 +++++++++++++++++++++ > drivers/firmware/efi/efi.c | 9 +++++++++ > drivers/firmware/efi/libstub/efi-stub-helper.c | 19 +++++++++++++++++++ > include/linux/efi.h | 8 ++++++++ > 5 files changed, 65 insertions(+), 1 deletion(-) > > diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt > index c7ac2f3ac99f..47478a730011 100644 > --- a/Documentation/admin-guide/kernel-parameters.txt > +++ b/Documentation/admin-guide/kernel-parameters.txt > @@ -1168,7 +1168,8 @@ > Format: {"off" | "on" | "skip[mbr]"} > > efi= [EFI] > - Format: { "old_map", "nochunk", "noruntime", "debug" } > + Format: { "old_map", "nochunk", "noruntime", "debug", > + "nosoftreserve" } > old_map [X86-64]: switch to the old ioremap-based EFI > runtime services mapping. 32-bit still uses this one by > default. > @@ -1177,6 +1178,12 @@ > firmware implementations. > noruntime : disable EFI runtime services support > debug: enable misc debug output > + nosoftreserve: The EFI_MEMORY_SP (Specific Purpose) > + attribute may cause the kernel to reserve the > + memory range for a memory mapping driver to > + claim. Specify efi=nosoftreserve to disable this > + reservation and treat the memory by its base type > + (i.e. EFI_CONVENTIONAL_MEMORY / "System RAM"). > > efi_no_storage_paranoia [EFI; X86] > Using this parameter you can use more than 50% of > diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig > index 178ee8106828..9fa79f9fa0af 100644 > --- a/drivers/firmware/efi/Kconfig > +++ b/drivers/firmware/efi/Kconfig > @@ -75,6 +75,27 @@ config EFI_MAX_FAKE_MEM > Ranges can be set up to this value using comma-separated list. > The default value is 8. > > +config EFI_SOFT_RESERVE > + bool "Reserve EFI Specific Purpose Memory" > + depends on EFI && ACPI_HMAT > + default ACPI_HMAT > + help > + On systems that have mixed performance classes of memory EFI > + may indicate specific purpose memory with an attribute (See > + EFI_MEMORY_SP in UEFI 2.8). A memory range tagged with this > + attribute may have unique performance characteristics compared > + to the system's general purpose "System RAM" pool. On the > + expectation that such memory has application specific usage, > + and its base EFI memory type is "conventional" answer Y to > + arrange for the kernel to reserve it as a "Soft Reserved" > + resource, and set aside for direct-access (device-dax) by > + default. The memory range can later be optionally assigned to > + the page allocator by system administrator policy via the > + device-dax kmem facility. Say N to have the kernel treat this > + memory as "System RAM" by default. > + > + If unsure, say Y. > + > config EFI_PARAMS_FROM_FDT > bool > help > diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c > index 68a4ec24b823..911a58be4a36 100644 > --- a/drivers/firmware/efi/efi.c > +++ b/drivers/firmware/efi/efi.c > @@ -81,6 +81,12 @@ bool efi_runtime_disabled(void) > return disable_runtime; > } > > +bool __pure efi_soft_reserve_enabled(void) > +{ > + return IS_ENABLED(CONFIG_EFI_SOFT_RESERVE) && > + !efi_enabled(EFI_MEM_NO_SOFT_RESERVE); > +} > + > static int __init parse_efi_cmdline(char *str) > { > if (!str) { > @@ -94,6 +100,9 @@ static int __init parse_efi_cmdline(char *str) > if (parse_option_str(str, "noruntime")) > disable_runtime = true; > > + if (parse_option_str(str, "nosoftreserve")) > + set_bit(EFI_MEM_NO_SOFT_RESERVE, &efi.flags); > + > return 0; > } > early_param("efi", parse_efi_cmdline); > diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c > index 3caae7f2cf56..5d901c56ac5f 100644 > --- a/drivers/firmware/efi/libstub/efi-stub-helper.c > +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c > @@ -32,6 +32,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; > +static bool __section(.data) efi_nosoftreserve; > > int __pure nokaslr(void) > { > @@ -45,6 +46,10 @@ int __pure novamap(void) > { > return __novamap; > } > +bool __pure efi_soft_reserve_enabled(void) > +{ > + return IS_ENABLED(CONFIG_EFI_SOFT_RESERVE) && !efi_nosoftreserve; > +} > > #define EFI_MMAP_NR_SLACK_SLOTS 8 > > @@ -211,6 +216,10 @@ efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg, > if (desc->type != EFI_CONVENTIONAL_MEMORY) > continue; > > + if (efi_soft_reserve_enabled() && > + (desc->attribute & EFI_MEMORY_SP)) > + continue; > + > if (desc->num_pages < nr_pages) > continue; > > @@ -305,6 +314,10 @@ efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg, > if (desc->type != EFI_CONVENTIONAL_MEMORY) > continue; > > + if (efi_soft_reserve_enabled() && > + (desc->attribute & EFI_MEMORY_SP)) > + continue; > + > if (desc->num_pages < nr_pages) > continue; > > @@ -489,6 +502,12 @@ efi_status_t efi_parse_options(char const *cmdline) > __novamap = 1; > } > > + if (IS_ENABLED(CONFIG_EFI_SOFT_RESERVE) && > + !strncmp(str, "nosoftreserve", 7)) { > + str += strlen("nosoftreserve"); > + efi_nosoftreserve = 1; > + } > + > /* Group words together, delimited by "," */ > while (*str && *str != ' ' && *str != ',') > str++; > diff --git a/include/linux/efi.h b/include/linux/efi.h > index baa275c56401..959c9650018f 100644 > --- a/include/linux/efi.h > +++ b/include/linux/efi.h > @@ -1202,6 +1202,7 @@ extern int __init efi_setup_pcdp_console(char *); > #define EFI_DBG 8 /* Print additional debug info at runtime */ > #define EFI_NX_PE_DATA 9 /* Can runtime data regions be mapped non-executable? */ > #define EFI_MEM_ATTR 10 /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */ > +#define EFI_MEM_NO_SOFT_RESERVE 11 /* Is the kernel configured to ignore soft reservations? */ > > #ifdef CONFIG_EFI > /* > @@ -1212,6 +1213,8 @@ static inline bool efi_enabled(int feature) > return test_bit(feature, &efi.flags) != 0; > } > extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused); > + > +bool __pure efi_soft_reserve_enabled(void); > #else > static inline bool efi_enabled(int feature) > { > @@ -1225,6 +1228,11 @@ efi_capsule_pending(int *reset_type) > { > return false; > } > + > +static inline bool efi_soft_reserve_enabled(void) > +{ > + return false; > +} > #endif > > extern int efi_status_to_err(efi_status_t status); >