diff --git a/SOURCES/kexec-tools-2.0.15-makedumpfile-sadump-kaslr-fix-failure-of-calculating-kaslr.patch b/SOURCES/kexec-tools-2.0.15-makedumpfile-sadump-kaslr-fix-failure-of-calculating-kaslr.patch
new file mode 100755
index 0000000..f48c361
--- /dev/null
+++ b/SOURCES/kexec-tools-2.0.15-makedumpfile-sadump-kaslr-fix-failure-of-calculating-kaslr.patch
@@ -0,0 +1,212 @@
+From 3c0cf7a93cff83f1e711e241eb47fcb096a451c5 Mon Sep 17 00:00:00 2001
+From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
+Date: Thu, 9 Jul 2020 18:27:49 +0900
+Subject: [PATCH] [PATCH] sadump, kaslr: fix failure of calculating
+ kaslr_offset due to an sadump format restriction
+
+We faced recently a memory dump collected by sadump where unused part
+of register values are non-zero. For the crash dump, calculating
+kaslr_offset fails because it is based on the assumption that unused
+part of register values in the sadump format are always zero cleared.
+
+The problem is that used and unused part of register values are
+rigorously indistinguishable in the sadump format. Although there is
+kernel data structure that represents a map between logical cpu
+numbers and lapic ids, they cannot be used in order to calculate
+kaslr_offset.
+
+To fix this, we have no choice but use a trial-and-error approach: try
+to use each entry of register values in order until we find a good
+pair of cr3 and idtr by which we can refer to linux_banner symbol as
+expected.
+
+Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
+---
+ sadump_info.c | 129 +++++++++++++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 91 insertions(+), 38 deletions(-)
+
+diff --git a/makedumpfile-1.6.2/sadump_info.c b/makedumpfile-1.6.2/sadump_info.c
+index 72a077b4f408..410c6bc2a909 100644
+--- a/makedumpfile-1.6.2/sadump_info.c
++++ b/makedumpfile-1.6.2/sadump_info.c
+@@ -101,6 +101,7 @@ static int lookup_diskset(unsigned long long whole_offset, int *diskid,
+			  unsigned long long *disk_offset);
+ static int max_mask_cpu(void);
+ static int cpu_online_mask_init(void);
++static int linux_banner_sanity_check(ulong cr3);
+ 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);
+@@ -1293,6 +1294,30 @@ finish:
+	return ret;
+ }
+
++static int linux_banner_sanity_check(ulong cr3)
++{
++	unsigned long linux_banner_paddr;
++	char buf[sizeof("Linux version")];
++
++	linux_banner_paddr = vtop4_x86_64_pagetable(SYMBOL(linux_banner), cr3);
++	if (linux_banner_paddr == NOT_PADDR) {
++		DEBUG_MSG("sadump: linux_banner address translation failed\n");
++		return FALSE;
++	}
++
++	if (!readmem(PADDR, linux_banner_paddr, &buf, sizeof(buf))) {
++		DEBUG_MSG("sadump: reading linux_banner failed\n");
++		return FALSE;
++	}
++
++	if (!STRNEQ(buf, "Linux version")) {
++		DEBUG_MSG("sadump: linux_banner sanity check failed\n");
++		return FALSE;
++	}
++
++	return TRUE;
++}
++
+ /*
+  * Calculate kaslr_offset and phys_base
+  *
+@@ -1370,59 +1395,85 @@ calc_kaslr_offset(void)
+ {
+	struct sadump_header *sh = si->sh_memory;
+	uint64_t idtr = 0, cr3 = 0, idtr_paddr;
+-	struct sadump_smram_cpu_state smram, zero;
++	struct sadump_smram_cpu_state smram;
+	int apicid;
+	unsigned long divide_error_vmcore, divide_error_vmlinux;
+	unsigned long kaslr_offset, phys_base;
+	unsigned long kaslr_offset_kdump, phys_base_kdump;
++	int sanity_check_passed = FALSE;
+
+-	memset(&zero, 0, sizeof(zero));
+	for (apicid = 0; apicid < sh->nr_cpus; ++apicid) {
++
++		DEBUG_MSG("sadump: apicid: %d\n", apicid);
++
+		if (!get_smram_cpu_state(apicid, &smram)) {
+			ERRMSG("get_smram_cpu_state error\n");
+			return FALSE;
+		}
+
+-		if (memcmp(&smram, &zero, sizeof(smram)) != 0)
+-			break;
+-	}
+-	if (apicid >= sh->nr_cpus) {
+-		ERRMSG("Can't get smram state\n");
+-		return FALSE;
+-	}
++		idtr = ((uint64_t)smram.IdtUpper)<<32|(uint64_t)smram.IdtLower;
+
+-	idtr = ((uint64_t)smram.IdtUpper)<<32 | (uint64_t)smram.IdtLower;
+-	if ((SYMBOL(pti_init) != NOT_FOUND_SYMBOL) ||
+-	    (SYMBOL(kaiser_init) != NOT_FOUND_SYMBOL))
+-		cr3 = smram.Cr3 & ~(CR3_PCID_MASK|PTI_USER_PGTABLE_MASK);
+-	else
+-		cr3 = smram.Cr3 & ~CR3_PCID_MASK;
++		if (!smram.Cr3 || !idtr) {
++			DEBUG_MSG("sadump: cr3: %lx idt: %lx, skipped\n",
++				  smram.Cr3, idtr);
++			continue;
++		}
+
+-	/* Convert virtual address of IDT table to physical address */
+-	if ((idtr_paddr = vtop4_x86_64_pagetable(idtr, cr3)) == NOT_PADDR)
+-		return FALSE;
++		if ((SYMBOL(pti_init) != NOT_FOUND_SYMBOL) ||
++		    (SYMBOL(kaiser_init) != NOT_FOUND_SYMBOL))
++			cr3 = smram.Cr3 & ~(CR3_PCID_MASK|PTI_USER_PGTABLE_MASK);
++		else
++			cr3 = smram.Cr3 & ~CR3_PCID_MASK;
+
+-	/* Now we can calculate kaslr_offset and phys_base */
+-	divide_error_vmlinux = SYMBOL(divide_error);
+-	divide_error_vmcore = get_vec0_addr(idtr_paddr);
+-	kaslr_offset = divide_error_vmcore - divide_error_vmlinux;
+-	phys_base = idtr_paddr -
+-		(SYMBOL(idt_table) + kaslr_offset - __START_KERNEL_map);
++		/* Convert virtual address of IDT table to physical address */
++		idtr_paddr = vtop4_x86_64_pagetable(idtr, cr3);
++		if (idtr_paddr == NOT_PADDR) {
++			DEBUG_MSG("sadump: converting IDT physical address "
++				  "failed.\n");
++			continue;
++		}
+
+-	info->kaslr_offset = kaslr_offset;
+-	info->phys_base = phys_base;
++		/* Now we can calculate kaslr_offset and phys_base */
++		divide_error_vmlinux = SYMBOL(divide_error);
++		divide_error_vmcore = get_vec0_addr(idtr_paddr);
++		kaslr_offset = divide_error_vmcore - divide_error_vmlinux;
++		phys_base = idtr_paddr -
++			(SYMBOL(idt_table)+kaslr_offset-__START_KERNEL_map);
+
+-	DEBUG_MSG("sadump: idtr=%" PRIx64 "\n", idtr);
+-	DEBUG_MSG("sadump: cr3=%" PRIx64 "\n", cr3);
+-	DEBUG_MSG("sadump: idtr(phys)=%" PRIx64 "\n", idtr_paddr);
+-	DEBUG_MSG("sadump: devide_error(vmlinux)=%lx\n",
+-		divide_error_vmlinux);
+-	DEBUG_MSG("sadump: devide_error(vmcore)=%lx\n",
+-		divide_error_vmcore);
++		info->kaslr_offset = kaslr_offset;
++		info->phys_base = phys_base;
+
+-	/* Reload symbol */
+-	if (!get_symbol_info())
+-		return FALSE;
++		DEBUG_MSG("sadump: idtr=%" PRIx64 "\n", idtr);
++		DEBUG_MSG("sadump: cr3=%" PRIx64 "\n", cr3);
++		DEBUG_MSG("sadump: idtr(phys)=%" PRIx64 "\n", idtr_paddr);
++		DEBUG_MSG("sadump: devide_error(vmlinux)=%lx\n",
++			  divide_error_vmlinux);
++		DEBUG_MSG("sadump: devide_error(vmcore)=%lx\n",
++			  divide_error_vmcore);
++
++		/* Reload symbol */
++		if (!get_symbol_info()) {
++			ERRMSG("Reading symbol table failed\n");
++			return FALSE;
++		}
++
++		/* Sanity check */
++		if (linux_banner_sanity_check(cr3)) {
++			sanity_check_passed = TRUE;
++			break;
++		}
++
++		info->kaslr_offset = 0;
++		info->phys_base = 0;
++	}
++
++	if (!sanity_check_passed) {
++		ERRMSG("failed to calculate kaslr_offset and phys_base; "
++		       "default to 0\n");
++		info->kaslr_offset = 0;
++		info->phys_base = 0;
++		return TRUE;
++	}
+
+	/*
+	 * Check if current kaslr_offset/phys_base is for 1st kernel or 2nd
+@@ -1430,13 +1481,15 @@ calc_kaslr_offset(void)
+	 * from vmcoreinfo
+	 */
+	if (get_kaslr_offset_from_vmcoreinfo(cr3, &kaslr_offset_kdump,
+-					    &phys_base_kdump)) {
++					     &phys_base_kdump)) {
+		info->kaslr_offset = kaslr_offset_kdump;
+		info->phys_base = phys_base_kdump;
+
+		/* Reload symbol */
+-		if (!get_symbol_info())
++		if (!get_symbol_info()) {
++			ERRMSG("Reading symbol table failed\n");
+			return FALSE;
++		}
+	}
+
+	DEBUG_MSG("sadump: kaslr_offset=%lx\n", info->kaslr_offset);
+--
+2.7.4
diff --git a/SPECS/kexec-tools.spec b/SPECS/kexec-tools.spec
index 52fd5aa..bd20dad 100644
--- a/SPECS/kexec-tools.spec
+++ b/SPECS/kexec-tools.spec
@@ -1,6 +1,6 @@
 Name: kexec-tools
 Version: 2.0.15
-Release: 51%{?dist}
+Release: 51%{?dist}.1
 License: GPLv2
 Group: Applications/System
 Summary: The kexec/kdump userspace component.
@@ -124,6 +124,7 @@ Patch725: kexec-tools-2.0.15-makedumpfile-x86_64-Add-support-for-AMD-Secure-Memo
 Patch726: kexec-tools-2.0.15-Limit-the-size-of-vmcore-dmesg.txt-to-2G.patch
 Patch727: kexec-tools-2.0.15-vmcore-dmesg-vmcore-dmesg.c-Fix-shifting-error-repor.patch
 Patch728: kexec-tools-2.0.15-makedumpfile-x86_64-Fix-incorrect-exclusion-by-e-option-wit.patch
+Patch729: kexec-tools-2.0.15-makedumpfile-sadump-kaslr-fix-failure-of-calculating-kaslr.patch
 
 
 #
@@ -199,6 +200,7 @@ tar -z -x -v -f %{SOURCE25}
 %patch726 -p1
 %patch727 -p1
 %patch728 -p1
+%patch729 -p1
 
 
 %ifarch ppc
@@ -444,6 +446,9 @@ done
 
 %changelog
 
+* Mon Sep 7 2020 Bhupesh Sharma <bhsharma@redhat.com> 2.0.15-51.1
+- makedumpfile/sadump: Fix a KASLR problem of sadump while kdump is working
+
 * Fri Jun 19 2020 Bhupesh Sharma <bhsharma@redhat.com> 2.0.15-51
 - Add a new option 'rd.znet_ifname' in order to use it in udev rules