[PATCH] makedumpfile: readpage_elf: handle 0-pages not stored in the ELF file

Atsushi Kumagai ats-kumagai at wm.jp.nec.com
Tue Jan 26 18:21:57 PST 2016


Hello Ivan,

>Handle pages filled with zeros that are not stored in the ELF file
>directly, but have addresses between p_filesz and p_memsz of a segment.

This fix looks reasonable, thanks for your work.

>This allows makedumpfile to dump-dmesg from a previously makedumpfile-ed
>vmcore where all 0-pages were excluded (dump_level & 1) for example.

I have some comments below:

>Signed-off-by: Ivan Delalande <colona at arista.com>
>---
> elf_info.c     | 22 ++++++++++++++++++++++
> elf_info.h     |  1 +
> makedumpfile.c | 16 ++++++++++++++++
> 3 files changed, 39 insertions(+)
>
>diff --git a/elf_info.c b/elf_info.c
>index 8bce942..340e885 100644
>--- a/elf_info.c
>+++ b/elf_info.c
>@@ -42,6 +42,7 @@ struct pt_load_segment {
> 	unsigned long long	phys_end;
> 	unsigned long long	virt_start;
> 	unsigned long long	virt_end;
>+	size_t			mem_size;
> };
>
> static int			nr_cpus;             /* number of cpu */
>@@ -166,6 +167,7 @@ dump_Elf_load(Elf64_Phdr *prog, int num_load)
> 	pls->virt_start  = prog->p_vaddr;
> 	pls->virt_end    = pls->virt_start + prog->p_filesz;
> 	pls->file_offset = prog->p_offset;
>+	pls->mem_size    = prog->p_memsz;
>
> 	DEBUG_MSG("LOAD (%d)\n", num_load);
> 	DEBUG_MSG("  phys_start : %llx\n", pls->phys_start);
>@@ -584,6 +586,26 @@ offset_to_pt_load_end(off_t offset)
> }
>
> /*
>+ * Return true if a page is in the zone between p_filesz and p_memsz of a
>+ * segment, which is a page filled with zero and not stored in the ELF file.
>+ */

This function checks just "if a page fits within a PT_LOAD", but this comment
and the function name don't match with it.

>+int
>+paddr_is_null(unsigned long long paddr)
>+{
>+	int i;
>+	struct pt_load_segment *pls;
>+
>+	for (i = 0; i < num_pt_loads; i++) {
>+		pls = &pt_loads[i];
>+		if ((paddr >= pls->phys_start)
>+		    && (paddr + info->page_size
>+			<= pls->phys_start + pls->mem_size))
>+			return TRUE;
>+	}
>+	return FALSE;
>+}

If you keep the function name, the conditional expression should be:

	if ((paddr >= pls->phys_end)
	    && (paddr + info->page_size
		<= pls->phys_start + pls->mem_size))
		return TRUE;

or,

>+
>+/*
>  * Judge whether the page is fractional or not.
>  */
> int
>diff --git a/elf_info.h b/elf_info.h
>index e712253..4823311 100644
>--- a/elf_info.h
>+++ b/elf_info.h
>@@ -36,6 +36,7 @@ unsigned long long page_head_to_phys_start(unsigned long long head_paddr);
> unsigned long long page_head_to_phys_end(unsigned long long head_paddr);
> off_t offset_to_pt_load_start(off_t offset);
> off_t offset_to_pt_load_end(off_t offset);
>+int paddr_is_null(unsigned long long paddr);
> unsigned long long vaddr_to_paddr_general(unsigned long long vaddr);
> off_t vaddr_to_offset_slow(int fd, char *filename, unsigned long long vaddr);
> unsigned long long get_max_paddr(void);
>diff --git a/makedumpfile.c b/makedumpfile.c
>index fa0b779..120bfdc 100644
>--- a/makedumpfile.c
>+++ b/makedumpfile.c
>@@ -654,6 +654,14 @@ readpage_elf(unsigned long long paddr, void *bufptr)
> 	phys_end = paddr + info->page_size;
>
> 	/*
>+	 * Check the 0-filled pages that are not in the ELF file.
>+	 */
>+	if (!offset1 && !offset2 && paddr_is_null(paddr)) {
>+		memset(bufptr, 0, info->page_size);
>+		return TRUE;
>+	}

Since this combination of three conditions is exactly *paddr_is_null()*,
the current paddr_is_null() should be renamed so that the name reflects
its contents.


Thanks,
Atsushi Kumagai

>+
>+	/*
> 	 * Check the case phys_start isn't aligned by page size like below:
> 	 *
> 	 *                           phys_start
>@@ -728,6 +736,14 @@ readpage_elf_parallel(int fd_memory, unsigned long long paddr, void *bufptr)
> 	phys_end = paddr + info->page_size;
>
> 	/*
>+	 * Check the 0-filled pages that are not in the ELF file.
>+	 */
>+	if (!offset1 && !offset2 && paddr_is_null(paddr)) {
>+		memset(bufptr, 0, info->page_size);
>+		return TRUE;
>+	}
>+
>+	/*
> 	 * Check the case phys_start isn't aligned by page size like below:
> 	 *
> 	 *                           phys_start
>--
>2.7.0
>
>--
>Ivan "Colona" Delalande
>Arista Networks



More information about the kexec mailing list