10 #include <linux/kernel.h>
11 #include <linux/module.h>
13 #include <linux/slab.h>
15 #include <linux/elf.h>
20 #define PTR_ADD(x, y) (((char *) (x)) + ((unsigned long) (y)))
21 #define PTR_SUB(x, y) (((char *) (x)) - ((unsigned long) (y)))
22 #define PTR_DIFF(x, y) ((unsigned long)(((char *) (x)) - ((unsigned long) (y))))
32 size_t csize,
unsigned long offset,
int userbuf)
58 unsigned long copied = 0;
67 return memcpy_real(dest + copied, src + copied, count - copied);
73 static void *kzalloc_panic(
int len)
79 panic(
"s390 kdump kzalloc (%d) failed", len);
86 static struct mem_chunk *get_memory_layout(
void)
126 static int cpu_nr = 1;
128 memset(&nt_prstatus, 0,
sizeof(nt_prstatus));
130 memcpy(&nt_prstatus.pr_reg.psw, sa->
psw,
sizeof(sa->
psw));
132 nt_prstatus.pr_pid = cpu_nr;
135 return nt_init(ptr,
NT_PRSTATUS, &nt_prstatus,
sizeof(nt_prstatus),
142 static void *nt_fpregset(
void *ptr,
struct save_area *sa)
146 memset(&nt_fpregset, 0,
sizeof(nt_fpregset));
150 return nt_init(ptr,
NT_PRFPREG, &nt_fpregset,
sizeof(nt_fpregset),
157 static void *nt_s390_timer(
void *ptr,
struct save_area *sa)
160 KEXEC_CORE_NOTE_NAME);
166 static void *nt_s390_tod_cmp(
void *ptr,
struct save_area *sa)
169 sizeof(sa->
clk_cmp), KEXEC_CORE_NOTE_NAME);
175 static void *nt_s390_tod_preg(
void *ptr,
struct save_area *sa)
178 sizeof(sa->
tod_reg), KEXEC_CORE_NOTE_NAME);
184 static void *nt_s390_ctrs(
void *ptr,
struct save_area *sa)
187 sizeof(sa->
ctrl_regs), KEXEC_CORE_NOTE_NAME);
193 static void *nt_s390_prefix(
void *ptr,
struct save_area *sa)
196 sizeof(sa->
pref_reg), KEXEC_CORE_NOTE_NAME);
204 ptr = nt_prstatus(ptr, sa);
205 ptr = nt_fpregset(ptr, sa);
206 ptr = nt_s390_timer(ptr, sa);
207 ptr = nt_s390_tod_cmp(ptr, sa);
208 ptr = nt_s390_tod_preg(ptr, sa);
209 ptr = nt_s390_ctrs(ptr, sa);
210 ptr = nt_s390_prefix(ptr, sa);
217 static void *nt_prpsinfo(
void *ptr)
221 memset(&prpsinfo, 0,
sizeof(prpsinfo));
222 prpsinfo.pr_sname =
'R';
223 strcpy(prpsinfo.pr_fname,
"vmlinux");
224 return nt_init(ptr,
NT_PRPSINFO, &prpsinfo,
sizeof(prpsinfo),
225 KEXEC_CORE_NOTE_NAME);
231 static void *get_vmcoreinfo_old(
unsigned long *
size)
233 char nt_name[11], *vmcoreinfo;
239 memset(nt_name, 0,
sizeof(nt_name));
244 if (
strcmp(nt_name,
"VMCOREINFO") != 0)
246 vmcoreinfo = kzalloc_panic(note.
n_descsz);
256 static void *nt_vmcoreinfo(
void *ptr)
263 vmcoreinfo = get_vmcoreinfo_old(&size);
266 return nt_init(ptr, 0, vmcoreinfo, size,
"VMCOREINFO");
272 static void *ehdr_init(
Elf64_Ehdr *ehdr,
int mem_chunk_cnt)
274 memset(ehdr, 0,
sizeof(*ehdr));
286 ehdr->
e_phnum = mem_chunk_cnt + 1;
293 static int get_cpu_cnt(
void)
297 for (i = 0; zfcpdump_save_areas[
i]; i++) {
298 if (zfcpdump_save_areas[i]->pref_reg == 0)
308 static int get_mem_chunk_cnt(
void)
313 chunk_array = get_memory_layout();
315 mem_chunk = &chunk_array[
i];
319 if (mem_chunk->
size == 0)
330 static inline unsigned long relocate(
unsigned long addr)
340 struct mem_chunk *chunk_array, *mem_chunk;
343 chunk_array = get_memory_layout();
345 mem_chunk = &chunk_array[
i];
346 if (mem_chunk->
size == 0)
369 static void *notes_init(
Elf64_Phdr *phdr,
void *ptr,
u64 notes_offset)
372 void *ptr_start =
ptr;
375 ptr = nt_prpsinfo(ptr);
377 for (i = 0; zfcpdump_save_areas[
i]; i++) {
378 sa = zfcpdump_save_areas[
i];
383 ptr = nt_vmcoreinfo(ptr);
384 memset(phdr, 0,
sizeof(*phdr));
386 phdr->
p_offset = relocate(notes_offset);
395 static void s390_elf_corehdr_create(
char **elfcorebuf,
size_t *elfcorebuf_sz)
403 mem_chunk_cnt = get_mem_chunk_cnt();
405 alloc_size = 0x1000 + get_cpu_cnt() * 0x300 +
407 hdr = kzalloc_panic(alloc_size);
409 ptr = ehdr_init(hdr, mem_chunk_cnt);
417 ptr = notes_init(phdr_notes, ptr, ((
unsigned long) hdr) + hdr_off);
420 loads_init(phdr_loads, ((
unsigned long) hdr) + hdr_off);
421 *elfcorebuf_sz = hdr_off;
422 *elfcorebuf = (
void *) relocate((
unsigned long)
hdr);
423 BUG_ON(*elfcorebuf_sz > alloc_size);
430 static int setup_kdump_elfcorehdr(
void)
432 size_t elfcorebuf_sz;
437 s390_elf_corehdr_create(&elfcorebuf, &elfcorebuf_sz);