summaryrefslogtreecommitdiffstats
path: root/arch/x86/realmode
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@kernel.org>2016-08-10 05:29:16 -0400
committerIngo Molnar <mingo@kernel.org>2016-08-11 05:15:01 -0400
commit5ff3e2c3c3eebe13967d81ad1f23b9468fefea81 (patch)
treeebd7923f9c8eb5d48710b8228577ea20f857c65c /arch/x86/realmode
parentd0de0f685db7faf2ae4597a39a59996dd84e18c7 (diff)
x86/boot: Rework reserve_real_mode() to allow multiple tries
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> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mario Limonciello <mario_limonciello@dell.com> Cc: Matt Fleming <mfleming@suse.de> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/876e383038f3e9971aa72fd20a4f5da05f9d193d.1470821230.git.luto@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/realmode')
-rw-r--r--arch/x86/realmode/init.c29
1 files changed, 21 insertions, 8 deletions
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 @@
1#include <linux/io.h> 1#include <linux/io.h>
2#include <linux/slab.h>
2#include <linux/memblock.h> 3#include <linux/memblock.h>
3 4
4#include <asm/cacheflush.h> 5#include <asm/cacheflush.h>
@@ -12,22 +13,34 @@ u32 *trampoline_cr4_features;
12/* Hold the pgd entry used on booting additional CPUs */ 13/* Hold the pgd entry used on booting additional CPUs */
13pgd_t trampoline_pgd_entry; 14pgd_t trampoline_pgd_entry;
14 15
16void __init set_real_mode_mem(phys_addr_t mem, size_t size)
17{
18 void *base = __va(mem);
19
20 real_mode_header = (struct real_mode_header *) base;
21 printk(KERN_DEBUG "Base memory trampoline at [%p] %llx size %zu\n",
22 base, (unsigned long long)mem, size);
23}
24
15void __init reserve_real_mode(void) 25void __init reserve_real_mode(void)
16{ 26{
17 phys_addr_t mem; 27 phys_addr_t mem;
18 unsigned char *base; 28 size_t size = real_mode_size_needed();
19 size_t size = PAGE_ALIGN(real_mode_blob_end - real_mode_blob); 29
30 if (!size)
31 return;
32
33 WARN_ON(slab_is_available());
20 34
21 /* Has to be under 1M so we can execute real-mode AP code. */ 35 /* Has to be under 1M so we can execute real-mode AP code. */
22 mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE); 36 mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
23 if (!mem) 37 if (!mem) {
24 panic("Cannot allocate trampoline\n"); 38 pr_info("No sub-1M memory is available for the trampoline\n");
39 return;
40 }
25 41
26 base = __va(mem);
27 memblock_reserve(mem, size); 42 memblock_reserve(mem, size);
28 real_mode_header = (struct real_mode_header *) base; 43 set_real_mode_mem(mem, size);
29 printk(KERN_DEBUG "Base memory trampoline at [%p] %llx size %zu\n",
30 base, (unsigned long long)mem, size);
31} 44}
32 45
33static void __init setup_real_mode(void) 46static void __init setup_real_mode(void)