Skip to content

Commit 6f599d8

Browse files
lian-bosuryasaimadhu
authored andcommitted
x86/kdump: Always reserve the low 1M when the crashkernel option is specified
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
1 parent 112eee5 commit 6f599d8

File tree

3 files changed

+23
-0
lines changed

3 files changed

+23
-0
lines changed

arch/x86/include/asm/crash.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,10 @@ int crash_setup_memmap_entries(struct kimage *image,
1010
struct boot_params *params);
1111
void crash_smp_send_stop(void);
1212

13+
#ifdef CONFIG_KEXEC_CORE
14+
void __init crash_reserve_low_1M(void);
15+
#else
16+
static inline void __init crash_reserve_low_1M(void) { }
17+
#endif
18+
1319
#endif /* _ASM_X86_CRASH_H */

arch/x86/kernel/crash.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <linux/export.h>
2525
#include <linux/slab.h>
2626
#include <linux/vmalloc.h>
27+
#include <linux/memblock.h>
2728

2829
#include <asm/processor.h>
2930
#include <asm/hardirq.h>
@@ -39,6 +40,7 @@
3940
#include <asm/virtext.h>
4041
#include <asm/intel_pt.h>
4142
#include <asm/crash.h>
43+
#include <asm/cmdline.h>
4244

4345
/* Used while preparing memory map entries for second kernel */
4446
struct crash_memmap_data {
@@ -68,6 +70,19 @@ static inline void cpu_crash_vmclear_loaded_vmcss(void)
6870
rcu_read_unlock();
6971
}
7072

73+
/*
74+
* When the crashkernel option is specified, only use the low
75+
* 1M for the real mode trampoline.
76+
*/
77+
void __init crash_reserve_low_1M(void)
78+
{
79+
if (cmdline_find_option(boot_command_line, "crashkernel", NULL, 0) < 0)
80+
return;
81+
82+
memblock_reserve(0, 1<<20);
83+
pr_info("Reserving the low 1M of memory for crashkernel\n");
84+
}
85+
7186
#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
7287

7388
static void kdump_nmi_callback(int cpu, struct pt_regs *regs)

arch/x86/realmode/init.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <asm/pgtable.h>
99
#include <asm/realmode.h>
1010
#include <asm/tlbflush.h>
11+
#include <asm/crash.h>
1112

1213
struct real_mode_header *real_mode_header;
1314
u32 *trampoline_cr4_features;
@@ -34,6 +35,7 @@ void __init reserve_real_mode(void)
3435

3536
memblock_reserve(mem, size);
3637
set_real_mode_mem(mem);
38+
crash_reserve_low_1M();
3739
}
3840

3941
static void __init setup_real_mode(void)

0 commit comments

Comments
 (0)