1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef LINUX_CRASH_CORE_H |
3 | #define LINUX_CRASH_CORE_H |
4 | |
5 | #include <linux/linkage.h> |
6 | #include <linux/elfcore.h> |
7 | #include <linux/elf.h> |
8 | #ifdef CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION |
9 | #include <asm/crash_core.h> |
10 | #endif |
11 | |
12 | /* Location of a reserved region to hold the crash kernel. |
13 | */ |
14 | extern struct resource crashk_res; |
15 | extern struct resource crashk_low_res; |
16 | |
17 | #define CRASH_CORE_NOTE_NAME "CORE" |
18 | #define CRASH_CORE_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4) |
19 | #define CRASH_CORE_NOTE_NAME_BYTES ALIGN(sizeof(CRASH_CORE_NOTE_NAME), 4) |
20 | #define CRASH_CORE_NOTE_DESC_BYTES ALIGN(sizeof(struct elf_prstatus), 4) |
21 | |
22 | /* |
23 | * The per-cpu notes area is a list of notes terminated by a "NULL" |
24 | * note header. For kdump, the code in vmcore.c runs in the context |
25 | * of the second kernel to combine them into one note. |
26 | */ |
27 | #define CRASH_CORE_NOTE_BYTES ((CRASH_CORE_NOTE_HEAD_BYTES * 2) + \ |
28 | CRASH_CORE_NOTE_NAME_BYTES + \ |
29 | CRASH_CORE_NOTE_DESC_BYTES) |
30 | |
31 | #define VMCOREINFO_BYTES PAGE_SIZE |
32 | #define VMCOREINFO_NOTE_NAME "VMCOREINFO" |
33 | #define VMCOREINFO_NOTE_NAME_BYTES ALIGN(sizeof(VMCOREINFO_NOTE_NAME), 4) |
34 | #define VMCOREINFO_NOTE_SIZE ((CRASH_CORE_NOTE_HEAD_BYTES * 2) + \ |
35 | VMCOREINFO_NOTE_NAME_BYTES + \ |
36 | VMCOREINFO_BYTES) |
37 | |
38 | typedef u32 note_buf_t[CRASH_CORE_NOTE_BYTES/4]; |
39 | /* Per cpu memory for storing cpu states in case of system crash. */ |
40 | extern note_buf_t __percpu *crash_notes; |
41 | |
42 | void crash_update_vmcoreinfo_safecopy(void *ptr); |
43 | void crash_save_vmcoreinfo(void); |
44 | void arch_crash_save_vmcoreinfo(void); |
45 | __printf(1, 2) |
46 | void vmcoreinfo_append_str(const char *fmt, ...); |
47 | phys_addr_t paddr_vmcoreinfo_note(void); |
48 | |
49 | #define VMCOREINFO_OSRELEASE(value) \ |
50 | vmcoreinfo_append_str("OSRELEASE=%s\n", value) |
51 | #define VMCOREINFO_BUILD_ID() \ |
52 | ({ \ |
53 | static_assert(sizeof(vmlinux_build_id) == 20); \ |
54 | vmcoreinfo_append_str("BUILD-ID=%20phN\n", vmlinux_build_id); \ |
55 | }) |
56 | |
57 | #define VMCOREINFO_PAGESIZE(value) \ |
58 | vmcoreinfo_append_str("PAGESIZE=%ld\n", value) |
59 | #define VMCOREINFO_SYMBOL(name) \ |
60 | vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)&name) |
61 | #define VMCOREINFO_SYMBOL_ARRAY(name) \ |
62 | vmcoreinfo_append_str("SYMBOL(%s)=%lx\n", #name, (unsigned long)name) |
63 | #define VMCOREINFO_SIZE(name) \ |
64 | vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \ |
65 | (unsigned long)sizeof(name)) |
66 | #define VMCOREINFO_STRUCT_SIZE(name) \ |
67 | vmcoreinfo_append_str("SIZE(%s)=%lu\n", #name, \ |
68 | (unsigned long)sizeof(struct name)) |
69 | #define VMCOREINFO_OFFSET(name, field) \ |
70 | vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \ |
71 | (unsigned long)offsetof(struct name, field)) |
72 | #define VMCOREINFO_TYPE_OFFSET(name, field) \ |
73 | vmcoreinfo_append_str("OFFSET(%s.%s)=%lu\n", #name, #field, \ |
74 | (unsigned long)offsetof(name, field)) |
75 | #define VMCOREINFO_LENGTH(name, value) \ |
76 | vmcoreinfo_append_str("LENGTH(%s)=%lu\n", #name, (unsigned long)value) |
77 | #define VMCOREINFO_NUMBER(name) \ |
78 | vmcoreinfo_append_str("NUMBER(%s)=%ld\n", #name, (long)name) |
79 | #define VMCOREINFO_CONFIG(name) \ |
80 | vmcoreinfo_append_str("CONFIG_%s=y\n", #name) |
81 | |
82 | extern unsigned char *vmcoreinfo_data; |
83 | extern size_t vmcoreinfo_size; |
84 | extern u32 *vmcoreinfo_note; |
85 | |
86 | Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type, |
87 | void *data, size_t data_len); |
88 | void final_note(Elf_Word *buf); |
89 | |
90 | #ifdef CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION |
91 | #ifndef DEFAULT_CRASH_KERNEL_LOW_SIZE |
92 | #define DEFAULT_CRASH_KERNEL_LOW_SIZE (128UL << 20) |
93 | #endif |
94 | #endif |
95 | |
96 | int __init parse_crashkernel(char *cmdline, unsigned long long system_ram, |
97 | unsigned long long *crash_size, unsigned long long *crash_base, |
98 | unsigned long long *low_size, bool *high); |
99 | |
100 | #ifdef CONFIG_ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION |
101 | #ifndef DEFAULT_CRASH_KERNEL_LOW_SIZE |
102 | #define DEFAULT_CRASH_KERNEL_LOW_SIZE (128UL << 20) |
103 | #endif |
104 | #ifndef CRASH_ALIGN |
105 | #define CRASH_ALIGN SZ_2M |
106 | #endif |
107 | #ifndef CRASH_ADDR_LOW_MAX |
108 | #define CRASH_ADDR_LOW_MAX SZ_4G |
109 | #endif |
110 | #ifndef CRASH_ADDR_HIGH_MAX |
111 | #define CRASH_ADDR_HIGH_MAX memblock_end_of_DRAM() |
112 | #endif |
113 | |
114 | void __init reserve_crashkernel_generic(char *cmdline, |
115 | unsigned long long crash_size, |
116 | unsigned long long crash_base, |
117 | unsigned long long crash_low_size, |
118 | bool high); |
119 | #else |
120 | static inline void __init reserve_crashkernel_generic(char *cmdline, |
121 | unsigned long long crash_size, |
122 | unsigned long long crash_base, |
123 | unsigned long long crash_low_size, |
124 | bool high) |
125 | {} |
126 | #endif |
127 | |
128 | /* Alignment required for elf header segment */ |
129 | #define 4096 |
130 | |
131 | struct crash_mem { |
132 | unsigned int max_nr_ranges; |
133 | unsigned int nr_ranges; |
134 | struct range ranges[] __counted_by(max_nr_ranges); |
135 | }; |
136 | |
137 | extern int crash_exclude_mem_range(struct crash_mem *mem, |
138 | unsigned long long mstart, |
139 | unsigned long long mend); |
140 | extern int (struct crash_mem *mem, int need_kernel_map, |
141 | void **addr, unsigned long *sz); |
142 | |
143 | struct kimage; |
144 | struct kexec_segment; |
145 | |
146 | #define KEXEC_CRASH_HP_NONE 0 |
147 | #define KEXEC_CRASH_HP_ADD_CPU 1 |
148 | #define KEXEC_CRASH_HP_REMOVE_CPU 2 |
149 | #define KEXEC_CRASH_HP_ADD_MEMORY 3 |
150 | #define KEXEC_CRASH_HP_REMOVE_MEMORY 4 |
151 | #define KEXEC_CRASH_HP_INVALID_CPU -1U |
152 | |
153 | #endif /* LINUX_CRASH_CORE_H */ |
154 | |