Skip to contentSkip to conversation

x86_64: Fix page_offset for randomized base enabled

PATCH Superseded Pratyush Anand 6 participants 26 messages Oct 24, 2016 – Nov 4, 2016 1 message not in the archive

Subsystems (2)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover x86_64: Fix page_offset for randomized base enabled

Patch 1/4 fixes page_offset calculation, so that it is correctly calculated on KASLR enabled kernel as well.
Patch 2/4 simplifies VA to PA translation. New code has been benchmarked against old code on a 4T system.
Patch 3/4 and 4/4 is removal of (now) unnecessary code.

I think, we should find a way to kill find_vememmap() as well, so that VMEMMAP_START can be removed. I have very limited idea about x86, so unable to do that as of now.

Pratyush Anand (4):
x86_64: Calculate page_offset from pt_load
x86_64: translate all VA to PA using page table values
x86_64: kill is_vmalloc_addr_x86_64()
x86_64: kill some unused initialization

 arch/x86_64.c  | 84 ++++++++++++++++++++--------------------------------------
 makedumpfile.h |  9 +++----
 2 files changed, 32 insertions(+), 61 deletions(-)
Signature · 7 lines
2.7.4


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#1 lore raw

PATCH 1/1 temp

---
 arch/x86_64.c  | 10 ++++++++--
 makedumpfile.h |  4 ++--
 2 files changed, 10 insertions(+), 4 deletions(-)
arch/x86_64.c +8 -2
index ddf7be6bc57b..3a53b4fa03ed 100644
@@ -187,6 +187,12 @@ vtop4_x86_64(unsigned long vaddr)
 {
 	unsigned long page_dir, pml4, pgd_paddr, pgd_pte, pmd_paddr, pmd_pte;
 	unsigned long pte_paddr, pte;
+	unsigned long phys_base;
+
+	if (SYMBOL(phys_base) != NOT_FOUND_SYMBOL)
+		phys_base = info->phys_base;
+	else
+		phys_base = 0;
 
 	if (SYMBOL(init_level4_pgt) == NOT_FOUND_SYMBOL) {
 		ERRMSG("Can't get the symbol of init_level4_pgt.\n");
@@ -196,9 +202,9 @@ vtop4_x86_64(unsigned long vaddr)
 	/*
 	 * Get PGD.
 	 */
-	page_dir  = SYMBOL(init_level4_pgt);
+	page_dir = SYMBOL(init_level4_pgt) - __START_KERNEL_map + phys_base;
 	page_dir += pml4_index(vaddr) * sizeof(unsigned long);
-	if (!readmem(VADDR, page_dir, &pml4, sizeof pml4)) {
+	if (!readmem(PADDR, page_dir, &pml4, sizeof pml4)) {
 		ERRMSG("Can't get pml4 (page_dir:%lx).\n", page_dir);
 		return NOT_PADDR;
 	}
makedumpfile.h +2 -2
index f0154226bcb8..f64652e34901 100644
@@ -876,12 +876,12 @@ int is_vmalloc_addr_x86_64(ulong vaddr);
 int get_phys_base_x86_64(void);
 int get_machdep_info_x86_64(void);
 int get_versiondep_info_x86_64(void);
-unsigned long long vaddr_to_paddr_x86_64(unsigned long vaddr);
+unsigned long long vtop4_x86_64(unsigned long vaddr);
 #define find_vmemmap()		find_vmemmap_x86_64()
 #define get_phys_base()		get_phys_base_x86_64()
 #define get_machdep_info()	get_machdep_info_x86_64()
 #define get_versiondep_info()	get_versiondep_info_x86_64()
-#define vaddr_to_paddr(X)	vaddr_to_paddr_x86_64(X)
+#define vaddr_to_paddr(X)	vtop4_x86_64(X)
 #define is_phys_addr(X)		(!is_vmalloc_addr_x86_64(X))
 #endif /* x86_64 */
 
Signature · 7 lines
2.7.4


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#13 lore raw

PATCH 3/4 x86_64: kill is_vmalloc_addr_x86_64()

In reply to Pratyush Anand

From kernel documentation:
ffffffff80000000 - ffffffff9fffffff (=512 MB) kernel text mapping, from phys 0 ffffffffa0000000 - ffffffffff5fffff (=1526 MB) module mapping space

So, it is only the module area which is lying above __START_KERNEL_map. However, kexec-tools only creates PT_LOAD segments for kernel text region and crash memory region. So, we can safely remove the check for !is_vmalloc_addr_x86_64() from get_phys_base_x86_64().

Since, this was the last usage of is_vmalloc_addr_x86_64(), so kill it as well.

---
 arch/x86_64.c  | 14 +-------------
 makedumpfile.h |  3 +--
 2 files changed, 2 insertions(+), 15 deletions(-)
arch/x86_64.c +1 -13
index fe2764a8bec2..597cdac36dfc 100644
@@ -21,17 +21,6 @@
 extern struct vmap_pfns *gvmem_pfns;
 extern int nr_gvmem_pfns;
 
-int
-is_vmalloc_addr_x86_64(ulong vaddr)
-{
-	/*
-	 *  vmalloc, virtual memmap, and module space as VMALLOC space.
-	 */
-	return ((vaddr >= VMALLOC_START && vaddr <= VMALLOC_END)
-	    || (vaddr >= VMEMMAP_START && vaddr <= VMEMMAP_END)
-	    || (vaddr >= MODULES_VADDR && vaddr <= MODULES_END));
-}
-
 static unsigned long
 get_xen_p2m_mfn(void)
 {
@@ -75,8 +64,7 @@ get_phys_base_x86_64(void)
 	info->phys_base = 0; /* default/traditional */
 
 	for (i = 0; get_pt_load(i, &phys_start, NULL, &virt_start, NULL); i++) {
-		if ((virt_start >= __START_KERNEL_map) &&
-		    !(is_vmalloc_addr_x86_64(virt_start))) {
+		if (virt_start >= __START_KERNEL_map) {
 
 			info->phys_base = phys_start -
 			    (virt_start & ~(__START_KERNEL_map));
makedumpfile.h +1 -2
index 13559651feb6..8a96da1f61bd 100644
@@ -859,7 +859,6 @@ unsigned long long vaddr_to_paddr_x86(unsigned long vaddr);
 #endif /* x86 */
 
 #ifdef __x86_64__
-int is_vmalloc_addr_x86_64(ulong vaddr);
 int get_phys_base_x86_64(void);
 int get_machdep_info_x86_64(void);
 int get_versiondep_info_x86_64(void);
@@ -869,7 +868,7 @@ unsigned long long vtop4_x86_64(unsigned long vaddr);
 #define get_machdep_info()	get_machdep_info_x86_64()
 #define get_versiondep_info()	get_versiondep_info_x86_64()
 #define vaddr_to_paddr(X)	vtop4_x86_64(X)
-#define is_phys_addr(X)		(!is_vmalloc_addr_x86_64(X))
+#define is_phys_addr(X)		stub_true_ul(X)
 #endif /* x86_64 */
 
 #ifdef __powerpc64__ /* powerpc64 */
Signature · 7 lines
2.7.4


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#14 lore raw

PATCH 4/4 x86_64: kill some unused initialization

In reply to Pratyush Anand

VMALLOC_START, VMALLOC_END, MODULES_VADDR and MODULES_END are mo more needed for x86_64 now. So, kill their initialization.

---
 arch/x86_64.c  | 4 ----
 makedumpfile.h | 2 --
 2 files changed, 6 deletions(-)
arch/x86_64.c +0 -4
index 597cdac36dfc..13990cef839b 100644
@@ -169,13 +169,9 @@ get_versiondep_info_x86_64(void)
 		return FALSE;
 
 	if (info->kernel_version < KERNEL_VERSION(2, 6, 31)) {
-		info->vmalloc_start = VMALLOC_START_ORIG;
-		info->vmalloc_end   = VMALLOC_END_ORIG;
 		info->vmemmap_start = VMEMMAP_START_ORIG;
 		info->vmemmap_end   = VMEMMAP_END_ORIG;
 	} else {
-		info->vmalloc_start = VMALLOC_START_2_6_31;
-		info->vmalloc_end   = VMALLOC_END_2_6_31;
 		info->vmemmap_start = VMEMMAP_START_2_6_31;
 		info->vmemmap_end   = VMEMMAP_END_2_6_31;
 	}
makedumpfile.h +0 -2
index 8a96da1f61bd..338c651388f0 100644
@@ -575,8 +575,6 @@ int get_va_bits_arm64(void);
 #define __START_KERNEL_map	(0xffffffff80000000)
 #define KERNEL_IMAGE_SIZE_ORIG		(0x0000000008000000) /* 2.6.25, or former */
 #define KERNEL_IMAGE_SIZE_2_6_26	(0x0000000020000000) /* 2.6.26, or later  */
-#define MODULES_VADDR          (__START_KERNEL_map + NUMBER(KERNEL_IMAGE_SIZE))
-#define MODULES_END		(0xfffffffffff00000)
 #define KVBASE			PAGE_OFFSET
 #define _SECTION_SIZE_BITS	(27)
 #define _MAX_PHYSMEM_BITS_ORIG		(40)
Signature · 7 lines
2.7.4


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#3 lore raw

PATCH 1/4 x86_64: Calculate page_offset from pt_load

In reply to Pratyush Anand

page_offset can always be calculated as 'virtual - physical' for a direct mapping area on x86. Therefore, remove the version dependent calculation and use this method.

---
 arch/x86_64.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)
arch/x86_64.c +20 -4
index ddf7be6bc57b..a96fd8ae00a1 100644
@@ -44,6 +44,24 @@ get_xen_p2m_mfn(void)
 	return NOT_FOUND_LONG_VALUE;
 }
 
+static int
+get_page_offset_x86_64(void)
+{
+	int i;
+	unsigned long long phys_start;
+	unsigned long long virt_start;
+
+	for (i = 0; get_pt_load(i, &phys_start, NULL, &virt_start, NULL); i++) {
+		if (virt_start >= __START_KERNEL_map) {
+			info->page_offset = virt_start - phys_start;
+			return TRUE;
+		}
+	}
+
+	ERRMSG("Can't get any pt_load to calculate page offset.\n");
+	return FALSE;
+}
+
 int
 get_phys_base_x86_64(void)
 {
@@ -159,10 +177,8 @@ get_versiondep_info_x86_64(void)
 	else
 		info->max_physmem_bits  = _MAX_PHYSMEM_BITS_2_6_31;
 
-	if (info->kernel_version < KERNEL_VERSION(2, 6, 27))
-		info->page_offset = __PAGE_OFFSET_ORIG;
-	else
-		info->page_offset = __PAGE_OFFSET_2_6_27;
+	if (!get_page_offset_x86_64())
+		return FALSE;
 
 	if (info->kernel_version < KERNEL_VERSION(2, 6, 31)) {
 		info->vmalloc_start = VMALLOC_START_ORIG;
Signature · 7 lines
2.7.4


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#8 lore raw

PATCH 2/4 x86_64: translate all VA to PA using page table values

In reply to Pratyush Anand

Currently we translate some of the VA areas using linear mapping while some other(which can not be linearly mapped) using page table.

However, we will have entry of a page in the page table irrespective of its virtual region. So, we can always look into page table for any VA to PA translation. This approach will solve lot of complexity in makedumpfile. It will in turn remove dependency over variables like VMALLOC_START, MODULES_VADDR etc whose definition keeps changing in newer kernel version.

Moreover, I do not see any side effect of this approach in terms of execution timing. I tested with IBM x3950 X6 machine having 4136359 MB of memory. These are the results of makedumpfile execution time:

Without this patch:
===================
With -d 31:
Trial 1: 237.59526248 S
Trial 2: 235.236914962 S
Trail 3: 237.678712045 S

With -d 1:
Trial 1: 2548.905296877 S
Trial 2: 2549.759881756 S

With this patch:
===================
With -d 31:
Trial 1: 232.713841516 S
Trial 2: 228.45697177 S
Trail 3: 232.942262441 S

With -d 1:
Trial 1: 2768.424565806 S
Trial 2: 2749.622115455 S
Trail 3: 2537.770359073 S

---
 arch/x86_64.c  | 42 ++++++++----------------------------------
 makedumpfile.h |  4 ++--
 2 files changed, 10 insertions(+), 36 deletions(-)
arch/x86_64.c +8 -34
index a96fd8ae00a1..fe2764a8bec2 100644
@@ -203,6 +203,12 @@ vtop4_x86_64(unsigned long vaddr)
 {
 	unsigned long page_dir, pml4, pgd_paddr, pgd_pte, pmd_paddr, pmd_pte;
 	unsigned long pte_paddr, pte;
+	unsigned long phys_base;
+
+	if (SYMBOL(phys_base) != NOT_FOUND_SYMBOL)
+		phys_base = info->phys_base;
+	else
+		phys_base = 0;
 
 	if (SYMBOL(init_level4_pgt) == NOT_FOUND_SYMBOL) {
 		ERRMSG("Can't get the symbol of init_level4_pgt.\n");
@@ -212,9 +218,9 @@ vtop4_x86_64(unsigned long vaddr)
 	/*
 	 * Get PGD.
 	 */
-	page_dir  = SYMBOL(init_level4_pgt);
+	page_dir = SYMBOL(init_level4_pgt) - __START_KERNEL_map + phys_base;
 	page_dir += pml4_index(vaddr) * sizeof(unsigned long);
-	if (!readmem(VADDR, page_dir, &pml4, sizeof pml4)) {
+	if (!readmem(PADDR, page_dir, &pml4, sizeof pml4)) {
 		ERRMSG("Can't get pml4 (page_dir:%lx).\n", page_dir);
 		return NOT_PADDR;
 	}
@@ -285,38 +291,6 @@ vtop4_x86_64(unsigned long vaddr)
 	return (pte & ENTRY_MASK) + PAGEOFFSET(vaddr);
 }
 
-unsigned long long
-vaddr_to_paddr_x86_64(unsigned long vaddr)
-{
-	unsigned long phys_base;
-	unsigned long long paddr;
-
-	/*
-	 * Check the relocatable kernel.
-	 */
-	if (SYMBOL(phys_base) != NOT_FOUND_SYMBOL)
-		phys_base = info->phys_base;
-	else
-		phys_base = 0;
-
-	if (is_vmalloc_addr_x86_64(vaddr)) {
-		if ((paddr = vtop4_x86_64(vaddr)) == NOT_PADDR) {
-			ERRMSG("Can't convert a virtual address(%lx) to " \
-			    "physical address.\n", vaddr);
-			return NOT_PADDR;
-		}
-	} else if (vaddr >= __START_KERNEL_map) {
-		paddr = vaddr - __START_KERNEL_map + phys_base;
-
-	} else {
-		if (is_xen_memory())
-			paddr = vaddr - PAGE_OFFSET_XEN_DOM0;
-		else
-			paddr = vaddr - PAGE_OFFSET;
-	}
-	return paddr;
-}
-
 /*
  * for Xen extraction
  */
makedumpfile.h +2 -2
index a5955ff750e5..13559651feb6 100644
@@ -863,12 +863,12 @@ int is_vmalloc_addr_x86_64(ulong vaddr);
 int get_phys_base_x86_64(void);
 int get_machdep_info_x86_64(void);
 int get_versiondep_info_x86_64(void);
-unsigned long long vaddr_to_paddr_x86_64(unsigned long vaddr);
+unsigned long long vtop4_x86_64(unsigned long vaddr);
 #define find_vmemmap()		find_vmemmap_x86_64()
 #define get_phys_base()		get_phys_base_x86_64()
 #define get_machdep_info()	get_machdep_info_x86_64()
 #define get_versiondep_info()	get_versiondep_info_x86_64()
-#define vaddr_to_paddr(X)	vaddr_to_paddr_x86_64(X)
+#define vaddr_to_paddr(X)	vtop4_x86_64(X)
 #define is_phys_addr(X)		(!is_vmalloc_addr_x86_64(X))
 #endif /* x86_64 */
 
Signature · 7 lines
2.7.4


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#2 lore raw

Re: [PATCH] temp

In reply to Pratyush Anand

Ohhh..Please ignore this patch. This temporary changes were lying in my directory and went away.

Sorry for this noise.

~Pratyush

Quoted 55 lines · Pratyush Anand
---
 arch/x86_64.c  | 10 ++++++++--
 makedumpfile.h |  4 ++--
 2 files changed, 10 insertions(+), 4 deletions(-)
arch/x86_64.c +8 -2
index ddf7be6bc57b..3a53b4fa03ed 100644
@@ -187,6 +187,12 @@ vtop4_x86_64(unsigned long vaddr)
 {
        unsigned long page_dir, pml4, pgd_paddr, pgd_pte, pmd_paddr, pmd_pte;
        unsigned long pte_paddr, pte;
+       unsigned long phys_base;
+
+       if (SYMBOL(phys_base) != NOT_FOUND_SYMBOL)
+               phys_base = info->phys_base;
+       else
+               phys_base = 0;
 
        if (SYMBOL(init_level4_pgt) == NOT_FOUND_SYMBOL) {
                ERRMSG("Can't get the symbol of init_level4_pgt.\n");
@@ -196,9 +202,9 @@ vtop4_x86_64(unsigned long vaddr)
        /*
         * Get PGD.
         */
-       page_dir  = SYMBOL(init_level4_pgt);
+       page_dir = SYMBOL(init_level4_pgt) - __START_KERNEL_map + phys_base;
        page_dir += pml4_index(vaddr) * sizeof(unsigned long);
-       if (!readmem(VADDR, page_dir, &pml4, sizeof pml4)) {
+       if (!readmem(PADDR, page_dir, &pml4, sizeof pml4)) {
                ERRMSG("Can't get pml4 (page_dir:%lx).\n", page_dir);
                return NOT_PADDR;
        }
makedumpfile.h +2 -3
index f0154226bcb8..f64652e34901 100644
@@ -876,12 +876,12 @@ int is_vmalloc_addr_x86_64(ulong vaddr);
 int get_phys_base_x86_64(void);
 int get_machdep_info_x86_64(void);
 int get_versiondep_info_x86_64(void);
-unsigned long long vaddr_to_paddr_x86_64(unsigned long vaddr);
+unsigned long long vtop4_x86_64(unsigned long vaddr);
 #define find_vmemmap()         find_vmemmap_x86_64()
 #define get_phys_base()                get_phys_base_x86_64()
 #define get_machdep_info()     get_machdep_info_x86_64()
 #define get_versiondep_info()  get_versiondep_info_x86_64()
-#define vaddr_to_paddr(X)      vaddr_to_paddr_x86_64(X)
+#define vaddr_to_paddr(X)      vtop4_x86_64(X)
 #define is_phys_addr(X)                (!is_vmalloc_addr_x86_64(X))
 #endif /* x86_64 */
 
--
Quoted 2 lines

2.7.4

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#15 lore raw
In reply to Pratyush Anand

Hello,

Quoted 16 lines · Pratyush Anand

Patch 1/4 fixes page_offset calculation, so that it is correctly calculated on KASLR enabled kernel as well.
Patch 2/4 simplifies VA to PA translation. New code has been benchmarked against old code on a 4T system.
Patch 3/4 and 4/4 is removal of (now) unnecessary code.

I think, we should find a way to kill find_vememmap() as well, so that VMEMMAP_START can be removed. I have very limited idea about x86, so unable to do that as of now.

Pratyush Anand (4):
x86_64: Calculate page_offset from pt_load
x86_64: translate all VA to PA using page table values
x86_64: kill is_vmalloc_addr_x86_64()
x86_64: kill some unused initialization

Quoted 4 lines
 arch/x86_64.c  | 84 ++++++++++++++++++++--------------------------------------
 makedumpfile.h |  9 +++----
 2 files changed, 32 insertions(+), 61 deletions(-)

Cross-posting but FYI, this patch fixes the issue reported in the following thread : makedumpfile issues many readpage_elf: Attempt to read non-existent page[1]

It corresponds to the commit identified by my kernel bisection.

I will wait until it is accepted in Kumagai-san's tree to include it in Debian/Ubuntu.

Kind regards,

...Louis

[1] https://www.mail-archive.com/[email protected]/msg16434.html

Signature · 10 lines
Louis Bouchard
Software engineer, Cloud & Sustaining eng.
Canonical Ltd
Ubuntu developer                       Debian Maintainer
GPG : 429D 7A3B DD05 B6F8 AF63  B9C4 8B3D 867C 823E 7A61

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec
#16 lore raw

Hi Louis,

Quoted 24 lines · Louis Bouchard

Hello,

Quoted 16 lines · Pratyush Anand

Patch 1/4 fixes page_offset calculation, so that it is correctly calculated on KASLR enabled kernel as well.
Patch 2/4 simplifies VA to PA translation. New code has been benchmarked against old code on a 4T system.
Patch 3/4 and 4/4 is removal of (now) unnecessary code.

I think, we should find a way to kill find_vememmap() as well, so that VMEMMAP_START can be removed. I have very limited idea about x86, so unable to do that as of now.

Pratyush Anand (4):
x86_64: Calculate page_offset from pt_load
x86_64: translate all VA to PA using page table values
x86_64: kill is_vmalloc_addr_x86_64()
x86_64: kill some unused initialization

Quoted 4 lines
 arch/x86_64.c  | 84 ++++++++++++++++++++--------------------------------------
 makedumpfile.h |  9 +++----
 2 files changed, 32 insertions(+), 61 deletions(-)
Quoted 7 lines

Cross-posting but FYI, this patch fixes the issue reported in the following thread : makedumpfile issues many readpage_elf: Attempt to read non-existent page[1]

It corresponds to the commit identified by my kernel bisection.

I will wait until it is accepted in Kumagai-san's tree to include it in Debian/Ubuntu.

Thanks a lot for your testing.

~Pratyush

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#9 lore raw

RE: [PATCH Makedumpfile 2/4] x86_64: translate all VA to PA using page table values

In reply to Pratyush Anand

Hello Pratysh,

Quoted 31 lines

Currently we translate some of the VA areas using linear mapping while some other(which can not be linearly mapped) using page table.

However, we will have entry of a page in the page table irrespective of its virtual region. So, we can always look into page table for any VA to PA translation. This approach will solve lot of complexity in makedumpfile. It will in turn remove dependency over variables like VMALLOC_START, MODULES_VADDR etc whose definition keeps changing in newer kernel version.

Moreover, I do not see any side effect of this approach in terms of execution timing. I tested with IBM x3950 X6 machine having 4136359 MB of memory. These are the results of makedumpfile execution time:

Without this patch:
===================
With -d 31:
Trial 1: 237.59526248 S
Trial 2: 235.236914962 S
Trail 3: 237.678712045 S

With -d 1:
Trial 1: 2548.905296877 S
Trial 2: 2549.759881756 S

With this patch:
===================
With -d 31:
Trial 1: 232.713841516 S
Trial 2: 228.45697177 S
Trail 3: 232.942262441 S

Quoted 4 lines

With -d 1:
Trial 1: 2768.424565806 S
Trial 2: 2749.622115455 S
Trail 3: 2537.770359073 S

Could you increase the number of trials ?
If the average time is close to the results of Trial 1 (2768s) and 2 (2749s), the regression rate is 8% and it sounds neither large nor small. If the average is a level of 2500s like Trial 3, it's ideal.

Quoted 24 lines

---
arch/x86_64.c | 42 ++++++++---------------------------------- makedumpfile.h | 4 ++--

2 files changed, 10 insertions(+), 36 deletions(-)
arch/x86_64.c +6 -0
index a96fd8ae00a1..fe2764a8bec2 100644
@@ -203,6 +203,12 @@ vtop4_x86_64(unsigned long vaddr)
 {
 	unsigned long page_dir, pml4, pgd_paddr, pgd_pte, pmd_paddr, pmd_pte;
 	unsigned long pte_paddr, pte;
+	unsigned long phys_base;
+
+	if (SYMBOL(phys_base) != NOT_FOUND_SYMBOL)
+		phys_base = info->phys_base;
+	else
+		phys_base = 0;
 
 	if (SYMBOL(init_level4_pgt) == NOT_FOUND_SYMBOL) {
 		ERRMSG("Can't get the symbol of init_level4_pgt.\n");

arch/x86_64.c vtop4_x86_64(unsigned long vaddr) · line 221

Quoted 5 lines
arch/x86_64.c +1 -1
@@ -212,9 +218,9 @@ vtop4_x86_64(unsigned long vaddr)
 	/*
 	 * Get PGD.
 	 */
-	page_dir  = SYMBOL(init_level4_pgt);
+	page_dir = SYMBOL(init_level4_pgt) - __START_KERNEL_map + phys_base;

I want to confirm that this VA to PA translation is always safe, otherwise we should do the condition check which was done in vaddr_to_paddr_x86_64(), isn't it ?

Thanks,
Atsushi Kumagai

Quoted 68 lines
arch/x86_64.c +1 -33
 	page_dir += pml4_index(vaddr) * sizeof(unsigned long);
-	if (!readmem(VADDR, page_dir, &pml4, sizeof pml4)) {
+	if (!readmem(PADDR, page_dir, &pml4, sizeof pml4)) {
 		ERRMSG("Can't get pml4 (page_dir:%lx).\n", page_dir);
 		return NOT_PADDR;
 	}
@@ -285,38 +291,6 @@ vtop4_x86_64(unsigned long vaddr)
 	return (pte & ENTRY_MASK) + PAGEOFFSET(vaddr);
 }
 
-unsigned long long
-vaddr_to_paddr_x86_64(unsigned long vaddr)
-{
-	unsigned long phys_base;
-	unsigned long long paddr;
-
-	/*
-	 * Check the relocatable kernel.
-	 */
-	if (SYMBOL(phys_base) != NOT_FOUND_SYMBOL)
-		phys_base = info->phys_base;
-	else
-		phys_base = 0;
-
-	if (is_vmalloc_addr_x86_64(vaddr)) {
-		if ((paddr = vtop4_x86_64(vaddr)) == NOT_PADDR) {
-			ERRMSG("Can't convert a virtual address(%lx) to " \
-			    "physical address.\n", vaddr);
-			return NOT_PADDR;
-		}
-	} else if (vaddr >= __START_KERNEL_map) {
-		paddr = vaddr - __START_KERNEL_map + phys_base;
-
-	} else {
-		if (is_xen_memory())
-			paddr = vaddr - PAGE_OFFSET_XEN_DOM0;
-		else
-			paddr = vaddr - PAGE_OFFSET;
-	}
-	return paddr;
-}
-
 /*
 * for Xen extraction
 */
makedumpfile.h +2 -3
index a5955ff750e5..13559651feb6 100644
@@ -863,12 +863,12 @@ int is_vmalloc_addr_x86_64(ulong vaddr);
 int get_phys_base_x86_64(void);
 int get_machdep_info_x86_64(void);
 int get_versiondep_info_x86_64(void);
-unsigned long long vaddr_to_paddr_x86_64(unsigned long vaddr);
+unsigned long long vtop4_x86_64(unsigned long vaddr);
 #define find_vmemmap()		find_vmemmap_x86_64()
 #define get_phys_base()		get_phys_base_x86_64()
 #define get_machdep_info()	get_machdep_info_x86_64()
 #define get_versiondep_info()	get_versiondep_info_x86_64()
-#define vaddr_to_paddr(X)	vaddr_to_paddr_x86_64(X)
+#define vaddr_to_paddr(X)	vtop4_x86_64(X)
 #define is_phys_addr(X)		(!is_vmalloc_addr_x86_64(X))
 #endif /* x86_64 */
 
--

2.7.4

Quoted 4 lines

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#10 lore raw

Re: [PATCH Makedumpfile 2/4] x86_64: translate all VA to PA using page table values

Hi Atsushi,

Thanks for the review.

Quoted 33 lines · Atsushi Kumagai

Hello Pratysh,

Quoted 31 lines

Currently we translate some of the VA areas using linear mapping while some other(which can not be linearly mapped) using page table.

However, we will have entry of a page in the page table irrespective of its virtual region. So, we can always look into page table for any VA to PA translation. This approach will solve lot of complexity in makedumpfile. It will in turn remove dependency over variables like VMALLOC_START, MODULES_VADDR etc whose definition keeps changing in newer kernel version.

Moreover, I do not see any side effect of this approach in terms of execution timing. I tested with IBM x3950 X6 machine having 4136359 MB of memory. These are the results of makedumpfile execution time:

Without this patch:
===================
With -d 31:
Trial 1: 237.59526248 S
Trial 2: 235.236914962 S
Trail 3: 237.678712045 S

With -d 1:
Trial 1: 2548.905296877 S
Trial 2: 2549.759881756 S

With this patch:
===================
With -d 31:
Trial 1: 232.713841516 S
Trial 2: 228.45697177 S
Trail 3: 232.942262441 S

Quoted 6 lines
Quoted 4 lines

With -d 1:
Trial 1: 2768.424565806 S
Trial 2: 2749.622115455 S
Trail 3: 2537.770359073 S

Could you increase the number of trials ?

OK, I can do that. Might take some time, as I will have to arrange that high memory machine again.

Quoted 25 lines

If the average time is close to the results of Trial 1 (2768s) and 2 (2749s), the regression rate is 8% and it sounds neither large nor small. If the average is a level of 2500s like Trial 3, it's ideal.

Quoted 21 lines

---
arch/x86_64.c | 42 ++++++++---------------------------------- makedumpfile.h | 4 ++--

2 files changed, 10 insertions(+), 36 deletions(-)
arch/x86_64.c +6 -0
index a96fd8ae00a1..fe2764a8bec2 100644
@@ -203,6 +203,12 @@ vtop4_x86_64(unsigned long vaddr)
 {
 	unsigned long page_dir, pml4, pgd_paddr, pgd_pte, pmd_paddr, pmd_pte;
 	unsigned long pte_paddr, pte;
+	unsigned long phys_base;
+
+	if (SYMBOL(phys_base) != NOT_FOUND_SYMBOL)
+		phys_base = info->phys_base;
+	else
+		phys_base = 0;
 
Quoted 13 lines

arch/x86_64.c vtop4_x86_64(unsigned long vaddr) · line 221

Quoted 8 lines
arch/x86_64.c +1 -1
 	if (SYMBOL(init_level4_pgt) == NOT_FOUND_SYMBOL) {
 		ERRMSG("Can't get the symbol of init_level4_pgt.\n");
@@ -212,9 +218,9 @@ vtop4_x86_64(unsigned long vaddr)
 	/*
 	 * Get PGD.
 	 */
-	page_dir  = SYMBOL(init_level4_pgt);
+	page_dir = SYMBOL(init_level4_pgt) - __START_KERNEL_map + phys_base;

I want to confirm that this VA to PA translation is always safe, otherwise we should do the condition check which was done in vaddr_to_paddr_x86_64(), isn't it ?

I think this should be safe, however x86 expert can comment better. Baoquan any comment here?

~Pratyush

Quoted 68 lines

Thanks,
Atsushi Kumagai

Quoted 64 lines
arch/x86_64.c +1 -33
 	page_dir += pml4_index(vaddr) * sizeof(unsigned long);
-	if (!readmem(VADDR, page_dir, &pml4, sizeof pml4)) {
+	if (!readmem(PADDR, page_dir, &pml4, sizeof pml4)) {
 		ERRMSG("Can't get pml4 (page_dir:%lx).\n", page_dir);
 		return NOT_PADDR;
 	}
@@ -285,38 +291,6 @@ vtop4_x86_64(unsigned long vaddr)
 	return (pte & ENTRY_MASK) + PAGEOFFSET(vaddr);
 }
 
-unsigned long long
-vaddr_to_paddr_x86_64(unsigned long vaddr)
-{
-	unsigned long phys_base;
-	unsigned long long paddr;
-
-	/*
-	 * Check the relocatable kernel.
-	 */
-	if (SYMBOL(phys_base) != NOT_FOUND_SYMBOL)
-		phys_base = info->phys_base;
-	else
-		phys_base = 0;
-
-	if (is_vmalloc_addr_x86_64(vaddr)) {
-		if ((paddr = vtop4_x86_64(vaddr)) == NOT_PADDR) {
-			ERRMSG("Can't convert a virtual address(%lx) to " \
-			    "physical address.\n", vaddr);
-			return NOT_PADDR;
-		}
-	} else if (vaddr >= __START_KERNEL_map) {
-		paddr = vaddr - __START_KERNEL_map + phys_base;
-
-	} else {
-		if (is_xen_memory())
-			paddr = vaddr - PAGE_OFFSET_XEN_DOM0;
-		else
-			paddr = vaddr - PAGE_OFFSET;
-	}
-	return paddr;
-}
-
 /*
 * for Xen extraction
 */
makedumpfile.h +2 -2
index a5955ff750e5..13559651feb6 100644
@@ -863,12 +863,12 @@ int is_vmalloc_addr_x86_64(ulong vaddr);
 int get_phys_base_x86_64(void);
 int get_machdep_info_x86_64(void);
 int get_versiondep_info_x86_64(void);
-unsigned long long vaddr_to_paddr_x86_64(unsigned long vaddr);
+unsigned long long vtop4_x86_64(unsigned long vaddr);
 #define find_vmemmap()		find_vmemmap_x86_64()
 #define get_phys_base()		get_phys_base_x86_64()
 #define get_machdep_info()	get_machdep_info_x86_64()
 #define get_versiondep_info()	get_versiondep_info_x86_64()
-#define vaddr_to_paddr(X)	vaddr_to_paddr_x86_64(X)
+#define vaddr_to_paddr(X)	vtop4_x86_64(X)
 #define is_phys_addr(X)		(!is_vmalloc_addr_x86_64(X))
 #endif /* x86_64 */
 
Quoted 8 lines
Quoted 8 lines

--
2.7.4

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#11 lore raw

Re: [PATCH Makedumpfile 2/4] x86_64: translate all VA to PA using page table values

Quoted 49 lines · Pratyush Anand
Quoted 6 lines
Quoted 4 lines

With -d 1:
Trial 1: 2768.424565806 S
Trial 2: 2749.622115455 S
Trail 3: 2537.770359073 S

Could you increase the number of trials ?

OK, I can do that. Might take some time, as I will have to arrange that high memory machine again.

Quoted 25 lines

If the average time is close to the results of Trial 1 (2768s) and 2 (2749s), the regression rate is 8% and it sounds neither large nor small. If the average is a level of 2500s like Trial 3, it's ideal.

Quoted 21 lines

---
arch/x86_64.c | 42 ++++++++---------------------------------- makedumpfile.h | 4 ++--

2 files changed, 10 insertions(+), 36 deletions(-)
arch/x86_64.c +6 -0
index a96fd8ae00a1..fe2764a8bec2 100644
@@ -203,6 +203,12 @@ vtop4_x86_64(unsigned long vaddr)
 {
 	unsigned long page_dir, pml4, pgd_paddr, pgd_pte, pmd_paddr, pmd_pte;
 	unsigned long pte_paddr, pte;
+	unsigned long phys_base;
+
+	if (SYMBOL(phys_base) != NOT_FOUND_SYMBOL)
+		phys_base = info->phys_base;
+	else
+		phys_base = 0;
 
Quoted 13 lines

arch/x86_64.c vtop4_x86_64(unsigned long vaddr) · line 221

Quoted 8 lines
arch/x86_64.c +1 -1
 	if (SYMBOL(init_level4_pgt) == NOT_FOUND_SYMBOL) {
 		ERRMSG("Can't get the symbol of init_level4_pgt.\n");
@@ -212,9 +218,9 @@ vtop4_x86_64(unsigned long vaddr)
 	/*
 	 * Get PGD.
 	 */
-	page_dir  = SYMBOL(init_level4_pgt);
+	page_dir = SYMBOL(init_level4_pgt) - __START_KERNEL_map + phys_base;

I want to confirm that this VA to PA translation is always safe, otherwise we should do the condition check which was done in vaddr_to_paddr_x86_64(), isn't it ?

Quoted 2 lines

I think this should be safe, however x86 expert can comment better. Baoquan any comment here?

Yes, I think this is safe. Below is the physical to virtual address translation function in x86 64. And init_level4_pgt is a global variable located in kernel text region.

arch/x86/include/asm/page_64.h

static inline unsigned long __phys_addr_nodebug(unsigned long x)

{
        unsigned long y = x - __START_KERNEL_map;
 
        /* use the carry flag to determine if x was < __START_KERNEL_map */
        x = y + ((x > y) ? phys_base : (__START_KERNEL_map - PAGE_OFFSET));
 
        return x;
}

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#12 lore raw

RE: [PATCH Makedumpfile 2/4] x86_64: translate all VA to PA using page table values

Quoted 60 lines · Pratyush Anand
Quoted 49 lines
Quoted 6 lines
Quoted 4 lines

With -d 1:
Trial 1: 2768.424565806 S
Trial 2: 2749.622115455 S
Trail 3: 2537.770359073 S

Could you increase the number of trials ?

OK, I can do that. Might take some time, as I will have to arrange that high memory machine again.

Quoted 25 lines

If the average time is close to the results of Trial 1 (2768s) and 2 (2749s), the regression rate is 8% and it sounds neither large nor small. If the average is a level of 2500s like Trial 3, it's ideal.

Quoted 21 lines

---
arch/x86_64.c | 42 ++++++++---------------------------------- makedumpfile.h | 4 ++--

2 files changed, 10 insertions(+), 36 deletions(-)
arch/x86_64.c +6 -0
index a96fd8ae00a1..fe2764a8bec2 100644
@@ -203,6 +203,12 @@ vtop4_x86_64(unsigned long vaddr)
 {
 	unsigned long page_dir, pml4, pgd_paddr, pgd_pte, pmd_paddr, pmd_pte;
 	unsigned long pte_paddr, pte;
+	unsigned long phys_base;
+
+	if (SYMBOL(phys_base) != NOT_FOUND_SYMBOL)
+		phys_base = info->phys_base;
+	else
+		phys_base = 0;
 
Quoted 13 lines

arch/x86_64.c vtop4_x86_64(unsigned long vaddr) · line 221

Quoted 8 lines
arch/x86_64.c +1 -1
 	if (SYMBOL(init_level4_pgt) == NOT_FOUND_SYMBOL) {
 		ERRMSG("Can't get the symbol of init_level4_pgt.\n");
@@ -212,9 +218,9 @@ vtop4_x86_64(unsigned long vaddr)
 	/*
 	 * Get PGD.
 	 */
-	page_dir  = SYMBOL(init_level4_pgt);
+	page_dir = SYMBOL(init_level4_pgt) - __START_KERNEL_map + phys_base;

I want to confirm that this VA to PA translation is always safe, otherwise we should do the condition check which was done in vaddr_to_paddr_x86_64(), isn't it ?

Quoted 2 lines

I think this should be safe, however x86 expert can comment better. Baoquan any comment here?

Yes, I think this is safe. Below is the physical to virtual address translation function in x86 64. And init_level4_pgt is a global variable located in kernel text region.

arch/x86/include/asm/page_64.h

static inline unsigned long __phys_addr_nodebug(unsigned long x)

Quoted 8 lines
{
       unsigned long y = x - __START_KERNEL_map;

       /* use the carry flag to determine if x was < __START_KERNEL_map */
       x = y + ((x > y) ? phys_base : (__START_KERNEL_map - PAGE_OFFSET));

       return x;
}

Good, thanks for your comment.
I'll wait for the result of the benchmark.

Regards,
Atsushi Kumagai

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#17 lore raw
In reply to Pratyush Anand

Hi Pratyush,

Quoted 16 lines · Pratyush Anand

Patch 1/4 fixes page_offset calculation, so that it is correctly calculated on KASLR enabled kernel as well.
Patch 2/4 simplifies VA to PA translation. New code has been benchmarked against old code on a 4T system.
Patch 3/4 and 4/4 is removal of (now) unnecessary code.

I think, we should find a way to kill find_vememmap() as well, so that VMEMMAP_START can be removed. I have very limited idea about x86, so unable to do that as of now.

Pratyush Anand (4):
x86_64: Calculate page_offset from pt_load
x86_64: translate all VA to PA using page table values
x86_64: kill is_vmalloc_addr_x86_64()
x86_64: kill some unused initialization

Quoted 4 lines
 arch/x86_64.c  | 84 ++++++++++++++++++++--------------------------------------
 makedumpfile.h |  9 +++----
 2 files changed, 32 insertions(+), 61 deletions(-)

According to our test, with these patches the dumped vmcore is correct which means simple crash test bt works. But the saved vmcore size is larger than before.

I collected two --message-level 31 logs with/without your patches, the kernel kaslr was disabled during my test so that we can focus on the vmcore size issue, it looks like mem_map address was not collected correctly.

[please ignore the patched log extra debug message I added]

patched-makedumpfile.txt renamed from unpatched-makedumpfile.txt +35 -29
@@ -1,4 +1,4 @@
-[127.0.0.1-2016-10-27-10:27:03]# /tmp/makedumpfile -l -d 31 --message-level 31 vmcore vmcore.m.1
+[127.0.0.1-2016-10-27-10:27:03]# /home/dyoung/git/makedumpfile/makedumpfile -l -d 31 --message-level 31 vmcore vmcore.m
 sadump: does not have partition header
 sadump: read dump device as unknown format
 sadump: unknown format
@@ -36,70 +36,76 @@
 
 Memory type  : SPARSEMEM_EX
 
+printing memmap .....
 mem_map (0)
-  mem_map    : ffffea0000000000
+  mem_map    : 0
   pfn_start  : 0
   pfn_end    : 8000
+printing memmap .....
 mem_map (1)
-  mem_map    : ffffea0000200000
+  mem_map    : 0
   pfn_start  : 8000
   pfn_end    : 10000
+printing memmap .....
 mem_map (2)
-  mem_map    : ffffea0000400000
+  mem_map    : 0
   pfn_start  : 10000
   pfn_end    : 18000
+printing memmap .....
 mem_map (3)
-  mem_map    : ffffea0000600000
+  mem_map    : 0
   pfn_start  : 18000
   pfn_end    : 20000
+printing memmap .....
 mem_map (4)
-  mem_map    : ffffea0000800000
+  mem_map    : 0
   pfn_start  : 20000
   pfn_end    : 28000
+printing memmap .....
 mem_map (5)
-  mem_map    : ffffea0000a00000
+  mem_map    : 0
   pfn_start  : 28000
   pfn_end    : 30000
+printing memmap .....
 mem_map (6)
-  mem_map    : ffffea0000c00000
+  mem_map    : 0
   pfn_start  : 30000
   pfn_end    : 38000
+printing memmap .....
 mem_map (7)
-  mem_map    : ffffea0000e00000
+  mem_map    : 0
   pfn_start  : 38000
   pfn_end    : 3ffda
 mmap() is available on the kernel.
 Checking for memory holes          : [100.0 %] |STEP [Checking for memory holes  ] : 0.000030 seconds
-Excluding unnecessary pages        : [100.0 %] \STEP [Excluding unnecessary pages] : 0.007547 seconds
-Checking for memory holes          : [100.0 %] -STEP [Checking for memory holes  ] : 0.000016 seconds
-Checking for memory holes          : [100.0 %] /STEP [Checking for memory holes  ] : 0.000009 seconds
-Excluding unnecessary pages        : [100.0 %] |STEP [Excluding unnecessary pages] : 0.006623 seconds
-Copying data                       : [100.0 %] \STEP [Copying data               ] : 0.184442 seconds
-Copying data                       : [100.0 %] -STEP [Copying data               ] : 0.000041 seconds
+Excluding unnecessary pages        : [100.0 %] \STEP [Excluding unnecessary pages] : 0.000007 seconds
+Checking for memory holes          : [100.0 %] -STEP [Checking for memory holes  ] : 0.000014 seconds
+Checking for memory holes          : [100.0 %] /STEP [Checking for memory holes  ] : 0.000008 seconds
+Excluding unnecessary pages        : [100.0 %] |STEP [Excluding unnecessary pages] : 0.000007 seconds
+Copying data                       : [100.0 %] /STEP [Copying data               ] : 1.421661 seconds
+Copying data                       : [100.0 %] |STEP [Copying data               ] : 0.000036 seconds
 
 Writing erase info...
-offset_eraseinfo: dd5c4e, size_eraseinfo: 0
+offset_eraseinfo: 888c149, size_eraseinfo: 0
 
 Original pages  : 0x0000000000030c7d
-  Excluded pages   : 0x000000000002cf58
-    Pages filled with zero  : 0x00000000000002be
-    Non-private cache pages : 0x0000000000006574
-    Private cache pages     : 0x0000000000000f27
-    User process data pages : 0x0000000000003481
-    Free pages              : 0x000000000002237e
+  Excluded pages   : 0x000000000001d534
+    Pages filled with zero  : 0x000000000001d534
+    Non-private cache pages : 0x0000000000000000
+    Private cache pages     : 0x0000000000000000
+    User process data pages : 0x0000000000000000
+    Free pages              : 0x0000000000000000
     Hwpoison pages          : 0x0000000000000000
-  Remaining pages  : 0x0000000000003d25
-  (The number of pages is reduced to 7%.)
+  Remaining pages  : 0x0000000000013749
+  (The number of pages is reduced to 39%.)
 Memory Hole     : 0x000000000000f35d
 --------------------------------------------------
 Total pages     : 0x000000000003ffda
 
-Cache hit: 29946, miss: 47, hit rate: 99.8%
+Cache hit: 196285, miss: 201, hit rate: 99.9%
 
 
-The dumpfile is saved to vmcore.m.1.
+The dumpfile is saved to vmcore.m.
 
 makedumpfile Completed.
-[root@dhcp-128-65 127.0.0.1-2016-10-27-10:27:03]# ls -lth vmcore.m*
--rw------- 1 root root  14M Oct 27 10:30 vmcore.m.1
--rw------- 1 root root 137M Oct 27 10:28 vmcore.m
+[root@dhcp-128-65 127.0.0.1-2016-10-27-10:27:03]# 

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#18 lore raw

I put the cped-vmcore/vmlinux here:
https://people.redhat.com/~ruyang/test/

Adding Dave Anderson for any comments about the vmcore correctness from crash point of view..

Quoted 149 lines · Dave Young

Hi Pratyush,

Quoted 16 lines · Pratyush Anand

Patch 1/4 fixes page_offset calculation, so that it is correctly calculated on KASLR enabled kernel as well.
Patch 2/4 simplifies VA to PA translation. New code has been benchmarked against old code on a 4T system.
Patch 3/4 and 4/4 is removal of (now) unnecessary code.

I think, we should find a way to kill find_vememmap() as well, so that VMEMMAP_START can be removed. I have very limited idea about x86, so unable to do that as of now.

Pratyush Anand (4):
x86_64: Calculate page_offset from pt_load
x86_64: translate all VA to PA using page table values
x86_64: kill is_vmalloc_addr_x86_64()
x86_64: kill some unused initialization

Quoted 4 lines
 arch/x86_64.c  | 84 ++++++++++++++++++++--------------------------------------
 makedumpfile.h |  9 +++----
 2 files changed, 32 insertions(+), 61 deletions(-)

According to our test, with these patches the dumped vmcore is correct which means simple crash test bt works. But the saved vmcore size is larger than before.

I collected two --message-level 31 logs with/without your patches, the kernel kaslr was disabled during my test so that we can focus on the vmcore size issue, it looks like mem_map address was not collected correctly.

[please ignore the patched log extra debug message I added]

patched-makedumpfile.txt renamed from unpatched-makedumpfile.txt +35 -29
@@ -1,4 +1,4 @@
-[127.0.0.1-2016-10-27-10:27:03]# /tmp/makedumpfile -l -d 31 --message-level 31 vmcore vmcore.m.1
+[127.0.0.1-2016-10-27-10:27:03]# /home/dyoung/git/makedumpfile/makedumpfile -l -d 31 --message-level 31 vmcore vmcore.m
 sadump: does not have partition header
 sadump: read dump device as unknown format
 sadump: unknown format
@@ -36,70 +36,76 @@
 
 Memory type  : SPARSEMEM_EX
 
+printing memmap .....
 mem_map (0)
-  mem_map    : ffffea0000000000
+  mem_map    : 0
   pfn_start  : 0
   pfn_end    : 8000
+printing memmap .....
 mem_map (1)
-  mem_map    : ffffea0000200000
+  mem_map    : 0
   pfn_start  : 8000
   pfn_end    : 10000
+printing memmap .....
 mem_map (2)
-  mem_map    : ffffea0000400000
+  mem_map    : 0
   pfn_start  : 10000
   pfn_end    : 18000
+printing memmap .....
 mem_map (3)
-  mem_map    : ffffea0000600000
+  mem_map    : 0
   pfn_start  : 18000
   pfn_end    : 20000
+printing memmap .....
 mem_map (4)
-  mem_map    : ffffea0000800000
+  mem_map    : 0
   pfn_start  : 20000
   pfn_end    : 28000
+printing memmap .....
 mem_map (5)
-  mem_map    : ffffea0000a00000
+  mem_map    : 0
   pfn_start  : 28000
   pfn_end    : 30000
+printing memmap .....
 mem_map (6)
-  mem_map    : ffffea0000c00000
+  mem_map    : 0
   pfn_start  : 30000
   pfn_end    : 38000
+printing memmap .....
 mem_map (7)
-  mem_map    : ffffea0000e00000
+  mem_map    : 0
   pfn_start  : 38000
   pfn_end    : 3ffda
 mmap() is available on the kernel.
 Checking for memory holes          : [100.0 %] |STEP [Checking for memory holes  ] : 0.000030 seconds
-Excluding unnecessary pages        : [100.0 %] \STEP [Excluding unnecessary pages] : 0.007547 seconds
-Checking for memory holes          : [100.0 %] -STEP [Checking for memory holes  ] : 0.000016 seconds
-Checking for memory holes          : [100.0 %] /STEP [Checking for memory holes  ] : 0.000009 seconds
-Excluding unnecessary pages        : [100.0 %] |STEP [Excluding unnecessary pages] : 0.006623 seconds
-Copying data                       : [100.0 %] \STEP [Copying data               ] : 0.184442 seconds
-Copying data                       : [100.0 %] -STEP [Copying data               ] : 0.000041 seconds
+Excluding unnecessary pages        : [100.0 %] \STEP [Excluding unnecessary pages] : 0.000007 seconds
+Checking for memory holes          : [100.0 %] -STEP [Checking for memory holes  ] : 0.000014 seconds
+Checking for memory holes          : [100.0 %] /STEP [Checking for memory holes  ] : 0.000008 seconds
+Excluding unnecessary pages        : [100.0 %] |STEP [Excluding unnecessary pages] : 0.000007 seconds
+Copying data                       : [100.0 %] /STEP [Copying data               ] : 1.421661 seconds
+Copying data                       : [100.0 %] |STEP [Copying data               ] : 0.000036 seconds
 
 Writing erase info...
-offset_eraseinfo: dd5c4e, size_eraseinfo: 0
+offset_eraseinfo: 888c149, size_eraseinfo: 0
 
 Original pages  : 0x0000000000030c7d
-  Excluded pages   : 0x000000000002cf58
-    Pages filled with zero  : 0x00000000000002be
-    Non-private cache pages : 0x0000000000006574
-    Private cache pages     : 0x0000000000000f27
-    User process data pages : 0x0000000000003481
-    Free pages              : 0x000000000002237e
+  Excluded pages   : 0x000000000001d534
+    Pages filled with zero  : 0x000000000001d534
+    Non-private cache pages : 0x0000000000000000
+    Private cache pages     : 0x0000000000000000
+    User process data pages : 0x0000000000000000
+    Free pages              : 0x0000000000000000
     Hwpoison pages          : 0x0000000000000000
-  Remaining pages  : 0x0000000000003d25
-  (The number of pages is reduced to 7%.)
+  Remaining pages  : 0x0000000000013749
+  (The number of pages is reduced to 39%.)
 Memory Hole     : 0x000000000000f35d
 --------------------------------------------------
 Total pages     : 0x000000000003ffda
 
-Cache hit: 29946, miss: 47, hit rate: 99.8%
+Cache hit: 196285, miss: 201, hit rate: 99.9%
 
 
-The dumpfile is saved to vmcore.m.1.
+The dumpfile is saved to vmcore.m.
 
 makedumpfile Completed.
-[root@dhcp-128-65 127.0.0.1-2016-10-27-10:27:03]# ls -lth vmcore.m*
--rw------- 1 root root  14M Oct 27 10:30 vmcore.m.1
--rw------- 1 root root 137M Oct 27 10:28 vmcore.m
+[root@dhcp-128-65 127.0.0.1-2016-10-27-10:27:03]# 
Quoted 4 lines

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#25 lore raw
In reply to Dave Young
Quoted 24 lines · Dave Young

Hi Pratyush,

Quoted 16 lines · Pratyush Anand

Patch 1/4 fixes page_offset calculation, so that it is correctly calculated on KASLR enabled kernel as well.
Patch 2/4 simplifies VA to PA translation. New code has been benchmarked against old code on a 4T system.
Patch 3/4 and 4/4 is removal of (now) unnecessary code.

I think, we should find a way to kill find_vememmap() as well, so that VMEMMAP_START can be removed. I have very limited idea about x86, so unable to do that as of now.

Pratyush Anand (4):
x86_64: Calculate page_offset from pt_load
x86_64: translate all VA to PA using page table values
x86_64: kill is_vmalloc_addr_x86_64()
x86_64: kill some unused initialization

Quoted 4 lines
 arch/x86_64.c  | 84 ++++++++++++++++++++--------------------------------------
 makedumpfile.h |  9 +++----
 2 files changed, 32 insertions(+), 61 deletions(-)
Quoted 8 lines

According to our test, with these patches the dumped vmcore is correct which means simple crash test bt works. But the saved vmcore size is larger than before.

I collected two --message-level 31 logs with/without your patches, the kernel kaslr was disabled during my test so that we can focus on the vmcore size issue, it looks like mem_map address was not collected correctly.

From printing log, this is not correct. Without memmap, filtering can't be done correctly.

Quoted 117 lines

[please ignore the patched log extra debug message I added]

patched-makedumpfile.txt renamed from unpatched-makedumpfile.txt +35 -29
@@ -1,4 +1,4 @@
-[127.0.0.1-2016-10-27-10:27:03]# /tmp/makedumpfile -l -d 31 --message-level 31 vmcore vmcore.m.1
+[127.0.0.1-2016-10-27-10:27:03]# /home/dyoung/git/makedumpfile/makedumpfile -l -d 31 --message-level 31 vmcore vmcore.m
 sadump: does not have partition header
 sadump: read dump device as unknown format
 sadump: unknown format
@@ -36,70 +36,76 @@
 
 Memory type  : SPARSEMEM_EX
 
+printing memmap .....
 mem_map (0)
-  mem_map    : ffffea0000000000
+  mem_map    : 0
   pfn_start  : 0
   pfn_end    : 8000
+printing memmap .....
 mem_map (1)
-  mem_map    : ffffea0000200000
+  mem_map    : 0
   pfn_start  : 8000
   pfn_end    : 10000
+printing memmap .....
 mem_map (2)
-  mem_map    : ffffea0000400000
+  mem_map    : 0
   pfn_start  : 10000
   pfn_end    : 18000
+printing memmap .....
 mem_map (3)
-  mem_map    : ffffea0000600000
+  mem_map    : 0
   pfn_start  : 18000
   pfn_end    : 20000
+printing memmap .....
 mem_map (4)
-  mem_map    : ffffea0000800000
+  mem_map    : 0
   pfn_start  : 20000
   pfn_end    : 28000
+printing memmap .....
 mem_map (5)
-  mem_map    : ffffea0000a00000
+  mem_map    : 0
   pfn_start  : 28000
   pfn_end    : 30000
+printing memmap .....
 mem_map (6)
-  mem_map    : ffffea0000c00000
+  mem_map    : 0
   pfn_start  : 30000
   pfn_end    : 38000
+printing memmap .....
 mem_map (7)
-  mem_map    : ffffea0000e00000
+  mem_map    : 0
   pfn_start  : 38000
   pfn_end    : 3ffda
 mmap() is available on the kernel.
 Checking for memory holes          : [100.0 %] |STEP [Checking for memory holes  ] : 0.000030 seconds
-Excluding unnecessary pages        : [100.0 %] \STEP [Excluding unnecessary pages] : 0.007547 seconds
-Checking for memory holes          : [100.0 %] -STEP [Checking for memory holes  ] : 0.000016 seconds
-Checking for memory holes          : [100.0 %] /STEP [Checking for memory holes  ] : 0.000009 seconds
-Excluding unnecessary pages        : [100.0 %] |STEP [Excluding unnecessary pages] : 0.006623 seconds
-Copying data                       : [100.0 %] \STEP [Copying data               ] : 0.184442 seconds
-Copying data                       : [100.0 %] -STEP [Copying data               ] : 0.000041 seconds
+Excluding unnecessary pages        : [100.0 %] \STEP [Excluding unnecessary pages] : 0.000007 seconds
+Checking for memory holes          : [100.0 %] -STEP [Checking for memory holes  ] : 0.000014 seconds
+Checking for memory holes          : [100.0 %] /STEP [Checking for memory holes  ] : 0.000008 seconds
+Excluding unnecessary pages        : [100.0 %] |STEP [Excluding unnecessary pages] : 0.000007 seconds
+Copying data                       : [100.0 %] /STEP [Copying data               ] : 1.421661 seconds
+Copying data                       : [100.0 %] |STEP [Copying data               ] : 0.000036 seconds
 
 Writing erase info...
-offset_eraseinfo: dd5c4e, size_eraseinfo: 0
+offset_eraseinfo: 888c149, size_eraseinfo: 0
 
 Original pages  : 0x0000000000030c7d
-  Excluded pages   : 0x000000000002cf58
-    Pages filled with zero  : 0x00000000000002be
-    Non-private cache pages : 0x0000000000006574
-    Private cache pages     : 0x0000000000000f27
-    User process data pages : 0x0000000000003481
-    Free pages              : 0x000000000002237e
+  Excluded pages   : 0x000000000001d534
+    Pages filled with zero  : 0x000000000001d534
+    Non-private cache pages : 0x0000000000000000
+    Private cache pages     : 0x0000000000000000
+    User process data pages : 0x0000000000000000
+    Free pages              : 0x0000000000000000
     Hwpoison pages          : 0x0000000000000000
-  Remaining pages  : 0x0000000000003d25
-  (The number of pages is reduced to 7%.)
+  Remaining pages  : 0x0000000000013749
+  (The number of pages is reduced to 39%.)
 Memory Hole     : 0x000000000000f35d
 --------------------------------------------------
 Total pages     : 0x000000000003ffda
 
-Cache hit: 29946, miss: 47, hit rate: 99.8%
+Cache hit: 196285, miss: 201, hit rate: 99.9%
 
 
-The dumpfile is saved to vmcore.m.1.
+The dumpfile is saved to vmcore.m.
 
 makedumpfile Completed.
-[root@dhcp-128-65 127.0.0.1-2016-10-27-10:27:03]# ls -lth vmcore.m*
--rw------- 1 root root  14M Oct 27 10:30 vmcore.m.1
--rw------- 1 root root 137M Oct 27 10:28 vmcore.m
+[root@dhcp-128-65 127.0.0.1-2016-10-27-10:27:03]# 
Quoted 4 lines

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#26 lore raw
In reply to Dave Young
Quoted 10 lines · Dave Young

According to our test, with these patches the dumped vmcore is correct which means simple crash test bt works. But the saved vmcore size is larger than before.

I collected two --message-level 31 logs with/without your patches, the kernel kaslr was disabled during my test so that we can focus on the vmcore size issue, it looks like mem_map address was not collected correctly.

[please ignore the patched log extra debug message I added]

Hummm..thanks for pointing it out.

Seems patch 1/4 is wrong.

with this patch page_offset = ffffffff80000000 while with original code page_offset = ffff880000000000

Trying to see where it is wrong

~Pratyush

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#4 lore raw

Re: [PATCH Makedumpfile 1/4] x86_64: Calculate page_offset from pt_load

In reply to Pratyush Anand
Quoted 16 lines · Pratyush Anand

page_offset can always be calculated as 'virtual - physical' for a direct mapping area on x86. Therefore, remove the version dependent calculation and use this method.

---
 arch/x86_64.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)
arch/x86_64.c +0 -0
index ddf7be6bc57b..a96fd8ae00a1 100644
@@ -44,6 +44,24 @@ get_xen_p2m_mfn(void)
 	return NOT_FOUND_LONG_VALUE;
 }

arch/x86_64.c get_xen_p2m_mfn(void) · line 55

Quoted 10 lines
arch/x86_64.c +9 -0
 
+static int
+get_page_offset_x86_64(void)
+{
+	int i;
+	unsigned long long phys_start;
+	unsigned long long virt_start;
+
+	for (i = 0; get_pt_load(i, &phys_start, NULL, &virt_start, NULL); i++) {
+		if (virt_start >= __START_KERNEL_map) {

OK..So, this is the problem. We should have

if (virt_start < __START_KERNEL_map) {

Kernel text region lies above __START_KERNEL_map, which is linearly mapped however not a direct mapping. Direct mapping region lies below it instead. So, page_offset can only be calculated with a region which is below __START_KERNEL_map.

Thanks Baoquan for finding it.

~Pratyush

Quoted 16 lines
arch/x86_64.c +9 -0
+			info->page_offset = virt_start - phys_start;
+			return TRUE;
+		}
+	}
+
+	ERRMSG("Can't get any pt_load to calculate page offset.\n");
+	return FALSE;
+}
+
 int
 get_phys_base_x86_64(void)
 {
@@ -159,10 +177,8 @@ get_versiondep_info_x86_64(void)
 	else
 		info->max_physmem_bits  = _MAX_PHYSMEM_BITS_2_6_31;

arch/x86_64.c get_versiondep_info_x86_64(void) · line 184

Quoted 10 lines
arch/x86_64.c +2 -4
 
-	if (info->kernel_version < KERNEL_VERSION(2, 6, 27))
-		info->page_offset = __PAGE_OFFSET_ORIG;
-	else
-		info->page_offset = __PAGE_OFFSET_2_6_27;
+	if (!get_page_offset_x86_64())
+		return FALSE;
 
 	if (info->kernel_version < KERNEL_VERSION(2, 6, 31)) {
 		info->vmalloc_start = VMALLOC_START_ORIG;

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#19 lore raw
In reply to Dave Young
Quoted 6 lines · Dave Young

I put the cped-vmcore/vmlinux here:
https://people.redhat.com/~ruyang/test/

Adding Dave Anderson for any comments about the vmcore correctness from crash point of view..

Since the reason has been found, the page_offset was not correct, I tested with a changed version of patch 1, it works. Please ignore the test vmcore, I deleted them.

Here is a new tarball which could be used by Dave to verify the kaslr, I enabled kaslr, also saved vmlinux/cped vmcore/makedumpfile saved vmcore in a tarball below.
http://people.redhat.com/~ruyang/test/vmcore-test.tar.gz

Thanks
Dave

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#21 lore raw
In reply to a message not in the archive

----- Original Message -----

Quoted 14 lines

That being said, my recent 4.8 and 4.9 KASLR testing has been on live systems and compressed kdumps, so the old tried-and-true manner of calculating the phys_base from the ELF PT_LOAD segments apparently no longer works with KASLR.

It would be so much more helpful if the VMCOREINFO data in the ELF header stored the actual phys_base value instead of its symbol value:

crash> help -D
...
SYMBOL(phys_base)=ffffffffa740b010
...

Quoted 6 lines

which is completely useless unless the phys_base value is known.

Anyway, can you send me the makedumpfile code that calculates the phys_base value?

Dave

As it turns out, the problem with the crash utility is that it has to calculate phys_base well before it even knows the kernel has been relocated by KASLR. So when it sees the __START_KERNEL_map PT_LOAD segment, it mistakes it for the kernel modules' virtual address region and skips it.

The kernel has this:

  #if defined(CONFIG_RANDOMIZE_BASE)
  #define KERNEL_IMAGE_SIZE       (1024 * 1024 * 1024)
  #else
  #define KERNEL_IMAGE_SIZE       (512 * 1024 * 1024)
  #endif

and then this:

  #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)

So with KASLR, MODULES_VADDR gets pushed up from the traditional ffffffffa0000000 up to ffffffffc0000000.

So I'm curious as to what you use in makedumpfile to determine whether CONFIG_RANDOMIZE_BASE has been configured?

Thanks,
Dave

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#22 lore raw

----- Original Message -----

Quoted 43 lines

----- Original Message -----

Quoted 14 lines

That being said, my recent 4.8 and 4.9 KASLR testing has been on live systems and compressed kdumps, so the old tried-and-true manner of calculating the phys_base from the ELF PT_LOAD segments apparently no longer works with KASLR.

It would be so much more helpful if the VMCOREINFO data in the ELF header stored the actual phys_base value instead of its symbol value:

crash> help -D
...
SYMBOL(phys_base)=ffffffffa740b010
...

Quoted 6 lines

which is completely useless unless the phys_base value is known.

Anyway, can you send me the makedumpfile code that calculates the phys_base value?

Dave

As it turns out, the problem with the crash utility is that it has to calculate phys_base well before it even knows the kernel has been relocated by KASLR. So when it sees the __START_KERNEL_map PT_LOAD segment, it mistakes
it for the kernel modules' virtual address region and skips it.

The kernel has this:

  #if defined(CONFIG_RANDOMIZE_BASE)
  #define KERNEL_IMAGE_SIZE       (1024 * 1024 * 1024)
  #else
  #define KERNEL_IMAGE_SIZE       (512 * 1024 * 1024)
  #endif

and then this:

  #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
Quoted 8 lines

So with KASLR, MODULES_VADDR gets pushed up from the traditional ffffffffa0000000 up to ffffffffc0000000.

So I'm curious as to what you use in makedumpfile to determine whether CONFIG_RANDOMIZE_BASE has been configured?

Thanks,
Dave

Hey, sorry, I didn't notice that this was added upstream:

commit 1303a27c9c32020a3b6ac89be270d2ab1f28be24
Author: Baoquan He <[email protected]>
Date: Wed Sep 9 15:39:03 2015 -0700

kexec: export KERNEL_IMAGE_SIZE to vmcoreinfo

With that in place, it will be an easy fix for the crash utility.

Thanks,
Dave

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#24 lore raw
In reply to Dave Anderson
Quoted 15 lines · Dave Anderson

As it turns out, the problem with the crash utility is that it has to calculate phys_base well before it even knows the kernel has been relocated by KASLR. So when it sees the __START_KERNEL_map PT_LOAD segment, it mistakes it for the kernel modules' virtual address region and skips it.

The kernel has this:

  #if defined(CONFIG_RANDOMIZE_BASE)
  #define KERNEL_IMAGE_SIZE       (1024 * 1024 * 1024)
  #else
  #define KERNEL_IMAGE_SIZE       (512 * 1024 * 1024)
  #endif

and then this:

Quoted 7 lines
  #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)

So with KASLR, MODULES_VADDR gets pushed up from the traditional ffffffffa0000000 up to ffffffffc0000000.

So I'm curious as to what you use in makedumpfile to determine whether CONFIG_RANDOMIZE_BASE has been configured?

So far we are trying to avoid to know that in makedumpfile. makedumpfile needed to know MODULES_VADDR, VMALLOC_START etc only to know that whether a VA to PA translation can be done using direct mapping or to be done by reading corresponding page table entry.

Now, we do VA to PA for all VAs using page table entry only.

https://github.com/pratyushanand/makedumpfile/blob/x86_devel/arch/x86_64.c#L186

~Pratyush

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#23 lore raw
In reply to Dave Anderson
Quoted 57 lines · Dave Anderson

----- Original Message -----

Quoted 43 lines

----- Original Message -----

Quoted 14 lines

That being said, my recent 4.8 and 4.9 KASLR testing has been on live systems and compressed kdumps, so the old tried-and-true manner of calculating the phys_base from the ELF PT_LOAD segments apparently no longer works with KASLR.

It would be so much more helpful if the VMCOREINFO data in the ELF header stored the actual phys_base value instead of its symbol value:

crash> help -D
...
SYMBOL(phys_base)=ffffffffa740b010
...

Quoted 6 lines

which is completely useless unless the phys_base value is known.

Anyway, can you send me the makedumpfile code that calculates the phys_base value?

Dave

As it turns out, the problem with the crash utility is that it has to calculate phys_base well before it even knows the kernel has been relocated by KASLR. So when it sees the __START_KERNEL_map PT_LOAD segment, it mistakes
it for the kernel modules' virtual address region and skips it.

The kernel has this:

  #if defined(CONFIG_RANDOMIZE_BASE)
  #define KERNEL_IMAGE_SIZE       (1024 * 1024 * 1024)
  #else
  #define KERNEL_IMAGE_SIZE       (512 * 1024 * 1024)
  #endif

and then this:

  #define MODULES_VADDR    (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
Quoted 8 lines

So with KASLR, MODULES_VADDR gets pushed up from the traditional ffffffffa0000000 up to ffffffffc0000000.

So I'm curious as to what you use in makedumpfile to determine whether CONFIG_RANDOMIZE_BASE has been configured?

Thanks,
Dave

Hey, sorry, I didn't notice that this was added upstream:

Quoted 7 lines

commit 1303a27c9c32020a3b6ac89be270d2ab1f28be24
Author: Baoquan He <[email protected]>
Date: Wed Sep 9 15:39:03 2015 -0700

kexec: export KERNEL_IMAGE_SIZE to vmcoreinfo

With that in place, it will be an easy fix for the crash utility.

Dave, I confirmed your fix in crash git tree works, it also works for the elf format vmcore, /proc/vmcore and makedumpfile -E created vmcore.

Thanks for the quick fix..

Quoted 13 lines

Thanks,
Dave

Quoted 4 lines

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#5 lore raw

RE: [PATCH Makedumpfile 1/4] x86_64: Calculate page_offset from pt_load

In reply to Pratyush Anand

Hello Pratyush,

Quoted 30 lines · Pratyush Anand
Quoted 16 lines

page_offset can always be calculated as 'virtual - physical' for a direct mapping area on x86. Therefore, remove the version dependent calculation and use this method.

---
 arch/x86_64.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)
arch/x86_64.c +0 -0
index ddf7be6bc57b..a96fd8ae00a1 100644
@@ -44,6 +44,24 @@ get_xen_p2m_mfn(void)
 	return NOT_FOUND_LONG_VALUE;
 }

arch/x86_64.c get_xen_p2m_mfn(void) · line 55

Quoted 10 lines
arch/x86_64.c +9 -0
 
+static int
+get_page_offset_x86_64(void)
+{
+	int i;
+	unsigned long long phys_start;
+	unsigned long long virt_start;
+
+	for (i = 0; get_pt_load(i, &phys_start, NULL, &virt_start, NULL); i++) {
+		if (virt_start >= __START_KERNEL_map) {

OK..So, this is the problem. We should have

Quoted 8 lines

if (virt_start < __START_KERNEL_map) {

Kernel text region lies above __START_KERNEL_map, which is linearly mapped however not a direct mapping. Direct mapping region lies below it instead. So, page_offset can only be calculated with a region which is below __START_KERNEL_map.

Thanks Baoquan for finding it.

Could you explain the issue in more detail, what is the difference between "linear map" and "direct map" ?

BTW, I confirmed that the difference of v2 patch is only this and the result of benchmark looks great, thank you very much.

Regards,
Atsushi Kumagai

Quoted 23 lines
Quoted 23 lines
arch/x86_64.c +11 -4
+			info->page_offset = virt_start - phys_start;
+			return TRUE;
+		}
+	}
+
+	ERRMSG("Can't get any pt_load to calculate page offset.\n");
+	return FALSE;
+}
+
 int
 get_phys_base_x86_64(void)
 {
@@ -159,10 +177,8 @@ get_versiondep_info_x86_64(void)
 	else
 		info->max_physmem_bits  = _MAX_PHYSMEM_BITS_2_6_31;
 
-	if (info->kernel_version < KERNEL_VERSION(2, 6, 27))
-		info->page_offset = __PAGE_OFFSET_ORIG;
-	else
-		info->page_offset = __PAGE_OFFSET_2_6_27;
+	if (!get_page_offset_x86_64())
+		return FALSE;
 
Quoted 8 lines

arch/x86_64.c get_versiondep_info_x86_64(void) · line 184

Quoted 3 lines
arch/x86_64.c +0 -0
 	if (info->kernel_version < KERNEL_VERSION(2, 6, 31)) {
 		info->vmalloc_start = VMALLOC_START_ORIG;

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#6 lore raw

Re: [PATCH Makedumpfile 1/4] x86_64: Calculate page_offset from pt_load

Quoted 39 lines · Atsushi Kumagai

Hello Pratyush,

Quoted 37 lines · Pratyush Anand
Quoted 16 lines

page_offset can always be calculated as 'virtual - physical' for a direct mapping area on x86. Therefore, remove the version dependent calculation and use this method.

---
 arch/x86_64.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)
arch/x86_64.c +0 -0
index ddf7be6bc57b..a96fd8ae00a1 100644
@@ -44,6 +44,24 @@ get_xen_p2m_mfn(void)
 	return NOT_FOUND_LONG_VALUE;
 }

arch/x86_64.c get_xen_p2m_mfn(void) · line 55

Quoted 10 lines
arch/x86_64.c +9 -0
 
+static int
+get_page_offset_x86_64(void)
+{
+	int i;
+	unsigned long long phys_start;
+	unsigned long long virt_start;
+
+	for (i = 0; get_pt_load(i, &phys_start, NULL, &virt_start, NULL); i++) {
+		if (virt_start >= __START_KERNEL_map) {

OK..So, this is the problem. We should have

if (virt_start < __START_KERNEL_map) {

Kernel text region lies above __START_KERNEL_map, which is linearly mapped however not a direct mapping. Direct mapping region lies below it instead. So, page_offset can only be calculated with a region which is below __START_KERNEL_map.

Quoted 4 lines
Quoted 1 line

Thanks Baoquan for finding it.

Could you explain the issue in more detail, what is the difference between "linear map" and "direct map" ?

Well, these could be easily misunderstood. Virtual address in kernel text region or within direct mapping which is from PAGE_OFFSET are all linear mapping. Because the related PA can be calculated by:
PA= VA - PAGE_OFFSET; //y=x - a;
PA= VA - __START_KERNEL_map + phys_base; //y=x-a+b

In user-space kexec-tools we created pt_load program segments for kernel text region and crash memory regions. The first program header is kernel text region. So here if we want to get page_offset, just need to ignore the 1st one, kernel text region.

Quoted 39 lines

BTW, I confirmed that the difference of v2 patch is only this and the result of benchmark looks great, thank you very much.

Regards,
Atsushi Kumagai

Quoted 31 lines
Quoted 16 lines
arch/x86_64.c +9 -0
+			info->page_offset = virt_start - phys_start;
+			return TRUE;
+		}
+	}
+
+	ERRMSG("Can't get any pt_load to calculate page offset.\n");
+	return FALSE;
+}
+
 int
 get_phys_base_x86_64(void)
 {
@@ -159,10 +177,8 @@ get_versiondep_info_x86_64(void)
 	else
 		info->max_physmem_bits  = _MAX_PHYSMEM_BITS_2_6_31;

arch/x86_64.c get_versiondep_info_x86_64(void) · line 184

Quoted 10 lines
arch/x86_64.c +2 -4
 
-	if (info->kernel_version < KERNEL_VERSION(2, 6, 27))
-		info->page_offset = __PAGE_OFFSET_ORIG;
-	else
-		info->page_offset = __PAGE_OFFSET_2_6_27;
+	if (!get_page_offset_x86_64())
+		return FALSE;
 
 	if (info->kernel_version < KERNEL_VERSION(2, 6, 31)) {
 		info->vmalloc_start = VMALLOC_START_ORIG;

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

#7 lore raw

RE: [PATCH Makedumpfile 1/4] x86_64: Calculate page_offset from pt_load

Hello,

Quoted 51 lines · Atsushi Kumagai
Quoted 39 lines

Hello Pratyush,

Quoted 37 lines · Pratyush Anand
Quoted 16 lines

page_offset can always be calculated as 'virtual - physical' for a direct mapping area on x86. Therefore, remove the version dependent calculation and use this method.

---
 arch/x86_64.c | 24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)
arch/x86_64.c +0 -0
index ddf7be6bc57b..a96fd8ae00a1 100644
@@ -44,6 +44,24 @@ get_xen_p2m_mfn(void)
 	return NOT_FOUND_LONG_VALUE;
 }

arch/x86_64.c get_xen_p2m_mfn(void) · line 55

Quoted 10 lines
arch/x86_64.c +9 -0
 
+static int
+get_page_offset_x86_64(void)
+{
+	int i;
+	unsigned long long phys_start;
+	unsigned long long virt_start;
+
+	for (i = 0; get_pt_load(i, &phys_start, NULL, &virt_start, NULL); i++) {
+		if (virt_start >= __START_KERNEL_map) {

OK..So, this is the problem. We should have

if (virt_start < __START_KERNEL_map) {

Kernel text region lies above __START_KERNEL_map, which is linearly mapped however not a direct mapping. Direct mapping region lies below it instead. So, page_offset can only be calculated with a region which is below __START_KERNEL_map.

Quoted 4 lines
Quoted 1 line

Thanks Baoquan for finding it.

Could you explain the issue in more detail, what is the difference between "linear map" and "direct map" ?

Well, these could be easily misunderstood. Virtual address in kernel text region or within direct mapping which is from PAGE_OFFSET are all linear mapping. Because the related PA can be calculated by:
PA= VA - PAGE_OFFSET; //y=x - a;
PA= VA - __START_KERNEL_map + phys_base; //y=x-a+b

Quoted 4 lines

In user-space kexec-tools we created pt_load program segments for kernel text region and crash memory regions. The first program header is kernel text region. So here if we want to get page_offset, just need to ignore the 1st one, kernel text region.

Thanks, I understand.
Now I have no concerns.

Regards,
Atsushi Kumagai

Quoted 39 lines
Quoted 4 lines

BTW, I confirmed that the difference of v2 patch is only this and the result of benchmark looks great, thank you very much.

Quoted 34 lines

Regards,
Atsushi Kumagai

Quoted 31 lines
Quoted 16 lines
arch/x86_64.c +9 -0
+			info->page_offset = virt_start - phys_start;
+			return TRUE;
+		}
+	}
+
+	ERRMSG("Can't get any pt_load to calculate page offset.\n");
+	return FALSE;
+}
+
 int
 get_phys_base_x86_64(void)
 {
@@ -159,10 +177,8 @@ get_versiondep_info_x86_64(void)
 	else
 		info->max_physmem_bits  = _MAX_PHYSMEM_BITS_2_6_31;

arch/x86_64.c get_versiondep_info_x86_64(void) · line 184

Quoted 10 lines
arch/x86_64.c +2 -4
 
-	if (info->kernel_version < KERNEL_VERSION(2, 6, 27))
-		info->page_offset = __PAGE_OFFSET_ORIG;
-	else
-		info->page_offset = __PAGE_OFFSET_2_6_27;
+	if (!get_page_offset_x86_64())
+		return FALSE;
 
 	if (info->kernel_version < KERNEL_VERSION(2, 6, 31)) {
 		info->vmalloc_start = VMALLOC_START_ORIG;

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

Quoted 4 lines

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec