Skip to content

Commit

Permalink
x86/kdump: Always reserve the low 1M when the crashkernel option is s…
Browse files Browse the repository at this point in the history
…pecified

On x86, purgatory() copies the first 640K of memory to a backup region
because the kernel needs those first 640K for the real mode trampoline
during boot, among others.

However, when SME is enabled, the kernel cannot properly copy the old
memory to the backup area but reads only its encrypted contents. The
result is that the crash tool gets invalid pointers when parsing vmcore:

  crash> kmem -s|grep -i invalid
  kmem: dma-kmalloc-512: slab:ffffd77680001c00 invalid freepointer:a6086ac099f0c5a4
  kmem: dma-kmalloc-512: slab:ffffd77680001c00 invalid freepointer:a6086ac099f0c5a4
  crash>

So reserve the remaining low 1M memory when the crashkernel option is
specified (after reserving real mode memory) so that allocated memory
does not fall into the low 1M area and thus the copying of the contents
of the first 640k to a backup region in purgatory() can be avoided
altogether.

This way, it does not need to be included in crash dumps or used for
anything except the trampolines that must live in the low 1M.

 [ bp: Heavily rewrite commit message, flip check logic in
   crash_reserve_low_1M().]

Signed-off-by: Lianbo Jiang <[email protected]>
Signed-off-by: Borislav Petkov <[email protected]>
Cc: [email protected]
Cc: Dave Young <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Cc: "H. Peter Anvin" <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Jürgen Gross <[email protected]>
Cc: [email protected]
Cc: Peter Zijlstra <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Tom Lendacky <[email protected]>
Cc: [email protected]
Cc: x86-ml <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]
Link: https://bugzilla.kernel.org/show_bug.cgi?id=204793
  • Loading branch information
lian-bo authored and suryasaimadhu committed Nov 14, 2019
1 parent 112eee5 commit 6f599d8
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 0 deletions.
6 changes: 6 additions & 0 deletions arch/x86/include/asm/crash.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,10 @@ int crash_setup_memmap_entries(struct kimage *image,
struct boot_params *params);
void crash_smp_send_stop(void);

#ifdef CONFIG_KEXEC_CORE
void __init crash_reserve_low_1M(void);
#else
static inline void __init crash_reserve_low_1M(void) { }
#endif

#endif /* _ASM_X86_CRASH_H */
15 changes: 15 additions & 0 deletions arch/x86/kernel/crash.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/memblock.h>

#include <asm/processor.h>
#include <asm/hardirq.h>
Expand All @@ -39,6 +40,7 @@
#include <asm/virtext.h>
#include <asm/intel_pt.h>
#include <asm/crash.h>
#include <asm/cmdline.h>

/* Used while preparing memory map entries for second kernel */
struct crash_memmap_data {
Expand Down Expand Up @@ -68,6 +70,19 @@ static inline void cpu_crash_vmclear_loaded_vmcss(void)
rcu_read_unlock();
}

/*
* When the crashkernel option is specified, only use the low
* 1M for the real mode trampoline.
*/
void __init crash_reserve_low_1M(void)
{
if (cmdline_find_option(boot_command_line, "crashkernel", NULL, 0) < 0)
return;

memblock_reserve(0, 1<<20);
pr_info("Reserving the low 1M of memory for crashkernel\n");
}

#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)

static void kdump_nmi_callback(int cpu, struct pt_regs *regs)
Expand Down
2 changes: 2 additions & 0 deletions arch/x86/realmode/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <asm/pgtable.h>
#include <asm/realmode.h>
#include <asm/tlbflush.h>
#include <asm/crash.h>

struct real_mode_header *real_mode_header;
u32 *trampoline_cr4_features;
Expand All @@ -34,6 +35,7 @@ void __init reserve_real_mode(void)

memblock_reserve(mem, size);
set_real_mode_mem(mem);
crash_reserve_low_1M();
}

static void __init setup_real_mode(void)
Expand Down

0 comments on commit 6f599d8

Please sign in to comment.