All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format
@ 2011-10-28  9:48 HATAYAMA Daisuke
  2011-10-28  9:48 ` [PATCH v2 01/14] Add sadump module header file HATAYAMA Daisuke
                   ` (14 more replies)
  0 siblings, 15 replies; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-10-28  9:48 UTC (permalink / raw)
  To: kexec

Hello Tachibana-san,

Since there's certain time until Tachibana-san's review, I made some
cleanups and bugfixes to the previous version. Could you review this
instead to reduce the review time?

==
The following series implements Fujitsu stand-alone dump (sadump)
format support for makedumpfile, converting sadump-related formats
into kdump-compressed format.

Based on makedumpfile version 1.4.0.

Here is summary of the changes.

No debug information on sadump-related formats
==============================================

Unlike other dump mechanisms, VMCORE created by sadump has NO debug
information including VMCOREINFO. So, -x VMLINUX is definitely
necessary.

Debug information gained from VMLINUX is used for:

    1. creating VMCOREINFO dynamically, saved in resulting dumpfiles
       in kdump-compressed format, and

    2. gaining symbolic and type information necessary to refer to ELF
       note information contained in VMCORE generated by kdump at
       crash, and to estimate phys_base value.

If no VMLINUX is specified, dumpfile with no VMCOREINFO and ELF note
is generated on the current implementation.


Command-line interface change
=============================

Introduce --diskset=VMCORE to pass multiple VMCOREs in a single
commnad-line input.

    makedumpfile [OPTION] -x VMLINUX --diskset=VMCORE1 --diskset=VMCORE2 \
    [--diskset=VMCORE3 ..] DUMPFILE


Architectures
=============

X86 and X86_64.

On the other unsupported architectures, sadump-related source files
are never compiled and linked into makedumpfile executable.

---

HATAYAMA Daisuke (14):
      Add description of sadump-related formats in manual page
      Add description of sadump-related formts in usage information
      Read kexec backup region
      Procees CPUs based on online ones
      Generate and save VMCOREINFO and ELF note information
      Estimate phys_base based on linux_banner position
      Implement readmem() interface on sadump-related formats
      Initialize debug information for ELF note extraction
      Initialize internal data according to sadump-related formats
      Export helpers for bitmap table handling
      Verify and read VMCORE(s) in sadump-related formats
      Implement command-line processing
      Extend DumpInfo structure
      Add sadump module header file


 Makefile       |    6 
 elf_info.c     |    2 
 makedumpfile.8 |   22 +
 makedumpfile.c |  455 +++++++++++--
 makedumpfile.h |  207 ++++++
 print_info.c   |   10 
 sadump_info.c  | 1945 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |  165 +++++
 sadump_mod.h   |  186 +++++
 9 files changed, 2907 insertions(+), 91 deletions(-)
 create mode 100644 sadump_info.c
 create mode 100644 sadump_info.h
 create mode 100644 sadump_mod.h

-- 
Thanks.
HATAYAMA, Daisuke

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH v2 01/14] Add sadump module header file
  2011-10-28  9:48 [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format HATAYAMA Daisuke
@ 2011-10-28  9:48 ` HATAYAMA Daisuke
  2011-10-28  9:48 ` [PATCH v2 02/14] Extend DumpInfo structure HATAYAMA Daisuke
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-10-28  9:48 UTC (permalink / raw)
  To: kexec

This header contains definitions of sadump-related dump format
headers. These datatype is handled in sadump module, introduced later
as sadump_info.c, only.

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

 Makefile     |    2 -
 sadump_mod.h |  174 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 175 insertions(+), 1 deletions(-)
 create mode 100644 sadump_mod.h

diff --git a/Makefile b/Makefile
index d643d2b..f7f22e5 100644
--- a/Makefile
+++ b/Makefile
@@ -23,7 +23,7 @@ CFLAGS += -m64
 CFLAGS_ARCH += -m64
 endif
 
-SRC	= makedumpfile.c makedumpfile.h diskdump_mod.h
+SRC	= makedumpfile.c makedumpfile.h diskdump_mod.h sadump_mod.h
 SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c
 OBJ_PART = print_info.o dwarf_info.o elf_info.o erase_info.o
 SRC_ARCH = arch/arm.c arch/x86.c arch/x86_64.c arch/ia64.c arch/ppc64.c arch/s390x.c
diff --git a/sadump_mod.h b/sadump_mod.h
new file mode 100644
index 0000000..98f5dd1
--- /dev/null
+++ b/sadump_mod.h
@@ -0,0 +1,174 @@
+/*
+ * sadump_mod.h
+ *
+ * Created by: HATAYAMA, Daisuke <d.hatayama@jp.fujitsu.com>
+ *
+ * Copyright (C) 2011  FUJITSU LIMITED
+ * Copyright (C) 2011  NEC Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SADUMP_MOD_H
+#define _SADUMP_MOD_H
+
+#if defined(__x86__) || defined(__x86_64__)
+
+#include <stdint.h>
+
+typedef struct efi_time {
+	uint16_t year;
+	uint8_t month;
+	uint8_t day;
+	uint8_t hour;
+	uint8_t minute;
+	uint8_t second;
+	uint8_t pad1;
+	uint32_t nanosecond;
+#define EFI_UNSPECIFIED_TIMEZONE 2047
+	int16_t timezone;
+	uint8_t daylight;
+	uint8_t pad2;
+} efi_time_t;
+
+typedef struct {
+	uint32_t data1;
+	uint16_t data2;
+	uint16_t data3;
+	uint8_t data4[8];
+} efi_guid_t;
+
+struct sadump_part_header {
+#define SADUMP_SIGNATURE1	0x75646173
+#define SADUMP_SIGNATURE2	0x0000706d
+	uint32_t signature1;	/* sadu */
+	uint32_t signature2;	/* mp\0\0 */
+	uint32_t enable;	/* set sadump service */
+	uint32_t reboot;	/* number of seconds until reboot. 1-3600 */
+	uint32_t compress;	/* memory image format. */
+	uint32_t recycle;	/* dump device recycle */
+	uint32_t label[16];	/* reserve */
+	efi_guid_t sadump_id;	/* system UUID */
+	efi_guid_t disk_set_id;	/* disk set UUID */
+	efi_guid_t vol_id;	/* device UUID */
+	efi_time_t time_stamp;	/* time stamp */
+	uint32_t set_disk_set;	/* device type */
+#define SADUMP_MAX_DISK_SET_NUM 16
+	uint32_t reserve;	/* Padding for Alignment */
+	uint64_t used_device;	/* used device */
+#define DUMP_PART_HEADER_MAGICNUM_SIZE 982
+	uint32_t magicnum[DUMP_PART_HEADER_MAGICNUM_SIZE]; /* magic number */
+};
+
+struct sadump_volume_info {
+	efi_guid_t id;		/* volume id */
+	uint64_t vol_size;	/* device size */
+	uint32_t status;	/* device status */
+	uint32_t cache_size;	/* cache size */
+};
+
+struct sadump_disk_set_header {
+	uint32_t disk_set_header_size;	/* disk set header size */
+	uint32_t disk_num;	/* disk number */
+	uint64_t disk_set_size;	/* disk set size */
+#define DUMP_DEVICE_MAX 16
+	struct sadump_volume_info vol_info[DUMP_DEVICE_MAX - 1];
+	/* struct VOL_INFO array */
+};
+
+struct sadump_header {
+#define SADUMP_SIGNATURE "sadump\0\0"
+	char signature[8];	/* = "sadump\0\0" */
+	uint32_t header_version;	/* Dump header version */
+	uint32_t reserve;	/* Padding for Alignment */
+	efi_time_t timestamp;	/* Time stamp */
+	uint32_t status;	/* Above flags */
+	uint32_t compress;	/* Above flags */
+	uint32_t block_size;	/* Size of a block in byte */
+#define SADUMP_DEFAULT_BLOCK_SIZE 4096
+	uint32_t extra_hdr_size;	/* Size of host dependent
+					 * header in blocks (reserve)
+					 */
+	uint32_t sub_hdr_size;	/* Size of arch dependent header in blocks */
+	uint32_t bitmap_blocks;	/* Size of Memory bitmap in block */
+	uint32_t dumpable_bitmap_blocks;	/* Size of Memory bitmap in block */
+	uint32_t max_mapnr;	/* = max_mapnr */
+	uint32_t total_ram_blocks;	/* Size of Memory in block */
+	uint32_t device_blocks;	/* Number of total blocks in the dump device */
+	uint32_t written_blocks;	/* Number of written blocks */
+	uint32_t current_cpu;	/* CPU# which handles dump */
+	uint32_t nr_cpus;	/* Number of CPUs */
+};
+
+struct sadump_apic_state {
+	uint64_t ApicId;	/* Local Apic ID register */
+	uint64_t Ldr;		/* Logical Destination Register */
+};
+
+struct sadump_smram_cpu_state {
+	uint64_t Reserved1[58];
+	uint32_t GdtUpper, LdtUpper, IdtUpper;
+	uint32_t Reserved2[3];
+	uint64_t IoEip;
+	uint64_t Reserved3[10];
+	uint32_t Cr4;
+	uint32_t Reserved4[18];
+	uint32_t GdtLower;
+	uint32_t GdtLimit;
+	uint32_t IdtLower;
+	uint32_t IdtLimit;
+	uint32_t LdtLower;
+	uint32_t LdtLimit;
+	uint32_t LdtInfo;
+	uint64_t Reserved5[6];
+	uint64_t Eptp;
+	uint32_t EptpSetting;
+	uint32_t Reserved6[5];
+	uint32_t Smbase;
+	uint32_t SmmRevisionId;
+	uint16_t IoInstructionRestart;
+	uint16_t AutoHaltRestart;
+	uint32_t Reserved7[6];
+	uint32_t R15Lower, R15Upper, R14Lower, R14Upper;
+	uint32_t R13Lower, R13Upper, R12Lower, R12Upper;
+	uint32_t R11Lower, R11Upper, R10Lower, R10Upper;
+	uint32_t R9Lower, R9Upper, R8Lower, R8Upper;
+	uint32_t RaxLower, RaxUpper, RcxLower, RcxUpper;
+	uint32_t RdxLower, RdxUpper, RbxLower, RbxUpper;
+	uint32_t RspLower, RspUpper, RbpLower, RbpUpper;
+	uint32_t RsiLower, RsiUpper, RdiLower, RdiUpper;
+	uint32_t IoMemAddrLower, IoMemAddrUpper;
+	uint32_t IoMisc, Es, Cs, Ss, Ds, Fs, Gs;
+	uint32_t Ldtr, Tr;
+	uint64_t Dr7, Dr6, Rip, Ia32Efer, Rflags;
+	uint64_t Cr3, Cr0;
+};
+
+struct sadump_page_header {
+	uint64_t page_flags;
+	uint32_t size;
+	uint32_t flags;
+};
+
+struct sadump_media_header {
+	efi_guid_t sadump_id;	// system UUID
+	efi_guid_t disk_set_id;	// disk set UUID
+	efi_time_t time_stamp;	/* time stamp */
+	char sequential_num;	// Medium sequential number
+	char term_cord;		// Termination cord
+	char disk_set_header_size;	// Size of original disk set header
+	char disks_in_use;	// Number of used disks of original dump device
+	char reserve[4044];	// reserve feild
+};
+
+#endif /* defined(__x86__) && defined(__x86_64__) */
+
+#endif /* _SADUMP_MOD_H */


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 02/14] Extend DumpInfo structure
  2011-10-28  9:48 [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format HATAYAMA Daisuke
  2011-10-28  9:48 ` [PATCH v2 01/14] Add sadump module header file HATAYAMA Daisuke
@ 2011-10-28  9:48 ` HATAYAMA Daisuke
  2011-10-28  9:48 ` [PATCH v2 03/14] Implement command-line processing HATAYAMA Daisuke
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-10-28  9:48 UTC (permalink / raw)
  To: kexec

Two members, flag_sadump_diskset and flag_sadump, are
introduced. flag_sadump_diskset is true if --diskset=VMCORE is
specified one or more times. flag_sadump has the corresponding value
of type enum sadump_format_type if VMCORE(s) is in sadump-related
formats.

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

 makedumpfile.h |    7 +++++++
 sadump_mod.h   |   10 ++++++++++
 2 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/makedumpfile.h b/makedumpfile.h
index f0e5da8..dee0a68 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -34,6 +34,7 @@
 #include "common.h"
 #include "dwarf_info.h"
 #include "diskdump_mod.h"
+#include "sadump_mod.h"
 
 /*
  * Result of command
@@ -894,6 +895,12 @@ struct DumpInfo {
 	 */
 	unsigned long long split_start_pfn;  
 	unsigned long long split_end_pfn;  
+
+	/*
+	 * sadump info:
+	 */
+	int flag_sadump_diskset;
+	enum sadump_format_type flag_sadump;         /* sadump format type */
 };
 extern struct DumpInfo		*info;
 
diff --git a/sadump_mod.h b/sadump_mod.h
index 98f5dd1..3385123 100644
--- a/sadump_mod.h
+++ b/sadump_mod.h
@@ -171,4 +171,14 @@ struct sadump_media_header {
 
 #endif /* defined(__x86__) && defined(__x86_64__) */
 
+/*
+ * Type of sadump related formats
+ */
+enum sadump_format_type {
+	SADUMP_UNKNOWN = 0,
+	SADUMP_SINGLE_PARTITION,
+	SADUMP_DISKSET,
+	SADUMP_MEDIA_BACKUP
+};
+
 #endif /* _SADUMP_MOD_H */


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 03/14] Implement command-line processing
  2011-10-28  9:48 [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format HATAYAMA Daisuke
  2011-10-28  9:48 ` [PATCH v2 01/14] Add sadump module header file HATAYAMA Daisuke
  2011-10-28  9:48 ` [PATCH v2 02/14] Extend DumpInfo structure HATAYAMA Daisuke
@ 2011-10-28  9:48 ` HATAYAMA Daisuke
  2011-10-28  9:48 ` [PATCH v2 04/14] Verify and read VMCORE(s) in sadump-related formats HATAYAMA Daisuke
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-10-28  9:48 UTC (permalink / raw)
  To: kexec

Introduce new long option --diskset=VMCORE, which is used for
specifying multiple VMCORE(s) generated on sadump diskset
configuration. --diskset and --split options can be specified at the
same time.

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

 Makefile       |    6 ++--
 makedumpfile.c |   39 ++++++++++++++++++++++++----
 sadump_info.c  |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |   61 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 176 insertions(+), 8 deletions(-)
 create mode 100644 sadump_info.c
 create mode 100644 sadump_info.h

diff --git a/Makefile b/Makefile
index f7f22e5..9b3ee9f 100644
--- a/Makefile
+++ b/Makefile
@@ -23,9 +23,9 @@ CFLAGS += -m64
 CFLAGS_ARCH += -m64
 endif
 
-SRC	= makedumpfile.c makedumpfile.h diskdump_mod.h sadump_mod.h
-SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c
-OBJ_PART = print_info.o dwarf_info.o elf_info.o erase_info.o
+SRC	= makedumpfile.c makedumpfile.h diskdump_mod.h sadump_mod.h sadump_info.h
+SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c
+OBJ_PART = print_info.o dwarf_info.o elf_info.o erase_info.o sadump_info.o
 SRC_ARCH = arch/arm.c arch/x86.c arch/x86_64.c arch/ia64.c arch/ppc64.c arch/s390x.c
 OBJ_ARCH = arch/arm.o arch/x86.o arch/x86_64.o arch/ia64.o arch/ppc64.o arch/s390x.o
 
diff --git a/makedumpfile.c b/makedumpfile.c
index 7b7c266..8a3a3d3 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -18,6 +18,7 @@
 #include "dwarf_info.h"
 #include "elf_info.h"
 #include "erase_info.h"
+#include "sadump_info.h"
 #include <sys/time.h>
 
 struct symbol_table	symbol_table;
@@ -6500,20 +6501,34 @@ check_param_for_creating_dumpfile(int argc, char *argv[])
 	if (info->name_filterconfig && !info->name_vmlinux)
 		return FALSE;
 
+	if (info->flag_sadump_diskset && !sadump_is_supported_arch())
+		return FALSE;
+
 	if ((argc == optind + 2) && !info->flag_flatten
-				 && !info->flag_split) {
+				 && !info->flag_split
+				 && !info->flag_sadump_diskset) {
 		/*
 		 * Parameters for creating the dumpfile from vmcore.
 		 */
 		info->name_memory   = argv[optind];
 		info->name_dumpfile = argv[optind+1];
 
-	} else if ((argc > optind + 2) && info->flag_split) {
+	} else if (info->flag_split && (info->flag_sadump_diskset
+					? (argc >= optind + 2)
+					: (argc > optind + 2))) {
+		int num_vmcore;
+
 		/*
 		 * Parameters for creating multiple dumpfiles from vmcore.
 		 */
-		info->num_dumpfile = argc - optind - 1;
-		info->name_memory  = argv[optind];
+		if (info->flag_sadump_diskset) {
+			num_vmcore = 0;
+			info->name_memory = sadump_head_disk_name_memory();
+		} else {
+			num_vmcore = 1;
+			info->name_memory = argv[optind];
+		}
+		info->num_dumpfile = argc - optind - num_vmcore;
 
 		if (info->flag_elf_dumpfile) {
 			MSG("Options for splitting dumpfile cannot be used with Elf format.\n");
@@ -6526,7 +6541,15 @@ check_param_for_creating_dumpfile(int argc, char *argv[])
 			return FALSE;
 		}
 		for (i = 0; i < info->num_dumpfile; i++)
-			SPLITTING_DUMPFILE(i) = argv[optind + 1 + i];
+			SPLITTING_DUMPFILE(i) = argv[optind + num_vmcore + i];
+
+	} else if ((argc == optind + 1) && !info->flag_split
+					&& info->flag_sadump_diskset) {
+		info->name_dumpfile = argv[optind];
+		info->name_memory = sadump_head_disk_name_memory();
+
+		DEBUG_MSG("name_dumpfile: %s\n", info->name_dumpfile);
+		DEBUG_MSG("name_memory: %s\n", info->name_memory);
 
 	} else if ((argc == optind + 1) && info->flag_flatten) {
 		/*
@@ -6594,6 +6617,7 @@ static struct option longopts[] = {
 	{"dump-dmesg", no_argument, NULL, 'M'}, 
 	{"config", required_argument, NULL, 'C'},
 	{"help", no_argument, NULL, 'h'},
+	{"diskset", required_argument, NULL, 'k'},
 	{0, 0, 0, 0}
 };
 
@@ -6661,6 +6685,11 @@ main(int argc, char *argv[])
 			info->flag_read_vmcoreinfo = 1;
 			info->name_vmcoreinfo = optarg;
 			break;
+		case 'k':
+			if (!sadump_add_diskset_info(optarg))
+				goto out;
+			info->flag_sadump_diskset = 1;
+			break;
 		case 'm':
 			message_level = atoi(optarg);
 			break;
diff --git a/sadump_info.c b/sadump_info.c
new file mode 100644
index 0000000..c94d233
--- /dev/null
+++ b/sadump_info.c
@@ -0,0 +1,78 @@
+/*
+ * sadump_info.c
+ *
+ * Created by: HATAYAMA, Daisuke <d.hatayama@jp.fujitsu.com>
+ *
+ * Copyright (C) 2011  FUJITSU LIMITED
+ * Copyright (C) 2011  NEC Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#if defined(__x86__) || defined(__x86_64__)
+
+#include "makedumpfile.h"
+#include "print_info.h"
+
+struct sadump_diskset_info {
+	char *name_memory;
+	int fd_memory;
+	struct sadump_part_header *sph_memory;
+	unsigned long data_offset;
+};
+
+struct sadump_info {
+	struct sadump_part_header *sph_memory;
+	struct sadump_header *sh_memory;
+	struct sadump_disk_set_header *sdh_memory;
+	struct sadump_media_header *smh_memory;
+	struct sadump_diskset_info *diskset_info;
+	int num_disks;
+	unsigned long sub_hdr_offset;
+	uint32_t smram_cpu_state_size;
+	unsigned long data_offset;
+};
+
+static struct sadump_info sadump_info = {};
+static struct sadump_info *si = &sadump_info;
+
+int
+sadump_add_diskset_info(char *name_memory)
+{
+	si->num_disks++;
+
+	si->diskset_info =
+		realloc(si->diskset_info,
+			si->num_disks*sizeof(struct sadump_diskset_info));
+	if (!si->diskset_info) {
+		ERRMSG("Can't allocate memory for sadump_diskset_info. %s\n",
+		       strerror(errno));
+		return FALSE;
+	}
+
+	si->diskset_info[si->num_disks - 1].name_memory = name_memory;
+
+	return TRUE;
+}
+
+char *
+sadump_head_disk_name_memory(void)
+{
+	return si->diskset_info[0].name_memory;
+}
+
+void
+free_sadump_info(void)
+{
+	if (si->diskset_info)
+		free(si->diskset_info);
+}
+
+#endif /* defined(__x86__) && defined(__x86_64__) */
diff --git a/sadump_info.h b/sadump_info.h
new file mode 100644
index 0000000..863956d
--- /dev/null
+++ b/sadump_info.h
@@ -0,0 +1,61 @@
+/*
+ * sadump_info.h
+ *
+ * Created by: HATAYAMA, Daisuke <d.hatayama@jp.fujitsu.com>
+ *
+ * Copyright (C) 2011  FUJITSU LIMITED
+ * Copyright (C) 2011  NEC Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _SADUMP_INFO_H
+#define _SADUMP_INFO_H
+
+#include "makedumpfile.h"
+
+#if defined(__x86__) || defined(__x86_64__)
+
+int sadump_add_diskset_info(char *name_memory);
+char *sadump_head_disk_name_memory(void);
+void free_sadump_info(void);
+
+static inline int sadump_is_supported_arch(void)
+{
+	return TRUE;
+}
+
+#else
+
+static inline int sadump_add_diskset_info(char *name_memory)
+{
+	return TRUE;
+}
+
+static inline char *
+sadump_head_disk_name_memory(void)
+{
+	return NULL;
+}
+
+static inline void free_sadump_info(void)
+{
+	return;
+}
+
+static inline int sadump_is_supported_arch(void)
+{
+	return FALSE;
+}
+
+#endif
+
+#endif /* _SADUMP_INFO_H */


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 04/14] Verify and read VMCORE(s) in sadump-related formats
  2011-10-28  9:48 [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format HATAYAMA Daisuke
                   ` (2 preceding siblings ...)
  2011-10-28  9:48 ` [PATCH v2 03/14] Implement command-line processing HATAYAMA Daisuke
@ 2011-10-28  9:48 ` HATAYAMA Daisuke
  2011-10-28  9:48 ` [PATCH v2 05/14] Export helpers for bitmap table handling HATAYAMA Daisuke
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-10-28  9:48 UTC (permalink / raw)
  To: kexec

Try to read VMCORE(s) as sadump-related formats: single partition,
diskset or media backup and verify their header information. If the
VMCORE(s) doesn't belong to each of them, the check continues to
checking of ELF format.

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

 makedumpfile.c |   17 +-
 sadump_info.c  |  480 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |   10 +
 3 files changed, 500 insertions(+), 7 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index 8a3a3d3..7057009 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -628,11 +628,16 @@ open_dump_memory(void)
 	if (status == TRUE) {
 		info->flag_refiltering = TRUE;
 		return get_kdump_compressed_header_info(info->name_memory);
-	} else if (status == FALSE) {
-		return TRUE;
-	} else {
-		return FALSE;
 	}
+
+	status = check_and_get_sadump_header_info(info->name_memory);
+	if (status == TRUE)
+		return TRUE;
+
+	if (status == ERROR)
+		return TRUE;
+
+	return FALSE;
 }
 
 int
@@ -3007,7 +3012,7 @@ dump_dmesg()
 	if (!open_files_for_creating_dumpfile())
 		return FALSE;
 
-	if (!info->flag_refiltering) {
+	if (!info->flag_refiltering && !info->flag_sadump) {
 		if (!get_elf_info(info->fd_memory, info->name_memory))
 			return FALSE;
 	}
@@ -5757,7 +5762,7 @@ create_dumpfile(void)
 	if (!open_files_for_creating_dumpfile())
 		return FALSE;
 
-	if (!info->flag_refiltering) {
+	if (!info->flag_refiltering && !info->flag_sadump) {
 		if (!get_elf_info(info->fd_memory, info->name_memory))
 			return FALSE;
 	}
diff --git a/sadump_info.c b/sadump_info.c
index c94d233..2f66148 100644
--- a/sadump_info.c
+++ b/sadump_info.c
@@ -20,6 +20,7 @@
 
 #include "makedumpfile.h"
 #include "print_info.h"
+#include "sadump_mod.h"
 
 struct sadump_diskset_info {
 	char *name_memory;
@@ -40,10 +41,470 @@ struct sadump_info {
 	unsigned long data_offset;
 };
 
+static char *guid_to_str(efi_guid_t *guid, char *buf, size_t buflen);
+static struct tm *efi_time_t_to_tm(const efi_time_t *e);
+static int verify_magic_number(uint32_t magicnum[DUMP_PART_HEADER_MAGICNUM_SIZE]);
+static int read_device(void *buf, size_t bytes, ulong *offset);
+static int read_device_diskset(struct sadump_diskset_info *sdi, void *buf,
+			       size_t bytes, ulong *offset);
+static int read_sadump_header(char *filename);
+static int read_sadump_header_diskset(int diskid, struct sadump_diskset_info *sdi);
+
 static struct sadump_info sadump_info = {};
 static struct sadump_info *si = &sadump_info;
 
 int
+check_and_get_sadump_header_info(char *filename)
+{
+	int i;
+
+	if (!read_sadump_header(filename))
+		return FALSE;
+
+	if (info->flag_sadump_diskset && info->flag_sadump == SADUMP_DISKSET) {
+
+		si->diskset_info[0].fd_memory = info->fd_memory;
+		si->diskset_info[0].sph_memory = si->sph_memory;
+		si->diskset_info[0].data_offset = si->data_offset;
+
+		for (i = 1; i < si->num_disks; ++i) {
+			struct sadump_diskset_info *sdi =
+				&si->diskset_info[i];
+
+			if ((sdi->fd_memory =
+			     open(sdi->name_memory, O_RDONLY)) < 0) {
+				ERRMSG("Can't open the dump diskset "
+				       "memory(%s). %s\n", sdi->name_memory,
+				       strerror(errno));
+				return FALSE;
+			}
+
+			if (!read_sadump_header_diskset(i, sdi))
+				return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+static char *
+guid_to_str(efi_guid_t *guid, char *buf, size_t buflen)
+{
+	snprintf(buf, buflen,
+		 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+		 guid->data1, guid->data2, guid->data3,
+		 guid->data4[0], guid->data4[1], guid->data4[2],
+		 guid->data4[3], guid->data4[4], guid->data4[5],
+		 guid->data4[6], guid->data4[7]);
+
+	return buf;
+}
+
+static struct tm *
+efi_time_t_to_tm(const efi_time_t *e)
+{
+	static struct tm t;
+	time_t ti;
+
+	memset(&t, 0, sizeof(t));
+
+	t.tm_sec  = e->second;
+	t.tm_min  = e->minute;
+	t.tm_hour = e->hour;
+	t.tm_mday = e->day;
+	t.tm_mon  = e->month - 1;
+	t.tm_year = e->year - 1900;
+
+	if (e->timezone != EFI_UNSPECIFIED_TIMEZONE)
+		t.tm_hour += e->timezone;
+
+	else
+		DEBUG_MSG("sadump: timezone information is missing\n");
+
+	ti = mktime(&t);
+	if (ti == (time_t)-1)
+		return &t;
+
+	return localtime_r(&ti, &t);
+}
+
+static int
+verify_magic_number(uint32_t magicnum[DUMP_PART_HEADER_MAGICNUM_SIZE])
+{
+	int i;
+
+	for (i = 1; i < DUMP_PART_HEADER_MAGICNUM_SIZE; ++i)
+		if (magicnum[i] != (magicnum[i - 1] + 7) * 11)
+			return FALSE;
+
+	return TRUE;
+}
+
+static int
+read_device(void *buf, size_t bytes, ulong *offset)
+{
+	if (lseek(info->fd_memory, *offset, SEEK_SET) < 0) {
+		ERRMSG("Can't seek a file(%s). %s\n",
+		       info->name_memory, strerror(errno));
+		return FALSE;
+	}
+	if (read(info->fd_memory, buf, bytes) != bytes) {
+		ERRMSG("Can't read a file(%s). %s\n",
+		       info->name_memory, strerror(errno));
+		return FALSE;
+	}
+	*offset += bytes;
+	return TRUE;
+}
+
+static int
+read_device_diskset(struct sadump_diskset_info *sdi, void *buf,
+		    size_t bytes, unsigned long *offset)
+{
+	if (lseek(sdi->fd_memory, *offset, SEEK_SET) < 0) {
+		ERRMSG("Can't seek a file(%s). %s\n",
+		       sdi->name_memory, strerror(errno));
+		return FALSE;
+	}
+	if (read(sdi->fd_memory, buf, bytes) != bytes) {
+		ERRMSG("Can't read a file(%s). %s\n",
+		       sdi->name_memory, strerror(errno));
+		return FALSE;
+	}
+	*offset += bytes;
+	return TRUE;
+}
+
+static int
+read_sadump_header(char *filename)
+{
+	struct sadump_part_header *sph = NULL;
+	struct sadump_header *sh = NULL;
+	struct sadump_disk_set_header *sdh = NULL;
+	struct sadump_media_header *smh = NULL;
+	unsigned long offset = 0, sub_hdr_offset;
+	unsigned long block_size = SADUMP_DEFAULT_BLOCK_SIZE;
+	unsigned long bitmap_len, dumpable_bitmap_len;
+	enum sadump_format_type flag_sadump;
+	uint32_t smram_cpu_state_size = 0;
+	char guid[33];
+
+	if ((si->sph_memory = malloc(SADUMP_DEFAULT_BLOCK_SIZE)) == NULL) {
+		ERRMSG("Can't allocate memory for partition header buffer: "
+		       "%s\n", strerror(errno));
+		return FALSE;
+	}
+
+	if ((si->sh_memory = malloc(SADUMP_DEFAULT_BLOCK_SIZE)) == NULL) {
+		ERRMSG("Can't allocate memory for dump header buffer: "
+		       "%s\n", strerror(errno));
+		return FALSE;
+	}
+
+	if ((si->sdh_memory = malloc(SADUMP_DEFAULT_BLOCK_SIZE)) == NULL) {
+		ERRMSG("Can't allocate memory for disk set header buffer: "
+		       "%s\n", strerror(errno));
+		return FALSE;
+	}
+
+	if ((si->smh_memory = malloc(SADUMP_DEFAULT_BLOCK_SIZE)) == NULL) {
+		ERRMSG("Can't allocate memory for media header buffer: "
+		       "%s\n", strerror(errno));
+		return FALSE;
+	}
+
+	sph = si->sph_memory;
+	sh = si->sh_memory;
+	sdh = si->sdh_memory;
+	smh = si->smh_memory;
+
+restart:
+	if (block_size < 0)
+		return FALSE;
+
+	if (!read_device(sph, block_size, &offset))
+		return ERROR;
+
+	if (sph->signature1 == SADUMP_SIGNATURE1 &&
+	    sph->signature2 == SADUMP_SIGNATURE2) {
+
+		if (sph->set_disk_set == 0) {
+
+			flag_sadump = SADUMP_SINGLE_PARTITION;
+
+			DEBUG_MSG("sadump: read dump device as single partition\n");
+
+		} else {
+
+			flag_sadump = SADUMP_DISKSET;
+
+			DEBUG_MSG("sadump: read dump device as diskset\n");
+
+		}
+
+	} else {
+
+		offset = 0;
+
+		if (!read_device(smh, block_size, &offset))
+			return ERROR;
+
+		if (!read_device(sph, block_size, &offset))
+			return ERROR;
+
+		if (sph->signature1 != SADUMP_SIGNATURE1 ||
+		    sph->signature2 != SADUMP_SIGNATURE2) {
+
+			DEBUG_MSG("sadump: does not have partition header\n");
+
+			flag_sadump = SADUMP_UNKNOWN;
+
+			DEBUG_MSG("sadump: read dump device as unknown format\n");
+
+			goto out;
+		}
+
+		flag_sadump = SADUMP_MEDIA_BACKUP;
+
+		DEBUG_MSG("sadump: read dump device as media backup format\n");
+
+	}
+
+	if (!verify_magic_number(sph->magicnum)) {
+		DEBUG_MSG("sadump: invalid magic number\n");
+		return FALSE;
+	}
+
+	if (flag_sadump == SADUMP_DISKSET) {
+		uint32_t header_blocks;
+		size_t header_size;
+
+		if (sph->set_disk_set != 1) {
+			DEBUG_MSG("sadump: id of this disk is %d\n",
+				  sph->set_disk_set);
+			return FALSE;
+		}
+
+		if (!read_device(&header_blocks, sizeof(uint32_t),
+					&offset))
+			return FALSE;
+
+		offset -= sizeof(uint32_t);
+		header_size = header_blocks * block_size;
+
+		if (header_size > block_size) {
+			sdh = realloc(sdh, header_size);
+			if (!sdh) {
+				ERRMSG("Can't allocate memory for disk "
+				       "set memory\n");
+				return FALSE;
+			}
+		}
+
+		if (!read_device(sdh, header_size, &offset))
+			return ERROR;
+
+		DEBUG_MSG("sadump: the diskset consists of %u disks\n",
+			  sdh->disk_num);
+
+	}
+
+	if (!read_device(sh, block_size, &offset))
+		return FALSE;
+
+	sub_hdr_offset = offset;
+
+	if (strncmp(sh->signature, SADUMP_SIGNATURE, 8) != 0) {
+		DEBUG_MSG("sadump: does not have dump header\n");
+		return FALSE;
+	}
+
+	if (flag_sadump == SADUMP_MEDIA_BACKUP) {
+
+		if (memcmp(&sph->sadump_id, &smh->sadump_id,
+			   sizeof(efi_guid_t)) != 0) {
+			DEBUG_MSG("sadump: system ID mismatch\n");
+			DEBUG_MSG("  partition header: %s\n",
+				  guid_to_str(&sph->sadump_id, guid,
+					      sizeof(guid)));
+			DEBUG_MSG("  media header: %s\n",
+				  guid_to_str(&smh->sadump_id, guid,
+					      sizeof(guid)));
+			return FALSE;
+		}
+
+		if (memcmp(&sph->disk_set_id, &smh->disk_set_id,
+			   sizeof(efi_guid_t)) != 0) {
+			DEBUG_MSG("sadump: disk set ID mismtch\n");
+			DEBUG_MSG("  partition header: %s\n",
+				  guid_to_str(&sph->disk_set_id, guid,
+					      sizeof(guid)));
+			DEBUG_MSG("  media header: %s\n",
+				  guid_to_str(&smh->disk_set_id, guid,
+					      sizeof(guid)));
+			return FALSE;
+		}
+
+		if (memcmp(&sph->time_stamp, &smh->time_stamp,
+			   sizeof(efi_time_t)) != 0) {
+			DEBUG_MSG("sadump: time stamp mismatch\n");
+			DEBUG_MSG("  partition header: %s",
+				  asctime(efi_time_t_to_tm(&sph->time_stamp)));
+			DEBUG_MSG("  media header: %s",
+				  asctime(efi_time_t_to_tm(&smh->time_stamp)));
+		}
+
+		if (smh->sequential_num != 1) {
+			DEBUG_MSG("sadump: first media file has sequential "
+				  "number %d\n", smh->sequential_num);
+			return FALSE;
+		}
+
+	}
+
+	if (sh->block_size != block_size) {
+		block_size = sh->block_size;
+		offset = 0;
+		goto restart;
+	}
+
+	if (sh->sub_hdr_size > 0) {
+		if (!read_device(&smram_cpu_state_size, sizeof(uint32_t),
+				 &offset)) {
+			DEBUG_MSG("sadump: cannot read SMRAM CPU STATE size\n");
+			return FALSE;
+		}
+		smram_cpu_state_size /= sh->nr_cpus;
+
+		offset -= sizeof(uint32_t);
+		offset += sh->sub_hdr_size * block_size;
+	}
+
+	if (!sh->bitmap_blocks) {
+		DEBUG_MSG("sadump: bitmap_blocks is zero\n");
+		return FALSE;
+	}
+
+	if (!sh->dumpable_bitmap_blocks) {
+		DEBUG_MSG("sadump: dumpable_bitmap_blocks is zero\n");
+		return FALSE;
+	}
+
+	bitmap_len = block_size * sh->bitmap_blocks;
+	dumpable_bitmap_len = block_size * sh->dumpable_bitmap_blocks;
+
+	si->sub_hdr_offset = sub_hdr_offset;
+	si->smram_cpu_state_size = smram_cpu_state_size;
+	si->data_offset = offset + bitmap_len + dumpable_bitmap_len;
+
+out:
+	switch (flag_sadump) {
+	case SADUMP_SINGLE_PARTITION:
+		DEBUG_MSG("sadump: single partition configuration\n");
+		break;
+	case SADUMP_DISKSET:
+		DEBUG_MSG("sadump: diskset configuration with %d disks\n",
+			  sdh->disk_num);
+		break;
+	case SADUMP_MEDIA_BACKUP:
+		DEBUG_MSG("sadump: media backup file\n");
+		break;
+	case SADUMP_UNKNOWN:
+		DEBUG_MSG("sadump: unknown format\n");
+		break;
+	}
+
+	info->flag_sadump = flag_sadump;
+
+	return TRUE;
+}
+
+static int
+read_sadump_header_diskset(int diskid, struct sadump_diskset_info *sdi)
+{
+	struct sadump_part_header *sph = NULL;
+	unsigned long offset = 0;
+	char guid[33];
+
+	if ((sph = malloc(si->sh_memory->block_size)) == NULL) {
+		ERRMSG("Can't allocate memory for partition header buffer. "
+		       "%s\n", strerror(errno));
+		goto error;
+	}
+
+	if (!read_device_diskset(sdi, sph, si->sh_memory->block_size,
+				 &offset))
+		goto error;
+
+	if (sph->signature1 != SADUMP_SIGNATURE1 ||
+	    sph->signature2 != SADUMP_SIGNATURE2) {
+		DEBUG_MSG("sadump: does not have partition header\n");
+		free(sph);
+		goto error;
+	}
+
+	if (memcmp(&si->sph_memory->sadump_id, &sph->sadump_id,
+		   sizeof(efi_guid_t)) != 0) {
+		DEBUG_MSG("sadump: system ID mismatch\n");
+		DEBUG_MSG("  partition header on disk #1: %s\n",
+			  guid_to_str(&si->sph_memory->sadump_id, guid,
+				      sizeof(guid)));
+		DEBUG_MSG("  partition header on disk #%d: %s\n", diskid,
+			  guid_to_str(&sph->sadump_id, guid, sizeof(guid)));
+		goto error;
+	}
+
+	if (memcmp(&si->sph_memory->disk_set_id, &sph->disk_set_id,
+		   sizeof(efi_guid_t)) != 0) {
+		DEBUG_MSG("sadump: disk set ID mismatch\n");
+		DEBUG_MSG("  partition header on disk #1: %s\n",
+			  guid_to_str(&si->sph_memory->disk_set_id, guid,
+				      sizeof(guid)));
+		DEBUG_MSG("  partition header on disk #%d: %s\n", diskid,
+			  guid_to_str(&sph->disk_set_id, guid, sizeof(guid)));
+		goto error;
+	}
+
+	if (memcmp(&si->sdh_memory->vol_info[diskid-1].id, &sph->vol_id,
+		   sizeof(efi_guid_t)) != 0) {
+		DEBUG_MSG("sadump: volume ID mismatch\n");
+		DEBUG_MSG("  disk set header on disk #1: %s\n",
+			  guid_to_str(&si->sdh_memory->vol_info[diskid-1].id,
+				      guid, sizeof(guid)));
+		DEBUG_MSG("  partition header on disk #%d: %s\n",
+			  diskid+1,
+			  guid_to_str(&sph->vol_id, guid, sizeof(guid)));
+		goto error;
+	}
+
+	if (memcmp(&si->sph_memory->time_stamp, &sph->time_stamp,
+		   sizeof(efi_time_t)) != 0) {
+		DEBUG_MSG("sadump time stamp mismatch\n");
+		DEBUG_MSG("  partition header on disk #1: %s\n",
+			  asctime(efi_time_t_to_tm
+				  (&si->sph_memory->time_stamp)));
+		DEBUG_MSG("  partition header on disk #%d: %s\n",
+			  diskid, asctime(efi_time_t_to_tm(&sph->time_stamp)));
+	}
+
+	if (diskid+1 != sph->set_disk_set) {
+		DEBUG_MSG("sadump: wrong disk order; #%d expected but #%d given\n",
+			  diskid+1, sph->set_disk_set);
+		goto error;
+	}
+
+	sdi->sph_memory = sph;
+	sdi->data_offset = si->sh_memory->block_size;
+
+	return TRUE;
+
+error:
+	free(sph);
+
+	return FALSE;
+}
+
+int
 sadump_add_diskset_info(char *name_memory)
 {
 	si->num_disks++;
@@ -71,8 +532,25 @@ sadump_head_disk_name_memory(void)
 void
 free_sadump_info(void)
 {
-	if (si->diskset_info)
+	if (si->sph_memory)
+		free(si->sph_memory);
+	if (si->sh_memory)
+		free(si->sh_memory);
+	if (si->sdh_memory)
+		free(si->sdh_memory);
+	if (si->smh_memory)
+		free(si->smh_memory);
+	if (si->diskset_info) {
+		int i;
+
+		for (i = 1; i < si->num_disks; ++i) {
+			if (si->diskset_info[i].fd_memory)
+				close(si->diskset_info[i].fd_memory);
+			if (si->diskset_info[i].sph_memory)
+				free(si->diskset_info[i].sph_memory);
+		}
 		free(si->diskset_info);
+	}
 }
 
 #endif /* defined(__x86__) && defined(__x86_64__) */
diff --git a/sadump_info.h b/sadump_info.h
index 863956d..c54d29f 100644
--- a/sadump_info.h
+++ b/sadump_info.h
@@ -24,6 +24,7 @@
 
 #if defined(__x86__) || defined(__x86_64__)
 
+int check_and_get_sadump_header_info(char *filename);
 int sadump_add_diskset_info(char *name_memory);
 char *sadump_head_disk_name_memory(void);
 void free_sadump_info(void);
@@ -35,6 +36,15 @@ static inline int sadump_is_supported_arch(void)
 
 #else
 
+static inline int check_and_get_sadump_header_info(char *filename)
+{
+	info->flag_sadump = SADUMP_UNKNOWN;
+
+	DEBUG_MSG("sadump: unsupported architecture\n");
+
+	return TRUE;
+}
+
 static inline int sadump_add_diskset_info(char *name_memory)
 {
 	return TRUE;


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 05/14] Export helpers for bitmap table handling
  2011-10-28  9:48 [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format HATAYAMA Daisuke
                   ` (3 preceding siblings ...)
  2011-10-28  9:48 ` [PATCH v2 04/14] Verify and read VMCORE(s) in sadump-related formats HATAYAMA Daisuke
@ 2011-10-28  9:48 ` HATAYAMA Daisuke
  2011-10-28  9:48 ` [PATCH v2 06/14] Initialize internal data according to sadump-related formats HATAYAMA Daisuke
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-10-28  9:48 UTC (permalink / raw)
  To: kexec

sadump-related formats and kdump-compressed format is similar in
structure. In particular, both have exactly the same in bitmap. So
reuse two helper functions, is_on() and is_dumpable(), in sadump
module.

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

 makedumpfile.c |   22 ----------------------
 makedumpfile.h |   24 ++++++++++++++++++++++++
 2 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index 7057009..96faf60 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -2543,28 +2543,6 @@ clear_bit_on_2nd_bitmap_for_kernel(unsigned long long pfn)
 }
 
 static inline int
-is_on(char *bitmap, int i)
-{
-	return bitmap[i>>3] & (1 << (i & 7));
-}
-
-static inline int
-is_dumpable(struct dump_bitmap *bitmap, unsigned long long pfn)
-{
-	off_t offset;
-	if (pfn == 0 || bitmap->no_block != pfn/PFN_BUFBITMAP) {
-		offset = bitmap->offset + BUFSIZE_BITMAP*(pfn/PFN_BUFBITMAP);
-		lseek(bitmap->fd, offset, SEEK_SET);
-		read(bitmap->fd, bitmap->buf, BUFSIZE_BITMAP);
-		if (pfn == 0)
-			bitmap->no_block = 0;
-		else
-			bitmap->no_block = pfn/PFN_BUFBITMAP;
-	}
-	return is_on(bitmap->buf, pfn%PFN_BUFBITMAP);
-}
-
-static inline int
 is_in_segs(unsigned long long paddr)
 {
 	if (info->flag_refiltering) {
diff --git a/makedumpfile.h b/makedumpfile.h
index dee0a68..17ec590 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -56,6 +56,8 @@ enum {
 	FLATMEM
 };
 
+int get_mem_type(void);
+
 /*
  * Page flags
  *
@@ -1244,4 +1246,26 @@ int get_xen_info_ia64(void);
 #define get_xen_info_arch(X) FALSE
 #endif	/* s390x */
 
+static inline int
+is_on(char *bitmap, int i)
+{
+	return bitmap[i>>3] & (1 << (i & 7));
+}
+
+static inline int
+is_dumpable(struct dump_bitmap *bitmap, unsigned long long pfn)
+{
+	off_t offset;
+	if (pfn == 0 || bitmap->no_block != pfn/PFN_BUFBITMAP) {
+		offset = bitmap->offset + BUFSIZE_BITMAP*(pfn/PFN_BUFBITMAP);
+		lseek(bitmap->fd, offset, SEEK_SET);
+		read(bitmap->fd, bitmap->buf, BUFSIZE_BITMAP);
+		if (pfn == 0)
+			bitmap->no_block = 0;
+		else
+			bitmap->no_block = pfn/PFN_BUFBITMAP;
+	}
+	return is_on(bitmap->buf, pfn%PFN_BUFBITMAP);
+}
+
 #endif /* MAKEDUMPFILE_H */


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 06/14] Initialize internal data according to sadump-related formats
  2011-10-28  9:48 [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format HATAYAMA Daisuke
                   ` (4 preceding siblings ...)
  2011-10-28  9:48 ` [PATCH v2 05/14] Export helpers for bitmap table handling HATAYAMA Daisuke
@ 2011-10-28  9:48 ` HATAYAMA Daisuke
  2011-10-28  9:48 ` [PATCH v2 07/14] Initialize debug information for ELF note extraction HATAYAMA Daisuke
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-10-28  9:48 UTC (permalink / raw)
  To: kexec

Set page_size, nr_cpus and time stamp. Also, initialize bitmap table
in the same way as initialize_bitmap_memory() for kdump-compressed
format.

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

 makedumpfile.c |   28 +++++++++++
 sadump_info.c  |  144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |   36 ++++++++++++++
 sadump_mod.h   |    2 +
 4 files changed, 210 insertions(+), 0 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index 96faf60..c5ea9ce 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -119,6 +119,12 @@ get_max_mapnr(void)
 		info->max_mapnr = info->dh_memory->max_mapnr;
 		return TRUE;
 	}
+
+	if (info->flag_sadump) {
+		info->max_mapnr = sadump_get_max_mapnr();
+		return TRUE;
+	}
+
 	max_paddr = get_max_paddr();
 	info->max_mapnr = paddr_to_pfn(max_paddr);
 
@@ -2305,6 +2311,28 @@ initial(void)
 		if (!initialize_bitmap_memory())
 			return FALSE;
 
+	} else if (info->flag_sadump) {
+		int nr_cpus;
+
+		if (info->flag_elf_dumpfile) {
+			MSG("'-E' option is disable, ");
+			MSG("because %s is sadump %s format.\n",
+			    info->name_memory, sadump_format_type_name());
+			return FALSE;
+		}
+
+		set_page_size(sadump_page_size());
+
+		if (!sadump_initialize_bitmap_memory())
+			return FALSE;
+
+		if (!sadump_get_nr_cpus(&nr_cpus))
+			return FALSE;
+
+		set_nr_cpus(nr_cpus);
+
+		(void) sadump_set_timestamp(&info->timestamp);
+
 	} else if (!get_phys_base())
 		return FALSE;
 
diff --git a/sadump_info.c b/sadump_info.c
index 2f66148..2efeb63 100644
--- a/sadump_info.c
+++ b/sadump_info.c
@@ -39,6 +39,7 @@ struct sadump_info {
 	unsigned long sub_hdr_offset;
 	uint32_t smram_cpu_state_size;
 	unsigned long data_offset;
+	unsigned long long *block_table;
 };
 
 static char *guid_to_str(efi_guid_t *guid, char *buf, size_t buflen);
@@ -505,6 +506,125 @@ error:
 }
 
 int
+sadump_initialize_bitmap_memory(void)
+{
+	struct sadump_header *sh = si->sh_memory;
+	struct dump_bitmap *bmp;
+	unsigned long dumpable_bitmap_offset, dumpable_bitmap_len;
+	unsigned long long section, max_section, pfn;
+	unsigned long long *block_table;
+
+	dumpable_bitmap_offset =
+		si->sub_hdr_offset +
+		sh->block_size * (sh->sub_hdr_size + sh->bitmap_blocks);
+
+	dumpable_bitmap_len = sh->block_size * sh->dumpable_bitmap_blocks;
+
+	bmp = malloc(sizeof(struct dump_bitmap));
+	if (bmp == NULL) {
+		ERRMSG("Can't allocate memory for the memory-bitmap. %s\n",
+		       strerror(errno));
+		return FALSE;
+	}
+	bmp->fd = info->fd_memory;
+	bmp->file_name = info->name_memory;
+	bmp->no_block = -1;
+	memset(bmp->buf, 0, BUFSIZE_BITMAP);
+	bmp->offset = dumpable_bitmap_offset;
+
+	max_section = divideup(sh->max_mapnr, SADUMP_PF_SECTION_NUM);
+
+	block_table = calloc(sizeof(unsigned long long), max_section);
+	if (block_table == NULL) {
+		ERRMSG("Can't allocate memory for the block_table. %s\n",
+		       strerror(errno));
+		free(bmp);
+		return FALSE;
+	}
+
+	for (section = 0; section < max_section; ++section) {
+		if (section > 0)
+			block_table[section] = block_table[section-1];
+		for (pfn = section * SADUMP_PF_SECTION_NUM;
+		     pfn < (section + 1) * SADUMP_PF_SECTION_NUM;
+		     ++pfn)
+			if (is_dumpable(bmp, pfn))
+				block_table[section]++;
+	}
+
+	info->bitmap_memory = bmp;
+	si->block_table = block_table;
+
+	return TRUE;
+}
+
+int
+sadump_get_nr_cpus(int *nr_cpus)
+{
+	unsigned long offset;
+	struct sadump_smram_cpu_state scs, zero;
+	uint32_t x_cpu;
+	int count;
+
+	memset(&zero, 0, sizeof(zero));
+
+	offset = si->sub_hdr_offset + sizeof(uint32_t) +
+		si->sh_memory->nr_cpus * sizeof(struct sadump_apic_state);
+
+	count = 0;
+	for (x_cpu = 0; x_cpu < si->sh_memory->nr_cpus; ++x_cpu) {
+		if (!read_device(&scs, sizeof(scs), &offset))
+			return FALSE;
+		if (memcmp(&scs, &zero, sizeof(scs)) != 0)
+			count++;
+	}
+
+	*nr_cpus = count;
+
+	DEBUG_MSG("sadump: nr_cpus: %d\n", *nr_cpus);
+
+	return TRUE;
+}
+
+int
+sadump_set_timestamp(struct timeval *ts)
+{
+	static struct tm t;
+	efi_time_t *e = &si->sph_memory->time_stamp;
+	time_t ti;
+
+	memset(&t, 0, sizeof(t));
+
+	t.tm_sec  = e->second;
+	t.tm_min  = e->minute;
+	t.tm_hour = e->hour;
+	t.tm_mday = e->day;
+	t.tm_mon  = e->month - 1;
+	t.tm_year = e->year - 1900;
+
+	if (e->timezone != EFI_UNSPECIFIED_TIMEZONE)
+		t.tm_hour += e->timezone;
+
+	else
+		DEBUG_MSG("sadump: timezone information is missing\n");
+
+	ti = mktime(&t);
+	if (ti == (time_t)-1)
+		return FALSE;
+
+	ts->tv_sec = ti;
+	ts->tv_usec = 0;
+
+	return TRUE;
+}
+
+unsigned long long
+sadump_get_max_mapnr(void)
+{
+	return si->sh_memory->max_mapnr;
+}
+
+int
 sadump_add_diskset_info(char *name_memory)
 {
 	si->num_disks++;
@@ -523,12 +643,34 @@ sadump_add_diskset_info(char *name_memory)
 	return TRUE;
 }
 
+long
+sadump_page_size(void)
+{
+	return si->sh_memory->block_size;
+}
+
 char *
 sadump_head_disk_name_memory(void)
 {
 	return si->diskset_info[0].name_memory;
 }
 
+char *
+sadump_format_type_name(void)
+{
+	switch (info->flag_sadump) {
+	case SADUMP_SINGLE_PARTITION:
+		return "single partition";
+	case SADUMP_DISKSET:
+		return "diskset";
+	case SADUMP_MEDIA_BACKUP:
+		return "media backup";
+	case SADUMP_UNKNOWN:
+		return "unknown";
+	}
+	return NULL;
+}
+
 void
 free_sadump_info(void)
 {
@@ -551,6 +693,8 @@ free_sadump_info(void)
 		}
 		free(si->diskset_info);
 	}
+	if (si->block_table)
+		free(si->block_table);
 }
 
 #endif /* defined(__x86__) && defined(__x86_64__) */
diff --git a/sadump_info.h b/sadump_info.h
index c54d29f..0a04141 100644
--- a/sadump_info.h
+++ b/sadump_info.h
@@ -25,8 +25,14 @@
 #if defined(__x86__) || defined(__x86_64__)
 
 int check_and_get_sadump_header_info(char *filename);
+int sadump_initialize_bitmap_memory(void);
+int sadump_get_nr_cpus(int *nr_cpus);
+int sadump_set_timestamp(struct timeval *ts);
+unsigned long long sadump_get_max_mapnr(void);
 int sadump_add_diskset_info(char *name_memory);
+long sadump_page_size(void);
 char *sadump_head_disk_name_memory(void);
+char *sadump_format_type_name(void);
 void free_sadump_info(void);
 
 static inline int sadump_is_supported_arch(void)
@@ -45,17 +51,47 @@ static inline int check_and_get_sadump_header_info(char *filename)
 	return TRUE;
 }
 
+static inline int sadump_initialize_bitmap_memory(void)
+{
+	return FALSE;
+}
+
+static inline int sadump_get_nr_cpus(int *nr_cpus)
+{
+	return 0;
+}
+
+static inline int sadump_set_timestamp(struct timeval *ts)
+{
+	return FALSE;
+}
+
+static inline unsigned long long sadump_get_max_mapnr(void)
+{
+	return 0;
+}
+
 static inline int sadump_add_diskset_info(char *name_memory)
 {
 	return TRUE;
 }
 
+static inline long sadump_page_size(void)
+{
+	return 0;
+}
+
 static inline char *
 sadump_head_disk_name_memory(void)
 {
 	return NULL;
 }
 
+static inline char *sadump_format_type_name(void)
+{
+	return NULL;
+}
+
 static inline void free_sadump_info(void)
 {
 	return;
diff --git a/sadump_mod.h b/sadump_mod.h
index 3385123..efd059f 100644
--- a/sadump_mod.h
+++ b/sadump_mod.h
@@ -169,6 +169,8 @@ struct sadump_media_header {
 	char reserve[4044];	// reserve feild
 };
 
+#define SADUMP_PF_SECTION_NUM 4096
+
 #endif /* defined(__x86__) && defined(__x86_64__) */
 
 /*


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 07/14] Initialize debug information for ELF note extraction
  2011-10-28  9:48 [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format HATAYAMA Daisuke
                   ` (5 preceding siblings ...)
  2011-10-28  9:48 ` [PATCH v2 06/14] Initialize internal data according to sadump-related formats HATAYAMA Daisuke
@ 2011-10-28  9:48 ` HATAYAMA Daisuke
  2011-10-28  9:48 ` [PATCH v2 08/14] Implement readmem() interface on sadump-related formats HATAYAMA Daisuke
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-10-28  9:48 UTC (permalink / raw)
  To: kexec

Initialize symbol and type information for acessing VMCORE(s) data.

Note that there's vmlinux not including data for user_regs_struct
type. In such case, we use the actual offset size calculated using
offsetof().

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

 makedumpfile.c |  168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 makedumpfile.h |  130 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 298 insertions(+), 0 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index c5ea9ce..5ceb986 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -19,6 +19,7 @@
 #include "elf_info.h"
 #include "erase_info.h"
 #include "sadump_info.h"
+#include <stddef.h>
 #include <sys/time.h>
 
 struct symbol_table	symbol_table;
@@ -809,6 +810,19 @@ get_symbol_info(void)
 	SYMBOL_INIT(log_end, "log_end");
 	SYMBOL_INIT(max_pfn, "max_pfn");
 	SYMBOL_INIT(modules, "modules");
+	SYMBOL_INIT(linux_banner, "linux_banner");
+	SYMBOL_INIT(bios_cpu_apicid, "bios_cpu_apicid");
+	SYMBOL_INIT(x86_bios_cpu_apicid, "x86_bios_cpu_apicid");
+	if (SYMBOL(x86_bios_cpu_apicid) == NOT_FOUND_SYMBOL)
+		SYMBOL_INIT(x86_bios_cpu_apicid,
+			    "per_cpu__x86_bios_cpu_apicid");
+	SYMBOL_INIT(x86_bios_cpu_apicid_early_ptr,
+		    "x86_bios_cpu_apicid_early_ptr");
+	SYMBOL_INIT(x86_bios_cpu_apicid_early_map,
+		    "x86_bios_cpu_apicid_early_map");
+	SYMBOL_INIT(crash_notes, "crash_notes");
+	SYMBOL_INIT(__per_cpu_load, "__per_cpu_load");
+	SYMBOL_INIT(__per_cpu_offset, "__per_cpu_offset");
 
 	if (SYMBOL(node_data) != NOT_FOUND_SYMBOL)
 		SYMBOL_ARRAY_TYPE_INIT(node_data, "node_data");
@@ -818,6 +832,8 @@ get_symbol_info(void)
 		SYMBOL_ARRAY_LENGTH_INIT(mem_section, "mem_section");
 	if (SYMBOL(node_memblk) != NOT_FOUND_SYMBOL)
 		SYMBOL_ARRAY_LENGTH_INIT(node_memblk, "node_memblk");
+	if (SYMBOL(__per_cpu_offset) != NOT_FOUND_SYMBOL)
+		SYMBOL_ARRAY_LENGTH_INIT(__per_cpu_offset, "__per_cpu_offset");
 
 	return TRUE;
 }
@@ -934,6 +950,158 @@ get_structure_info(void)
 
 	TYPEDEF_SIZE_INIT(nodemask_t, "nodemask_t");
 
+	SIZE_INIT(percpu_data, "percpu_data");
+
+	/*
+	 * Get offset of the elf_prstatus members.
+	 */
+	SIZE_INIT(elf_prstatus, "elf_prstatus");
+	OFFSET_INIT(elf_prstatus.pr_reg, "elf_prstatus", "pr_reg");
+
+	/*
+	 * Get offset of the user_regs_struct members.
+	 */
+	SIZE_INIT(user_regs_struct, "user_regs_struct");
+
+#ifdef __x86__
+	if (SIZE(user_regs_struct) != NOT_FOUND_STRUCTURE) {
+		OFFSET_INIT(user_regs_struct.bx, "user_regs_struct", "bx");
+		OFFSET_INIT(user_regs_struct.cx, "user_regs_struct", "cx");
+		OFFSET_INIT(user_regs_struct.dx, "user_regs_struct", "dx");
+		OFFSET_INIT(user_regs_struct.si, "user_regs_struct", "si");
+		OFFSET_INIT(user_regs_struct.di, "user_regs_struct", "di");
+		OFFSET_INIT(user_regs_struct.bp, "user_regs_struct", "bp");
+		OFFSET_INIT(user_regs_struct.ax, "user_regs_struct", "ax");
+		OFFSET_INIT(user_regs_struct.ds, "user_regs_struct", "ds");
+		OFFSET_INIT(user_regs_struct.es, "user_regs_struct", "es");
+		OFFSET_INIT(user_regs_struct.fs, "user_regs_struct", "fs");
+		OFFSET_INIT(user_regs_struct.gs, "user_regs_struct", "gs");
+		OFFSET_INIT(user_regs_struct.orig_ax, "user_regs_struct",
+			    "orig_ax");
+		OFFSET_INIT(user_regs_struct.ip, "user_regs_struct", "ip");
+		OFFSET_INIT(user_regs_struct.cs, "user_regs_struct", "cs");
+		OFFSET_INIT(user_regs_struct.flags, "user_regs_struct",
+			    "flags");
+		OFFSET_INIT(user_regs_struct.sp, "user_regs_struct", "sp");
+		OFFSET_INIT(user_regs_struct.ss, "user_regs_struct", "ss");
+
+		if (OFFSET(user_regs_struct.bx) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.bx, "user_regs_struct", "ebx");
+		if (OFFSET(user_regs_struct.cx) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.cx, "user_regs_struct", "ecx");
+		if (OFFSET(user_regs_struct.dx) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.dx, "user_regs_struct", "edx");
+		if (OFFSET(user_regs_struct.si) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.si, "user_regs_struct", "esi");
+		if (OFFSET(user_regs_struct.di) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.di, "user_regs_struct", "edi");
+		if (OFFSET(user_regs_struct.bp) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.bp, "user_regs_struct", "ebp");
+		if (OFFSET(user_regs_struct.ax) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.ax, "user_regs_struct", "eax");
+		if (OFFSET(user_regs_struct.orig_ax) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.orig_ax, "user_regs_struct", "orig_eax");
+		if (OFFSET(user_regs_struct.ip) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.ip, "user_regs_struct", "eip");
+		if (OFFSET(user_regs_struct.flags) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.flags, "user_regs_struct", "eflags");
+		if (OFFSET(user_regs_struct.sp) == NOT_FOUND_STRUCTURE)
+			OFFSET_INIT(user_regs_struct.sp, "user_regs_struct", "esp");
+	} else {
+		/*
+		 * Note: Sometimes kernel debuginfo doesn't contain
+		 * user_regs_struct structure information. Instead, we
+		 * take offsets from actual datatype.
+		 */
+		OFFSET(user_regs_struct.bx) = offsetof(struct user_regs_struct, bx);
+		OFFSET(user_regs_struct.cx) = offsetof(struct user_regs_struct, cx);
+		OFFSET(user_regs_struct.dx) = offsetof(struct user_regs_struct, dx);
+		OFFSET(user_regs_struct.si) = offsetof(struct user_regs_struct, si);
+		OFFSET(user_regs_struct.di) = offsetof(struct user_regs_struct, di);
+		OFFSET(user_regs_struct.bp) = offsetof(struct user_regs_struct, bp);
+		OFFSET(user_regs_struct.ax) = offsetof(struct user_regs_struct, ax);
+		OFFSET(user_regs_struct.ds) = offsetof(struct user_regs_struct, ds);
+		OFFSET(user_regs_struct.es) = offsetof(struct user_regs_struct, es);
+		OFFSET(user_regs_struct.fs) = offsetof(struct user_regs_struct, fs);
+		OFFSET(user_regs_struct.gs) = offsetof(struct user_regs_struct, gs);
+		OFFSET(user_regs_struct.orig_ax) = offsetof(struct user_regs_struct, orig_ax);
+		OFFSET(user_regs_struct.ip) = offsetof(struct user_regs_struct, ip);
+		OFFSET(user_regs_struct.cs) = offsetof(struct user_regs_struct, cs);
+		OFFSET(user_regs_struct.flags) = offsetof(struct user_regs_struct, flags);
+		OFFSET(user_regs_struct.sp) = offsetof(struct user_regs_struct, sp);
+		OFFSET(user_regs_struct.ss) = offsetof(struct user_regs_struct, ss);
+	}
+#endif /* __x86__ */
+
+#ifdef __x86_64__
+	if (SIZE(user_regs_struct) != NOT_FOUND_STRUCTURE) {
+		OFFSET_INIT(user_regs_struct.r15, "user_regs_struct", "r15");
+		OFFSET_INIT(user_regs_struct.r14, "user_regs_struct", "r14");
+		OFFSET_INIT(user_regs_struct.r13, "user_regs_struct", "r13");
+		OFFSET_INIT(user_regs_struct.r12, "user_regs_struct", "r12");
+		OFFSET_INIT(user_regs_struct.bp, "user_regs_struct", "bp");
+		OFFSET_INIT(user_regs_struct.bx, "user_regs_struct", "bx");
+		OFFSET_INIT(user_regs_struct.r11, "user_regs_struct", "r11");
+		OFFSET_INIT(user_regs_struct.r10, "user_regs_struct", "r10");
+		OFFSET_INIT(user_regs_struct.r9, "user_regs_struct", "r9");
+		OFFSET_INIT(user_regs_struct.r8, "user_regs_struct", "r8");
+		OFFSET_INIT(user_regs_struct.ax, "user_regs_struct", "ax");
+		OFFSET_INIT(user_regs_struct.cx, "user_regs_struct", "cx");
+		OFFSET_INIT(user_regs_struct.dx, "user_regs_struct", "dx");
+		OFFSET_INIT(user_regs_struct.si, "user_regs_struct", "si");
+		OFFSET_INIT(user_regs_struct.di, "user_regs_struct", "di");
+		OFFSET_INIT(user_regs_struct.orig_ax, "user_regs_struct",
+			    "orig_ax");
+		OFFSET_INIT(user_regs_struct.ip, "user_regs_struct", "ip");
+		OFFSET_INIT(user_regs_struct.cs, "user_regs_struct", "cs");
+		OFFSET_INIT(user_regs_struct.flags, "user_regs_struct",
+			    "flags");
+		OFFSET_INIT(user_regs_struct.sp, "user_regs_struct", "sp");
+		OFFSET_INIT(user_regs_struct.ss, "user_regs_struct", "ss");
+		OFFSET_INIT(user_regs_struct.fs_base, "user_regs_struct",
+			    "fs_base");
+		OFFSET_INIT(user_regs_struct.gs_base, "user_regs_struct",
+			    "gs_base");
+		OFFSET_INIT(user_regs_struct.ds, "user_regs_struct", "ds");
+		OFFSET_INIT(user_regs_struct.es, "user_regs_struct", "es");
+		OFFSET_INIT(user_regs_struct.fs, "user_regs_struct", "fs");
+		OFFSET_INIT(user_regs_struct.gs, "user_regs_struct", "gs");
+	} else {
+		/*
+		 * Note: Sometimes kernel debuginfo doesn't contain
+		 * user_regs_struct structure information. Instead, we
+		 * take offsets from actual datatype.
+		 */
+		OFFSET(user_regs_struct.r15) = offsetof(struct user_regs_struct, r15);
+		OFFSET(user_regs_struct.r14) = offsetof(struct user_regs_struct, r14);
+		OFFSET(user_regs_struct.r13) = offsetof(struct user_regs_struct, r13);
+		OFFSET(user_regs_struct.r12) = offsetof(struct user_regs_struct, r12);
+		OFFSET(user_regs_struct.bp) = offsetof(struct user_regs_struct, bp);
+		OFFSET(user_regs_struct.bx) = offsetof(struct user_regs_struct, bx);
+		OFFSET(user_regs_struct.r11) = offsetof(struct user_regs_struct, r11);
+		OFFSET(user_regs_struct.r10) = offsetof(struct user_regs_struct, r10);
+		OFFSET(user_regs_struct.r9) = offsetof(struct user_regs_struct, r9);
+		OFFSET(user_regs_struct.r8) = offsetof(struct user_regs_struct, r8);
+		OFFSET(user_regs_struct.ax) = offsetof(struct user_regs_struct, ax);
+		OFFSET(user_regs_struct.cx) = offsetof(struct user_regs_struct, cx);
+		OFFSET(user_regs_struct.dx) = offsetof(struct user_regs_struct, dx);
+		OFFSET(user_regs_struct.si) = offsetof(struct user_regs_struct, si);
+		OFFSET(user_regs_struct.di) = offsetof(struct user_regs_struct, di);
+		OFFSET(user_regs_struct.orig_ax) = offsetof(struct user_regs_struct, orig_ax);
+		OFFSET(user_regs_struct.ip) = offsetof(struct user_regs_struct, ip);
+		OFFSET(user_regs_struct.cs) = offsetof(struct user_regs_struct, cs);
+		OFFSET(user_regs_struct.flags) = offsetof(struct user_regs_struct, flags);
+		OFFSET(user_regs_struct.sp) = offsetof(struct user_regs_struct, sp);
+		OFFSET(user_regs_struct.ss) = offsetof(struct user_regs_struct, ss);
+		OFFSET(user_regs_struct.fs_base) = offsetof(struct user_regs_struct, fs_base);
+		OFFSET(user_regs_struct.gs_base) = offsetof(struct user_regs_struct, gs_base);
+		OFFSET(user_regs_struct.ds) = offsetof(struct user_regs_struct, ds);
+		OFFSET(user_regs_struct.es) = offsetof(struct user_regs_struct, es);
+		OFFSET(user_regs_struct.fs) = offsetof(struct user_regs_struct, fs);
+		OFFSET(user_regs_struct.gs) = offsetof(struct user_regs_struct, gs);
+	}
+#endif /* __x86_64__ */
+
 	return TRUE;
 }
 
diff --git a/makedumpfile.h b/makedumpfile.h
index 17ec590..433bc49 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -983,6 +983,18 @@ struct symbol_table {
 	 */
 
 	unsigned long long	modules;
+
+	/*
+	 * for sadump
+	 */
+	unsigned long long	linux_banner;
+	unsigned long long	bios_cpu_apicid;
+	unsigned long long	x86_bios_cpu_apicid;
+	unsigned long long	x86_bios_cpu_apicid_early_ptr;
+	unsigned long long	x86_bios_cpu_apicid_early_map;
+	unsigned long long	crash_notes;
+	unsigned long long	__per_cpu_offset;
+	unsigned long long	__per_cpu_load;
 };
 
 struct size_table {
@@ -1005,6 +1017,13 @@ struct size_table {
 	 * for loading module symbol data
 	 */
 	long	module;
+
+	/*
+	 * for sadump
+	 */
+	long	percpu_data;
+	long	elf_prstatus;
+	long	user_regs_struct;
 };
 
 struct offset_table {
@@ -1073,6 +1092,46 @@ struct offset_table {
 		long	symtab;
 		long	strtab;
 	} module;
+
+	/*
+	 * for loading elf_prstaus symbol data
+	 */
+	struct elf_prstatus_s {
+		long	pr_reg;
+	} elf_prstatus;
+
+	/*
+	 * for loading user_regs_struct symbol data
+	 */
+	struct user_regs_struct_s {
+		long	r15;
+		long	r14;
+		long	r13;
+		long	r12;
+		long	bp;
+		long	bx;
+		long	r11;
+		long	r10;
+		long	r9;
+		long	r8;
+		long	ax;
+		long	cx;
+		long	dx;
+		long	si;
+		long	di;
+		long	orig_ax;
+		long	ip;
+		long	cs;
+		long	flags;
+		long	sp;
+		long	ss;
+		long	fs_base;
+		long	gs_base;
+		long	ds;
+		long	es;
+		long	fs;
+		long	gs;
+	} user_regs_struct;
 };
 
 /*
@@ -1086,6 +1145,7 @@ struct array_table {
 	long	pgdat_list;
 	long	mem_section;
 	long	node_memblk;
+	long	__per_cpu_offset;
 
 	/*
 	 * Structure
@@ -1268,4 +1328,74 @@ is_dumpable(struct dump_bitmap *bitmap, unsigned long long pfn)
 	return is_on(bitmap->buf, pfn%PFN_BUFBITMAP);
 }
 
+#ifdef __x86__
+
+struct user_regs_struct {
+	unsigned long bx;
+	unsigned long cx;
+	unsigned long dx;
+	unsigned long si;
+	unsigned long di;
+	unsigned long bp;
+	unsigned long ax;
+	unsigned long ds;
+	unsigned long es;
+	unsigned long fs;
+	unsigned long gs;
+	unsigned long orig_ax;
+	unsigned long ip;
+	unsigned long cs;
+	unsigned long flags;
+	unsigned long sp;
+	unsigned long ss;
+};
+
+struct elf_prstatus {
+	char pad1[72];
+	struct user_regs_struct pr_reg;
+	char pad2[4];
+};
+
+#endif
+
+#ifdef __x86_64__
+
+struct user_regs_struct {
+	unsigned long r15;
+	unsigned long r14;
+	unsigned long r13;
+	unsigned long r12;
+	unsigned long bp;
+	unsigned long bx;
+	unsigned long r11;
+	unsigned long r10;
+	unsigned long r9;
+	unsigned long r8;
+	unsigned long ax;
+	unsigned long cx;
+	unsigned long dx;
+	unsigned long si;
+	unsigned long di;
+	unsigned long orig_ax;
+	unsigned long ip;
+	unsigned long cs;
+	unsigned long flags;
+	unsigned long sp;
+	unsigned long ss;
+	unsigned long fs_base;
+	unsigned long gs_base;
+	unsigned long ds;
+	unsigned long es;
+	unsigned long fs;
+	unsigned long gs;
+};
+
+struct elf_prstatus {
+	char pad1[112];
+	struct user_regs_struct pr_reg;
+	char pad2[4];
+};
+
+#endif
+
 #endif /* MAKEDUMPFILE_H */


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 08/14] Implement readmem() interface on sadump-related formats
  2011-10-28  9:48 [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format HATAYAMA Daisuke
                   ` (6 preceding siblings ...)
  2011-10-28  9:48 ` [PATCH v2 07/14] Initialize debug information for ELF note extraction HATAYAMA Daisuke
@ 2011-10-28  9:48 ` HATAYAMA Daisuke
  2011-10-28  9:48 ` [PATCH v2 09/14] Estimate phys_base based on linux_banner position HATAYAMA Daisuke
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-10-28  9:48 UTC (permalink / raw)
  To: kexec

Very similar to the ones in kdump-compressed format.

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

 makedumpfile.c |    8 +++
 sadump_info.c  |  145 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |   13 +++++
 3 files changed, 165 insertions(+), 1 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index 5ceb986..205d3de 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -346,6 +346,9 @@ readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size)
 	if (info->flag_refiltering)
 		return readpmem_kdump_compressed(paddr, bufptr, read_size);
 
+	if (info->flag_sadump)
+		return readpmem_sadump(paddr, bufptr, read_size);
+
 	if (!(offset = paddr_to_offset(paddr))) {
 		ERRMSG("Can't convert a physical address(%llx) to offset.\n",
 		    paddr);
@@ -3436,6 +3439,9 @@ create_1st_bitmap(void)
 	if (info->flag_refiltering)
 		return copy_1st_bitmap_from_memory();
 
+	if (info->flag_sadump)
+		return sadump_copy_1st_bitmap_from_memory();
+
 	/*
 	 * At first, clear all the bits on the 1st-bitmap.
 	 */
@@ -4535,7 +4541,7 @@ read_pfn(unsigned long long pfn, unsigned char *buf)
 	size_t size1, size2;
 
 	paddr = pfn_to_paddr(pfn);
-	if (info->flag_refiltering) {
+	if (info->flag_refiltering || info->flag_sadump) {
 		if (!readmem(PADDR, paddr, buf, info->page_size)) {
 			ERRMSG("Can't get the page data.\n");
 			return FALSE;
diff --git a/sadump_info.c b/sadump_info.c
index 2efeb63..abc81d9 100644
--- a/sadump_info.c
+++ b/sadump_info.c
@@ -50,6 +50,9 @@ static int read_device_diskset(struct sadump_diskset_info *sdi, void *buf,
 			       size_t bytes, ulong *offset);
 static int read_sadump_header(char *filename);
 static int read_sadump_header_diskset(int diskid, struct sadump_diskset_info *sdi);
+static unsigned long long pfn_to_block(unsigned long long pfn);
+static int lookup_diskset(unsigned long long whole_offset, int *diskid,
+			  unsigned long long *disk_offset);
 
 static struct sadump_info sadump_info = {};
 static struct sadump_info *si = &sadump_info;
@@ -88,6 +91,45 @@ check_and_get_sadump_header_info(char *filename)
 	return TRUE;
 }
 
+int
+sadump_copy_1st_bitmap_from_memory(void)
+{
+	struct sadump_header *sh = si->sh_memory;
+	char buf[si->sh_memory->block_size];
+	off_t offset_page;
+	unsigned long bitmap_offset, bitmap_len;
+
+	bitmap_offset =	si->sub_hdr_offset + sh->block_size*sh->sub_hdr_size;
+	bitmap_len = sh->block_size * sh->bitmap_blocks;
+
+	if (lseek(info->fd_memory, bitmap_offset, SEEK_SET) < 0) {
+		ERRMSG("Can't seek %s. %s\n",
+		       info->name_memory, strerror(errno));
+		return FALSE;
+	}
+	if (lseek(info->bitmap1->fd, info->bitmap1->offset, SEEK_SET) < 0) {
+		ERRMSG("Can't seek the bitmap(%s). %s\n",
+		       info->bitmap1->file_name, strerror(errno));
+		return FALSE;
+	}
+	offset_page = 0;
+	while (offset_page < bitmap_len) {
+		if (read(info->fd_memory, buf, sizeof(buf)) != sizeof(buf)) {
+			ERRMSG("Can't read %s. %s\n",
+			       info->name_memory, strerror(errno));
+			return FALSE;
+		}
+		if (write(info->bitmap1->fd, buf, sizeof(buf)) != sizeof(buf)) {
+			ERRMSG("Can't write the bitmap(%s). %s\n",
+			       info->bitmap1->file_name, strerror(errno));
+			return FALSE;
+		}
+		offset_page += sizeof(buf);
+	}
+
+	return TRUE;
+}
+
 static char *
 guid_to_str(efi_guid_t *guid, char *buf, size_t buflen)
 {
@@ -625,6 +667,109 @@ sadump_get_max_mapnr(void)
 }
 
 int
+readpmem_sadump(unsigned long long paddr, void *bufptr, size_t size)
+{
+	unsigned long long pfn, block, whole_offset, perdisk_offset;
+	ulong page_offset;
+	char buf[info->page_size];
+	int fd_memory;
+
+	pfn = paddr_to_pfn(paddr);
+	page_offset = paddr % info->page_size;
+
+	if (pfn >= si->sh_memory->max_mapnr)
+		goto error;
+
+	if (!is_dumpable(info->bitmap_memory, pfn)) {
+		ERRMSG("pfn(%llx) is excluded from %s.\n", pfn,
+		       info->name_memory);
+		goto error;
+	}
+
+	block = pfn_to_block(pfn);
+	whole_offset = block * si->sh_memory->block_size;
+
+	if (info->flag_sadump == SADUMP_DISKSET) {
+		int diskid;
+
+		if (!lookup_diskset(whole_offset, &diskid, &perdisk_offset))
+			goto error;
+
+		fd_memory = si->diskset_info[diskid].fd_memory;
+		perdisk_offset += si->diskset_info[diskid].data_offset;
+
+	} else {
+		fd_memory = info->fd_memory;
+		perdisk_offset = whole_offset + si->data_offset;
+
+	}
+
+	if (lseek(fd_memory, perdisk_offset, SEEK_SET) < 0)
+		goto error;
+
+	if (read(fd_memory, buf, sizeof(buf)) != sizeof(buf))
+		goto error;
+
+	memcpy(bufptr, buf + page_offset, size);
+
+	return size;
+
+error:
+	DEBUG_MSG("type_addr: %d, addr:%llx, size:%zd\n", PADDR, paddr, size);
+
+	return FALSE;
+}
+
+static unsigned long long
+pfn_to_block(unsigned long long pfn)
+{
+	unsigned long long block, section, p;
+
+	section = pfn / SADUMP_PF_SECTION_NUM;
+
+	if (section)
+		block = si->block_table[section - 1];
+	else
+		block = 0;
+
+	for (p = section * SADUMP_PF_SECTION_NUM; p < pfn; ++p)
+		if (is_dumpable(info->bitmap_memory, p))
+			block++;
+
+	return block;
+}
+
+static int
+lookup_diskset(unsigned long long whole_offset, int *diskid,
+	       unsigned long long *disk_offset)
+{
+	unsigned long long offset = whole_offset;
+	int i;
+
+	for (i = 0; i < si->num_disks; ++i) {
+		struct sadump_diskset_info *sdi = &si->diskset_info[i];
+		unsigned long long used_device_i, data_offset_i, ram_size;
+
+		used_device_i = sdi->sph_memory->used_device;
+		data_offset_i = sdi->data_offset;
+
+		ram_size = used_device_i - data_offset_i;
+
+		if (offset < ram_size)
+			break;
+		offset -= ram_size;
+	}
+
+	if (i == si->num_disks)
+		return FALSE;
+
+	*diskid = i;
+	*disk_offset = offset;
+
+	return TRUE;
+}
+
+int
 sadump_add_diskset_info(char *name_memory)
 {
 	si->num_disks++;
diff --git a/sadump_info.h b/sadump_info.h
index 0a04141..b6b9cdd 100644
--- a/sadump_info.h
+++ b/sadump_info.h
@@ -25,10 +25,12 @@
 #if defined(__x86__) || defined(__x86_64__)
 
 int check_and_get_sadump_header_info(char *filename);
+int sadump_copy_1st_bitmap_from_memory(void);
 int sadump_initialize_bitmap_memory(void);
 int sadump_get_nr_cpus(int *nr_cpus);
 int sadump_set_timestamp(struct timeval *ts);
 unsigned long long sadump_get_max_mapnr(void);
+int readpmem_sadump(unsigned long long paddr, void *bufptr, size_t size);
 int sadump_add_diskset_info(char *name_memory);
 long sadump_page_size(void);
 char *sadump_head_disk_name_memory(void);
@@ -51,6 +53,11 @@ static inline int check_and_get_sadump_header_info(char *filename)
 	return TRUE;
 }
 
+static inline int sadump_copy_1st_bitmap_from_memory(void)
+{
+	return FALSE;
+}
+
 static inline int sadump_initialize_bitmap_memory(void)
 {
 	return FALSE;
@@ -71,6 +78,12 @@ static inline unsigned long long sadump_get_max_mapnr(void)
 	return 0;
 }
 
+static inline int readpmem_sadump(unsigned long long paddr,
+				  void *bufptr, size_t size)
+{
+	return FALSE;
+}
+
 static inline int sadump_add_diskset_info(char *name_memory)
 {
 	return TRUE;


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 09/14] Estimate phys_base based on linux_banner position
  2011-10-28  9:48 [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format HATAYAMA Daisuke
                   ` (7 preceding siblings ...)
  2011-10-28  9:48 ` [PATCH v2 08/14] Implement readmem() interface on sadump-related formats HATAYAMA Daisuke
@ 2011-10-28  9:48 ` HATAYAMA Daisuke
  2011-10-28  9:48 ` [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information HATAYAMA Daisuke
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-10-28  9:48 UTC (permalink / raw)
  To: kexec

sadump doesn't save phys_base, so we must estimate it in any way. Here
we borrow the method in crash utility that we search a certain range
of addresses for linux_banner symbol value.

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

 makedumpfile.c |   12 ++++++++++++
 sadump_info.c  |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |   13 +++++++++++++
 3 files changed, 72 insertions(+), 0 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index 205d3de..6e9dd83 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -2504,6 +2504,15 @@ initial(void)
 
 		(void) sadump_set_timestamp(&info->timestamp);
 
+		/*
+		 * NOTE: phys_base is never saved by sadump and so
+		 * must be computed in some way. We here choose the
+		 * way of looking at linux_banner. See
+		 * sadump_virt_phys_base(). The processing is
+		 * postponed until debug information becomes
+		 * available.
+		 */
+
 	} else if (!get_phys_base())
 		return FALSE;
 
@@ -2579,6 +2588,9 @@ out:
 		return FALSE;
 
 	if (debug_info) {
+		if (info->flag_sadump)
+			(void) sadump_virt_phys_base();
+
 		if (!get_machdep_info())
 			return FALSE;
 
diff --git a/sadump_info.c b/sadump_info.c
index abc81d9..adca47b 100644
--- a/sadump_info.c
+++ b/sadump_info.c
@@ -22,6 +22,12 @@
 #include "print_info.h"
 #include "sadump_mod.h"
 
+#ifdef __x86_64__
+
+#define MEGABYTES(x)	((x) * (1048576))
+
+#endif
+
 struct sadump_diskset_info {
 	char *name_memory;
 	int fd_memory;
@@ -666,6 +672,47 @@ sadump_get_max_mapnr(void)
 	return si->sh_memory->max_mapnr;
 }
 
+#ifdef __x86_64__
+
+int
+sadump_virt_phys_base(void)
+{
+        char buf[BUFSIZE];
+        unsigned long phys, linux_banner_phys;
+
+	if (SYMBOL(linux_banner) == NOT_FOUND_SYMBOL) {
+		DEBUG_MSG("sadump: symbol linux_banner is not found\n");
+		goto failed;
+	}
+
+        linux_banner_phys = SYMBOL(linux_banner) - __START_KERNEL_map;
+
+        if (readmem(PADDR, linux_banner_phys + info->phys_base, buf,
+		    strlen("Linux version")) && STRNEQ(buf, "Linux version"))
+                return TRUE;
+
+        for (phys = (-MEGABYTES(16)); phys != MEGABYTES(16+1);
+             phys += MEGABYTES(1)) {
+                if (readmem(PADDR, linux_banner_phys + phys, buf,
+			    strlen("Linux version")) &&
+		    STRNEQ(buf, "Linux version")) {
+                        DEBUG_MSG("sadump: phys_base: %lx %s\n", phys,
+				  info->phys_base != phys ? "override" : "");
+                        info->phys_base = phys;
+                        return TRUE;
+                }
+        }
+
+failed:
+	info->phys_base = 0;
+
+	DEBUG_MSG("sadump: failed to calculate phys_base; default to 0\n");
+
+        return FALSE;
+}
+
+#endif /* __x86_64__ */
+
 int
 readpmem_sadump(unsigned long long paddr, void *bufptr, size_t size)
 {
diff --git a/sadump_info.h b/sadump_info.h
index b6b9cdd..401b769 100644
--- a/sadump_info.h
+++ b/sadump_info.h
@@ -22,6 +22,19 @@
 
 #include "makedumpfile.h"
 
+#ifdef __x86_64__
+
+int sadump_virt_phys_base(void);
+
+#else
+
+static inline int sadump_virt_phys_base(void)
+{
+	return TRUE;
+}
+
+#endif
+
 #if defined(__x86__) || defined(__x86_64__)
 
 int check_and_get_sadump_header_info(char *filename);


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information
  2011-10-28  9:48 [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format HATAYAMA Daisuke
                   ` (8 preceding siblings ...)
  2011-10-28  9:48 ` [PATCH v2 09/14] Estimate phys_base based on linux_banner position HATAYAMA Daisuke
@ 2011-10-28  9:48 ` HATAYAMA Daisuke
  2011-12-20  8:18   ` Atsushi Kumagai
  2011-10-28  9:49 ` [PATCH v2 11/14] Procees CPUs based on online ones HATAYAMA Daisuke
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-10-28  9:48 UTC (permalink / raw)
  To: kexec

Retrieve VMCOREINFO from VMLINUX and ELF note information from
VMCORE(s) and save them in generated DUMPFILE.

ELF note information is NT_PRSTATUS only. If crash_notes is NULL,
indicating kdump has not saved register values, save SMRAM CPU STATE
values. If crash_notes is not NULL, indicating kdump has saved
register values at crash, then save the register values in
crash_notes.

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

 elf_info.c     |    2 
 makedumpfile.c |  103 ++++---
 makedumpfile.h |    2 
 sadump_info.c  |  823 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |   26 ++
 5 files changed, 913 insertions(+), 43 deletions(-)

diff --git a/elf_info.c b/elf_info.c
index 114dd05..48f8510 100644
--- a/elf_info.c
+++ b/elf_info.c
@@ -760,7 +760,7 @@ get_nr_cpus(void)
 int
 has_pt_note(void)
 {
-	if (offset_pt_note_memory && size_pt_note_memory)
+	if (offset_pt_note_memory || size_pt_note_memory)
 		return TRUE;
 	return FALSE;
 }
diff --git a/makedumpfile.c b/makedumpfile.c
index 6e9dd83..750dcb6 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -1221,40 +1221,9 @@ get_mem_type(void)
 	return ret;
 }
 
-int
-generate_vmcoreinfo(void)
+void
+write_vmcoreinfo_data(void)
 {
-	if (!set_page_size(sysconf(_SC_PAGE_SIZE)))
-		return FALSE;
-
-	set_dwarf_debuginfo("vmlinux", NULL,
-			    info->name_vmlinux, info->fd_vmlinux);
-
-	if (!get_symbol_info())
-		return FALSE;
-
-	if (!get_structure_info())
-		return FALSE;
-
-	if (!get_srcfile_info())
-		return FALSE;
-
-	if ((SYMBOL(system_utsname) == NOT_FOUND_SYMBOL)
-	    && (SYMBOL(init_uts_ns) == NOT_FOUND_SYMBOL)) {
-		ERRMSG("Can't get the symbol of system_utsname.\n");
-		return FALSE;
-	}
-	if (!get_str_osrelease_from_vmlinux())
-		return FALSE;
-
-	if (!(info->kernel_version = get_kernel_version(info->release)))
-		return FALSE;
-
-	if (get_mem_type() == NOT_FOUND_MEMTYPE) {
-		ERRMSG("Can't find the memory type.\n");
-		return FALSE;
-	}
-
 	/*
 	 * write 1st kernel's OSRELEASE
 	 */
@@ -1357,6 +1326,43 @@ generate_vmcoreinfo(void)
 	 * write the source file of 1st kernel
 	 */
 	WRITE_SRCFILE("pud_t", pud_t);
+}
+
+int
+generate_vmcoreinfo(void)
+{
+	if (!set_page_size(sysconf(_SC_PAGE_SIZE)))
+		return FALSE;
+
+	set_dwarf_debuginfo("vmlinux", NULL,
+			    info->name_vmlinux, info->fd_vmlinux);
+
+	if (!get_symbol_info())
+		return FALSE;
+
+	if (!get_structure_info())
+		return FALSE;
+
+	if (!get_srcfile_info())
+		return FALSE;
+
+	if ((SYMBOL(system_utsname) == NOT_FOUND_SYMBOL)
+	    && (SYMBOL(init_uts_ns) == NOT_FOUND_SYMBOL)) {
+		ERRMSG("Can't get the symbol of system_utsname.\n");
+		return FALSE;
+	}
+	if (!get_str_osrelease_from_vmlinux())
+		return FALSE;
+
+	if (!(info->kernel_version = get_kernel_version(info->release)))
+		return FALSE;
+
+	if (get_mem_type() == NOT_FOUND_MEMTYPE) {
+		ERRMSG("Can't find the memory type.\n");
+		return FALSE;
+	}
+
+	write_vmcoreinfo_data();
 
 	return TRUE;
 }
@@ -2605,6 +2611,12 @@ out:
 
 		if (!get_mem_map())
 			return FALSE;
+
+		if (!info->flag_dmesg && info->flag_sadump &&
+		    sadump_check_debug_info() &&
+		    !sadump_generate_elf_note_from_dumpfile())
+			return FALSE;
+
 	} else {
 		if (!get_mem_map_without_mm())
 			return FALSE;
@@ -4236,16 +4248,23 @@ write_kdump_header(void)
 			    strerror(errno));
 			return FALSE;
 		}
-		if (lseek(info->fd_memory, offset_note, SEEK_SET) < 0) {
-			ERRMSG("Can't seek the dump memory(%s). %s\n",
-			    info->name_memory, strerror(errno));
-			goto out;
-		}
-		if (read(info->fd_memory, buf, size_note) != size_note) {
-			ERRMSG("Can't read the dump memory(%s). %s\n",
-			    info->name_memory, strerror(errno));
-			goto out;
+
+		if (!info->flag_sadump) {
+			if (lseek(info->fd_memory, offset_note, SEEK_SET) < 0) {
+				ERRMSG("Can't seek the dump memory(%s). %s\n",
+				       info->name_memory, strerror(errno));
+				goto out;
+			}
+			if (read(info->fd_memory, buf, size_note) != size_note) {
+				ERRMSG("Can't read the dump memory(%s). %s\n",
+				       info->name_memory, strerror(errno));
+				goto out;
+			}
+		} else {
+			if (!sadump_read_elf_note(buf, size_note))
+				goto out;
 		}
+
 		if (!write_buffer(info->fd_dumpfile, kh.offset_note, buf,
 		    kh.size_note, info->name_dumpfile))
 			goto out;
diff --git a/makedumpfile.h b/makedumpfile.h
index 433bc49..67a6b4f 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -1328,6 +1328,8 @@ is_dumpable(struct dump_bitmap *bitmap, unsigned long long pfn)
 	return is_on(bitmap->buf, pfn%PFN_BUFBITMAP);
 }
 
+void write_vmcoreinfo_data(void);
+
 #ifdef __x86__
 
 struct user_regs_struct {
diff --git a/sadump_info.c b/sadump_info.c
index adca47b..0b9c524 100644
--- a/sadump_info.c
+++ b/sadump_info.c
@@ -19,15 +19,33 @@
 #if defined(__x86__) || defined(__x86_64__)
 
 #include "makedumpfile.h"
+#include "elf_info.h"
 #include "print_info.h"
+#include "elf_info.h"
 #include "sadump_mod.h"
 
+#ifdef __x86__
+
+#define KEXEC_NOTE_HEAD_BYTES roundup(sizeof(Elf32_Nhdr), 4)
+
+#endif
+
 #ifdef __x86_64__
 
 #define MEGABYTES(x)	((x) * (1048576))
 
+#define KEXEC_NOTE_HEAD_BYTES roundup(sizeof(Elf64_Nhdr), 4)
+
 #endif
 
+#define KEXEC_CORE_NOTE_NAME "CORE"
+#define KEXEC_CORE_NOTE_NAME_BYTES roundup(sizeof(KEXEC_CORE_NOTE_NAME), 4)
+#define KEXEC_CORE_NOTE_DESC_BYTES roundup(sizeof(struct elf_prstatus), 4)
+
+#define KEXEC_NOTE_BYTES ((KEXEC_NOTE_HEAD_BYTES * 2) +                \
+			  KEXEC_CORE_NOTE_NAME_BYTES +		       \
+			  KEXEC_CORE_NOTE_DESC_BYTES )
+
 struct sadump_diskset_info {
 	char *name_memory;
 	int fd_memory;
@@ -46,6 +64,10 @@ struct sadump_info {
 	uint32_t smram_cpu_state_size;
 	unsigned long data_offset;
 	unsigned long long *block_table;
+	unsigned long *__per_cpu_offset;
+	unsigned long __per_cpu_load;
+	FILE *file_elf_note;
+
 };
 
 static char *guid_to_str(efi_guid_t *guid, char *buf, size_t buflen);
@@ -59,6 +81,28 @@ static int read_sadump_header_diskset(int diskid, struct sadump_diskset_info *sd
 static unsigned long long pfn_to_block(unsigned long long pfn);
 static int lookup_diskset(unsigned long long whole_offset, int *diskid,
 			  unsigned long long *disk_offset);
+static int per_cpu_init(void);
+static int get_data_from_elf_note_desc(const char *note_buf, uint32_t n_descsz,
+				       char *name, uint32_t n_type, char **data);
+static int alignfile(unsigned long *offset);
+static int
+write_elf_note_header(char *name, void *data, size_t descsz, uint32_t type,
+		      unsigned long *offset, unsigned long *desc_offset);
+static unsigned long legacy_per_cpu_ptr(unsigned long ptr, int cpu);
+static unsigned long per_cpu_ptr(unsigned long ptr, int cpu);
+static int get_prstatus_from_crash_notes(int cpu, char *prstatus_buf);
+static int cpu_to_apicid(int cpu, int *apicid);
+static int get_smram_cpu_state(int apicid, struct sadump_smram_cpu_state *smram);
+static int copy_regs_from_prstatus(struct elf_prstatus *prstatus,
+				   const char *prstatus_buf);
+static int
+copy_regs_from_smram_cpu_state(struct elf_prstatus *prstatus,
+			       const struct sadump_smram_cpu_state *smram);
+static void
+debug_message_smram_cpu_state(int apicid, struct sadump_smram_cpu_state *s);
+static void
+debug_message_user_regs_struct(int cpu, struct elf_prstatus *prstatus);
+static int get_registers(int cpu, struct elf_prstatus *prstatus);
 
 static struct sadump_info sadump_info = {};
 static struct sadump_info *si = &sadump_info;
@@ -136,6 +180,112 @@ sadump_copy_1st_bitmap_from_memory(void)
 	return TRUE;
 }
 
+int
+sadump_generate_vmcoreinfo_from_vmlinux(size_t *vmcoreinfo_size)
+{
+	size_t size;
+
+	if (!info->file_vmcoreinfo)
+		return FALSE;
+
+	if ((SYMBOL(system_utsname) == NOT_FOUND_SYMBOL) &&
+	    (SYMBOL(init_uts_ns) == NOT_FOUND_SYMBOL)) {
+		ERRMSG("Can't get the symbol of system_utsname.\n");
+		return FALSE;
+	}
+
+	if (get_mem_type() == NOT_FOUND_MEMTYPE) {
+		ERRMSG("Can't find the memory type.\n");
+		return FALSE;
+	}
+
+	strncpy(info->release, info->system_utsname.release,
+		strlen(info->system_utsname.release) + 1);
+
+	write_vmcoreinfo_data();
+
+	size = ftell(info->file_vmcoreinfo);
+
+	*vmcoreinfo_size = size;
+
+	return TRUE;
+}
+
+int
+sadump_generate_elf_note_from_dumpfile(void)
+{
+	size_t size_vmcoreinfo, size_pt_note;
+	int x_cpu;
+	unsigned long offset, offset_vmcoreinfo;
+	char *vmcoreinfo_buf = NULL;
+	int retval = FALSE;
+
+	if (!per_cpu_init())
+		return FALSE;
+
+	if (!(info->file_vmcoreinfo = tmpfile())) {
+		ERRMSG("Can't create a temporary strings(%s).\n",
+		       FILENAME_VMCOREINFO);
+		return FALSE;
+	}
+	if (!sadump_generate_vmcoreinfo_from_vmlinux(&size_vmcoreinfo)) {
+		ERRMSG("Can't generate vmcoreinfo data.\n");
+		goto error;
+	}
+	if ((vmcoreinfo_buf = malloc(size_vmcoreinfo)) == NULL) {
+		ERRMSG("Can't allocate vmcoreinfo buffer. %s\n",
+		       strerror(errno));
+		goto cleanup;
+	}
+	rewind(info->file_vmcoreinfo);
+	if (fread(vmcoreinfo_buf, size_vmcoreinfo, 1,
+		  info->file_vmcoreinfo) != 1) {
+		ERRMSG("Can't read vmcoreinfo temporary file. %s\n",
+		       strerror(errno));
+		goto cleanup;
+	}
+
+	if (!(si->file_elf_note = tmpfile())) {
+		ERRMSG("Can't create a temporary elf_note file. %s\n",
+		       strerror(errno));
+		goto cleanup;
+	}
+	offset = 0;
+	for (x_cpu = 0; x_cpu < get_nr_cpus(); ++x_cpu) {
+		struct elf_prstatus prstatus;
+
+		memset(&prstatus, 0, sizeof(prstatus));
+
+		if (!get_registers(x_cpu, &prstatus))
+			goto cleanup;
+
+		if (!write_elf_note_header("CORE", &prstatus, sizeof(prstatus),
+					   NT_PRSTATUS, &offset, NULL))
+			goto cleanup;
+
+	}
+
+	if (!write_elf_note_header("VMCOREINFO", vmcoreinfo_buf,
+				   size_vmcoreinfo, 0, &offset,
+				   &offset_vmcoreinfo))
+		goto cleanup;
+
+	size_pt_note = ftell(si->file_elf_note);
+	set_pt_note(0, size_pt_note);
+	set_vmcoreinfo(offset_vmcoreinfo, size_vmcoreinfo);
+
+	retval = TRUE;
+
+cleanup:
+	free(vmcoreinfo_buf);
+	if (info->file_vmcoreinfo) {
+		fclose(info->file_vmcoreinfo);
+		info->file_vmcoreinfo = NULL;
+	}
+error:
+	return retval;
+}
+
 static char *
 guid_to_str(efi_guid_t *guid, char *buf, size_t buflen)
 {
@@ -767,6 +917,125 @@ error:
 	return FALSE;
 }
 
+int
+sadump_check_debug_info(void)
+{
+	if (SYMBOL(linux_banner) == NOT_FOUND_SYMBOL)
+		return FALSE;
+	if (SYMBOL(bios_cpu_apicid) == NOT_FOUND_SYMBOL &&
+	    SYMBOL(x86_bios_cpu_apicid) == NOT_FOUND_SYMBOL)
+		return FALSE;
+	if (SYMBOL(x86_bios_cpu_apicid) != NOT_FOUND_SYMBOL &&
+	    (SYMBOL(x86_bios_cpu_apicid_early_ptr) == NOT_FOUND_SYMBOL ||
+	     SYMBOL(x86_bios_cpu_apicid_early_map) == NOT_FOUND_SYMBOL))
+		return FALSE;
+	if (SYMBOL(crash_notes) == NOT_FOUND_SYMBOL)
+		return FALSE;
+	if (SIZE(percpu_data) == NOT_FOUND_STRUCTURE &&
+	    SYMBOL(__per_cpu_load) == NOT_FOUND_SYMBOL)
+		return FALSE;
+	if (SYMBOL(__per_cpu_load) != NOT_FOUND_SYMBOL &&
+	    (SYMBOL(__per_cpu_offset) == NOT_FOUND_SYMBOL &&
+	     ARRAY_LENGTH(__per_cpu_offset) == NOT_FOUND_STRUCTURE))
+		return FALSE;
+	if (SIZE(elf_prstatus) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(elf_prstatus.pr_reg) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+#ifdef __x86__
+	if (OFFSET(user_regs_struct.bx) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.cx) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.dx) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.si) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.di) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.bp) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.ax) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.ds) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.es) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.fs) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.gs) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.orig_ax) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.ip) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.cs) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.flags) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.sp) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.ss) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+#elif defined(__x86_64__)
+	if (OFFSET(user_regs_struct.r15) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.r14) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.r13) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.r12) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.bp) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.bx) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.r11) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.r10) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.r9) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.r8) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.ax) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.cx) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.dx) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.si) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.di) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.orig_ax) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.ip) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.cs) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.flags) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.sp) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.ss) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.fs_base) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.gs_base) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.ds) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.es) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+	if (OFFSET(user_regs_struct.fs) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+        if (OFFSET(user_regs_struct.gs) == NOT_FOUND_STRUCTURE)
+		return FALSE;
+#endif /* __x86_64__ */
+	return TRUE;
+}
+
 static unsigned long long
 pfn_to_block(unsigned long long pfn)
 {
@@ -816,6 +1085,539 @@ lookup_diskset(unsigned long long whole_offset, int *diskid,
 	return TRUE;
 }
 
+static int
+per_cpu_init(void)
+{
+	size_t __per_cpu_offset_size;
+	int i;
+
+	if (SIZE(percpu_data) != NOT_FOUND_STRUCTURE)
+		return TRUE;
+
+	__per_cpu_offset_size =
+		ARRAY_LENGTH(__per_cpu_offset) * sizeof(unsigned long);
+
+	if (!(si->__per_cpu_offset = malloc(__per_cpu_offset_size))) {
+		ERRMSG("Can't allocate __per_cpu_offset buffer.\n");
+		return FALSE;
+	}
+
+	if (!readmem(VADDR, SYMBOL(__per_cpu_offset), si->__per_cpu_offset,
+		     __per_cpu_offset_size)) {
+		ERRMSG("Can't read __per_cpu_offset memory.\n");
+		return FALSE;
+	}
+
+	if (!readmem(VADDR, SYMBOL(__per_cpu_load), &si->__per_cpu_load,
+		     sizeof(unsigned long))) {
+		ERRMSG("Can't read __per_cpu_load memory.\n");
+		return FALSE;
+	}
+
+	DEBUG_MSG("sadump: __per_cpu_load: %#lx\n", si->__per_cpu_load);
+	DEBUG_MSG("sadump: __per_cpu_offset: LENGTH: %ld\n",
+		  ARRAY_LENGTH(__per_cpu_offset));
+
+	for (i = 0; i < ARRAY_LENGTH(__per_cpu_offset); ++i) {
+		DEBUG_MSG("sadump: __per_cpu_offset[%d]: %#lx\n", i,
+			  si->__per_cpu_offset[i]);
+	}
+
+	return TRUE;
+}
+
+static int
+get_data_from_elf_note_desc(const char *note_buf, uint32_t n_descsz,
+			    char *name, uint32_t n_type, char **data)
+{
+	Elf32_Nhdr *note32;
+	char *note_name;
+
+	note32 = (Elf32_Nhdr *)note_buf;
+	note_name = (char *)(note32 + 1);
+
+	if (note32->n_type != n_type ||
+	    note32->n_namesz != strlen(name) + 1 ||
+	    note32->n_descsz != n_descsz ||
+	    strncmp(note_name, name, note32->n_namesz))
+		return FALSE;
+
+	*data = (char *)note_buf +
+		roundup(sizeof(Elf32_Nhdr) + note32->n_namesz, 4);
+
+	return TRUE;
+}
+
+static int
+alignfile(unsigned long *offset)
+{
+	char nullbyte = '\0';
+	unsigned int len;
+
+	len = roundup(*offset, 4) - *offset;
+	if (fwrite(&nullbyte, 1, len, si->file_elf_note) != len) {
+		ERRMSG("Can't write elf_note file. %s\n", strerror(errno));
+		return FALSE;
+	}
+	*offset += len;
+	return TRUE;
+}
+
+static int
+write_elf_note_header(char *name, void *data, size_t descsz, uint32_t type,
+		      unsigned long *offset, unsigned long *desc_offset)
+{
+	Elf32_Nhdr nhdr;
+
+	nhdr.n_namesz = strlen(name) + 1;
+	nhdr.n_descsz = descsz;
+	nhdr.n_type = type;
+
+	if (fwrite(&nhdr, sizeof(nhdr), 1, si->file_elf_note) != 1) {
+		ERRMSG("Can't write elf_note file. %s\n", strerror(errno));
+		return FALSE;
+	}
+	*offset += sizeof(nhdr);
+
+	if (fwrite(name, nhdr.n_namesz, 1, si->file_elf_note) != 1) {
+		ERRMSG("Can't write elf_note file. %s\n", strerror(errno));
+		return FALSE;
+	}
+	*offset += nhdr.n_namesz;
+	if (!alignfile(offset))
+		return FALSE;
+
+	if (desc_offset)
+		*desc_offset = *offset;
+
+	if (fwrite(data, nhdr.n_descsz, 1, si->file_elf_note) != 1) {
+		ERRMSG("Can't write elf_note file. %s\n", strerror(errno));
+		return FALSE;
+	}
+	*offset += nhdr.n_descsz;
+	if (!alignfile(offset))
+		return FALSE;
+
+	return TRUE;
+}
+
+static unsigned long
+legacy_per_cpu_ptr(unsigned long ptr, int cpu)
+{
+	unsigned long addr;
+
+	if (cpu < 0 || cpu >= get_nr_cpus())
+		return 0UL;
+
+	if (!readmem(VADDR, ~ptr + cpu*sizeof(unsigned long), &addr,
+		     sizeof(addr)))
+		return 0UL;
+
+	return addr;
+}
+
+static unsigned long
+per_cpu_ptr(unsigned long ptr, int cpu)
+{
+	if (cpu < 0 || cpu >= get_nr_cpus())
+		return 0UL;
+
+	if (si->__per_cpu_offset[cpu] == si->__per_cpu_load)
+		return 0UL;
+
+	return ptr + si->__per_cpu_offset[cpu];
+}
+
+static int
+get_prstatus_from_crash_notes(int cpu, char *prstatus_buf)
+{
+	unsigned long crash_notes_vaddr, percpu_addr;
+	char note_buf[KEXEC_NOTE_BYTES], zero_buf[KEXEC_NOTE_BYTES];
+	char *prstatus_ptr;
+
+	if (cpu < 0 || get_nr_cpus() <= cpu)
+		return FALSE;
+
+	if (SYMBOL(crash_notes) == NOT_FOUND_SYMBOL)
+		return FALSE;
+
+	if (!readmem(VADDR, SYMBOL(crash_notes), &crash_notes_vaddr,
+		     sizeof(crash_notes_vaddr)))
+		return FALSE;
+
+	if (!crash_notes_vaddr) {
+		DEBUG_MSG("sadump: crash_notes %d is NULL\n", cpu);
+		return FALSE;
+	}
+
+	memset(zero_buf, 0, KEXEC_NOTE_BYTES);
+
+	percpu_addr = SIZE(percpu_data) != NOT_FOUND_STRUCTURE
+		? legacy_per_cpu_ptr(crash_notes_vaddr, cpu)
+		: per_cpu_ptr(crash_notes_vaddr, cpu);
+
+	if (!readmem(VADDR, percpu_addr, note_buf, KEXEC_NOTE_BYTES))
+		return FALSE;
+
+	if (memcmp(note_buf, zero_buf, KEXEC_NOTE_BYTES) == 0)
+		return FALSE;
+
+	if (!get_data_from_elf_note_desc(note_buf, SIZE(elf_prstatus), "CORE",
+					 NT_PRSTATUS, (void *)&prstatus_ptr))
+		return FALSE;
+
+	memcpy(prstatus_buf, prstatus_ptr, SIZE(elf_prstatus));
+
+	return TRUE;
+}
+
+static int
+cpu_to_apicid(int cpu, int *apicid)
+{
+	if (SYMBOL(bios_cpu_apicid) != NOT_FOUND_SYMBOL) {
+		uint8_t apicid_u8;
+
+		if (!readmem(VADDR, SYMBOL(bios_cpu_apicid)+cpu*sizeof(uint8_t),
+			     &apicid_u8, sizeof(uint8_t)))
+			return FALSE;
+
+		*apicid = (int)apicid_u8;
+
+		DEBUG_MSG("sadump: apicid %u for cpu %d from "
+			  "bios_cpu_apicid\n", apicid_u8, cpu);
+
+	} else if (SYMBOL(x86_bios_cpu_apicid) != NOT_FOUND_SYMBOL) {
+		uint16_t apicid_u16;
+		unsigned long early_ptr, apicid_addr;
+
+		if (!readmem(VADDR, SYMBOL(x86_bios_cpu_apicid_early_ptr),
+			     &early_ptr, sizeof(early_ptr)))
+			return FALSE;
+
+		apicid_addr = early_ptr
+			? SYMBOL(x86_bios_cpu_apicid_early_map)+cpu*sizeof(uint16_t)
+			: per_cpu_ptr(SYMBOL(x86_bios_cpu_apicid), cpu);
+
+		if (!readmem(VADDR, apicid_addr, &apicid_u16, sizeof(uint16_t)))
+			return FALSE;
+
+		*apicid = (int)apicid_u16;
+
+		DEBUG_MSG("sadump: apicid %u for cpu %d from "
+			  "x86_bios_cpu_apicid\n", apicid_u16, cpu);
+
+	} else {
+
+		ERRMSG("sadump: no symbols for access to acpidid\n");
+
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+static int
+get_smram_cpu_state(int apicid, struct sadump_smram_cpu_state *smram)
+{
+	unsigned long offset;
+
+	if (!si->sub_hdr_offset || !si->smram_cpu_state_size ||
+	    apicid >= si->sh_memory->nr_cpus)
+		return FALSE;
+
+	offset = si->sub_hdr_offset + sizeof(uint32_t) +
+		si->sh_memory->nr_cpus * sizeof(struct sadump_apic_state);
+
+	if (lseek(info->fd_memory, offset+apicid*si->smram_cpu_state_size,
+		  SEEK_SET) < 0)
+		DEBUG_MSG("sadump: cannot lseek smram cpu state in dump sub "
+			  "header\n");
+
+	if (read(info->fd_memory, smram, si->smram_cpu_state_size) !=
+	    si->smram_cpu_state_size)
+		DEBUG_MSG("sadump: cannot read smram cpu state in dump sub "
+			  "header\n");
+
+	return TRUE;
+}
+
+#ifdef __x86__
+
+static int
+copy_regs_from_prstatus(struct elf_prstatus *prstatus,
+			const char *prstatus_buf)
+{
+	struct user_regs_struct *r = &prstatus->pr_reg;
+	const char *pr_reg_buf = prstatus_buf + OFFSET(elf_prstatus.pr_reg);
+
+	r->bx = ULONG(pr_reg_buf + OFFSET(user_regs_struct.bx));
+	r->cx = ULONG(pr_reg_buf + OFFSET(user_regs_struct.cx));
+	r->dx = ULONG(pr_reg_buf + OFFSET(user_regs_struct.dx));
+	r->si = ULONG(pr_reg_buf + OFFSET(user_regs_struct.si));
+	r->di = ULONG(pr_reg_buf + OFFSET(user_regs_struct.di));
+	r->bp = ULONG(pr_reg_buf + OFFSET(user_regs_struct.bp));
+	r->ax = ULONG(pr_reg_buf + OFFSET(user_regs_struct.ax));
+	r->ds = ULONG(pr_reg_buf + OFFSET(user_regs_struct.ds));
+	r->es = ULONG(pr_reg_buf + OFFSET(user_regs_struct.es));
+	r->fs = ULONG(pr_reg_buf + OFFSET(user_regs_struct.fs));
+	r->gs = ULONG(pr_reg_buf + OFFSET(user_regs_struct.gs));
+	r->orig_ax = ULONG(pr_reg_buf + OFFSET(user_regs_struct.orig_ax));
+	r->ip = ULONG(pr_reg_buf + OFFSET(user_regs_struct.ip));
+	r->cs = ULONG(pr_reg_buf + OFFSET(user_regs_struct.cs));
+	r->flags = ULONG(pr_reg_buf + OFFSET(user_regs_struct.flags));
+	r->sp = ULONG(pr_reg_buf + OFFSET(user_regs_struct.sp));
+	r->ss = ULONG(pr_reg_buf + OFFSET(user_regs_struct.ss));
+
+	return TRUE;
+}
+
+static int
+copy_regs_from_smram_cpu_state(struct elf_prstatus *prstatus,
+			       const struct sadump_smram_cpu_state *smram)
+{
+	struct user_regs_struct *regs = &prstatus->pr_reg;
+
+	regs->bx = smram->RbxLower;
+	regs->cx = smram->RcxLower;
+	regs->dx = smram->RdxLower;
+	regs->si = smram->RsiLower;
+	regs->di = smram->RdiLower;
+	regs->bp = smram->RbpLower;
+	regs->ax = smram->RaxLower;
+	regs->ds = smram->Ds & 0xffff;
+	regs->es = smram->Es & 0xffff;
+	regs->fs = smram->Fs & 0xffff;
+	regs->gs = smram->Gs & 0xffff;
+	regs->orig_ax = smram->RaxLower;
+	regs->ip = (uint32_t)smram->Rip;
+	regs->cs = smram->Cs & 0xffff;
+	regs->flags = (uint32_t)smram->Rflags;
+	regs->sp = smram->RspLower;
+	regs->ss = smram->Ss & 0xffff;
+
+	return TRUE;
+}
+
+static void
+debug_message_user_regs_struct(int cpu, struct elf_prstatus *prstatus)
+{
+	struct user_regs_struct *r = &prstatus->pr_reg;
+
+	DEBUG_MSG(
+		"sadump: CPU: %d\n"
+		"    BX: %08lx CX: %08lx DX: %08lx SI: %08lx\n"
+		"    DI: %08lx BP: %08lx AX: %08lx ORIG_AX: %08lx\n"
+		"    DS: %04lx ES: %04lx FS: %04lx GS: %04lx CS: %04lx SS: %04lx\n"
+		"    IP: %08lx FLAGS: %04lx SP: %08lx\n",
+		cpu,
+		r->bx, r->cx, r->dx, r->si,
+		r->di, r->bp, r->ax, r->orig_ax,
+		r->ds, r->es, r->fs, r->gs, r->cs, r->ss,
+		r->ip, r->flags, r->sp);
+}
+
+#elif defined(__x86_64__)
+
+static int
+copy_regs_from_prstatus(struct elf_prstatus *prstatus,
+			const char *prstatus_buf)
+{
+	struct user_regs_struct *r = &prstatus->pr_reg;
+	const char *pr_reg_buf = prstatus_buf + OFFSET(elf_prstatus.pr_reg);
+
+	r->r15 = ULONG(pr_reg_buf + OFFSET(user_regs_struct.r15));
+	r->r14 = ULONG(pr_reg_buf + OFFSET(user_regs_struct.r14));
+	r->r13 = ULONG(pr_reg_buf + OFFSET(user_regs_struct.r13));
+	r->bp = ULONG(pr_reg_buf + OFFSET(user_regs_struct.bp));
+	r->bx = ULONG(pr_reg_buf + OFFSET(user_regs_struct.bx));
+	r->r11 = ULONG(pr_reg_buf + OFFSET(user_regs_struct.r11));
+	r->r10 = ULONG(pr_reg_buf + OFFSET(user_regs_struct.r10));
+	r->r9 = ULONG(pr_reg_buf + OFFSET(user_regs_struct.r9));
+	r->r8 = ULONG(pr_reg_buf + OFFSET(user_regs_struct.r8));
+	r->ax = ULONG(pr_reg_buf + OFFSET(user_regs_struct.ax));
+	r->cx = ULONG(pr_reg_buf + OFFSET(user_regs_struct.cx));
+	r->dx = ULONG(pr_reg_buf + OFFSET(user_regs_struct.dx));
+	r->si = ULONG(pr_reg_buf + OFFSET(user_regs_struct.si));
+	r->di = ULONG(pr_reg_buf + OFFSET(user_regs_struct.di));
+	r->orig_ax = ULONG(pr_reg_buf + OFFSET(user_regs_struct.orig_ax));
+	r->ip = ULONG(pr_reg_buf + OFFSET(user_regs_struct.ip));
+	r->cs = ULONG(pr_reg_buf + OFFSET(user_regs_struct.cs));
+	r->flags = ULONG(pr_reg_buf + OFFSET(user_regs_struct.flags));
+	r->sp = ULONG(pr_reg_buf + OFFSET(user_regs_struct.sp));
+	r->ss = ULONG(pr_reg_buf + OFFSET(user_regs_struct.ss));
+	r->fs_base = ULONG(pr_reg_buf + OFFSET(user_regs_struct.fs_base));
+	r->gs_base = ULONG(pr_reg_buf + OFFSET(user_regs_struct.gs_base));
+	r->ds = ULONG(pr_reg_buf + OFFSET(user_regs_struct.ds));
+	r->es = ULONG(pr_reg_buf + OFFSET(user_regs_struct.es));
+	r->fs = ULONG(pr_reg_buf + OFFSET(user_regs_struct.fs));
+	r->gs = ULONG(pr_reg_buf + OFFSET(user_regs_struct.gs));
+
+	return TRUE;
+}
+
+static int
+copy_regs_from_smram_cpu_state(struct elf_prstatus *prstatus,
+			       const struct sadump_smram_cpu_state *smram)
+{
+	struct user_regs_struct *regs = &prstatus->pr_reg;
+
+	regs->r15 = ((uint64_t)smram->R15Upper<<32)+smram->R15Lower;
+	regs->r14 = ((uint64_t)smram->R14Upper<<32)+smram->R14Lower;
+	regs->r13 = ((uint64_t)smram->R13Upper<<32)+smram->R13Lower;
+	regs->r12 = ((uint64_t)smram->R12Upper<<32)+smram->R12Lower;
+	regs->bp = ((uint64_t)smram->RbpUpper<<32)+smram->RbpLower;
+	regs->bx = ((uint64_t)smram->RbxUpper<<32)+smram->RbxLower;
+	regs->r11 = ((uint64_t)smram->R11Upper<<32)+smram->R11Lower;
+	regs->r10 = ((uint64_t)smram->R10Upper<<32)+smram->R10Lower;
+	regs->r9 = ((uint64_t)smram->R9Upper<<32)+smram->R9Lower;
+	regs->r8 = ((uint64_t)smram->R8Upper<<32)+smram->R8Lower;
+	regs->ax = ((uint64_t)smram->RaxUpper<<32)+smram->RaxLower;
+	regs->cx = ((uint64_t)smram->RcxUpper<<32)+smram->RcxLower;
+	regs->dx = ((uint64_t)smram->RdxUpper<<32)+smram->RdxLower;
+	regs->si = ((uint64_t)smram->RsiUpper<<32)+smram->RsiLower;
+	regs->di = ((uint64_t)smram->RdiUpper<<32)+smram->RdiLower;
+	regs->orig_ax = ((uint64_t)smram->RaxUpper<<32)+smram->RaxLower;
+	regs->ip = smram->Rip;
+	regs->cs = smram->Cs;
+	regs->flags = smram->Rflags;
+	regs->sp = ((uint64_t)smram->RspUpper<<32)+smram->RspLower;
+	regs->ss = smram->Ss;
+	regs->fs_base = 0;
+	regs->gs_base = 0;
+	regs->ds = smram->Ds;
+	regs->es = smram->Es;
+	regs->fs = smram->Fs;
+	regs->gs = smram->Gs;
+
+	return TRUE;
+}
+
+static void
+debug_message_user_regs_struct(int cpu, struct elf_prstatus *prstatus)
+{
+	struct user_regs_struct *r = &prstatus->pr_reg;
+
+	DEBUG_MSG(
+		"sadump: CPU: %d\n"
+		"    R15: %016llx R14: %016llx R13: %016llx\n"
+		"    R12: %016llx RBP: %016llx RBX: %016llx\n"
+		"    R11: %016llx R10: %016llx R9: %016llx\n"
+		"    R8: %016llx RAX: %016llx RCX: %016llx\n"
+		"    RDX: %016llx RSI: %016llx RDI: %016llx\n"
+		"    ORIG_RAX: %016llx RIP: %016llx\n"
+		"    CS: %04lx FLAGS: %08llx RSP: %016llx\n"
+		"    SS: %04lx FS_BASE: %04lx GS_BASE: %04lx\n"
+		"    DS: %04lx ES: %04lx FS: %04lx GS: %04lx\n",
+		cpu,
+		(unsigned long long)r->r15, (unsigned long long)r->r14,
+		(unsigned long long)r->r13, (unsigned long long)r->r12,
+		(unsigned long long)r->bp, (unsigned long long)r->bx,
+		(unsigned long long)r->r11, (unsigned long long)r->r10,
+		(unsigned long long)r->r9, (unsigned long long)r->r8,
+		(unsigned long long)r->ax, (unsigned long long)r->cx,
+		(unsigned long long)r->dx, (unsigned long long)r->si,
+		(unsigned long long)r->di,
+		(unsigned long long)r->orig_ax,
+		(unsigned long long)r->ip, r->cs,
+		(unsigned long long)r->flags, (unsigned long long)r->sp,
+		r->ss, r->fs_base, r->gs_base, r->ds, r->es, r->fs,
+		r->gs);
+}
+
+#endif /* __x86_64__ */
+
+static void
+debug_message_smram_cpu_state(int apicid, struct sadump_smram_cpu_state *s)
+{
+	DEBUG_MSG(
+		"sadump: APIC ID: %d\n"
+		"    RIP: %016llx RSP: %08x%08x RBP: %08x%08x\n"
+		"    RAX: %08x%08x RBX: %08x%08x RCX: %08x%08x\n"
+		"    RDX: %08x%08x RSI: %08x%08x RDI: %08x%08x\n"
+		"    R08: %08x%08x R09: %08x%08x R10: %08x%08x\n"
+		"    R11: %08x%08x R12: %08x%08x R13: %08x%08x\n"
+		"    R14: %08x%08x R15: %08x%08x\n"
+		"    SMM REV: %08x SMM BASE %08x\n"
+		"    CS : %08x DS: %08x SS: %08x ES: %08x FS: %08x\n"
+		"    GS : %08x\n"
+		"    CR0: %016llx CR3: %016llx CR4: %08x\n"
+		"    GDT: %08x%08x LDT: %08x%08x IDT: %08x%08x\n"
+		"    GDTlim: %08x LDTlim: %08x IDTlim: %08x\n"
+		"    LDTR: %08x TR: %08x RFLAGS: %016llx\n"
+		"    EPTP: %016llx EPTP_SETTING: %08x\n"
+		"    DR6: %016llx DR7: %016llx\n"
+		"    Ia32Efer: %016llx\n"
+		"    IoMemAddr: %08x%08x IoEip: %016llx\n"
+		"    IoMisc: %08x LdtInfo: %08x\n"
+		"    IoInstructionRestart: %04x AutoHaltRestart: %04x\n",
+		apicid,
+		(unsigned long long)s->Rip, s->RspUpper, s->RspLower, s->RbpUpper, s->RbpLower,
+		s->RaxUpper, s->RaxLower, s->RbxUpper, s->RbxLower, s->RcxUpper, s->RcxLower,
+		s->RdxUpper, s->RdxLower, s->RsiUpper, s->RsiLower, s->RdiUpper, s->RdiLower,
+		s->R8Upper, s->R8Lower, s->R9Upper, s->R9Lower, s->R10Upper, s->R10Lower,
+		s->R11Upper, s->R11Lower, s->R12Upper, s->R12Lower, s->R13Upper, s->R13Lower,
+		s->R14Upper, s->R14Lower, s->R15Upper, s->R15Lower,
+		s->SmmRevisionId, s->Smbase,
+		s->Cs, s->Ds, s->Ss, s->Es, s->Fs, s->Gs,
+		(unsigned long long)s->Cr0, (unsigned long long)s->Cr3, s->Cr4,
+		s->GdtUpper, s->GdtLower, s->LdtUpper, s->LdtLower, s->IdtUpper, s->IdtLower,
+		s->GdtLimit, s->LdtLimit, s->IdtLimit,
+		s->Ldtr, s->Tr, (unsigned long long)s->Rflags,
+		(unsigned long long)s->Eptp, s->EptpSetting,
+		(unsigned long long)s->Dr6, (unsigned long long)s->Dr7,
+		(unsigned long long)s->Ia32Efer,
+		s->IoMemAddrUpper, s->IoMemAddrLower, (unsigned long long)s->IoEip,
+		s->IoMisc, s->LdtInfo,
+		s->IoInstructionRestart,
+		s->AutoHaltRestart);
+}
+
+static int
+get_registers(int cpu, struct elf_prstatus *prstatus)
+{
+	struct sadump_smram_cpu_state smram;
+	char *prstatus_buf = NULL;
+	int retval = FALSE, apicid = 0;
+
+	if (!(prstatus_buf = malloc(SIZE(elf_prstatus)))) {
+		ERRMSG("Can't allocate elf_prstatus buffer. %s\n",
+		       strerror(errno));
+		goto error;
+	}
+
+	if (get_prstatus_from_crash_notes(cpu, prstatus_buf)) {
+
+		if (!copy_regs_from_prstatus(prstatus, prstatus_buf))
+			goto cleanup;
+
+		DEBUG_MSG("sadump: cpu #%d registers from crash_notes\n", cpu);
+
+		debug_message_user_regs_struct(cpu, prstatus);
+
+	} else {
+
+		if (!cpu_to_apicid(cpu, &apicid))
+			goto cleanup;
+
+		if (!get_smram_cpu_state(apicid, &smram))
+			goto cleanup;
+
+		copy_regs_from_smram_cpu_state(prstatus, &smram);
+
+		DEBUG_MSG("sadump: cpu #%d registers from SMRAM\n", cpu);
+
+		debug_message_smram_cpu_state(apicid, &smram);
+		debug_message_user_regs_struct(cpu, prstatus);
+
+	}
+
+	retval = TRUE;
+cleanup:
+	free(prstatus_buf);
+error:
+	return retval;
+}
+
 int
 sadump_add_diskset_info(char *name_memory)
 {
@@ -835,6 +1637,23 @@ sadump_add_diskset_info(char *name_memory)
 	return TRUE;
 }
 
+int
+sadump_read_elf_note(char *buf, size_t size_note)
+{
+	if (!si->file_elf_note)
+		return FALSE;
+
+	rewind(si->file_elf_note);
+
+	if (fread(buf, size_note, 1, si->file_elf_note) != 1) {
+		ERRMSG("Can't read elf note file. %s\n",
+		       strerror(errno));
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
 long
 sadump_page_size(void)
 {
@@ -885,8 +1704,12 @@ free_sadump_info(void)
 		}
 		free(si->diskset_info);
 	}
+	if (si->__per_cpu_offset)
+		free(si->__per_cpu_offset);
 	if (si->block_table)
 		free(si->block_table);
+	if (si->file_elf_note)
+		fclose(si->file_elf_note);
 }
 
 #endif /* defined(__x86__) && defined(__x86_64__) */
diff --git a/sadump_info.h b/sadump_info.h
index 401b769..c1f948f 100644
--- a/sadump_info.h
+++ b/sadump_info.h
@@ -44,7 +44,12 @@ int sadump_get_nr_cpus(int *nr_cpus);
 int sadump_set_timestamp(struct timeval *ts);
 unsigned long long sadump_get_max_mapnr(void);
 int readpmem_sadump(unsigned long long paddr, void *bufptr, size_t size);
+int sadump_check_debug_info(void);
+int sadump_generate_vmcoreinfo_from_vmlinux(size_t *vmcoreinfo_size);
+int sadump_generate_elf_note_from_dumpfile(void);
+int sadump_copy_1st_bitmap_from_memory(void);
 int sadump_add_diskset_info(char *name_memory);
+int sadump_read_elf_note(char *buf, size_t size_note);
 long sadump_page_size(void);
 char *sadump_head_disk_name_memory(void);
 char *sadump_format_type_name(void);
@@ -97,11 +102,32 @@ static inline int readpmem_sadump(unsigned long long paddr,
 	return FALSE;
 }
 
+static inline int sadump_check_debug_info(void)
+{
+	return FALSE;
+}
+
+static inline int
+sadump_generate_vmcoreinfo_from_vmlinux(size_t *vmcoreinfo_size)
+{
+	return FALSE;
+}
+
+static inline int sadump_generate_elf_note_from_dumpfile(void)
+{
+	return FALSE;
+}
+
 static inline int sadump_add_diskset_info(char *name_memory)
 {
 	return TRUE;
 }
 
+static inline int sadump_read_elf_note(char *buf, size_t size_note)
+{
+	return FALSE;
+}
+
 static inline long sadump_page_size(void)
 {
 	return 0;


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 11/14] Procees CPUs based on online ones
  2011-10-28  9:48 [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format HATAYAMA Daisuke
                   ` (9 preceding siblings ...)
  2011-10-28  9:48 ` [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information HATAYAMA Daisuke
@ 2011-10-28  9:49 ` HATAYAMA Daisuke
  2011-10-28  9:49 ` [PATCH v2 12/14] Read kexec backup region HATAYAMA Daisuke
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-10-28  9:49 UTC (permalink / raw)
  To: kexec

Assign the number of online cpus to nr_cpus member in diskset header,
and create NR_PRSTATUS for each online cpu. This behaviour is sound
with respect to kdump's and crash's on kdump-compressed format.

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

 makedumpfile.c |   27 +++++++++++----
 makedumpfile.h |    3 ++
 sadump_info.c  |  100 +++++++++++++++++++++++++++++++++++++++++++++-----------
 sadump_info.h  |    4 +-
 4 files changed, 106 insertions(+), 28 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index 750dcb6..44f6ee6 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -826,6 +826,9 @@ get_symbol_info(void)
 	SYMBOL_INIT(crash_notes, "crash_notes");
 	SYMBOL_INIT(__per_cpu_load, "__per_cpu_load");
 	SYMBOL_INIT(__per_cpu_offset, "__per_cpu_offset");
+	SYMBOL_INIT(cpu_online_mask, "cpu_online_mask");
+	if (SYMBOL(cpu_online_mask) == NOT_FOUND_SYMBOL)
+		SYMBOL_INIT(cpu_online_mask, "cpu_online_map");
 
 	if (SYMBOL(node_data) != NOT_FOUND_SYMBOL)
 		SYMBOL_ARRAY_TYPE_INIT(node_data, "node_data");
@@ -962,6 +965,13 @@ get_structure_info(void)
 	OFFSET_INIT(elf_prstatus.pr_reg, "elf_prstatus", "pr_reg");
 
 	/*
+	 * Get size of cpumask and cpumask_t.
+	 */
+	SIZE_INIT(cpumask, "cpumask");
+
+	TYPEDEF_SIZE_INIT(cpumask_t, "cpumask_t");
+
+	/*
 	 * Get offset of the user_regs_struct members.
 	 */
 	SIZE_INIT(user_regs_struct, "user_regs_struct");
@@ -2489,8 +2499,6 @@ initial(void)
 			return FALSE;
 
 	} else if (info->flag_sadump) {
-		int nr_cpus;
-
 		if (info->flag_elf_dumpfile) {
 			MSG("'-E' option is disable, ");
 			MSG("because %s is sadump %s format.\n",
@@ -2503,11 +2511,6 @@ initial(void)
 		if (!sadump_initialize_bitmap_memory())
 			return FALSE;
 
-		if (!sadump_get_nr_cpus(&nr_cpus))
-			return FALSE;
-
-		set_nr_cpus(nr_cpus);
-
 		(void) sadump_set_timestamp(&info->timestamp);
 
 		/*
@@ -2600,6 +2603,16 @@ out:
 		if (!get_machdep_info())
 			return FALSE;
 
+		if (info->flag_sadump) {
+			int online_cpus;
+
+			online_cpus = sadump_num_online_cpus();
+			if (!online_cpus)
+				return FALSE;
+
+			set_nr_cpus(online_cpus);
+		}
+
 		if (!check_release())
 			return FALSE;
 
diff --git a/makedumpfile.h b/makedumpfile.h
index 67a6b4f..020d99c 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -995,6 +995,7 @@ struct symbol_table {
 	unsigned long long	crash_notes;
 	unsigned long long	__per_cpu_offset;
 	unsigned long long	__per_cpu_load;
+	unsigned long long	cpu_online_mask;
 };
 
 struct size_table {
@@ -1024,6 +1025,8 @@ struct size_table {
 	long	percpu_data;
 	long	elf_prstatus;
 	long	user_regs_struct;
+	long	cpumask;
+	long	cpumask_t;
 };
 
 struct offset_table {
diff --git a/sadump_info.c b/sadump_info.c
index 0b9c524..2538da6 100644
--- a/sadump_info.c
+++ b/sadump_info.c
@@ -46,6 +46,14 @@
 			  KEXEC_CORE_NOTE_NAME_BYTES +		       \
 			  KEXEC_CORE_NOTE_DESC_BYTES )
 
+#define for_each_online_cpu(cpu)					\
+	for (cpu = 0; cpu < BITPERBYTE * si->cpumask_size; ++cpu)	\
+		if (is_online_cpu(cpu))
+
+enum {
+	BITPERWORD = BITPERBYTE * sizeof(unsigned long)
+};
+
 struct sadump_diskset_info {
 	char *name_memory;
 	int fd_memory;
@@ -67,7 +75,8 @@ struct sadump_info {
 	unsigned long *__per_cpu_offset;
 	unsigned long __per_cpu_load;
 	FILE *file_elf_note;
-
+	char *cpu_online_mask_buf;
+	size_t cpumask_size;
 };
 
 static char *guid_to_str(efi_guid_t *guid, char *buf, size_t buflen);
@@ -81,6 +90,7 @@ static int read_sadump_header_diskset(int diskid, struct sadump_diskset_info *sd
 static unsigned long long pfn_to_block(unsigned long long pfn);
 static int lookup_diskset(unsigned long long whole_offset, int *diskid,
 			  unsigned long long *disk_offset);
+static int cpu_online_mask_init(void);
 static int per_cpu_init(void);
 static int get_data_from_elf_note_desc(const char *note_buf, uint32_t n_descsz,
 				       char *name, uint32_t n_type, char **data);
@@ -88,6 +98,7 @@ static int alignfile(unsigned long *offset);
 static int
 write_elf_note_header(char *name, void *data, size_t descsz, uint32_t type,
 		      unsigned long *offset, unsigned long *desc_offset);
+static int is_online_cpu(int cpu);
 static unsigned long legacy_per_cpu_ptr(unsigned long ptr, int cpu);
 static unsigned long per_cpu_ptr(unsigned long ptr, int cpu);
 static int get_prstatus_from_crash_notes(int cpu, char *prstatus_buf);
@@ -250,8 +261,10 @@ sadump_generate_elf_note_from_dumpfile(void)
 		       strerror(errno));
 		goto cleanup;
 	}
+	if (!cpu_online_mask_init())
+		goto cleanup;
 	offset = 0;
-	for (x_cpu = 0; x_cpu < get_nr_cpus(); ++x_cpu) {
+	for_each_online_cpu(x_cpu) {
 		struct elf_prstatus prstatus;
 
 		memset(&prstatus, 0, sizeof(prstatus));
@@ -756,35 +769,71 @@ sadump_initialize_bitmap_memory(void)
 	return TRUE;
 }
 
-int
-sadump_get_nr_cpus(int *nr_cpus)
+static int
+cpu_online_mask_init(void)
 {
-	unsigned long offset;
-	struct sadump_smram_cpu_state scs, zero;
-	uint32_t x_cpu;
-	int count;
+	ulong cpu_online_mask_addr;
 
-	memset(&zero, 0, sizeof(zero));
+	if (si->cpu_online_mask_buf && si->cpumask_size)
+		return TRUE;
 
-	offset = si->sub_hdr_offset + sizeof(uint32_t) +
-		si->sh_memory->nr_cpus * sizeof(struct sadump_apic_state);
+	if (SYMBOL(cpu_online_mask) == NOT_FOUND_SYMBOL ||
+	    (SIZE(cpumask) == NOT_FOUND_STRUCTURE &&
+	     SIZE(cpumask_t) == NOT_FOUND_STRUCTURE))
+		return FALSE;
 
-	count = 0;
-	for (x_cpu = 0; x_cpu < si->sh_memory->nr_cpus; ++x_cpu) {
-		if (!read_device(&scs, sizeof(scs), &offset))
-			return FALSE;
-		if (memcmp(&scs, &zero, sizeof(scs)) != 0)
-			count++;
+	si->cpumask_size = SIZE(cpumask) == NOT_FOUND_STRUCTURE
+		? SIZE(cpumask_t)
+		: SIZE(cpumask);
+
+	if (!(si->cpu_online_mask_buf = calloc(1, si->cpumask_size))) {
+		ERRMSG("Can't allocate cpu_online_mask buffer. %s\n",
+		       strerror(errno));
+		return FALSE;
 	}
 
-	*nr_cpus = count;
+	if (SIZE(cpumask) == NOT_FOUND_STRUCTURE)
+		cpu_online_mask_addr = SYMBOL(cpu_online_mask);
+
+	else {
+		if (!readmem(VADDR, SYMBOL(cpu_online_mask),
+			     &cpu_online_mask_addr, sizeof(unsigned long))) {
+			ERRMSG("Can't read cpu_online_mask pointer.\n");
+			return FALSE;
+		}
+
+	}
 
-	DEBUG_MSG("sadump: nr_cpus: %d\n", *nr_cpus);
+	if (!readmem(VADDR, cpu_online_mask_addr, si->cpu_online_mask_buf,
+		     si->cpumask_size)) {
+		ERRMSG("Can't read cpu_online_mask memory.\n");
+		return FALSE;
+	}
 
 	return TRUE;
 }
 
 int
+sadump_num_online_cpus(void)
+{
+	int cpu, count = 0;
+
+	if (!cpu_online_mask_init())
+		return FALSE;
+
+	DEBUG_MSG("sadump: online cpus:");
+
+	for_each_online_cpu(cpu) {
+		count++;
+		DEBUG_MSG(" %d", cpu);
+	}
+
+	DEBUG_MSG("\nsadump: nr_cpus: %d\n", count);
+
+	return count;
+}
+
+int
 sadump_set_timestamp(struct timeval *ts)
 {
 	static struct tm t;
@@ -1201,6 +1250,17 @@ write_elf_note_header(char *name, void *data, size_t descsz, uint32_t type,
 	return TRUE;
 }
 
+static int
+is_online_cpu(int cpu)
+{
+	unsigned long mask;
+
+	mask = ULONG(si->cpu_online_mask_buf +
+		     (cpu / BITPERWORD) * sizeof(unsigned long));
+
+	return (mask & (1UL << (cpu % BITPERWORD))) ? TRUE : FALSE;
+}
+
 static unsigned long
 legacy_per_cpu_ptr(unsigned long ptr, int cpu)
 {
@@ -1710,6 +1770,8 @@ free_sadump_info(void)
 		free(si->block_table);
 	if (si->file_elf_note)
 		fclose(si->file_elf_note);
+	if (si->cpu_online_mask_buf)
+		free(si->cpu_online_mask_buf);
 }
 
 #endif /* defined(__x86__) && defined(__x86_64__) */
diff --git a/sadump_info.h b/sadump_info.h
index c1f948f..f90ea5a 100644
--- a/sadump_info.h
+++ b/sadump_info.h
@@ -40,7 +40,7 @@ static inline int sadump_virt_phys_base(void)
 int check_and_get_sadump_header_info(char *filename);
 int sadump_copy_1st_bitmap_from_memory(void);
 int sadump_initialize_bitmap_memory(void);
-int sadump_get_nr_cpus(int *nr_cpus);
+int sadump_num_online_cpus(void);
 int sadump_set_timestamp(struct timeval *ts);
 unsigned long long sadump_get_max_mapnr(void);
 int readpmem_sadump(unsigned long long paddr, void *bufptr, size_t size);
@@ -81,7 +81,7 @@ static inline int sadump_initialize_bitmap_memory(void)
 	return FALSE;
 }
 
-static inline int sadump_get_nr_cpus(int *nr_cpus)
+static inline int sadump_num_online_cpus(void);
 {
 	return 0;
 }


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 12/14] Read kexec backup region
  2011-10-28  9:48 [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format HATAYAMA Daisuke
                   ` (10 preceding siblings ...)
  2011-10-28  9:49 ` [PATCH v2 11/14] Procees CPUs based on online ones HATAYAMA Daisuke
@ 2011-10-28  9:49 ` HATAYAMA Daisuke
  2011-10-28  9:49 ` [PATCH v2 13/14] Add description of sadump-related formts in usage information HATAYAMA Daisuke
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-10-28  9:49 UTC (permalink / raw)
  To: kexec

Deal with the first 640kB memory backed up by kdump by interpreting
the read request to the region as the request to the backup region
that is specially prepared to preserve the original first kernel's
memory situtation.

The first 640kB memory contains the data necessary for paging: PTE,
for example. So, initialization must be done before trying to read
memory requiring paging to read such as VMALLOC'ed data.

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

 makedumpfile.c |   45 +++++++++++----
 makedumpfile.h |   41 ++++++++++++++
 sadump_info.c  |  168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sadump_info.h  |    6 ++
 4 files changed, 249 insertions(+), 11 deletions(-)

diff --git a/makedumpfile.c b/makedumpfile.c
index 44f6ee6..df82a48 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -829,6 +829,7 @@ get_symbol_info(void)
 	SYMBOL_INIT(cpu_online_mask, "cpu_online_mask");
 	if (SYMBOL(cpu_online_mask) == NOT_FOUND_SYMBOL)
 		SYMBOL_INIT(cpu_online_mask, "cpu_online_map");
+	SYMBOL_INIT(kexec_crash_image, "kexec_crash_image");
 
 	if (SYMBOL(node_data) != NOT_FOUND_SYMBOL)
 		SYMBOL_ARRAY_TYPE_INIT(node_data, "node_data");
@@ -1115,6 +1116,23 @@ get_structure_info(void)
 	}
 #endif /* __x86_64__ */
 
+	OFFSET_INIT(kimage.segment, "kimage", "segment");
+
+	MEMBER_ARRAY_LENGTH_INIT(kimage.segment, "kimage", "segment");
+
+	SIZE_INIT(kexec_segment, "kexec_segment");
+	OFFSET_INIT(kexec_segment.mem, "kexec_segment", "mem");
+
+	OFFSET_INIT(elf64_hdr.e_phnum, "elf64_hdr", "e_phnum");
+	OFFSET_INIT(elf64_hdr.e_phentsize, "elf64_hdr", "e_phentsize");
+	OFFSET_INIT(elf64_hdr.e_phoff, "elf64_hdr", "e_phoff");
+
+	SIZE_INIT(elf64_hdr, "elf64_hdr");
+	OFFSET_INIT(elf64_phdr.p_type, "elf64_phdr", "p_type");
+	OFFSET_INIT(elf64_phdr.p_offset, "elf64_phdr", "p_offset");
+	OFFSET_INIT(elf64_phdr.p_paddr, "elf64_phdr", "p_paddr");
+	OFFSET_INIT(elf64_phdr.p_memsz, "elf64_phdr", "p_memsz");
+
 	return TRUE;
 }
 
@@ -2619,6 +2637,16 @@ out:
 		if (!get_versiondep_info())
 			return FALSE;
 
+		/*
+		 * NOTE: This must be done before refering to
+		 * VMALLOC'ed memory. The first 640kB contains data
+		 * necessary for paging, like PTE. The absence of the
+		 * region affects reading VMALLOC'ed memory such as
+		 * module data.
+		 */
+		if (info->flag_sadump)
+			sadump_kdump_backup_region_init();
+
 		if (!get_numnodes())
 			return FALSE;
 
@@ -2756,6 +2784,12 @@ set_bit_on_1st_bitmap(unsigned long long pfn)
 }
 
 int
+clear_bit_on_1st_bitmap(unsigned long long pfn)
+{
+	return set_bitmap(info->bitmap1, pfn, 0);
+}
+
+int
 clear_bit_on_2nd_bitmap(unsigned long long pfn)
 {
 	return set_bitmap(info->bitmap2, pfn, 0);
@@ -2796,17 +2830,6 @@ is_in_segs(unsigned long long paddr)
 		return FALSE;
 }
 
-static inline int
-is_zero_page(unsigned char *buf, long page_size)
-{
-	size_t i;
-
-	for (i = 0; i < page_size; i++)
-		if (buf[i])
-			return FALSE;
-	return TRUE;
-}
-
 int
 read_cache(struct cache_data *cd)
 {
diff --git a/makedumpfile.h b/makedumpfile.h
index 020d99c..6ae37d9 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -181,6 +181,7 @@ isAnon(unsigned long mapping)
 #define STRNEQ(A, B)	(A && B && \
 	(strncmp((char *)(A), (char *)(B), strlen((char *)(B))) == 0))
 
+#define USHORT(ADDR)	*((unsigned short *)(ADDR))
 #define UINT(ADDR)	*((unsigned int *)(ADDR))
 #define ULONG(ADDR)	*((unsigned long *)(ADDR))
 
@@ -996,6 +997,7 @@ struct symbol_table {
 	unsigned long long	__per_cpu_offset;
 	unsigned long long	__per_cpu_load;
 	unsigned long long	cpu_online_mask;
+	unsigned long long	kexec_crash_image;
 };
 
 struct size_table {
@@ -1027,6 +1029,8 @@ struct size_table {
 	long	user_regs_struct;
 	long	cpumask;
 	long	cpumask_t;
+	long	kexec_segment;
+	long	elf64_hdr;
 };
 
 struct offset_table {
@@ -1135,6 +1139,27 @@ struct offset_table {
 		long	fs;
 		long	gs;
 	} user_regs_struct;
+
+	struct kimage_s {
+		long	segment;
+	} kimage;
+
+	struct kexec_segment_s {
+		long	mem;
+	} kexec_segment;
+
+	struct elf64_hdr_s {
+		long	e_phnum;
+		long	e_phentsize;
+		long	e_phoff;
+	} elf64_hdr;
+
+	struct elf64_phdr_s {
+		long	p_type;
+		long	p_offset;
+		long	p_paddr;
+		long	p_memsz;
+	} elf64_phdr;
 };
 
 /*
@@ -1159,6 +1184,9 @@ struct array_table {
 	struct free_area_at {
 		long	free_list;
 	} free_area;
+	struct kimage_at {
+		long	segment;
+	} kimage;
 };
 
 struct number_table {
@@ -1331,7 +1359,20 @@ is_dumpable(struct dump_bitmap *bitmap, unsigned long long pfn)
 	return is_on(bitmap->buf, pfn%PFN_BUFBITMAP);
 }
 
+static inline int
+is_zero_page(unsigned char *buf, long page_size)
+{
+	size_t i;
+
+	for (i = 0; i < page_size; i++)
+		if (buf[i])
+			return FALSE;
+	return TRUE;
+}
+
 void write_vmcoreinfo_data(void);
+int set_bit_on_1st_bitmap(unsigned long long pfn);
+int clear_bit_on_1st_bitmap(unsigned long long pfn);
 
 #ifdef __x86__
 
diff --git a/sadump_info.c b/sadump_info.c
index 2538da6..69296ce 100644
--- a/sadump_info.c
+++ b/sadump_info.c
@@ -77,6 +77,12 @@ struct sadump_info {
 	FILE *file_elf_note;
 	char *cpu_online_mask_buf;
 	size_t cpumask_size;
+/* Backup Region, First 640K of System RAM. */
+#define KEXEC_BACKUP_SRC_END    0x0009ffff
+        unsigned long long backup_src_start;
+        unsigned long backup_src_size;
+        unsigned long long backup_offset;
+	int kdump_backed_up;
 };
 
 static char *guid_to_str(efi_guid_t *guid, char *buf, size_t buflen);
@@ -188,6 +194,30 @@ sadump_copy_1st_bitmap_from_memory(void)
 		offset_page += sizeof(buf);
 	}
 
+	/*
+	 * kdump uses the first 640kB on the 2nd kernel. But both
+	 * bitmaps should reflect the 1st kernel memory situation. We
+	 * modify bitmap accordingly.
+	 */
+	if (si->kdump_backed_up) {
+		unsigned long long paddr, pfn, backup_src_pfn;
+
+		for (paddr = si->backup_src_start;
+		     paddr < si->backup_src_start + si->backup_src_size;
+		     paddr += info->page_size) {
+
+			pfn = paddr_to_pfn(paddr);
+			backup_src_pfn = paddr_to_pfn(paddr +
+						      si->backup_offset -
+						      si->backup_src_start);
+
+			if (is_dumpable(info->bitmap_memory, backup_src_pfn))
+				set_bit_on_1st_bitmap(pfn);
+			else
+				clear_bit_on_1st_bitmap(pfn);
+		}
+	}
+
 	return TRUE;
 }
 
@@ -920,6 +950,11 @@ readpmem_sadump(unsigned long long paddr, void *bufptr, size_t size)
 	char buf[info->page_size];
 	int fd_memory;
 
+	if (si->kdump_backed_up &&
+	    paddr >= si->backup_src_start &&
+	    paddr < si->backup_src_start + si->backup_src_size)
+		paddr += si->backup_offset - si->backup_src_start;
+
 	pfn = paddr_to_pfn(paddr);
 	page_offset = paddr % info->page_size;
 
@@ -1774,4 +1809,137 @@ free_sadump_info(void)
 		free(si->cpu_online_mask_buf);
 }
 
+void
+sadump_kdump_backup_region_init(void)
+{
+	unsigned char buf[BUFSIZE];
+	unsigned long i, total, kexec_crash_image_p, elfcorehdr_p;
+	Elf64_Off e_phoff;
+	uint16_t e_phnum, e_phentsize;
+	unsigned long long backup_offset;
+	unsigned long backup_src_start, backup_src_size;
+	size_t bufsize;
+	
+	if (!readmem(VADDR, SYMBOL(kexec_crash_image), &kexec_crash_image_p,
+		     sizeof(unsigned long))) {
+		ERRMSG("Can't read kexec_crash_image pointer. %s\n",
+		       strerror(errno));
+		return;
+	}
+
+	if (!kexec_crash_image_p) {
+		DEBUG_MSG("sadump: kexec crash image was not loaded\n");
+		return;
+	}
+
+	if (!readmem(VADDR, kexec_crash_image_p+OFFSET(kimage.segment),
+		     buf, SIZE(kexec_segment)*ARRAY_LENGTH(kimage.segment))) {
+		ERRMSG("Can't read kexec_crash_image->segment. %s\n",
+		       strerror(errno));
+		return;
+	}
+
+	elfcorehdr_p = 0;
+	for (i = 0; i < ARRAY_LENGTH(kimage.segment); ++i) {
+		char e_ident[EI_NIDENT];
+		unsigned mem;
+
+		mem=ULONG(buf+i*SIZE(kexec_segment)+OFFSET(kexec_segment.mem));
+		if (!mem)
+			continue;
+
+		if (!readmem(PADDR, mem, e_ident, SELFMAG)) {
+			DEBUG_MSG("sadump: failed to read elfcorehdr buffer\n");
+			return;
+		}
+
+		if (strncmp(ELFMAG, e_ident, SELFMAG) == 0) {
+			elfcorehdr_p = mem;
+			break;
+		}
+	}
+	if (!elfcorehdr_p) {
+		DEBUG_MSG("sadump: kexec_crash_image contains no elfcorehdr "
+			  "segment\n");
+		return;
+	}
+
+        if (!readmem(PADDR, elfcorehdr_p, buf, SIZE(elf64_hdr))) {
+		ERRMSG("Can't read elfcorehdr ELF header. %s\n",
+		       strerror(errno));
+		return;
+	}
+
+	e_phnum = USHORT(buf + OFFSET(elf64_hdr.e_phnum));
+	e_phentsize = USHORT(buf + OFFSET(elf64_hdr.e_phentsize));
+	e_phoff = ULONG(buf + OFFSET(elf64_hdr.e_phoff));
+
+	backup_src_start = backup_src_size = backup_offset = 0;
+	for (i = 0; i < e_phnum; ++i) {
+		unsigned long p_type, p_offset, p_paddr, p_memsz;
+
+		if (!readmem(PADDR, elfcorehdr_p+e_phoff+i*e_phentsize, buf,
+			     e_phentsize)) {
+			ERRMSG("Can't read elfcorehdr program header. %s\n",
+			       strerror(errno));
+			return;
+		}
+
+		p_type = UINT(buf + OFFSET(elf64_phdr.p_type));
+		p_offset = ULONG(buf + OFFSET(elf64_phdr.p_offset));
+		p_paddr = ULONG(buf + OFFSET(elf64_phdr.p_paddr));
+		p_memsz = ULONG(buf + OFFSET(elf64_phdr.p_memsz));
+
+		if (p_type == PT_LOAD &&
+		    p_paddr <= KEXEC_BACKUP_SRC_END &&
+		    p_paddr + p_memsz <= p_offset) {
+
+			backup_src_start = p_paddr;
+			backup_src_size = p_memsz;
+			backup_offset = p_offset;
+
+DEBUG_MSG("sadump: SRC_START: %#016lx SRC_SIZE: %#016lx SRC_OFFSET: %#016llx\n",
+	  backup_src_start, backup_src_size, backup_offset);
+
+			break;
+		}
+	}
+	if (i == e_phnum) {
+DEBUG_MSG("sadump: No PT_LOAD in elfcorehdr for backup area\n");
+		return;
+	}
+
+	bufsize = BUFSIZE;
+	for (total = 0; total < backup_src_size; total += bufsize) {
+
+		if (backup_src_size - total < BUFSIZE)
+			bufsize = backup_src_size - total;
+
+		if (!readmem(PADDR, backup_offset + total, buf, bufsize)) {
+			ERRMSG("Can't read bacckup region. %s\n",
+			       strerror(errno));
+			return;
+		}
+
+		/*
+		 * We're assuming that the backup region is full of 0
+		 * before kdump saves the first 640kB memory of the
+		 * 1st kernel in the region.
+		 */
+		if (!is_zero_page(buf, bufsize)) {
+
+			si->kdump_backed_up = TRUE;
+			si->backup_src_start = backup_src_start;
+			si->backup_src_size = backup_src_size;
+			si->backup_offset = backup_offset;
+
+			DEBUG_MSG("sadump: kdump backup region used\n");
+
+			return;
+		}
+	}
+
+	DEBUG_MSG("sadump: kdump backup region unused\n");
+}
+
 #endif /* defined(__x86__) && defined(__x86_64__) */
diff --git a/sadump_info.h b/sadump_info.h
index f90ea5a..1f74ee5 100644
--- a/sadump_info.h
+++ b/sadump_info.h
@@ -54,6 +54,7 @@ long sadump_page_size(void);
 char *sadump_head_disk_name_memory(void);
 char *sadump_format_type_name(void);
 void free_sadump_info(void);
+void sadump_kdump_backup_region_init(void);
 
 static inline int sadump_is_supported_arch(void)
 {
@@ -154,6 +155,11 @@ static inline int sadump_is_supported_arch(void)
 	return FALSE;
 }
 
+static inline void sadump_kdump_backup_region_init(void)
+{
+	return;
+}
+
 #endif
 
 #endif /* _SADUMP_INFO_H */


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 13/14] Add description of sadump-related formts in usage information
  2011-10-28  9:48 [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format HATAYAMA Daisuke
                   ` (11 preceding siblings ...)
  2011-10-28  9:49 ` [PATCH v2 12/14] Read kexec backup region HATAYAMA Daisuke
@ 2011-10-28  9:49 ` HATAYAMA Daisuke
  2011-10-28  9:49 ` [PATCH v2 14/14] Add description of sadump-related formats in manual page HATAYAMA Daisuke
  2011-10-28 12:05 ` [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format tachibana
  14 siblings, 0 replies; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-10-28  9:49 UTC (permalink / raw)
  To: kexec

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

 print_info.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/print_info.c b/print_info.c
index 547976e..19a578b 100644
--- a/print_info.c
+++ b/print_info.c
@@ -69,6 +69,11 @@ print_usage(void)
 	MSG("  # makedumpfile -g VMCOREINFO --xen-syms XEN-SYMS\n");
 	MSG("\n");
 	MSG("\n");
+	MSG("  Creating DUMPFILE from multiple VMCOREs generated on sadump diskset configuration:\n");
+	MSG("  # makedumpfile [-c] [-d DL] -x VMLINUX --diskset=VMCORE1 --diskset=VMCORE2\n");
+	MSG("    [--diskset=VMCORE3 ..] DUMPFILE\n");
+	MSG("\n");
+	MSG("\n");
 	MSG("Available options:\n");
 	MSG("  [-c]:\n");
 	MSG("      Compress dump data by each page.\n");
@@ -163,6 +168,11 @@ print_usage(void)
 	MSG("      Exclude all the user domain pages from Xen kdump's VMCORE, and extract\n");
 	MSG("      the part of Xen and domain-0.\n");
 	MSG("\n");
+	MSG("  [--diskset=VMCORE]:\n");
+	MSG("      Specify multiple VMCOREs created on sadump diskset configuration the same\n");
+	MSG("      number of times as the number of VMCOREs in increasing order from left to\n");
+	MSG("      right.\n");
+	MSG("\n");
 	MSG("  [--message-level ML]:\n");
 	MSG("      Specify the message types.\n");
 	MSG("      Users can restrict output printed by specifying Message_Level (ML) with\n");


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH v2 14/14] Add description of sadump-related formats in manual page
  2011-10-28  9:48 [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format HATAYAMA Daisuke
                   ` (12 preceding siblings ...)
  2011-10-28  9:49 ` [PATCH v2 13/14] Add description of sadump-related formts in usage information HATAYAMA Daisuke
@ 2011-10-28  9:49 ` HATAYAMA Daisuke
  2011-10-28 12:05 ` [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format tachibana
  14 siblings, 0 replies; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-10-28  9:49 UTC (permalink / raw)
  To: kexec

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

 makedumpfile.8 |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/makedumpfile.8 b/makedumpfile.8
index 1da16b9..f7dfe04 100644
--- a/makedumpfile.8
+++ b/makedumpfile.8
@@ -20,6 +20,8 @@ makedumpfile \- make a small dumpfile of kdump
 .br
 \fBmakedumpfile\fR \-\-dump-dmesg [\-x \fIVMLINUX\fR|\-i \fIVMCOREINFO\fR] \fIVMCORE\fR \fILOGFILE\fR
 .br
+\fBmakedumpfile\fR    [\fIOPTION\fR] \-x \fIVMLINUX\fR \-\-diskset=\fIVMCORE1\fR \-\-diskset=\fIVMCORE2\fR [\-\-diskset=\fIVMCORE3\fR ..] \fIDUMPFILE\fR
+.br
 .B makedumpfile
 \-h
 .br
@@ -104,6 +106,14 @@ one of dump_level 3 like the following:
 # makedumpfile \-c \-d 3 /proc/vmcore dumpfile.1
 .br
 # makedumpfile \-c \-d 31 dumpfile.1 dumpfile.2
+.PP
+makedumpfile can read \fIVMCORE\fR(s) in three kinds of sadump
+formats: single partition format, diskset format and media backup
+format, and can convert each of them into kdump-compressed format with
+filtering and compression processing. Note that for \fIVMCORE\fR(s)
+created by sadump, you always need to pass \fIVMLINUX\fR with -x
+option. Also, to pass multiple \fIVMCORE\fRs created on diskset
+configuration, you need to use --diskset option.
 
 .PP
 .SH OPTIONS
@@ -460,6 +470,18 @@ it is necessary to specfiy [\-x \fIVMLINUX\fR] or [\-i \fIVMCOREINFO\fR].
 .br
 
 .TP
+\fB\-\-diskset=VMCORE\fR
+Specify multiple \fIVMCORE\fRs created on sadump diskset configuration
+the same number of times as the number of \fIVMCORE\fRs in increasing
+order from left to right.  \fIVMCORE\fRs are assembled into a single
+\fIDUMPFILE.
+
+.br
+.B Example:
+.br
+# makedumpfile \-x vmlinux \-\-diskset=vmcore1 \-\-diskset=vmcore2 dumpfile
+
+.TP
 \fB\-D\fR
 Print debugging message.
 


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format
  2011-10-28  9:48 [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format HATAYAMA Daisuke
                   ` (13 preceding siblings ...)
  2011-10-28  9:49 ` [PATCH v2 14/14] Add description of sadump-related formats in manual page HATAYAMA Daisuke
@ 2011-10-28 12:05 ` tachibana
  2011-12-15  6:47   ` HATAYAMA Daisuke
  14 siblings, 1 reply; 23+ messages in thread
From: tachibana @ 2011-10-28 12:05 UTC (permalink / raw)
  To: HATAYAMA Daisuke; +Cc: kexec

Hi HATAYAMA-san

Thank you for updating patches.
I will review them.


Thanks.
tachibana


On 2011/10/28 18:48:04 +0900, HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com> wrote:
> Hello Tachibana-san,
> 
> Since there's certain time until Tachibana-san's review, I made some
> cleanups and bugfixes to the previous version. Could you review this
> instead to reduce the review time?
> 
> ==
> The following series implements Fujitsu stand-alone dump (sadump)
> format support for makedumpfile, converting sadump-related formats
> into kdump-compressed format.
> 
> Based on makedumpfile version 1.4.0.
> 
> Here is summary of the changes.
> 
> No debug information on sadump-related formats
> ==============================================
> 
> Unlike other dump mechanisms, VMCORE created by sadump has NO debug
> information including VMCOREINFO. So, -x VMLINUX is definitely
> necessary.
> 
> Debug information gained from VMLINUX is used for:
> 
>     1. creating VMCOREINFO dynamically, saved in resulting dumpfiles
>        in kdump-compressed format, and
> 
>     2. gaining symbolic and type information necessary to refer to ELF
>        note information contained in VMCORE generated by kdump at
>        crash, and to estimate phys_base value.
> 
> If no VMLINUX is specified, dumpfile with no VMCOREINFO and ELF note
> is generated on the current implementation.
> 
> 
> Command-line interface change
> =============================
> 
> Introduce --diskset=VMCORE to pass multiple VMCOREs in a single
> commnad-line input.
> 
>     makedumpfile [OPTION] -x VMLINUX --diskset=VMCORE1 --diskset=VMCORE2 \
>     [--diskset=VMCORE3 ..] DUMPFILE
> 
> 
> Architectures
> =============
> 
> X86 and X86_64.
> 
> On the other unsupported architectures, sadump-related source files
> are never compiled and linked into makedumpfile executable.
> 
> ---
> 
> HATAYAMA Daisuke (14):
>       Add description of sadump-related formats in manual page
>       Add description of sadump-related formts in usage information
>       Read kexec backup region
>       Procees CPUs based on online ones
>       Generate and save VMCOREINFO and ELF note information
>       Estimate phys_base based on linux_banner position
>       Implement readmem() interface on sadump-related formats
>       Initialize debug information for ELF note extraction
>       Initialize internal data according to sadump-related formats
>       Export helpers for bitmap table handling
>       Verify and read VMCORE(s) in sadump-related formats
>       Implement command-line processing
>       Extend DumpInfo structure
>       Add sadump module header file
> 
> 
>  Makefile       |    6 
>  elf_info.c     |    2 
>  makedumpfile.8 |   22 +
>  makedumpfile.c |  455 +++++++++++--
>  makedumpfile.h |  207 ++++++
>  print_info.c   |   10 
>  sadump_info.c  | 1945 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  sadump_info.h  |  165 +++++
>  sadump_mod.h   |  186 +++++
>  9 files changed, 2907 insertions(+), 91 deletions(-)
>  create mode 100644 sadump_info.c
>  create mode 100644 sadump_info.h
>  create mode 100644 sadump_mod.h
> 
> -- 
> Thanks.
> HATAYAMA, Daisuke
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format
  2011-10-28 12:05 ` [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format tachibana
@ 2011-12-15  6:47   ` HATAYAMA Daisuke
  2011-12-15  8:55     ` tachibana
  0 siblings, 1 reply; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-12-15  6:47 UTC (permalink / raw)
  To: tachibana; +Cc: kexec

Hello Tachibana-san,

From: tachibana@mxm.nes.nec.co.jp
Subject: Re: [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format
Date: Fri, 28 Oct 2011 21:05:03 +0900

> Hi HATAYAMA-san
> 
> Thank you for updating patches.
> I will review them.
> 
> 
> Thanks.
> tachibana
> 

Could you tell me the status?

Thanks.
HATAYAMA, Daisuke


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format
  2011-12-15  6:47   ` HATAYAMA Daisuke
@ 2011-12-15  8:55     ` tachibana
  2011-12-15  9:09       ` HATAYAMA Daisuke
  0 siblings, 1 reply; 23+ messages in thread
From: tachibana @ 2011-12-15  8:55 UTC (permalink / raw)
  To: HATAYAMA Daisuke; +Cc: tachibana, kexec

Hi Hatayama-san,

Sorry for late reply.
Now we are executing regression tests.
If no problem will be detected, we will merge sadump patches 
into makedumpfile V.1.4.1 around the new year.

Thanks.
tachibana

On 2011/12/15 15:47:22 +0900, HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com> wrote:
> Hello Tachibana-san,
> 
> From: tachibana@mxm.nes.nec.co.jp
> Subject: Re: [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format
> Date: Fri, 28 Oct 2011 21:05:03 +0900
> 
> > Hi HATAYAMA-san
> > 
> > Thank you for updating patches.
> > I will review them.
> > 
> > 
> > Thanks.
> > tachibana
> > 
> 
> Could you tell me the status?
> 
> Thanks.
> HATAYAMA, Daisuke
> 

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format
  2011-12-15  8:55     ` tachibana
@ 2011-12-15  9:09       ` HATAYAMA Daisuke
  0 siblings, 0 replies; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-12-15  9:09 UTC (permalink / raw)
  To: tachibana; +Cc: kexec

Hello Tachibana-san,

From: tachibana@mxm.nes.nec.co.jp
Subject: Re: [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format
Date: Thu, 15 Dec 2011 17:55:22 +0900

> Hi Hatayama-san,
> 
> Sorry for late reply.
> Now we are executing regression tests.
> If no problem will be detected, we will merge sadump patches 
> into makedumpfile V.1.4.1 around the new year.
> 
> Thanks.
> tachibana

So I'm waiting for the result.

Thanks.
HATAYAMA, Daisuke


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information
  2011-10-28  9:48 ` [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information HATAYAMA Daisuke
@ 2011-12-20  8:18   ` Atsushi Kumagai
  2011-12-20  9:31     ` HATAYAMA Daisuke
  0 siblings, 1 reply; 23+ messages in thread
From: Atsushi Kumagai @ 2011-12-20  8:18 UTC (permalink / raw)
  To: kexec

Hi Hatayama-san,

> [snipped]
>
> diff --git a/elf_info.c b/elf_info.c
> index 114dd05..48f8510 100644
> --- a/elf_info.c
> +++ b/elf_info.c
> @@ -760,7 +760,7 @@ get_nr_cpus(void)
>  int
>  has_pt_note(void)
>  {
> -	if (offset_pt_note_memory && size_pt_note_memory)
> +	if (offset_pt_note_memory || size_pt_note_memory)
>  		return TRUE;
>  	return FALSE;
>  }

I have a question.
In what kind of case is only one of the offset or the size set to 0 in PT_NOTE?

Thanks.
Atsushi Kumagai


On Fri, 28 Oct 2011 18:48:58 +0900
HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com> wrote:

> Retrieve VMCOREINFO from VMLINUX and ELF note information from
> VMCORE(s) and save them in generated DUMPFILE.
> 
> ELF note information is NT_PRSTATUS only. If crash_notes is NULL,
> indicating kdump has not saved register values, save SMRAM CPU STATE
> values. If crash_notes is not NULL, indicating kdump has saved
> register values at crash, then save the register values in
> crash_notes.
> 
> Signed-off-by: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
> ---
> 
>  elf_info.c     |    2 
>  makedumpfile.c |  103 ++++---
>  makedumpfile.h |    2 
>  sadump_info.c  |  823 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  sadump_info.h  |   26 ++
>  5 files changed, 913 insertions(+), 43 deletions(-)
>
> [snipped]
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information
  2011-12-20  8:18   ` Atsushi Kumagai
@ 2011-12-20  9:31     ` HATAYAMA Daisuke
  2011-12-21  8:22       ` Atsushi Kumagai
  0 siblings, 1 reply; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-12-20  9:31 UTC (permalink / raw)
  To: kumagai-atsushi; +Cc: kexec

Hello Kumagai-san,

From: Atsushi Kumagai <kumagai-atsushi@mxc.nes.nec.co.jp>
Subject: Re: [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information
Date: Tue, 20 Dec 2011 17:18:12 +0900

> Hi Hatayama-san,
> 
>> [snipped]
>>
>> diff --git a/elf_info.c b/elf_info.c
>> index 114dd05..48f8510 100644
>> --- a/elf_info.c
>> +++ b/elf_info.c
>> @@ -760,7 +760,7 @@ get_nr_cpus(void)
>>  int
>>  has_pt_note(void)
>>  {
>> -	if (offset_pt_note_memory && size_pt_note_memory)
>> +	if (offset_pt_note_memory || size_pt_note_memory)
>>  		return TRUE;
>>  	return FALSE;
>>  }
> 
> I have a question.
> In what kind of case is only one of the offset or the size set to 0 in PT_NOTE?
> 

Thanks for your reviewing.

On sadump processing, offset_pt_note_memory represents file offset to
a temporary file created specifically for writing PT_NOTE section. So
offset_pt_note_memory is always 0. Its file pointer is set to struct
sadump_info::file_elf_note. Please look at the end of
sadump_generate_elf_note_from_dumpfile().

On the other hand, on both ELF and kdump-compressed format, PT_NOTE
section is always located in the middle of the vmcores. On either
formats, there's always another header before the PT_NOTE section: on
ELF, ELF header, and on kdump-compressed format, at least. So
offset_pt_note_memory is always strictly greater than 0 on these
formats.

If condition of has_pt_note() is not weakened in such a way,
has_pt_note() amounts to always false and execution in
write_kdump_header() always passes through writing oepration for
PT_NOTE section.

Thanks.
HATAYAMA, Daisuke


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information
  2011-12-20  9:31     ` HATAYAMA Daisuke
@ 2011-12-21  8:22       ` Atsushi Kumagai
  2011-12-21  8:39         ` HATAYAMA Daisuke
  0 siblings, 1 reply; 23+ messages in thread
From: Atsushi Kumagai @ 2011-12-21  8:22 UTC (permalink / raw)
  To: d.hatayama; +Cc: kexec

Hi Hatayama-san,

> > I have a question.
> > In what kind of case is only one of the offset or the size set to 0 in PT_NOTE?
> > 
> 
> Thanks for your reviewing.
> 
> On sadump processing, offset_pt_note_memory represents file offset to
> a temporary file created specifically for writing PT_NOTE section. So
> offset_pt_note_memory is always 0. Its file pointer is set to struct
> sadump_info::file_elf_note. Please look at the end of
> sadump_generate_elf_note_from_dumpfile().
> 
> On the other hand, on both ELF and kdump-compressed format, PT_NOTE
> section is always located in the middle of the vmcores. On either
> formats, there's always another header before the PT_NOTE section: on
> ELF, ELF header, and on kdump-compressed format, at least. So
> offset_pt_note_memory is always strictly greater than 0 on these
> formats.
> 
> If condition of has_pt_note() is not weakened in such a way,
> has_pt_note() amounts to always false and execution in
> write_kdump_header() always passes through writing oepration for
> PT_NOTE section.


Thank you for your explanation. I understand.
However
	if (offset_pt_note_memory || size_pt_note_memory)
seems to allow the offset != 0 and the size == 0.
Is the following fixing right?
I would like to fix has_pt_note() like this.
How about this?

-	if (offset_pt_note_memory && size_pt_note_memory)
+       if (info->flag_sadump) {
+		if (size_pt_note_memory)
+			return TRUE;
+	} else if (offset_pt_note_memory && size_pt_note_memory)
			return TRUE;

Thanks.
Atsushi Kumagai

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information
  2011-12-21  8:22       ` Atsushi Kumagai
@ 2011-12-21  8:39         ` HATAYAMA Daisuke
  0 siblings, 0 replies; 23+ messages in thread
From: HATAYAMA Daisuke @ 2011-12-21  8:39 UTC (permalink / raw)
  To: kumagai-atsushi; +Cc: kexec

From: Atsushi Kumagai <kumagai-atsushi@mxc.nes.nec.co.jp>
Subject: Re: [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information
Date: Wed, 21 Dec 2011 17:22:30 +0900

> Hi Hatayama-san,
> 
>> > I have a question.
>> > In what kind of case is only one of the offset or the size set to 0 in PT_NOTE?
>> > 
>> 
>> Thanks for your reviewing.
>> 
>> On sadump processing, offset_pt_note_memory represents file offset to
>> a temporary file created specifically for writing PT_NOTE section. So
>> offset_pt_note_memory is always 0. Its file pointer is set to struct
>> sadump_info::file_elf_note. Please look at the end of
>> sadump_generate_elf_note_from_dumpfile().
>> 
>> On the other hand, on both ELF and kdump-compressed format, PT_NOTE
>> section is always located in the middle of the vmcores. On either
>> formats, there's always another header before the PT_NOTE section: on
>> ELF, ELF header, and on kdump-compressed format, at least. So
>> offset_pt_note_memory is always strictly greater than 0 on these
>> formats.
>> 
>> If condition of has_pt_note() is not weakened in such a way,
>> has_pt_note() amounts to always false and execution in
>> write_kdump_header() always passes through writing oepration for
>> PT_NOTE section.
> 
> 
> Thank you for your explanation. I understand.
> However
> 	if (offset_pt_note_memory || size_pt_note_memory)
> seems to allow the offset != 0 and the size == 0.
> Is the following fixing right?
> I would like to fix has_pt_note() like this.
> How about this?
> 
> -	if (offset_pt_note_memory && size_pt_note_memory)
> +       if (info->flag_sadump) {
> +		if (size_pt_note_memory)
> +			return TRUE;
> +	} else if (offset_pt_note_memory && size_pt_note_memory)
> 			return TRUE;
> 

I agree. It looks better.

Thanks.
HATAYAMA, Daisuke


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2011-12-21  8:40 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-28  9:48 [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format HATAYAMA Daisuke
2011-10-28  9:48 ` [PATCH v2 01/14] Add sadump module header file HATAYAMA Daisuke
2011-10-28  9:48 ` [PATCH v2 02/14] Extend DumpInfo structure HATAYAMA Daisuke
2011-10-28  9:48 ` [PATCH v2 03/14] Implement command-line processing HATAYAMA Daisuke
2011-10-28  9:48 ` [PATCH v2 04/14] Verify and read VMCORE(s) in sadump-related formats HATAYAMA Daisuke
2011-10-28  9:48 ` [PATCH v2 05/14] Export helpers for bitmap table handling HATAYAMA Daisuke
2011-10-28  9:48 ` [PATCH v2 06/14] Initialize internal data according to sadump-related formats HATAYAMA Daisuke
2011-10-28  9:48 ` [PATCH v2 07/14] Initialize debug information for ELF note extraction HATAYAMA Daisuke
2011-10-28  9:48 ` [PATCH v2 08/14] Implement readmem() interface on sadump-related formats HATAYAMA Daisuke
2011-10-28  9:48 ` [PATCH v2 09/14] Estimate phys_base based on linux_banner position HATAYAMA Daisuke
2011-10-28  9:48 ` [PATCH v2 10/14] Generate and save VMCOREINFO and ELF note information HATAYAMA Daisuke
2011-12-20  8:18   ` Atsushi Kumagai
2011-12-20  9:31     ` HATAYAMA Daisuke
2011-12-21  8:22       ` Atsushi Kumagai
2011-12-21  8:39         ` HATAYAMA Daisuke
2011-10-28  9:49 ` [PATCH v2 11/14] Procees CPUs based on online ones HATAYAMA Daisuke
2011-10-28  9:49 ` [PATCH v2 12/14] Read kexec backup region HATAYAMA Daisuke
2011-10-28  9:49 ` [PATCH v2 13/14] Add description of sadump-related formts in usage information HATAYAMA Daisuke
2011-10-28  9:49 ` [PATCH v2 14/14] Add description of sadump-related formats in manual page HATAYAMA Daisuke
2011-10-28 12:05 ` [PATCH v2 00/14] Support Fujitsu Stand Alone Dump Format tachibana
2011-12-15  6:47   ` HATAYAMA Daisuke
2011-12-15  8:55     ` tachibana
2011-12-15  9:09       ` HATAYAMA Daisuke

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.