Skip to content

Commit

Permalink
kexec: move vmcoreinfo out of the kernel's .bss section
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Xunlei Pang authored and torvalds committed Jul 12, 2017
1 parent 112166f commit 203e9e4
Show file tree
Hide file tree
Showing 8 changed files with 29 additions and 21 deletions.
5 changes: 0 additions & 5 deletions arch/ia64/kernel/machine_kexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,3 @@ void arch_crash_save_vmcoreinfo(void)
#endif
}

phys_addr_t paddr_vmcoreinfo_note(void)
{
return ia64_tpa((unsigned long)(char *)&vmcoreinfo_note);
}

1 change: 1 addition & 0 deletions arch/s390/kernel/machine_kexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ void arch_crash_save_vmcoreinfo(void)
VMCOREINFO_SYMBOL(lowcore_ptr);
VMCOREINFO_SYMBOL(high_memory);
VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS);
mem_assign_absolute(S390_lowcore.vmcore_info, paddr_vmcoreinfo_note());
}

void machine_shutdown(void)
Expand Down
6 changes: 0 additions & 6 deletions arch/s390/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,11 +496,6 @@ static void __init setup_memory_end(void)
pr_notice("The maximum memory size is %luMB\n", memory_end >> 20);
}

static void __init setup_vmcoreinfo(void)
{
mem_assign_absolute(S390_lowcore.vmcore_info, paddr_vmcoreinfo_note());
}

#ifdef CONFIG_CRASH_DUMP

/*
Expand Down Expand Up @@ -939,7 +934,6 @@ void __init setup_arch(char **cmdline_p)
#endif

setup_resources();
setup_vmcoreinfo();
setup_lowcore();
smp_fill_possible_mask();
cpu_detect_mhz_feature();
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/crash.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ static int prepare_elf64_headers(struct crash_elf_data *ced,
bufp += sizeof(Elf64_Phdr);
phdr->p_type = PT_NOTE;
phdr->p_offset = phdr->p_paddr = paddr_vmcoreinfo_note();
phdr->p_filesz = phdr->p_memsz = sizeof(vmcoreinfo_note);
phdr->p_filesz = phdr->p_memsz = VMCOREINFO_NOTE_SIZE;
(ehdr->e_phnum)++;

#ifdef CONFIG_X86_64
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/xen/mmu_pv.c
Original file line number Diff line number Diff line change
Expand Up @@ -2693,8 +2693,8 @@ EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region);
phys_addr_t paddr_vmcoreinfo_note(void)
{
if (xen_pv_domain())
return virt_to_machine(&vmcoreinfo_note).maddr;
return virt_to_machine(vmcoreinfo_note).maddr;
else
return __pa_symbol(&vmcoreinfo_note);
return __pa(vmcoreinfo_note);
}
#endif /* CONFIG_KEXEC_CORE */
4 changes: 2 additions & 2 deletions include/linux/crash_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
CRASH_CORE_NOTE_NAME_BYTES + \
CRASH_CORE_NOTE_DESC_BYTES)

#define VMCOREINFO_BYTES (4096)
#define VMCOREINFO_BYTES PAGE_SIZE
#define VMCOREINFO_NOTE_NAME "VMCOREINFO"
#define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4)
#define VMCOREINFO_NOTE_SIZE ((CRASH_CORE_NOTE_HEAD_BYTES * 2) + \
Expand Down Expand Up @@ -56,7 +56,7 @@ phys_addr_t paddr_vmcoreinfo_note(void);
#define VMCOREINFO_CONFIG(name) \
vmcoreinfo_append_str("CONFIG_%s=y\n", #name)

extern u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
extern u32 *vmcoreinfo_note;
extern size_t vmcoreinfo_size;
extern size_t vmcoreinfo_max_size;

Expand Down
26 changes: 22 additions & 4 deletions kernel/crash_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
#include <asm/sections.h>

/* vmcoreinfo stuff */
static unsigned char vmcoreinfo_data[VMCOREINFO_BYTES];
u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4];
static unsigned char *vmcoreinfo_data;
size_t vmcoreinfo_size;
size_t vmcoreinfo_max_size = sizeof(vmcoreinfo_data);
size_t vmcoreinfo_max_size = VMCOREINFO_BYTES;
u32 *vmcoreinfo_note;

/*
* parsing the "crashkernel" commandline
Expand Down Expand Up @@ -326,6 +326,9 @@ static void update_vmcoreinfo_note(void)

void crash_save_vmcoreinfo(void)
{
if (!vmcoreinfo_note)
return;

vmcoreinfo_append_str("CRASHTIME=%ld\n", get_seconds());
update_vmcoreinfo_note();
}
Expand Down Expand Up @@ -356,11 +359,26 @@ void __weak arch_crash_save_vmcoreinfo(void)

phys_addr_t __weak paddr_vmcoreinfo_note(void)
{
return __pa_symbol((unsigned long)(char *)&vmcoreinfo_note);
return __pa(vmcoreinfo_note);
}

static int __init crash_save_vmcoreinfo_init(void)
{
vmcoreinfo_data = (unsigned char *)get_zeroed_page(GFP_KERNEL);
if (!vmcoreinfo_data) {
pr_warn("Memory allocation for vmcoreinfo_data failed\n");
return -ENOMEM;
}

vmcoreinfo_note = alloc_pages_exact(VMCOREINFO_NOTE_SIZE,
GFP_KERNEL | __GFP_ZERO);
if (!vmcoreinfo_note) {
free_page((unsigned long)vmcoreinfo_data);
vmcoreinfo_data = NULL;
pr_warn("Memory allocation for vmcoreinfo_note failed\n");
return -ENOMEM;
}

VMCOREINFO_OSRELEASE(init_uts_ns.name.release);
VMCOREINFO_PAGESIZE(PAGE_SIZE);

Expand Down
2 changes: 1 addition & 1 deletion kernel/ksysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ static ssize_t vmcoreinfo_show(struct kobject *kobj,
{
phys_addr_t vmcore_base = paddr_vmcoreinfo_note();
return sprintf(buf, "%pa %x\n", &vmcore_base,
(unsigned int)sizeof(vmcoreinfo_note));
(unsigned int)VMCOREINFO_NOTE_SIZE);
}
KERNEL_ATTR_RO(vmcoreinfo);

Expand Down

0 comments on commit 203e9e4

Please sign in to comment.