public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Matt Fleming <matt@codeblueprint.co.uk>
To: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: "linux-efi@vger.kernel.org" <linux-efi@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"x86@kernel.org" <x86@kernel.org>,
	Matt Fleming <matt.fleming@intel.com>,
	Borislav Petkov <bp@suse.de>,
	Leif Lindholm <leif.lindholm@linaro.org>,
	Peter Jones <pjones@redhat.com>,
	James Bottomley <JBottomley@odin.com>,
	Matthew Garrett <mjg59@srcf.ucam.org>,
	"H. Peter Anvin" <hpa@zytor.com>, Dave Young <dyoung@redhat.com>,
	"stable@vger.kernel.org" <stable@vger.kernel.org>
Subject: Re: [PATCH] x86/efi: Map EFI memmap entries in-order at runtime
Date: Tue, 8 Sep 2015 21:37:42 +0100	[thread overview]
Message-ID: <20150908203630.GB2854@codeblueprint.co.uk> (raw)
In-Reply-To: <CAKv+Gu_us3Nu_gMd4GxPe7z0eqtMfM4DM_UEmGW2MTqVDxg5vA@mail.gmail.com>

On Tue, 08 Sep, at 03:21:17PM, Ard Biesheuvel wrote:
> 
> I noticed that the 64-bit version of efi_map_region() preserves the
> relative alignment with respect to a 2 MB boundary for /each/ region.
> Since the regions are mapped in reverse order, it is highly unlikely
> that each region starts at the same 2 MB relative alignment that the
> previous region ended at, so you are likely wasting quite a bit of VA
> space.
> 
> I don't think it is a bug, though, but it does not seem intentional.

Yeah, that's a very good catch. The existing code, that is, top-down
allocation scheme where we map ealier EFI memmap entries at higher
virtual addresses, does incur quite a bit of wasted address space.

That's not true of this patch, though, and it's also not true if we
map the entries in reverse order of the EFI memmap, that is, mapping
the last memmap entry at the highest virtual address.

So it's a bug in the original code, or rather an unintended feature.

Ard, based on your suggestion I cooked this patch up to show what
iterating the EFI memmap in reverse looks like in terms of code. The
below diff and the original patch from this thread give me identical
virtual address space layouts.

Admittedly the below is missing a whole bunch of comments so makes the
diff look smaller, but something like this could work,

---

diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 691b333e0038..a2af35f6093a 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -704,6 +704,44 @@ out:
 	return ret;
 }
 
+static inline void *efi_map_next_entry_reverse(void *entry)
+{
+	if (!entry)
+		return memmap.map_end - memmap.desc_size;
+
+	entry -= memmap.desc_size;
+	if (entry < memmap.map)
+		return NULL;
+
+	return entry;
+}
+
+static void *efi_map_next_entry(void *entry)
+{
+	bool reverse = false;
+
+	if (!efi_enabled(EFI_OLD_MEMMAP) && efi_enabled(EFI_64BIT)) {
+		/*
+		 * Iterate the EFI memory map in reverse order because
+		 * the regions will be mapped top-down. The end result
+		 * is the same as if we had mapped things forward, but
+		 * doesn't require us to change the implementation of
+		 * efi_map_region().
+		 */
+		return efi_map_next_entry_reverse(entry);
+	}
+
+	/* Initial call */
+	if (!entry)
+		return memmap.map;
+
+	entry += memmap.desc_size;
+	if (entry >= memmap.map_end)
+		return NULL;
+
+	return entry;
+}
+
 /*
  * Map the efi memory ranges of the runtime services and update new_mmap with
  * virtual addresses.
@@ -718,7 +756,8 @@ static void * __init efi_map_regions(int *count, int *pg_shift)
 	start = -1UL;
 	end = 0;
 
-	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
+	p = NULL;
+	while ((p = efi_map_next_entry(p))) {
 		md = p;
 		if (!(md->attribute & EFI_MEMORY_RUNTIME)) {
 #ifdef CONFIG_X86_64

-- 
Matt Fleming, Intel Open Source Technology Center

  reply	other threads:[~2015-09-08 20:37 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-04 13:14 [PATCH] x86/efi: Map EFI memmap entries in-order at runtime Matt Fleming
2015-09-04 13:24 ` Ard Biesheuvel
2015-09-04 18:23   ` Matt Fleming
2015-09-04 18:53     ` Ard Biesheuvel
2015-09-06 14:06       ` Ard Biesheuvel
2015-09-08 13:16       ` Matt Fleming
2015-09-08 13:21         ` Ard Biesheuvel
2015-09-08 20:37           ` Matt Fleming [this message]
2015-09-09  7:37             ` Ard Biesheuvel
2015-09-09  9:58               ` Matt Fleming
2015-09-09  9:59                 ` Ard Biesheuvel
2015-09-07  4:07 ` joeyli
2015-09-08 20:41   ` Matt Fleming
2015-09-09  0:33     ` joeyli
2015-09-09 11:21       ` Matt Fleming
2015-09-10  3:38         ` joeyli
2015-09-16 10:08         ` Borislav Petkov
2015-09-16 11:25           ` Ard Biesheuvel
2015-09-16 13:28             ` Borislav Petkov
2015-09-16 13:38               ` Ard Biesheuvel
2015-09-17  8:05                 ` Borislav Petkov
2015-09-16 13:37             ` James Bottomley
2015-09-16 14:07               ` Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150908203630.GB2854@codeblueprint.co.uk \
    --to=matt@codeblueprint.co.uk \
    --cc=JBottomley@odin.com \
    --cc=ard.biesheuvel@linaro.org \
    --cc=bp@suse.de \
    --cc=dyoung@redhat.com \
    --cc=hpa@zytor.com \
    --cc=leif.lindholm@linaro.org \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=matt.fleming@intel.com \
    --cc=mjg59@srcf.ucam.org \
    --cc=pjones@redhat.com \
    --cc=stable@vger.kernel.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox