mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
To: ebiederm@xmission.com, vgoyal@redhat.com, cpw@sgi.com,
	kumagai-atsushi@mxc.nes.nec.co.jp, lisa.mitchell@hp.com
Cc: kexec@lists.infradead.org, linux-kernel@vger.kernel.org
Subject: [PATCH 09/13] vmcore: copy ELF note segments in buffer on 2nd kernel
Date: Thu, 14 Feb 2013 19:12:32 +0900	[thread overview]
Message-ID: <20130214101232.22466.44026.stgit@localhost6.localdomain6> (raw)
In-Reply-To: <20130214100945.22466.4172.stgit@localhost6.localdomain6>

Objects exported from ELF note segments are in fact located apart from
each other on old memory. But on /proc/vmcore they are exported as a
single ELF note segment. To satisfy mmap()'s page-size boundary
requirement, copy them in a page-size aligned buffer allocated by
__get_free_pages() on 2nd kernel and remap the buffer to user-space.

The buffer for ELF note segments is added to vmcore_list as the object
of VMCORE_2ND_KERNEL type.

Copy of ELF note segments is done in two pass: first pass tries to
calculate real total size of ELF note segments, and then 2nd pass
copies the segment data into the buffer of the real total size.

Signed-off-by: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
---

 fs/proc/vmcore.c |   78 +++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 59 insertions(+), 19 deletions(-)

diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index 3aedb52..ccf0dc5 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -230,27 +230,25 @@ static u64 __init get_vmcore_size_elf32(char *elfptr)
 	return size;
 }
 
-/* Merges all the PT_NOTE headers into one. */
-static int __init merge_note_headers_elf64(char *elfptr, size_t *elfsz,
-						struct list_head *vc_list)
+static int __init parse_note_segments_elf64(char *elfptr, int *nr_ptnote,
+					    u64 *phdr_sz, char *notebuf)
 {
-	int i, nr_ptnote=0, rc=0;
-	char *tmp;
+	int i, rc=0;
+	loff_t notebuf_off = 0;
 	Elf64_Ehdr *ehdr_ptr;
-	Elf64_Phdr phdr, *phdr_ptr;
 	Elf64_Nhdr *nhdr_ptr;
-	u64 phdr_sz = 0, note_off;
+	Elf64_Phdr *phdr_ptr;
 
 	ehdr_ptr = (Elf64_Ehdr *)elfptr;
 	phdr_ptr = (Elf64_Phdr*)(elfptr + sizeof(Elf64_Ehdr));
 	for (i = 0; i < ehdr_ptr->e_phnum; i++, phdr_ptr++) {
 		int j;
 		void *notes_section;
-		struct vmcore *new;
 		u64 offset, max_sz, sz, real_sz = 0;
 		if (phdr_ptr->p_type != PT_NOTE)
 			continue;
-		nr_ptnote++;
+		if (nr_ptnote)
+			*nr_ptnote = *nr_ptnote + 1;
 		max_sz = phdr_ptr->p_memsz;
 		offset = phdr_ptr->p_offset;
 		notes_section = kmalloc(max_sz, GFP_KERNEL);
@@ -271,20 +269,51 @@ static int __init merge_note_headers_elf64(char *elfptr, size_t *elfsz,
 			real_sz += sz;
 			nhdr_ptr = (Elf64_Nhdr*)((char*)nhdr_ptr + sz);
 		}
-
-		/* Add this contiguous chunk of notes section to vmcore list.*/
-		new = get_new_element();
-		if (!new) {
-			kfree(notes_section);
-			return -ENOMEM;
+		if (phdr_sz)
+			*phdr_sz += real_sz;
+		if (notebuf) {
+			memcpy(notebuf + notebuf_off, notes_section, real_sz);
+			notebuf_off += real_sz;
 		}
-		new->paddr = phdr_ptr->p_offset;
-		new->size = real_sz;
-		list_add_tail(&new->list, vc_list);
-		phdr_sz += real_sz;
 		kfree(notes_section);
 	}
 
+	return 0;
+}
+
+/* Merges all the PT_NOTE headers into one. */
+static int __init merge_note_headers_elf64(char *elfptr, size_t *elfsz,
+						struct list_head *vc_list)
+{
+	int i, nr_ptnote, rc=0;
+	char *tmp, *notebuf;
+	Elf64_Ehdr *ehdr_ptr;
+	Elf64_Phdr phdr;
+	u64 phdr_sz, note_off, notebuf_sz;
+	struct vmcore *new;
+
+	ehdr_ptr = (Elf64_Ehdr *)elfptr;
+
+	/* The 1st pass calculates real size of ELF note segments. */
+	nr_ptnote = 0;
+	phdr_sz = 0;
+	rc = parse_note_segments_elf64(elfptr, &nr_ptnote, &phdr_sz, NULL);
+	if (rc < 0)
+		return rc;
+
+	/* The 2nd pass copies the ELF note segments into the buffer
+	 * of the exact size. */
+	notebuf_sz = roundup(phdr_sz, PAGE_SIZE);
+	notebuf = (char *) __get_free_pages(GFP_KERNEL | __GFP_ZERO,
+					    get_order(notebuf_sz));
+	if (!notebuf)
+		return -ENOMEM;
+	rc = parse_note_segments_elf64(elfptr, NULL, NULL, notebuf);
+	if (rc < 0) {
+		free_pages((unsigned long)notebuf, get_order(notebuf_sz));
+		return rc;
+	}
+
 	/* Prepare merged PT_NOTE program header. */
 	phdr.p_type    = PT_NOTE;
 	phdr.p_flags   = 0;
@@ -315,6 +344,17 @@ static int __init merge_note_headers_elf64(char *elfptr, size_t *elfsz,
 
 	*elfsz = roundup(*elfsz, PAGE_SIZE);
 
+	/* Add the merged unique ELF note segments in vmcore_list. */
+	new = get_new_element();
+	if (!new) {
+		free_pages((unsigned long)notebuf, get_order(notebuf_sz));
+		return -ENOMEM;
+	}
+	new->type = VMCORE_2ND_KERNEL;
+	new->buf = notebuf;
+	new->size = notebuf_sz;
+	list_add_tail(&new->list, vc_list);
+
 	return 0;
 }
 


  parent reply	other threads:[~2013-02-14 10:12 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-02-14 10:11 [PATCH 00/13] kdump, vmcore: support mmap() on /proc/vmcore HATAYAMA Daisuke
2013-02-14 10:11 ` [PATCH 01/13] vmcore: allocate buffer for ELF headers on page-size alignment HATAYAMA Daisuke
2013-02-15 15:01   ` Vivek Goyal
2013-02-14 10:11 ` [PATCH 02/13] vmcore: round up buffer size of ELF headers by PAGE_SIZE HATAYAMA Daisuke
2013-02-15 15:18   ` Vivek Goyal
2013-02-18 15:58     ` HATAYAMA Daisuke
2013-02-14 10:11 ` [PATCH 03/13] vmcore: fill unused part of buffer for ELF headers with 0 HATAYAMA Daisuke
2013-02-14 10:12 ` [PATCH 04/13] vmcore: introduce types for objects copied in 2nd kernel HATAYAMA Daisuke
2013-02-15 15:28   ` Vivek Goyal
2013-02-18 16:06     ` HATAYAMA Daisuke
2013-02-19 23:07       ` Vivek Goyal
2013-02-14 10:12 ` [PATCH 05/13] vmcore: modify ELF32 code according to new type HATAYAMA Daisuke
2013-02-15 15:30   ` Vivek Goyal
2013-02-18 16:11     ` HATAYAMA Daisuke
2013-02-14 10:12 ` [PATCH 06/13] vmcore: modify vmcore clean-up function to free buffer on 2nd kernel HATAYAMA Daisuke
2013-02-15 15:32   ` Vivek Goyal
2013-02-14 10:12 ` [PATCH 07/13] vmcore: modify read_vmcore() to read " HATAYAMA Daisuke
2013-02-15 15:51   ` Vivek Goyal
2013-02-14 10:12 ` [PATCH 08/13] vmcore: remove unused helper function HATAYAMA Daisuke
2013-02-15 15:52   ` Vivek Goyal
2013-02-14 10:12 ` HATAYAMA Daisuke [this message]
2013-02-15 16:53   ` [PATCH 09/13] vmcore: copy ELF note segments in buffer on 2nd kernel Vivek Goyal
2013-02-18 17:02     ` HATAYAMA Daisuke
2013-02-19 23:05       ` Vivek Goyal
2013-02-14 10:12 ` [PATCH 10/13] vmcore: round-up offset of vmcore object in page-size boundary HATAYAMA Daisuke
2013-02-14 10:12 ` [PATCH 11/13] vmcore: count holes generated by round-up operation for vmcore size HATAYAMA Daisuke
2013-02-14 10:12 ` [PATCH 12/13] vmcore: copy non page-size aligned head and tail pages in 2nd kernel HATAYAMA Daisuke
2013-02-14 10:12 ` [PATCH 13/13] vmcore: introduce mmap_vmcore() HATAYAMA Daisuke
2013-02-15  3:57 ` [PATCH 00/13] kdump, vmcore: support mmap() on /proc/vmcore Atsushi Kumagai
2013-02-18  0:16   ` Hatayama, Daisuke
2013-03-27  5:51 ` makedumpfile mmap() benchmark Jingbai Ma
2013-03-27  6:23   ` HATAYAMA Daisuke
2013-03-27  6:35     ` Jingbai Ma

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130214101232.22466.44026.stgit@localhost6.localdomain6 \
    --to=d.hatayama@jp.fujitsu.com \
    --cc=cpw@sgi.com \
    --cc=ebiederm@xmission.com \
    --cc=kexec@lists.infradead.org \
    --cc=kumagai-atsushi@mxc.nes.nec.co.jp \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lisa.mitchell@hp.com \
    --cc=vgoyal@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®