Skip to content

Commit 203e9e4

Browse files
Xunlei Pangtorvalds
authored andcommitted
kexec: move vmcoreinfo out of the kernel's .bss section
As Eric said, "what we need to do is move the variable vmcoreinfo_note out of the kernel's .bss section. And modify the code to regenerate and keep this information in something like the control page. Definitely something like this needs a page all to itself, and ideally far away from any other kernel data structures. I clearly was not watching closely the data someone decided to keep this silly thing in the kernel's .bss section." This patch allocates extra pages for these vmcoreinfo_XXX variables, one advantage is that it enhances some safety of vmcoreinfo, because vmcoreinfo now is kept far away from other kernel data structures. Link: http://lkml.kernel.org/r/1493281021-20737-1-git-send-email-xlpang@redhat.com Signed-off-by: Xunlei Pang <xlpang@redhat.com> Tested-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> Reviewed-by: Juergen Gross <jgross@suse.com> Suggested-by: Eric Biederman <ebiederm@xmission.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Dave Young <dyoung@redhat.com> Cc: Hari Bathini <hbathini@linux.vnet.ibm.com> Cc: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 112166f commit 203e9e4

8 files changed

Lines changed: 29 additions & 21 deletions

File tree

arch/ia64/kernel/machine_kexec.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,3 @@ void arch_crash_save_vmcoreinfo(void)
163163
#endif
164164
}
165165

166-
phys_addr_t paddr_vmcoreinfo_note(void)
167-
{
168-
return ia64_tpa((unsigned long)(char *)&vmcoreinfo_note);
169-
}
170-

arch/s390/kernel/machine_kexec.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ void arch_crash_save_vmcoreinfo(void)
246246
VMCOREINFO_SYMBOL(lowcore_ptr);
247247
VMCOREINFO_SYMBOL(high_memory);
248248
VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS);
249+
mem_assign_absolute(S390_lowcore.vmcore_info, paddr_vmcoreinfo_note());
249250
}
250251

251252
void machine_shutdown(void)

arch/s390/kernel/setup.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -496,11 +496,6 @@ static void __init setup_memory_end(void)
496496
pr_notice("The maximum memory size is %luMB\n", memory_end >> 20);
497497
}
498498

499-
static void __init setup_vmcoreinfo(void)
500-
{
501-
mem_assign_absolute(S390_lowcore.vmcore_info, paddr_vmcoreinfo_note());
502-
}
503-
504499
#ifdef CONFIG_CRASH_DUMP
505500

506501
/*
@@ -939,7 +934,6 @@ void __init setup_arch(char **cmdline_p)
939934
#endif
940935

941936
setup_resources();
942-
setup_vmcoreinfo();
943937
setup_lowcore();
944938
smp_fill_possible_mask();
945939
cpu_detect_mhz_feature();

arch/x86/kernel/crash.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ static int prepare_elf64_headers(struct crash_elf_data *ced,
457457
bufp += sizeof(Elf64_Phdr);
458458
phdr->p_type = PT_NOTE;
459459
phdr->p_offset = phdr->p_paddr = paddr_vmcoreinfo_note();
460-
phdr->p_filesz = phdr->p_memsz = sizeof(vmcoreinfo_note);
460+
phdr->p_filesz = phdr->p_memsz = VMCOREINFO_NOTE_SIZE;
461461
(ehdr->e_phnum)++;
462462

463463
#ifdef CONFIG_X86_64

arch/x86/xen/mmu_pv.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2693,8 +2693,8 @@ EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region);
26932693
phys_addr_t paddr_vmcoreinfo_note(void)
26942694
{
26952695
if (xen_pv_domain())
2696-
return virt_to_machine(&vmcoreinfo_note).maddr;
2696+
return virt_to_machine(vmcoreinfo_note).maddr;
26972697
else
2698-
return __pa_symbol(&vmcoreinfo_note);
2698+
return __pa(vmcoreinfo_note);
26992699
}
27002700
#endif /* CONFIG_KEXEC_CORE */

include/linux/crash_core.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
CRASH_CORE_NOTE_NAME_BYTES + \
2020
CRASH_CORE_NOTE_DESC_BYTES)
2121

22-
#define VMCOREINFO_BYTES (4096)
22+
#define VMCOREINFO_BYTES PAGE_SIZE
2323
#define VMCOREINFO_NOTE_NAME "VMCOREINFO"
2424
#define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4)
2525
#define VMCOREINFO_NOTE_SIZE ((CRASH_CORE_NOTE_HEAD_BYTES * 2) + \
@@ -56,7 +56,7 @@ phys_addr_t paddr_vmcoreinfo_note(void);
5656
#define VMCOREINFO_CONFIG(name) \
5757
vmcoreinfo_append_str("CONFIG_%s=y\n", #name)
5858

59-
extern u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
59+
extern u32 *vmcoreinfo_note;
6060
extern size_t vmcoreinfo_size;
6161
extern size_t vmcoreinfo_max_size;
6262

kernel/crash_core.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
#include <asm/sections.h>
1515

1616
/* vmcoreinfo stuff */
17-
static unsigned char vmcoreinfo_data[VMCOREINFO_BYTES];
18-
u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
17+
static unsigned char *vmcoreinfo_data;
1918
size_t vmcoreinfo_size;
20-
size_t vmcoreinfo_max_size = sizeof(vmcoreinfo_data);
19+
size_t vmcoreinfo_max_size = VMCOREINFO_BYTES;
20+
u32 *vmcoreinfo_note;
2121

2222
/*
2323
* parsing the "crashkernel" commandline
@@ -326,6 +326,9 @@ static void update_vmcoreinfo_note(void)
326326

327327
void crash_save_vmcoreinfo(void)
328328
{
329+
if (!vmcoreinfo_note)
330+
return;
331+
329332
vmcoreinfo_append_str("CRASHTIME=%ld\n", get_seconds());
330333
update_vmcoreinfo_note();
331334
}
@@ -356,11 +359,26 @@ void __weak arch_crash_save_vmcoreinfo(void)
356359

357360
phys_addr_t __weak paddr_vmcoreinfo_note(void)
358361
{
359-
return __pa_symbol((unsigned long)(char *)&vmcoreinfo_note);
362+
return __pa(vmcoreinfo_note);
360363
}
361364

362365
static int __init crash_save_vmcoreinfo_init(void)
363366
{
367+
vmcoreinfo_data = (unsigned char *)get_zeroed_page(GFP_KERNEL);
368+
if (!vmcoreinfo_data) {
369+
pr_warn("Memory allocation for vmcoreinfo_data failed\n");
370+
return -ENOMEM;
371+
}
372+
373+
vmcoreinfo_note = alloc_pages_exact(VMCOREINFO_NOTE_SIZE,
374+
GFP_KERNEL | __GFP_ZERO);
375+
if (!vmcoreinfo_note) {
376+
free_page((unsigned long)vmcoreinfo_data);
377+
vmcoreinfo_data = NULL;
378+
pr_warn("Memory allocation for vmcoreinfo_note failed\n");
379+
return -ENOMEM;
380+
}
381+
364382
VMCOREINFO_OSRELEASE(init_uts_ns.name.release);
365383
VMCOREINFO_PAGESIZE(PAGE_SIZE);
366384

kernel/ksysfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ static ssize_t vmcoreinfo_show(struct kobject *kobj,
134134
{
135135
phys_addr_t vmcore_base = paddr_vmcoreinfo_note();
136136
return sprintf(buf, "%pa %x\n", &vmcore_base,
137-
(unsigned int)sizeof(vmcoreinfo_note));
137+
(unsigned int)VMCOREINFO_NOTE_SIZE);
138138
}
139139
KERNEL_ATTR_RO(vmcoreinfo);
140140

0 commit comments

Comments
 (0)