From: harald-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Harald Hoyer <harald-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Subject: [PATCH V2] efi_high_alloc: use EFI_ALLOCATE_MAX_ADDRESS
Date: Mon, 25 Aug 2014 13:55:32 +0200 [thread overview]
Message-ID: <1408967732-2381-1-git-send-email-harald@redhat.com> (raw)
In-Reply-To: <1408715303-2215-1-git-send-email-harald-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
From: Harald Hoyer <harald-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
On my Lenovo T420s with 4GB memory, efi_high_alloc() was checking the
following memory regions:
0x0000000000100000 - 0x0000000020000000
0x0000000020200000 - 0x0000000040000000
0x0000000040200000 - 0x00000000d2c02000
0x00000000d6e9f000 - 0x000000011e600000
and decided to allocate 2649 pages at address 0x11dba7000.
...
[ 0.000000] efi: mem53: type=2, attr=0xf, range=[0x000000011dba7000-0x000000011e600000) (10MB)
...
[ 0.000000] RAMDISK: [mem 0x11dba7000-0x11e5fffff]
...
[ 0.154933] Unpacking initramfs...
[ 0.160990] Initramfs unpacking failed: junk in compressed archive
[ 0.163436] Freeing initrd memory: 10596K (ffff88011dba7000 - ffff88011e600000)
...
Nevertheless, unpacking of the initramfs later on failed.
This is maybe caused by my buggy EFI BIOS and
commit 4bf7111f50167133a71c23530ca852a41355e739,
which enables loading the initramfs above 4G addresses.
With this patch efi_high_alloc() now uses EFI_ALLOCATE_MAX_ADDRESS,
which should do the same as before, but use the EFI logic to select the high memory range.
This returns 0x00000000d2c02000 on my machine and the initramfs is
loaded, uncompressed and executed correctly.
...
[ 0.000000] efi: mem15: type=2, attr=0xf, range=[0x00000000d2c02000-0x00000000d365b000) (10MB)
...
[ 0.000000] RAMDISK: [mem 0xd2c02000-0xd365afff]
...
[ 0.151269] Unpacking initramfs...
[ 0.309868] Freeing initrd memory: 10596K (ffff8800d2c02000 - ffff8800d365b000)
...
Signed-off-by: Harald Hoyer <harald-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
V2: return value of EFI_ALLOCATE_MAX_ADDRESS is the begin of the segment, and not the end
drivers/firmware/efi/libstub/efi-stub-helper.c | 74 +++++---------------------
1 file changed, 14 insertions(+), 60 deletions(-)
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index 32d5cca..9aafcf8 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -118,82 +118,36 @@ efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg,
unsigned long size, unsigned long align,
unsigned long *addr, unsigned long max)
{
- unsigned long map_size, desc_size;
- efi_memory_desc_t *map;
efi_status_t status;
unsigned long nr_pages;
u64 max_addr = 0;
- int i;
-
- status = efi_get_memory_map(sys_table_arg, &map, &map_size, &desc_size,
- NULL, NULL);
- if (status != EFI_SUCCESS)
- goto fail;
/*
* Enforce minimum alignment that EFI requires when requesting
- * a specific address. We are doing page-based allocations,
+ * a specific address. We are doing page-based allocations,
* so we must be aligned to a page.
*/
if (align < EFI_PAGE_SIZE)
align = EFI_PAGE_SIZE;
- nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
-again:
- for (i = 0; i < map_size / desc_size; i++) {
- efi_memory_desc_t *desc;
- unsigned long m = (unsigned long)map;
- u64 start, end;
-
- desc = (efi_memory_desc_t *)(m + (i * desc_size));
- if (desc->type != EFI_CONVENTIONAL_MEMORY)
- continue;
-
- if (desc->num_pages < nr_pages)
- continue;
-
- start = desc->phys_addr;
- end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
-
- if ((start + size) > end || (start + size) > max)
- continue;
-
- if (end - size > max)
- end = max;
-
- if (round_down(end - size, align) < start)
- continue;
-
- start = round_down(end - size, align);
-
- /*
- * Don't allocate at 0x0. It will confuse code that
- * checks pointers against NULL.
- */
- if (start == 0x0)
- continue;
+ nr_pages = round_up(size, align) / EFI_PAGE_SIZE;
+ max_addr = round_down(round_down((max_addr-size), align) + size, EFI_PAGE_SIZE);
- if (start > max_addr)
- max_addr = start;
- }
+ /*
+ * In case align > EFI_PAGE_SIZE, we need a little more space,
+ * to round_up() later
+ */
+ if (align > EFI_PAGE_SIZE)
+ nr_pages += round_up(align, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
- if (!max_addr)
- status = EFI_NOT_FOUND;
- else {
- status = efi_call_early(allocate_pages,
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
- nr_pages, &max_addr);
- if (status != EFI_SUCCESS) {
- max = max_addr;
- max_addr = 0;
- goto again;
- }
+ status = efi_call_early(allocate_pages,
+ EFI_ALLOCATE_MAX_ADDRESS, EFI_LOADER_DATA,
+ nr_pages, &max_addr);
- *addr = max_addr;
+ if (status == EFI_SUCCESS) {
+ *addr = round_up(max_addr, align);
}
- efi_call_early(free_pool, map);
-fail:
return status;
}
--
2.1.0
next prev parent reply other threads:[~2014-08-25 11:55 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1408715303-2215-1-git-send-email-harald@redhat.com>
2014-08-25 10:34 ` [PATCH] efi_high_alloc: use EFI_ALLOCATE_MAX_ADDRESS Matt Fleming
[not found] ` <20140825103447.GP29733-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2014-08-25 11:10 ` Harald Hoyer
[not found] ` <1408715303-2215-1-git-send-email-harald-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-08-25 11:55 ` harald-H+wXaHxf7aLQT0dZR+AlfA [this message]
[not found] ` <1408967732-2381-1-git-send-email-harald-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2014-08-25 13:07 ` [PATCH V2] " Matt Fleming
[not found] ` <20140825130724.GT29733-HNK1S37rvNbeXh+fF434Mdi2O/JbrIOy@public.gmane.org>
2014-08-25 14:33 ` Harald Hoyer
2014-08-27 10:30 ` Matt Fleming
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=1408967732-2381-1-git-send-email-harald@redhat.com \
--to=harald-h+wxahxf7alqt0dzr+alfa@public.gmane.org \
--cc=linux-efi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.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;
as well as URLs for NNTP newsgroup(s).