From patchwork Tue Aug 29 16:00:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 111231 Delivered-To: patch@linaro.org Received: by 10.140.95.112 with SMTP id h103csp1556077qge; Tue, 29 Aug 2017 09:06:11 -0700 (PDT) X-Received: by 10.233.239.4 with SMTP id d4mr6339659qkg.196.1504022771729; Tue, 29 Aug 2017 09:06:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504022771; cv=none; d=google.com; s=arc-20160816; b=VyGAcBeAp2/O2vsA4cX4mjw3rndC5UtH8IzWWYU/u7yoGujtn+e8IOIos+9KqbPH18 elocu5P1oS3ZE6QN9lPFf3ocQ4RoPM3NXB5TuaFo9uttR+dLTqv2wS47B2acHBs6VLvE WC8sxnjTHRKuwgh7+EFH6sVi26BGoAuRhOVDB59sOAatLRbRbxLsAw02arfiEGnV79gE 8ixJvQ1WNZoL3nRrS7hZwJn5ed9UNrNTFGc1HJQ3x7pTYhPnaJYENJPwn1nobqbPnc5p HBHSTnS6hbbY/xAAo4h81EJvqtdVQLrupGCLmn6Bu5XCZDp+5/lMO0gzmnWqgmqWkuCf nCng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:references:in-reply-to:message-id:date:subject :to:from:arc-authentication-results; bh=ioJVMUeHASUvUOu5UYgAlwhPsSjKUBd0ycJtn0UvZQ4=; b=pDKSaMRAlqmgUiDitWWUoNI2kgH/fh/GkT91DGEEIOGvpuvGIhlFpVr549r7S6O+y5 S3IrKl7wsaB5JrfOmINu6prPzBBBOmRmixyyF2OOfOkuVjiapdpWgBLQ3lU8J0QtgFpb fFjpcMfEk/gCfI1gKiGWFYcCpjg0oFvZd852gd2epXb1XNJkKv/9+/+3EtIcCg8mfh3A CnmNVG9/mIdcsf09iNvoUrrsfUfrmcplOsuZtMoOGb4feKI2pPZ2zNnslSjhAEetT/S0 j7iwrF9XJPLuL7cgGXjRDlyrvRDY42rt7+FAveSdTdHUems1Ego3snH4xol5BczBxd0r gwXg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of grub-devel-bounces+patch=linaro.org@gnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=grub-devel-bounces+patch=linaro.org@gnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id a65si3144291qkd.308.2017.08.29.09.06.11 for (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 29 Aug 2017 09:06:11 -0700 (PDT) Received-SPF: pass (google.com: domain of grub-devel-bounces+patch=linaro.org@gnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of grub-devel-bounces+patch=linaro.org@gnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=grub-devel-bounces+patch=linaro.org@gnu.org Received: from localhost ([::1]:45814 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dmj1l-0007SY-9O for patch@linaro.org; Tue, 29 Aug 2017 12:06:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57477) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dmiwX-0004Et-Hv for grub-devel@gnu.org; Tue, 29 Aug 2017 12:00:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dmiwR-0007lI-2a for grub-devel@gnu.org; Tue, 29 Aug 2017 12:00:45 -0400 Received: from mx2.suse.de ([195.135.220.15]:60431 helo=mx1.suse.de) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dmiwQ-0007jt-On for grub-devel@gnu.org; Tue, 29 Aug 2017 12:00:39 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 425FEAEA4; Tue, 29 Aug 2017 16:00:36 +0000 (UTC) From: Alexander Graf To: grub-devel@gnu.org Subject: [PATCH v3 2/2] efi: Free malloc regions on exit Date: Tue, 29 Aug 2017 18:00:35 +0200 Message-Id: <20170829160035.11987-3-agraf@suse.de> X-Mailer: git-send-email 2.12.3 In-Reply-To: <20170829160035.11987-1-agraf@suse.de> References: <20170829160035.11987-1-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Received-From: 195.135.220.15 X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: The development of GNU GRUB Cc: phcoder@gmail.com, mchang@suse.com, Daniel Kiper , elliott@hpe.com MIME-Version: 1.0 Errors-To: grub-devel-bounces+patch=linaro.org@gnu.org Sender: "Grub-devel" When we exit grub, we don't free all the memory that we allocated earlier for our heap region. This can cause problems with setups where you try to descend the boot order using "exit" entries, such as PXE -> HD boot scenarios. Signed-off-by: Alexander Graf --- v1 -> v2: - add comment explaining the number of regions - move nr of regions into a define - add warning if we exceed the number of freeable regions - reset region counter to 0 on fini v2 -> v3: - use dynamic list instead of static array at runtime - use allocate_pool for list, so we are not bound by heap or random numbers --- grub-core/kern/efi/init.c | 1 + grub-core/kern/efi/mm.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++ include/grub/efi/efi.h | 1 + 3 files changed, 61 insertions(+) -- 2.12.3 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c index 2c31847bf..3dfdf2d22 100644 --- a/grub-core/kern/efi/init.c +++ b/grub-core/kern/efi/init.c @@ -80,4 +80,5 @@ grub_efi_fini (void) { grub_efidisk_fini (); grub_console_fini (); + grub_efi_memory_fini (); } diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c index ac2a4c556..3455076e3 100644 --- a/grub-core/kern/efi/mm.c +++ b/grub-core/kern/efi/mm.c @@ -49,6 +49,18 @@ static grub_efi_uintn_t finish_desc_size; static grub_efi_uint32_t finish_desc_version; int grub_efi_is_finished = 0; +/* + * We need to roll back EFI allocations on exit. Remember allocations that + * we'll free on exit. In most cases only one will be used. + */ +struct efi_allocation; +struct efi_allocation { + struct efi_allocation *next; + grub_efi_physical_address_t start_addr; + grub_efi_uint64_t pages; +}; +static struct efi_allocation *efi_allocated_memory; + /* Allocate pages. Return the pointer to the first of allocated pages. */ void * grub_efi_allocate_pages_real (grub_efi_physical_address_t address, @@ -386,14 +398,19 @@ add_memory_regions (grub_efi_memory_descriptor_t *memory_map, grub_efi_uint64_t required_pages) { grub_efi_memory_descriptor_t *desc; + grub_efi_boot_services_t *b; + + b = grub_efi_system_table->boot_services; for (desc = memory_map; desc < memory_map_end; desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) { + struct efi_allocation *alloc; grub_efi_uint64_t pages; grub_efi_physical_address_t start; void *addr; + grub_efi_status_t status; start = desc->physical_start; pages = desc->num_pages; @@ -411,6 +428,19 @@ add_memory_regions (grub_efi_memory_descriptor_t *memory_map, (void *) ((grub_addr_t) start), (unsigned) pages); + status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA, + sizeof(*alloc), (void**)&alloc); + if (status == GRUB_EFI_SUCCESS) + { + alloc->next = efi_allocated_memory; + alloc->start_addr = start; + alloc->pages = pages; + efi_allocated_memory = alloc; + } + else + grub_printf ("Could not malloc memory to remember EFI allocation. " + "Exiting grub2 won't free all memory.\n"); + grub_mm_init_region (addr, PAGES_TO_BYTES (pages)); required_pages -= pages; @@ -422,6 +452,35 @@ add_memory_regions (grub_efi_memory_descriptor_t *memory_map, grub_fatal ("too little memory"); } +void +grub_efi_memory_fini (void) +{ + struct efi_allocation *alloc; + grub_efi_boot_services_t *b; + + b = grub_efi_system_table->boot_services; + + for (alloc = efi_allocated_memory; alloc;) + { + struct efi_allocation *next; + + /* Free the allocation */ + grub_efi_free_pages (alloc->start_addr, + alloc->pages); + + /* Remember the next entry */ + next = alloc->next; + + /* Free the current list entry */ + efi_call_1 (b->free_pool, alloc); + + /* And move on to the next */ + alloc = next; + } + + efi_allocated_memory = NULL; +} + #if 0 /* Print the memory map. */ static void diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index 3fa082816..c996913e5 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -55,6 +55,7 @@ EXPORT_FUNC(grub_efi_get_memory_map) (grub_efi_uintn_t *memory_map_size, grub_efi_uintn_t *map_key, grub_efi_uintn_t *descriptor_size, grub_efi_uint32_t *descriptor_version); +void grub_efi_memory_fini (void); grub_efi_loaded_image_t *EXPORT_FUNC(grub_efi_get_loaded_image) (grub_efi_handle_t image_handle); void EXPORT_FUNC(grub_efi_print_device_path) (grub_efi_device_path_t *dp); char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp);