diff --git a/kexec-tools-2.0.4-makedumpfile-Fix-max_mapnr-issue-on-system-has-over-44-b.patch b/kexec-tools-2.0.4-makedumpfile-Fix-max_mapnr-issue-on-system-has-over-44-b.patch new file mode 100644 index 0000000..fee9cb8 --- /dev/null +++ b/kexec-tools-2.0.4-makedumpfile-Fix-max_mapnr-issue-on-system-has-over-44-b.patch @@ -0,0 +1,329 @@ +From 8e124174b62376b17ac909bc68622ef07bde6840 Mon Sep 17 00:00:00 2001 +Message-Id: <8e124174b62376b17ac909bc68622ef07bde6840.1382323707.git.bhe@redhat.com> +From: Jingbai Ma +Date: Fri, 18 Oct 2013 18:53:38 +0900 +Subject: [PATCH] [PATCH v4] Fix max_mapnr issue on system has over 44-bit + addressing. + +This patch will fix a bug of makedumpfile doesn't work correctly on system +has over 44-bit addressing in compression dump mode. +This bug was posted here: +http://lists.infradead.org/pipermail/kexec/2013-September/009587.html + +This patch will add 3 new fields in struct kdump_sub_header. +unsigned long long start_pfn_64; /* header_version 6 and later */ +unsigned long long end_pfn_64; /* header_version 6 and later */ +unsigned long long max_mapnr_64; /* header_version 6 and later */ + +And the old "unsigned int max_mapnr" in struct disk_dump_header will +not be used anymore, but still be there for compatibility purpose. + +The max_mapnr_64 only exists in strcut kdump_sub_header, and that only +for compressed kdump format, so for ELF format kdump files (non-compressed), +only the max_mapnr is available, so it still may be truncated for addresses +exceed 44bit (above 16TB). + +This patch will change the header_version to 6. + +The corresponding patch for crash utility can be found here: +http://lists.infradead.org/pipermail/kexec/2013-October/009750.html + +This patch doesn't change sadump_header. + +Changelog: +v4: +- Do not change max_mapnr_64 in kdump_sub_header in memory for old kernel. + +v3: +- Change notes for max_mapnr, start_pfn and end_pfn as obsolete. +- Remove "(32bit)" from debug messages of max_mapnr, start_pfn and end_pfn. +- Set the 32bit start_pfn and end_pfn to UINT_MAX. +- Remove bitmap writting enhancement to another seperate patch. +- Change type of len_bitmap in struct DumpInfo back to unsigned long. + +v2: +- Rename max_mapnr in struct kdump_sub_header to max_mapnr_64. +- Change type of max_mapnr_64 from unsigned long to unsigned long long. + In x86 PAE mode on x86_32 kernel, the address may exceeds 44bit limit. +- Add start_pfn_64, end_pfn_64 for struct kdump_sub_header. +- Only print 64bit start_pfn_64, end_pfn_64 and max_mapnr_64 + debug messages for disk dump header version >= 6. +- Change type of bitmap_len in struct DumpInfo, from unsigned long to + unsigned long long. +- Enhance bitmap writting function in reassemble_kdump_header(). + Prevent bitmap writting failure if the size of bitmap is too large to + fit a sigle write. + +v1: +- http://lists.infradead.org/pipermail/kexec/2013-September/009662.html + +Signed-off-by: Jingbai Ma +Tested-by: Lisa Mitchell +--- + IMPLEMENTATION | 15 ++++++++++--- + diskdump_mod.h | 15 ++++++++++--- + makedumpfile.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++------------ + 3 files changed, 77 insertions(+), 20 deletions(-) + +diff --git a/makedumpfile-1.5.4/IMPLEMENTATION b/makedumpfile-1.5.4/IMPLEMENTATION +index f0f3135..2f4cfd6 100644 +--- a/makedumpfile-1.5.4/IMPLEMENTATION ++++ b/makedumpfile-1.5.4/IMPLEMENTATION +@@ -48,7 +48,9 @@ + header in blocks */ + unsigned int bitmap_blocks; /* Size of Memory bitmap in + block */ +- unsigned int max_mapnr; /* = max_mapnr */ ++ unsigned int max_mapnr; /* = max_mapnr, OBSOLETE! ++ 32bit only, full 64bit ++ in sub header. */ + unsigned int total_ram_blocks;/* Number of blocks should be + written */ + unsigned int device_blocks; /* Number of total blocks in +@@ -69,14 +71,21 @@ + unsigned long phys_base; + int dump_level; /* header_version 1 and later */ + int split; /* header_version 2 and later */ +- unsigned long start_pfn; /* header_version 2 and later */ +- unsigned long end_pfn; /* header_version 2 and later */ ++ unsigned long start_pfn; /* header_version 2 and later, ++ OBSOLETE! 32bit only, full ++ 64bit in start_pfn_64. */ ++ unsigned long end_pfn; /* header_version 2 and later, ++ OBSOLETE! 32bit only, full ++ 64bit in end_pfn_64. */ + off_t offset_vmcoreinfo;/* header_version 3 and later */ + unsigned long size_vmcoreinfo; /* header_version 3 and later */ + off_t offset_note; /* header_version 4 and later */ + unsigned long size_note; /* header_version 4 and later */ + off_t offset_eraseinfo; /* header_version 5 and later */ + unsigned long size_eraseinfo; /* header_version 5 and later */ ++ unsigned long long start_pfn_64; /* header_version 6 and later */ ++ unsigned long long end_pfn_64; /* header_version 6 and later */ ++ unsigned long long max_mapnr_64; /* header_version 6 and later */ + }; + + - 1st-bitmap +diff --git a/makedumpfile-1.5.4/diskdump_mod.h b/makedumpfile-1.5.4/diskdump_mod.h +index 00ab852..dd24eb2 100644 +--- a/makedumpfile-1.5.4/diskdump_mod.h ++++ b/makedumpfile-1.5.4/diskdump_mod.h +@@ -52,7 +52,9 @@ struct disk_dump_header { + header in blocks */ + unsigned int bitmap_blocks; /* Size of Memory bitmap in + block */ +- unsigned int max_mapnr; /* = max_mapnr */ ++ unsigned int max_mapnr; /* = max_mapnr, OBSOLETE! ++ 32bit only, full 64bit ++ in sub header. */ + unsigned int total_ram_blocks;/* Number of blocks should be + written */ + unsigned int device_blocks; /* Number of total blocks in +@@ -71,14 +73,21 @@ struct kdump_sub_header { + unsigned long phys_base; + int dump_level; /* header_version 1 and later */ + int split; /* header_version 2 and later */ +- unsigned long start_pfn; /* header_version 2 and later */ +- unsigned long end_pfn; /* header_version 2 and later */ ++ unsigned long start_pfn; /* header_version 2 and later, ++ OBSOLETE! 32bit only, full ++ 64bit in start_pfn_64. */ ++ unsigned long end_pfn; /* header_version 2 and later, ++ OBSOLETE! 32bit only, full ++ 64bit in end_pfn_64. */ + off_t offset_vmcoreinfo;/* header_version 3 and later */ + unsigned long size_vmcoreinfo; /* header_version 3 and later */ + off_t offset_note; /* header_version 4 and later */ + unsigned long size_note; /* header_version 4 and later */ + off_t offset_eraseinfo; /* header_version 5 and later */ + unsigned long size_eraseinfo; /* header_version 5 and later */ ++ unsigned long long start_pfn_64; /* header_version 6 and later */ ++ unsigned long long end_pfn_64; /* header_version 6 and later */ ++ unsigned long long max_mapnr_64; /* header_version 6 and later */ + }; + + /* page flags */ +diff --git a/makedumpfile-1.5.4/makedumpfile.c b/makedumpfile-1.5.4/makedumpfile.c +index 9892108..428c53e 100644 +--- a/makedumpfile-1.5.4/makedumpfile.c ++++ b/makedumpfile-1.5.4/makedumpfile.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + + struct symbol_table symbol_table; + struct size_table size_table; +@@ -125,7 +126,10 @@ get_max_mapnr(void) + unsigned long long max_paddr; + + if (info->flag_refiltering) { +- info->max_mapnr = info->dh_memory->max_mapnr; ++ if (info->dh_memory->header_version >= 6) ++ info->max_mapnr = info->kh_memory->max_mapnr_64; ++ else ++ info->max_mapnr = info->dh_memory->max_mapnr; + return TRUE; + } + +@@ -802,6 +806,12 @@ get_kdump_compressed_header_info(char *filename) + DEBUG_MSG(" split : %d\n", kh.split); + DEBUG_MSG(" start_pfn : 0x%lx\n", kh.start_pfn); + DEBUG_MSG(" end_pfn : 0x%lx\n", kh.end_pfn); ++ if (dh.header_version >= 6) { ++ /* A dumpfile contains full 64bit values. */ ++ DEBUG_MSG(" start_pfn_64 : 0x%llx\n", kh.start_pfn_64); ++ DEBUG_MSG(" end_pfn_64 : 0x%llx\n", kh.end_pfn_64); ++ DEBUG_MSG(" max_mapnr_64 : 0x%llx\n", kh.max_mapnr_64); ++ } + + info->dh_memory = malloc(sizeof(dh)); + if (info->dh_memory == NULL) { +@@ -2799,14 +2809,16 @@ int + initialize_bitmap_memory(void) + { + struct disk_dump_header *dh; ++ struct kdump_sub_header *kh; + struct dump_bitmap *bmp; + off_t bitmap_offset; +- int bitmap_len, max_sect_len; ++ off_t bitmap_len, max_sect_len; + unsigned long pfn; + int i, j; + long block_size; + + dh = info->dh_memory; ++ kh = info->kh_memory; + block_size = dh->block_size; + + bitmap_offset +@@ -2826,7 +2838,10 @@ initialize_bitmap_memory(void) + bmp->offset = bitmap_offset + bitmap_len / 2; + info->bitmap_memory = bmp; + +- max_sect_len = divideup(dh->max_mapnr, BITMAP_SECT_LEN); ++ if (dh->header_version >= 6) ++ max_sect_len = divideup(kh->max_mapnr_64, BITMAP_SECT_LEN); ++ else ++ max_sect_len = divideup(dh->max_mapnr, BITMAP_SECT_LEN); + info->valid_pages = calloc(sizeof(ulong), max_sect_len); + if (info->valid_pages == NULL) { + ERRMSG("Can't allocate memory for the valid_pages. %s\n", +@@ -4743,7 +4758,7 @@ create_2nd_bitmap(void) + int + prepare_bitmap_buffer(void) + { +- unsigned long tmp; ++ unsigned long long tmp; + + /* + * Create 2 bitmaps (1st-bitmap & 2nd-bitmap) on block_size boundary. +@@ -4775,7 +4790,7 @@ prepare_bitmap_buffer(void) + int + prepare_bitmap_buffer_cyclic(void) + { +- unsigned long tmp; ++ unsigned long long tmp; + + /* + * Create 2 bitmaps (1st-bitmap & 2nd-bitmap) on block_size boundary. +@@ -5190,11 +5205,12 @@ write_kdump_header(void) + * Write common header + */ + strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE)); +- dh->header_version = 5; ++ dh->header_version = 6; + dh->block_size = info->page_size; + dh->sub_hdr_size = sizeof(kh) + size_note; + dh->sub_hdr_size = divideup(dh->sub_hdr_size, dh->block_size); +- dh->max_mapnr = info->max_mapnr; ++ /* dh->max_mapnr may be truncated, full 64bit in kh.max_mapnr_64 */ ++ dh->max_mapnr = MIN(info->max_mapnr, UINT_MAX); + dh->nr_cpus = get_nr_cpus(); + dh->bitmap_blocks = divideup(info->len_bitmap, dh->block_size); + memcpy(&dh->timestamp, &info->timestamp, sizeof(dh->timestamp)); +@@ -5219,12 +5235,22 @@ write_kdump_header(void) + */ + size = sizeof(struct kdump_sub_header); + memset(&kh, 0, size); ++ /* 64bit max_mapnr_64 */ ++ kh.max_mapnr_64 = info->max_mapnr; + kh.phys_base = info->phys_base; + kh.dump_level = info->dump_level; + if (info->flag_split) { + kh.split = 1; +- kh.start_pfn = info->split_start_pfn; +- kh.end_pfn = info->split_end_pfn; ++ /* ++ * start_pfn and end_pfn may be truncated, ++ * only for compatibility purpose ++ */ ++ kh.start_pfn = MIN(info->split_start_pfn, UINT_MAX); ++ kh.end_pfn = MIN(info->split_end_pfn, UINT_MAX); ++ ++ /* 64bit start_pfn_64 and end_pfn_64 */ ++ kh.start_pfn_64 = info->split_start_pfn; ++ kh.end_pfn_64 = info->split_end_pfn; + } + if (has_pt_note()) { + /* +@@ -6470,7 +6496,7 @@ int + write_kdump_bitmap(void) + { + struct cache_data bm; +- long buf_size; ++ long long buf_size; + off_t offset; + + int ret = FALSE; +@@ -7853,10 +7879,8 @@ store_splitting_info(void) + + if (i == 0) { + memcpy(&dh, &tmp_dh, sizeof(tmp_dh)); +- info->max_mapnr = dh.max_mapnr; + if (!set_page_size(dh.block_size)) + return FALSE; +- DEBUG_MSG("max_mapnr : %llx\n", info->max_mapnr); + DEBUG_MSG("page_size : %ld\n", info->page_size); + } + +@@ -7873,11 +7897,24 @@ store_splitting_info(void) + return FALSE; + + if (i == 0) { ++ if (dh.header_version >= 6) ++ info->max_mapnr = kh.max_mapnr_64; ++ else ++ info->max_mapnr = dh.max_mapnr; ++ ++ DEBUG_MSG("max_mapnr : %llx\n", info->max_mapnr); ++ + info->dump_level = kh.dump_level; + DEBUG_MSG("dump_level : %d\n", info->dump_level); + } +- SPLITTING_START_PFN(i) = kh.start_pfn; +- SPLITTING_END_PFN(i) = kh.end_pfn; ++ ++ if (dh.header_version >= 6) { ++ SPLITTING_START_PFN(i) = kh.start_pfn_64; ++ SPLITTING_END_PFN(i) = kh.end_pfn_64; ++ } else { ++ SPLITTING_START_PFN(i) = kh.start_pfn; ++ SPLITTING_END_PFN(i) = kh.end_pfn; ++ } + SPLITTING_OFFSET_EI(i) = kh.offset_eraseinfo; + SPLITTING_SIZE_EI(i) = kh.size_eraseinfo; + } +@@ -8039,6 +8076,8 @@ reassemble_kdump_header(void) + kh.split = 0; + kh.start_pfn = 0; + kh.end_pfn = 0; ++ kh.start_pfn_64 = 0; ++ kh.end_pfn_64 = 0; + + if (lseek(info->fd_dumpfile, info->page_size, SEEK_SET) < 0) { + ERRMSG("Can't seek a file(%s). %s\n", +-- +1.8.3.1 + diff --git a/kexec-tools.spec b/kexec-tools.spec index 73098bb..513537a 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -82,6 +82,7 @@ Patch301: kexec-tools-2.0.4-makedumpfile-Add-vmap_area_list-definition-for-ppc-p Patch601: kexec-tools-2.0.3-disable-kexec-test.patch Patch604: kexec-tools-2.0.3-build-makedumpfile-eppic-shared-object.patch Patch605: kexec-tools-2.0.4-makedumpfile-PATCH-Support-newer-kernels.patch +Patch606: kexec-tools-2.0.4-makedumpfile-Fix-max_mapnr-issue-on-system-has-over-44-b.patch %description kexec-tools provides /sbin/kexec binary that facilitates a new @@ -114,6 +115,7 @@ tar -z -x -v -f %{SOURCE19} %patch601 -p1 %patch604 -p1 %patch605 -p1 +%patch606 -p1 %patch001 -p1 %patch002 -p1 %patch003 -p1