mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
crash: split vmcoreinfo exporting code out from crash_core.c
Now move the relevant codes into separate files:
kernel/crash_reserve.c, include/linux/crash_reserve.h.
And add config item CRASH_RESERVE to control its enabling.
And also update the old ifdeffery of CONFIG_CRASH_CORE, including of
<linux/crash_core.h> and config item dependency on CRASH_CORE
accordingly.
And also do renaming as follows:
- arch/xxx/kernel/{crash_core.c => vmcore_info.c}
because they are only related to vmcoreinfo exporting on x86, arm64,
riscv.
And also Remove config item CRASH_CORE, and rely on CONFIG_KEXEC_CORE to
decide if build in crash_core.c.
[yang.lee@linux.alibaba.com: remove duplicated include in vmcore_info.c]
Link: https://lkml.kernel.org/r/20240126005744.16561-1-yang.lee@linux.alibaba.com
Link: https://lkml.kernel.org/r/20240124051254.67105-3-bhe@redhat.com
Signed-off-by: Baoquan He <bhe@redhat.com>
Signed-off-by: Yang Li <yang.lee@linux.alibaba.com>
Acked-by: Hari Bathini <hbathini@linux.ibm.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Cc: Pingfan Liu <piliu@redhat.com>
Cc: Klara Modin <klarasmodin@gmail.com>
Cc: Michael Kelley <mhklinux@outlook.com>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Cc: Yang Li <yang.lee@linux.alibaba.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
committed by
Andrew Morton
parent
85fcde402d
commit
443cbaf9e2
@@ -26,14 +26,6 @@
|
||||
/* Per cpu memory for storing cpu states in case of system crash. */
|
||||
note_buf_t __percpu *crash_notes;
|
||||
|
||||
/* vmcoreinfo stuff */
|
||||
unsigned char *vmcoreinfo_data;
|
||||
size_t vmcoreinfo_size;
|
||||
u32 *vmcoreinfo_note;
|
||||
|
||||
/* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */
|
||||
static unsigned char *vmcoreinfo_data_safecopy;
|
||||
|
||||
int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map,
|
||||
void **addr, unsigned long *sz)
|
||||
{
|
||||
@@ -195,204 +187,6 @@ int crash_exclude_mem_range(struct crash_mem *mem,
|
||||
return 0;
|
||||
}
|
||||
|
||||
Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
|
||||
void *data, size_t data_len)
|
||||
{
|
||||
struct elf_note *note = (struct elf_note *)buf;
|
||||
|
||||
note->n_namesz = strlen(name) + 1;
|
||||
note->n_descsz = data_len;
|
||||
note->n_type = type;
|
||||
buf += DIV_ROUND_UP(sizeof(*note), sizeof(Elf_Word));
|
||||
memcpy(buf, name, note->n_namesz);
|
||||
buf += DIV_ROUND_UP(note->n_namesz, sizeof(Elf_Word));
|
||||
memcpy(buf, data, data_len);
|
||||
buf += DIV_ROUND_UP(data_len, sizeof(Elf_Word));
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void final_note(Elf_Word *buf)
|
||||
{
|
||||
memset(buf, 0, sizeof(struct elf_note));
|
||||
}
|
||||
|
||||
static void update_vmcoreinfo_note(void)
|
||||
{
|
||||
u32 *buf = vmcoreinfo_note;
|
||||
|
||||
if (!vmcoreinfo_size)
|
||||
return;
|
||||
buf = append_elf_note(buf, VMCOREINFO_NOTE_NAME, 0, vmcoreinfo_data,
|
||||
vmcoreinfo_size);
|
||||
final_note(buf);
|
||||
}
|
||||
|
||||
void crash_update_vmcoreinfo_safecopy(void *ptr)
|
||||
{
|
||||
if (ptr)
|
||||
memcpy(ptr, vmcoreinfo_data, vmcoreinfo_size);
|
||||
|
||||
vmcoreinfo_data_safecopy = ptr;
|
||||
}
|
||||
|
||||
void crash_save_vmcoreinfo(void)
|
||||
{
|
||||
if (!vmcoreinfo_note)
|
||||
return;
|
||||
|
||||
/* Use the safe copy to generate vmcoreinfo note if have */
|
||||
if (vmcoreinfo_data_safecopy)
|
||||
vmcoreinfo_data = vmcoreinfo_data_safecopy;
|
||||
|
||||
vmcoreinfo_append_str("CRASHTIME=%lld\n", ktime_get_real_seconds());
|
||||
update_vmcoreinfo_note();
|
||||
}
|
||||
|
||||
void vmcoreinfo_append_str(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[0x50];
|
||||
size_t r;
|
||||
|
||||
va_start(args, fmt);
|
||||
r = vscnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
r = min(r, (size_t)VMCOREINFO_BYTES - vmcoreinfo_size);
|
||||
|
||||
memcpy(&vmcoreinfo_data[vmcoreinfo_size], buf, r);
|
||||
|
||||
vmcoreinfo_size += r;
|
||||
|
||||
WARN_ONCE(vmcoreinfo_size == VMCOREINFO_BYTES,
|
||||
"vmcoreinfo data exceeds allocated size, truncating");
|
||||
}
|
||||
|
||||
/*
|
||||
* provide an empty default implementation here -- architecture
|
||||
* code may override this
|
||||
*/
|
||||
void __weak arch_crash_save_vmcoreinfo(void)
|
||||
{}
|
||||
|
||||
phys_addr_t __weak paddr_vmcoreinfo_note(void)
|
||||
{
|
||||
return __pa(vmcoreinfo_note);
|
||||
}
|
||||
EXPORT_SYMBOL(paddr_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_BUILD_ID();
|
||||
VMCOREINFO_PAGESIZE(PAGE_SIZE);
|
||||
|
||||
VMCOREINFO_SYMBOL(init_uts_ns);
|
||||
VMCOREINFO_OFFSET(uts_namespace, name);
|
||||
VMCOREINFO_SYMBOL(node_online_map);
|
||||
#ifdef CONFIG_MMU
|
||||
VMCOREINFO_SYMBOL_ARRAY(swapper_pg_dir);
|
||||
#endif
|
||||
VMCOREINFO_SYMBOL(_stext);
|
||||
vmcoreinfo_append_str("NUMBER(VMALLOC_START)=0x%lx\n", (unsigned long) VMALLOC_START);
|
||||
|
||||
#ifndef CONFIG_NUMA
|
||||
VMCOREINFO_SYMBOL(mem_map);
|
||||
VMCOREINFO_SYMBOL(contig_page_data);
|
||||
#endif
|
||||
#ifdef CONFIG_SPARSEMEM
|
||||
VMCOREINFO_SYMBOL_ARRAY(mem_section);
|
||||
VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS);
|
||||
VMCOREINFO_STRUCT_SIZE(mem_section);
|
||||
VMCOREINFO_OFFSET(mem_section, section_mem_map);
|
||||
VMCOREINFO_NUMBER(SECTION_SIZE_BITS);
|
||||
VMCOREINFO_NUMBER(MAX_PHYSMEM_BITS);
|
||||
#endif
|
||||
VMCOREINFO_STRUCT_SIZE(page);
|
||||
VMCOREINFO_STRUCT_SIZE(pglist_data);
|
||||
VMCOREINFO_STRUCT_SIZE(zone);
|
||||
VMCOREINFO_STRUCT_SIZE(free_area);
|
||||
VMCOREINFO_STRUCT_SIZE(list_head);
|
||||
VMCOREINFO_SIZE(nodemask_t);
|
||||
VMCOREINFO_OFFSET(page, flags);
|
||||
VMCOREINFO_OFFSET(page, _refcount);
|
||||
VMCOREINFO_OFFSET(page, mapping);
|
||||
VMCOREINFO_OFFSET(page, lru);
|
||||
VMCOREINFO_OFFSET(page, _mapcount);
|
||||
VMCOREINFO_OFFSET(page, private);
|
||||
VMCOREINFO_OFFSET(page, compound_head);
|
||||
VMCOREINFO_OFFSET(pglist_data, node_zones);
|
||||
VMCOREINFO_OFFSET(pglist_data, nr_zones);
|
||||
#ifdef CONFIG_FLATMEM
|
||||
VMCOREINFO_OFFSET(pglist_data, node_mem_map);
|
||||
#endif
|
||||
VMCOREINFO_OFFSET(pglist_data, node_start_pfn);
|
||||
VMCOREINFO_OFFSET(pglist_data, node_spanned_pages);
|
||||
VMCOREINFO_OFFSET(pglist_data, node_id);
|
||||
VMCOREINFO_OFFSET(zone, free_area);
|
||||
VMCOREINFO_OFFSET(zone, vm_stat);
|
||||
VMCOREINFO_OFFSET(zone, spanned_pages);
|
||||
VMCOREINFO_OFFSET(free_area, free_list);
|
||||
VMCOREINFO_OFFSET(list_head, next);
|
||||
VMCOREINFO_OFFSET(list_head, prev);
|
||||
VMCOREINFO_LENGTH(zone.free_area, NR_PAGE_ORDERS);
|
||||
log_buf_vmcoreinfo_setup();
|
||||
VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES);
|
||||
VMCOREINFO_NUMBER(NR_FREE_PAGES);
|
||||
VMCOREINFO_NUMBER(PG_lru);
|
||||
VMCOREINFO_NUMBER(PG_private);
|
||||
VMCOREINFO_NUMBER(PG_swapcache);
|
||||
VMCOREINFO_NUMBER(PG_swapbacked);
|
||||
VMCOREINFO_NUMBER(PG_slab);
|
||||
#ifdef CONFIG_MEMORY_FAILURE
|
||||
VMCOREINFO_NUMBER(PG_hwpoison);
|
||||
#endif
|
||||
VMCOREINFO_NUMBER(PG_head_mask);
|
||||
#define PAGE_BUDDY_MAPCOUNT_VALUE (~PG_buddy)
|
||||
VMCOREINFO_NUMBER(PAGE_BUDDY_MAPCOUNT_VALUE);
|
||||
#ifdef CONFIG_HUGETLB_PAGE
|
||||
VMCOREINFO_NUMBER(PG_hugetlb);
|
||||
#define PAGE_OFFLINE_MAPCOUNT_VALUE (~PG_offline)
|
||||
VMCOREINFO_NUMBER(PAGE_OFFLINE_MAPCOUNT_VALUE);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KALLSYMS
|
||||
VMCOREINFO_SYMBOL(kallsyms_names);
|
||||
VMCOREINFO_SYMBOL(kallsyms_num_syms);
|
||||
VMCOREINFO_SYMBOL(kallsyms_token_table);
|
||||
VMCOREINFO_SYMBOL(kallsyms_token_index);
|
||||
#ifdef CONFIG_KALLSYMS_BASE_RELATIVE
|
||||
VMCOREINFO_SYMBOL(kallsyms_offsets);
|
||||
VMCOREINFO_SYMBOL(kallsyms_relative_base);
|
||||
#else
|
||||
VMCOREINFO_SYMBOL(kallsyms_addresses);
|
||||
#endif /* CONFIG_KALLSYMS_BASE_RELATIVE */
|
||||
#endif /* CONFIG_KALLSYMS */
|
||||
|
||||
arch_crash_save_vmcoreinfo();
|
||||
update_vmcoreinfo_note();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
subsys_initcall(crash_save_vmcoreinfo_init);
|
||||
|
||||
static int __init crash_notes_memory_init(void)
|
||||
{
|
||||
/* Allocate memory for saving cpu registers. */
|
||||
|
||||
Reference in New Issue
Block a user