Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1450962 > unrolled thread
| Started by | Andy Lutomirski <luto@kernel.org> |
|---|---|
| First post | 2016-07-27 01:00 +0200 |
| Last post | 2016-08-04 11:30 +0200 |
| Articles | 7 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH 4.8? 0/4] Allow the trampoline to use EFI boot services RAM Andy Lutomirski <luto@kernel.org> - 2016-07-27 01:00 +0200
[PATCH 4/4] x86/efi: Allocate a trampoline if needed in efi_free_boot_services() Andy Lutomirski <luto@kernel.org> - 2016-07-27 01:00 +0200
Re: [PATCH 4/4] x86/efi: Allocate a trampoline if needed in efi_free_boot_services() "H. Peter Anvin" <hpa@zytor.com> - 2016-08-01 07:10 +0200
Re: [PATCH 4/4] x86/efi: Allocate a trampoline if needed in efi_free_boot_services() Andy Lutomirski <luto@amacapital.net> - 2016-08-02 20:30 +0200
[PATCH 3/4] x86/boot: Rework reserve_real_mode() to allow multiple tries Andy Lutomirski <luto@kernel.org> - 2016-07-27 01:00 +0200
Re: [PATCH 4.8? 0/4] Allow the trampoline to use EFI boot services RAM Matt Fleming <matt@codeblueprint.co.uk> - 2016-07-31 23:40 +0200
Re: [PATCH 4.8? 0/4] Allow the trampoline to use EFI boot services RAM Matt Fleming <matt@codeblueprint.co.uk> - 2016-08-04 11:30 +0200
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2016-07-27 01:00 +0200 |
| Subject | [PATCH 4.8? 0/4] Allow the trampoline to use EFI boot services RAM |
| Message-ID | <rZjup-84c-3@gated-at.bofh.it> |
As currently configured, my laptop cannot boot any existing kernel
because the real mode trampoline can't be reserved. The ranges in
which it could live are rejected by the kernel: one is EFI boot
services data and the other is above the EBDA.
Allowing use of RAM between the EBDA and 640k is scary: there are
probably many quirky BIOSes out there, and, as currently structured,
it would be awkward to allow it just on EFI boots because we
currently reserve that range before we figure out whether we're
using EFI.
This series fixes it the other way: it allow the trampoline to live
in boot services memory. It achieves this by deferring the panic
due to failure to reserve a trampoline until early_initcall time
and then adjusting the EFI boot services quirk to reserve space
for the trampoline if we haven't already found it a home.
I'm hoping this is okay for 4.8 even though it's late: it fixes
a boot failure and it's fairly conservative -- the only significant
changes in behavior should be on systems that currently fail to boot.
I'm not currently proposing it for stable because AFAIK I'm the
only person to have seen this issue. If it survives in Linus'
tree for a while, though, I might propose it for -stable later
on.
Andy Lutomirski (4):
x86/boot: Synchronize trampoline_cr4_features and mmu_cr4_features
directly
x86/boot: Defer setup_real_mode() to early_initcall time
x86/boot: Rework reserve_real_mode() to allow multiple tries
x86/efi: Allocate a trampoline if needed in efi_free_boot_services()
arch/x86/include/asm/realmode.h | 10 ++++++++-
arch/x86/kernel/setup.c | 17 ++++++++-------
arch/x86/platform/efi/quirks.c | 21 ++++++++++++++++++
arch/x86/realmode/init.c | 47 ++++++++++++++++++++++++++++++-----------
4 files changed, 74 insertions(+), 21 deletions(-)
--
2.7.4
[toc] | [next] | [standalone]
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2016-07-27 01:00 +0200 |
| Subject | [PATCH 4/4] x86/efi: Allocate a trampoline if needed in efi_free_boot_services() |
| Message-ID | <rZjup-84c-15@gated-at.bofh.it> |
| In reply to | #1450962 |
On my Dell XPS 13 9350 with firmware 1.4.4 and SGX on, if I boot
Fedora 24's grub2-efi off a hard disk, my first 1MB of RAM looks
like:
efi: mem00: [Runtime Data |RUN| | | | | | | |WB|WT|WC|UC] range=[0x0000000000000000-0x0000000000000fff] (0MB)
efi: mem01: [Boot Data | | | | | | | | |WB|WT|WC|UC] range=[0x0000000000001000-0x0000000000027fff] (0MB)
efi: mem02: [Loader Data | | | | | | | | |WB|WT|WC|UC] range=[0x0000000000028000-0x0000000000029fff] (0MB)
efi: mem03: [Reserved | | | | | | | | |WB|WT|WC|UC] range=[0x000000000002a000-0x000000000002bfff] (0MB)
efi: mem04: [Runtime Data |RUN| | | | | | | |WB|WT|WC|UC] range=[0x000000000002c000-0x000000000002cfff] (0MB)
efi: mem05: [Loader Data | | | | | | | | |WB|WT|WC|UC] range=[0x000000000002d000-0x000000000002dfff] (0MB)
efi: mem06: [Conventional Memory| | | | | | | | |WB|WT|WC|UC] range=[0x000000000002e000-0x0000000000057fff] (0MB)
efi: mem07: [Reserved | | | | | | | | |WB|WT|WC|UC] range=[0x0000000000058000-0x0000000000058fff] (0MB)
efi: mem08: [Conventional Memory| | | | | | | | |WB|WT|WC|UC] range=[0x0000000000059000-0x000000000009ffff] (0MB)
My EBDA is at 0x2c000, which blocks off everything from 0x2c000 and
up, and my trampoline is 0x6000 bytes (6 pages), so it doesn't fit
in the loader data range at 0x28000.
Without this patch, it panics due to a failure to allocate the
trampoline. With this patch, it works:
[ +0.001744] Base memory trampoline at [ffff880000001000] 1000 size 24576
Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
arch/x86/platform/efi/quirks.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index 4480c06cade7..b9c0eee649ef 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -254,6 +254,7 @@ void __init efi_free_boot_services(void)
for_each_efi_memory_desc(md) {
unsigned long long start = md->phys_addr;
unsigned long long size = md->num_pages << EFI_PAGE_SHIFT;
+ size_t rm_size;
if (md->type != EFI_BOOT_SERVICES_CODE &&
md->type != EFI_BOOT_SERVICES_DATA)
@@ -263,6 +264,26 @@ void __init efi_free_boot_services(void)
if (md->attribute & EFI_MEMORY_RUNTIME)
continue;
+ /*
+ * Nasty quirk: if all sub-1MB memory is used for boot
+ * services, we can get here without having allocated the
+ * real mode trampoline. It's too late to hand boot services
+ * memory back to the memblock allocator, so instead
+ * try to reclaim a single page if needed.
+ *
+ * I've seen this on a Dell XPS 13 9350 with firmware
+ * 1.4.4 with SGX enabled booting Linux via Fedora 24's
+ * grub2-efi on a hard disk. (And no, I don't know why
+ * this happened, but Linux should still try to boot rather
+ * panicing early.)
+ */
+ rm_size = real_mode_size_needed();
+ if (rm_size && (start + rm_size) < (1<<20) && size >= rm_size) {
+ set_real_mode_mem(start, rm_size);
+ start += rm_size;
+ size -= rm_size;
+ }
+
free_bootmem_late(start, size);
}
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | "H. Peter Anvin" <hpa@zytor.com> |
|---|---|
| Date | 2016-08-01 07:10 +0200 |
| Subject | Re: [PATCH 4/4] x86/efi: Allocate a trampoline if needed in efi_free_boot_services() |
| Message-ID | <s1dEd-1XU-5@gated-at.bofh.it> |
| In reply to | #1450963 |
On 07/26/16 15:55, Andy Lutomirski wrote: > + /* > + * Nasty quirk: if all sub-1MB memory is used for boot > + * services, we can get here without having allocated the > + * real mode trampoline. It's too late to hand boot services > + * memory back to the memblock allocator, so instead > + * try to reclaim a single page if needed. > + * This comment makes no sense. Nowhere is there a dependency on a single page, and this refers to allocation, not reclaim... -hpa
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@amacapital.net> |
|---|---|
| Date | 2016-08-02 20:30 +0200 |
| Subject | Re: [PATCH 4/4] x86/efi: Allocate a trampoline if needed in efi_free_boot_services() |
| Message-ID | <s1MBY-8c3-47@gated-at.bofh.it> |
| In reply to | #1452989 |
On Sun, Jul 31, 2016 at 10:07 PM, H. Peter Anvin <hpa@zytor.com> wrote: > On 07/26/16 15:55, Andy Lutomirski wrote: >> + /* >> + * Nasty quirk: if all sub-1MB memory is used for boot >> + * services, we can get here without having allocated the >> + * real mode trampoline. It's too late to hand boot services >> + * memory back to the memblock allocator, so instead >> + * try to reclaim a single page if needed. >> + * > > This comment makes no sense. Nowhere is there a dependency on a single > page, and this refers to allocation, not reclaim... I wrote that while I had the misapprehension that it was a page and I forgot to fix it. How about: Nasty quirk: if all sub-1MB memory is used for boot services, we can get here without having allocated the real mode trampoline. It's too late to hand boot services memory back to the memblock allocator, so instead try to manually allocate the trampoline if needed.
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2016-07-27 01:00 +0200 |
| Subject | [PATCH 3/4] x86/boot: Rework reserve_real_mode() to allow multiple tries |
| Message-ID | <rZjup-84c-11@gated-at.bofh.it> |
| In reply to | #1450962 |
If reserve_real_mode() fails, panicing immediately means we're
doomed. Make it safe to try more than once to allocate the
trampoline:
- Degrade a failure from panic() to pr_info(). (If we make it to
setup_real_mode() without reserving the trampoline, we'll panic
them.)
- Factor out helpers so that platform code can supply a specific
address to try.
- Warn if reserve_real_mode() is called after we're done with the
memblock allocator. If that were to happen, we would behave
unpredictably.
Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
arch/x86/include/asm/realmode.h | 9 +++++++++
arch/x86/realmode/init.c | 29 +++++++++++++++++++++--------
2 files changed, 30 insertions(+), 8 deletions(-)
diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h
index 8d6777724ba4..b2988c0ed829 100644
--- a/arch/x86/include/asm/realmode.h
+++ b/arch/x86/include/asm/realmode.h
@@ -58,6 +58,15 @@ extern unsigned char boot_gdt[];
extern unsigned char secondary_startup_64[];
#endif
+static inline size_t real_mode_size_needed(void)
+{
+ if (real_mode_header)
+ return 0; /* already allocated. */
+
+ return ALIGN(real_mode_blob_end - real_mode_blob, PAGE_SIZE);
+}
+
+void set_real_mode_mem(phys_addr_t mem, size_t size);
void reserve_real_mode(void);
#endif /* _ARCH_X86_REALMODE_H */
diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c
index 747b71e8f547..5db706f14111 100644
--- a/arch/x86/realmode/init.c
+++ b/arch/x86/realmode/init.c
@@ -1,4 +1,5 @@
#include <linux/io.h>
+#include <linux/slab.h>
#include <linux/memblock.h>
#include <asm/cacheflush.h>
@@ -12,22 +13,34 @@ u32 *trampoline_cr4_features;
/* Hold the pgd entry used on booting additional CPUs */
pgd_t trampoline_pgd_entry;
+void __init set_real_mode_mem(phys_addr_t mem, size_t size)
+{
+ void *base = __va(mem);
+
+ real_mode_header = (struct real_mode_header *) base;
+ printk(KERN_DEBUG "Base memory trampoline at [%p] %llx size %zu\n",
+ base, (unsigned long long)mem, size);
+}
+
void __init reserve_real_mode(void)
{
phys_addr_t mem;
- unsigned char *base;
- size_t size = PAGE_ALIGN(real_mode_blob_end - real_mode_blob);
+ size_t size = real_mode_size_needed();
+
+ if (!size)
+ return;
+
+ WARN_ON(slab_is_available());
/* Has to be under 1M so we can execute real-mode AP code. */
mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
- if (!mem)
- panic("Cannot allocate trampoline\n");
+ if (!mem) {
+ pr_info("No sub-1M memory is available for the trampoline\n");
+ return;
+ }
- base = __va(mem);
memblock_reserve(mem, size);
- real_mode_header = (struct real_mode_header *) base;
- printk(KERN_DEBUG "Base memory trampoline at [%p] %llx size %zu\n",
- base, (unsigned long long)mem, size);
+ set_real_mode_mem(mem, size);
}
static void __init setup_real_mode(void)
--
2.7.4
[toc] | [prev] | [next] | [standalone]
| From | Matt Fleming <matt@codeblueprint.co.uk> |
|---|---|
| Date | 2016-07-31 23:40 +0200 |
| Subject | Re: [PATCH 4.8? 0/4] Allow the trampoline to use EFI boot services RAM |
| Message-ID | <s16CJ-5vO-13@gated-at.bofh.it> |
| In reply to | #1450962 |
On Tue, 26 Jul, at 03:55:24PM, Andy Lutomirski wrote: > As currently configured, my laptop cannot boot any existing kernel > because the real mode trampoline can't be reserved. The ranges in > which it could live are rejected by the kernel: one is EFI boot > services data and the other is above the EBDA. > > Allowing use of RAM between the EBDA and 640k is scary: there are > probably many quirky BIOSes out there, and, as currently structured, > it would be awkward to allow it just on EFI boots because we > currently reserve that range before we figure out whether we're > using EFI. > > This series fixes it the other way: it allow the trampoline to live > in boot services memory. It achieves this by deferring the panic > due to failure to reserve a trampoline until early_initcall time > and then adjusting the EFI boot services quirk to reserve space > for the trampoline if we haven't already found it a home. > > I'm hoping this is okay for 4.8 even though it's late: it fixes > a boot failure and it's fairly conservative -- the only significant > changes in behavior should be on systems that currently fail to boot. > > I'm not currently proposing it for stable because AFAIK I'm the > only person to have seen this issue. If it survives in Linus' > tree for a while, though, I might propose it for -stable later > on. I took a very, very quick look over this series and nothing jumped out as being wrong. I'll take a much closer look this week.
[toc] | [prev] | [next] | [standalone]
| From | Matt Fleming <matt@codeblueprint.co.uk> |
|---|---|
| Date | 2016-08-04 11:30 +0200 |
| Subject | Re: [PATCH 4.8? 0/4] Allow the trampoline to use EFI boot services RAM |
| Message-ID | <s2n8u-6ZA-31@gated-at.bofh.it> |
| In reply to | #1452897 |
On Sun, 31 Jul, at 10:38:17PM, Matt Fleming wrote: > > I took a very, very quick look over this series and nothing jumped out > as being wrong. I'll take a much closer look this week. FWIW, this all looks fine to me and passes my EFI boot tests.
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web