From patchwork Tue Dec 10 11:51:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 11282055 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 CDB40112B for ; Tue, 10 Dec 2019 11:51:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A2B2120726 for ; Tue, 10 Dec 2019 11:51:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="fwmY4RUN" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727540AbfLJLvh (ORCPT ); Tue, 10 Dec 2019 06:51:37 -0500 Received: from us-smtp-delivery-1.mimecast.com ([207.211.31.120]:45010 "EHLO us-smtp-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727501AbfLJLvf (ORCPT ); Tue, 10 Dec 2019 06:51:35 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1575978694; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=x85HLpSVXUpESKASgozyJonASmyTtrZ6tatnJUlwI+Y=; b=fwmY4RUNHgViFDe6a6kLc0HjP9yzFkJFhlXnEYEewwhe7XZoqUHx5EQK0hivqgoZxw+HQV KuGc2WkkoDfaMgArapt0zOabg2cbCAJ3umEPKYqOlX0KNse8hyZdmTedNfqr740C9d4L/O zPY8YyXflpdIS+nKImyMkcRSuZqxk6o= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-415-gpWyPKUJNL-J9E7vhKGKIA-1; Tue, 10 Dec 2019 06:51:30 -0500 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 3C78580440F; Tue, 10 Dec 2019 11:51:28 +0000 (UTC) Received: from shalem.localdomain.com (unknown [10.36.118.144]) by smtp.corp.redhat.com (Postfix) with ESMTP id A23065DA60; Tue, 10 Dec 2019 11:51:24 +0000 (UTC) From: Hans de Goede To: Ard Biesheuvel , Darren Hart , Andy Shevchenko , Luis Chamberlain , Greg Kroah-Hartman , "Rafael J . Wysocki" , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H . Peter Anvin" , Jonathan Corbet , Dmitry Torokhov Cc: Hans de Goede , Peter Jones , Dave Olsthoorn , x86@kernel.org, platform-driver-x86@vger.kernel.org, linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-input@vger.kernel.org Subject: [PATCH v10 01/10] efi: Export boot-services code and data as debugfs-blobs Date: Tue, 10 Dec 2019 12:51:08 +0100 Message-Id: <20191210115117.303935-2-hdegoede@redhat.com> In-Reply-To: <20191210115117.303935-1-hdegoede@redhat.com> References: <20191210115117.303935-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-MC-Unique: gpWyPKUJNL-J9E7vhKGKIA-1 X-Mimecast-Spam-Score: 0 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org Sometimes it is useful to be able to dump the efi boot-services code and data. This commit adds these as debugfs-blobs to /sys/kernel/debug/efi, but only if efi=debug is passed on the kernel-commandline as this requires not freeing those memory-regions, which costs 20+ MB of RAM. Reviewed-by: Greg Kroah-Hartman Acked-by: Ard Biesheuvel Signed-off-by: Hans de Goede --- Changes in v8: -Add pr_warn if there are mode then EFI_DEBUGFS_MAX_BLOBS boot service segments -Document how the boot_service_code? files can be used to check for embedded firmware. Note since this is related to the firmware EFI embedded fw support, these docs are added in the 4th patch of this patch-set, not in this one. Changes in v5: -Rename the EFI_BOOT_SERVICES flag to EFI_PRESERVE_BS_REGIONS Changes in v4: -Add new EFI_BOOT_SERVICES flag and use it to determine if the boot-services memory segments are available (and thus if it makes sense to register the debugfs bits for them) Changes in v2: -Do not call pr_err on debugfs call failures --- arch/x86/platform/efi/efi.c | 1 + arch/x86/platform/efi/quirks.c | 4 +++ drivers/firmware/efi/efi.c | 57 ++++++++++++++++++++++++++++++++++ include/linux/efi.h | 1 + 4 files changed, 63 insertions(+) diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 38d44f36d5ed..3e5375ee53a0 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -269,6 +269,7 @@ int __init efi_memblock_x86_reserve_range(void) efi.memmap.desc_version); memblock_reserve(pmap, efi.memmap.nr_map * efi.memmap.desc_size); + set_bit(EFI_PRESERVE_BS_REGIONS, &efi.flags); return 0; } diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index 7675cf754d90..84a9de64e8e1 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -414,6 +414,10 @@ void __init efi_free_boot_services(void) int num_entries = 0; void *new, *new_md; + /* Keep all regions for /sys/kernel/debug/efi */ + if (efi_enabled(EFI_DBG)) + return; + for_each_efi_memory_desc(md) { unsigned long long start = md->phys_addr; unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index d101f072c8f8..7575401e6ea6 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -325,6 +326,59 @@ static __init int efivar_ssdt_load(void) static inline int efivar_ssdt_load(void) { return 0; } #endif +#ifdef CONFIG_DEBUG_FS + +#define EFI_DEBUGFS_MAX_BLOBS 32 + +static struct debugfs_blob_wrapper debugfs_blob[EFI_DEBUGFS_MAX_BLOBS]; + +static void __init efi_debugfs_init(void) +{ + struct dentry *efi_debugfs; + efi_memory_desc_t *md; + char name[32]; + int type_count[EFI_BOOT_SERVICES_DATA + 1] = {}; + int i = 0; + + efi_debugfs = debugfs_create_dir("efi", NULL); + if (IS_ERR_OR_NULL(efi_debugfs)) + return; + + for_each_efi_memory_desc(md) { + switch (md->type) { + case EFI_BOOT_SERVICES_CODE: + snprintf(name, sizeof(name), "boot_services_code%d", + type_count[md->type]++); + break; + case EFI_BOOT_SERVICES_DATA: + snprintf(name, sizeof(name), "boot_services_data%d", + type_count[md->type]++); + break; + default: + continue; + } + + if (i >= EFI_DEBUGFS_MAX_BLOBS) { + pr_warn("More then %d EFI boot service segments, only showing first %d in debugfs\n", + EFI_DEBUGFS_MAX_BLOBS, EFI_DEBUGFS_MAX_BLOBS); + break; + } + + debugfs_blob[i].size = md->num_pages << EFI_PAGE_SHIFT; + debugfs_blob[i].data = memremap(md->phys_addr, + debugfs_blob[i].size, + MEMREMAP_WB); + if (!debugfs_blob[i].data) + continue; + + debugfs_create_blob(name, 0400, efi_debugfs, &debugfs_blob[i]); + i++; + } +} +#else +static inline void efi_debugfs_init(void) {} +#endif + /* * We register the efi subsystem with the firmware subsystem and the * efivars subsystem with the efi subsystem, if the system was booted with @@ -381,6 +435,9 @@ static int __init efisubsys_init(void) goto err_remove_group; } + if (efi_enabled(EFI_DBG) && efi_enabled(EFI_PRESERVE_BS_REGIONS)) + efi_debugfs_init(); + return 0; err_remove_group: diff --git a/include/linux/efi.h b/include/linux/efi.h index 99dfea595c8c..c364106250e9 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -1203,6 +1203,7 @@ extern int __init efi_setup_pcdp_console(char *); #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? */ +#define EFI_PRESERVE_BS_REGIONS 12 /* Are EFI boot-services memory segments available? */ #ifdef CONFIG_EFI /*