Ku, Eugene | 29 Jul 18:10 2014

Debuginfo packages for Ubuntu 12.04

Hello,

 

I am working on a product that supports Ubuntu 12.04 LTS.  Ubuntu 12.04 LTS has delivered many different versions of Linux kernel.  In order to run crash to analyze crash dump from Ubuntu 12.04 LTS, we need a matching debugging Linux kernel module, vmlinux.  Do you know if there is repository for all released Ubuntu kernel debuginfo packages?  I have searched Ubunut and Debian web sites but could not find such a site.  The closest thing I have found is http://ddebs.ubuntu.com/pool/main/l/linux/; however it only has linux-image-3.2.0-* ddeb packages.  For Ubuntu 12.04 LTS it has delivered 3.2.0-*, 3.5.0-* and 3.8.0-* kernels.  These ddeb packages are also huge, more than 600MB each.  If there is a repository for vmlinux files only, that will be even better.

 

Please advise.  Thank you so much.

 

Eugene

<div>
<div class="WordSection1">
<p class="MsoNormal">Hello,<p></p></p>
<p class="MsoNormal"><p>&nbsp;</p></p>
<p class="MsoNormal">I am working on a product that supports Ubuntu 12.04 LTS.&nbsp; Ubuntu 12.04 LTS has delivered many different versions of Linux kernel.&nbsp; In order to run crash to analyze crash dump from Ubuntu 12.04 LTS, we need a matching debugging Linux kernel
 module, vmlinux.&nbsp; Do you know if there is repository for all released Ubuntu kernel debuginfo packages?&nbsp; I have searched Ubunut and Debian web sites but could not find such a site.&nbsp; The closest thing I have found is
<a href="http://ddebs.ubuntu.com/pool/main/l/linux/">http://ddebs.ubuntu.com/pool/main/l/linux/</a>; however it only has linux-image-3.2.0-* ddeb packages.&nbsp; For Ubuntu 12.04 LTS it has delivered 3.2.0-*, 3.5.0-* and 3.8.0-* kernels.&nbsp; These ddeb packages are
 also huge, more than 600MB each.&nbsp; If there is a repository for vmlinux files only, that will be even better.<p></p></p>
<p class="MsoNormal"><p>&nbsp;</p></p>
<p class="MsoNormal">Please advise.&nbsp; Thank you so much.<p></p></p>
<p class="MsoNormal"><p>&nbsp;</p></p>
<p class="MsoNormal">Eugene<p></p></p>
</div>
</div>
qiaonuohan | 22 Jul 11:26 2014

display slabs in cpu partial list for slub

Hello Dave,

Please check this patch. It is used for slub to display slabs in
kmem_cache_cpu.partial list.

I can only get it test on RHEL7.0GA right now. Would you please
help get some other test? Thanks a lot.

-- 
Regards
Qiao Nuohan
From f47f195e4c5e9d3b0e013f6f68b9f1e9d0cf58fa Mon Sep 17 00:00:00 2001
From: qiaonuohan <qiaonuohan <at> cn.fujitsu.com>
Date: Tue, 22 Jul 2014 05:18:53 -0400
Subject: [PATCH] display slabs in cpu partial list for slub

The following kernel commit adds per cpu partial list.

commit 49e2258586b423684f03c278149ab46d8f8b6700
Author: Christoph Lameter <cl <at> linux.com>
Date:   Tue Aug 9 16:12:27 2011 -0500

    slub: per cpu cache for partial pages

This patch is used for slub. It will display slabs in per cpu partial pages.
---
 defs.h   |  1 +
 memory.c | 51 +++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/defs.h b/defs.h
index 44df6ae..1798d7b 100755
--- a/defs.h
+++ b/defs.h
 <at>  <at>  -1661,6 +1661,7  <at>  <at>  struct offset_table {                    /* stash of commonly-used offsets */
         long kmem_cache_cpu_freelist;
         long kmem_cache_cpu_page;
         long kmem_cache_cpu_node;
+	long kmem_cache_cpu_partial;
 	long kmem_cache_flags;
 	long zone_nr_active;
 	long zone_nr_inactive;
diff --git a/memory.c b/memory.c
index c97dd39..8a16426 100755
--- a/memory.c
+++ b/memory.c
 <at>  <at>  -271,6 +271,7  <at>  <at>  static long count_partial(ulong, struct meminfo *);
 static ulong get_freepointer(struct meminfo *, void *);
 static int count_free_objects(struct meminfo *, ulong);
 char *is_slab_page(struct meminfo *, char *);
+static void do_cpu_partial_slub(struct meminfo *, int);
 static void do_node_lists_slub(struct meminfo *, ulong, int);
 static int devmem_is_restricted(void);
 static int switch_to_proc_kcore(void);
 <at>  <at>  -392,6 +393,8  <at>  <at>  vm_init(void)
 	MEMBER_OFFSET_INIT(page_next, "page", "next");
 	if (VALID_MEMBER(page_next)) 
 		MEMBER_OFFSET_INIT(page_prev, "page", "prev");
+	if (INVALID_MEMBER(page_next))
+		ANON_MEMBER_OFFSET_INIT(page_next, "page", "next");

 	MEMBER_OFFSET_INIT(page_list, "page", "list");
 	if (VALID_MEMBER(page_list)) {
 <at>  <at>  -675,6 +678,7  <at>  <at>  vm_init(void)
 		MEMBER_OFFSET_INIT(kmem_cache_cpu_freelist, "kmem_cache_cpu", "freelist");
 		MEMBER_OFFSET_INIT(kmem_cache_cpu_page, "kmem_cache_cpu", "page");
 		MEMBER_OFFSET_INIT(kmem_cache_cpu_node, "kmem_cache_cpu", "node");
+		MEMBER_OFFSET_INIT(kmem_cache_cpu_partial, "kmem_cache_cpu", "partial");
 		ANON_MEMBER_OFFSET_INIT(page_inuse, "page", "inuse");
 		ANON_MEMBER_OFFSET_INIT(page_offset, "page", "offset");
 		ANON_MEMBER_OFFSET_INIT(page_slab, "page", "slab");
 <at>  <at>  -17324,6 +17328,34  <at>  <at>  bailout:
 	return FALSE;
 }

+static void
+do_cpu_partial_slub(struct meminfo *si, int cpu)
+{
+	ulong cpu_slab_ptr;
+	void *partial;
+
+	cpu_slab_ptr = ULONG(si->cache_buf + OFFSET(kmem_cache_cpu_slab)) +
+				kt->__per_cpu_offset[cpu];
+	readmem(cpu_slab_ptr + OFFSET(kmem_cache_cpu_partial), KVADDR,
+		&partial, sizeof(void *), "kmem_cache_cpu.partial",
+		RETURN_ON_ERROR);
+
+	fprintf(fp, "CPU %d PARTIAL:\n%s", cpu,
+		partial ? "" : "  (empty)\n");
+
+	/*
+	 * kmem_cache_cpu.partial points to the first page of per cpu partial
+	 * list.
+	 */ 
+	while (partial) {
+		si->slab = (ulong)partial;
+		do_slab_slub(si, VERBOSE);
+
+		readmem((ulong)partial + OFFSET(page_next), KVADDR, &partial,
+			sizeof(void *), "page.next", RETURN_ON_ERROR);
+
+	}
+}

 static void
 do_kmem_cache_slub(struct meminfo *si)  
 <at>  <at>  -17337,19 +17369,26  <at>  <at>  do_kmem_cache_slub(struct meminfo *si)
 	per_cpu = (ulong *)GETBUF(sizeof(ulong) * vt->numnodes);

         for (i = 0; i < kt->cpus; i++) {
+		cpu_slab_ptr = ULONG(si->cache_buf + OFFSET(kmem_cache_cpu_slab)) +
+				kt->__per_cpu_offset[i];
+		fprintf(fp, "KMEM_CACHE_CPU    CPU\n%lx%s%3d\n", cpu_slab_ptr,
+			space(VADDR_PRLEN > 8 ? 2 : 10), i);
+
 		cpu_slab_ptr = get_cpu_slab_ptr(si, i, NULL);

 		fprintf(fp, "CPU %d SLAB:\n%s", i, 
 			cpu_slab_ptr ? "" : "  (empty)\n");

-                if (!cpu_slab_ptr)
-                        continue;
+                if (cpu_slab_ptr) {
+                	if ((n = page_to_nid(cpu_slab_ptr)) >= 0)
+				per_cpu[n]++;

-                if ((n = page_to_nid(cpu_slab_ptr)) >= 0)
-			per_cpu[n]++;
+			si->slab = cpu_slab_ptr;
+			do_slab_slub(si, VERBOSE);
+		}

-		si->slab = cpu_slab_ptr;
-		do_slab_slub(si, VERBOSE);
+		if (VALID_MEMBER(kmem_cache_cpu_partial))
+			do_cpu_partial_slub(si, i);

 		if (received_SIGINT())
 			restart(0);
-- 
1.8.3.1

From f47f195e4c5e9d3b0e013f6f68b9f1e9d0cf58fa Mon Sep 17 00:00:00 2001
From: qiaonuohan <qiaonuohan <at> cn.fujitsu.com>
Date: Tue, 22 Jul 2014 05:18:53 -0400
Subject: [PATCH] display slabs in cpu partial list for slub

The following kernel commit adds per cpu partial list.

commit 49e2258586b423684f03c278149ab46d8f8b6700
Author: Christoph Lameter <cl <at> linux.com>
Date:   Tue Aug 9 16:12:27 2011 -0500

    slub: per cpu cache for partial pages

This patch is used for slub. It will display slabs in per cpu partial pages.
---
 defs.h   |  1 +
 memory.c | 51 +++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/defs.h b/defs.h
index 44df6ae..1798d7b 100755
--- a/defs.h
+++ b/defs.h
 <at>  <at>  -1661,6 +1661,7  <at>  <at>  struct offset_table {                    /* stash of commonly-used offsets */
         long kmem_cache_cpu_freelist;
         long kmem_cache_cpu_page;
         long kmem_cache_cpu_node;
+	long kmem_cache_cpu_partial;
 	long kmem_cache_flags;
 	long zone_nr_active;
 	long zone_nr_inactive;
diff --git a/memory.c b/memory.c
index c97dd39..8a16426 100755
--- a/memory.c
+++ b/memory.c
 <at>  <at>  -271,6 +271,7  <at>  <at>  static long count_partial(ulong, struct meminfo *);
 static ulong get_freepointer(struct meminfo *, void *);
 static int count_free_objects(struct meminfo *, ulong);
 char *is_slab_page(struct meminfo *, char *);
+static void do_cpu_partial_slub(struct meminfo *, int);
 static void do_node_lists_slub(struct meminfo *, ulong, int);
 static int devmem_is_restricted(void);
 static int switch_to_proc_kcore(void);
 <at>  <at>  -392,6 +393,8  <at>  <at>  vm_init(void)
 	MEMBER_OFFSET_INIT(page_next, "page", "next");
 	if (VALID_MEMBER(page_next)) 
 		MEMBER_OFFSET_INIT(page_prev, "page", "prev");
+	if (INVALID_MEMBER(page_next))
+		ANON_MEMBER_OFFSET_INIT(page_next, "page", "next");

 	MEMBER_OFFSET_INIT(page_list, "page", "list");
 	if (VALID_MEMBER(page_list)) {
 <at>  <at>  -675,6 +678,7  <at>  <at>  vm_init(void)
 		MEMBER_OFFSET_INIT(kmem_cache_cpu_freelist, "kmem_cache_cpu", "freelist");
 		MEMBER_OFFSET_INIT(kmem_cache_cpu_page, "kmem_cache_cpu", "page");
 		MEMBER_OFFSET_INIT(kmem_cache_cpu_node, "kmem_cache_cpu", "node");
+		MEMBER_OFFSET_INIT(kmem_cache_cpu_partial, "kmem_cache_cpu", "partial");
 		ANON_MEMBER_OFFSET_INIT(page_inuse, "page", "inuse");
 		ANON_MEMBER_OFFSET_INIT(page_offset, "page", "offset");
 		ANON_MEMBER_OFFSET_INIT(page_slab, "page", "slab");
 <at>  <at>  -17324,6 +17328,34  <at>  <at>  bailout:
 	return FALSE;
 }

+static void
+do_cpu_partial_slub(struct meminfo *si, int cpu)
+{
+	ulong cpu_slab_ptr;
+	void *partial;
+
+	cpu_slab_ptr = ULONG(si->cache_buf + OFFSET(kmem_cache_cpu_slab)) +
+				kt->__per_cpu_offset[cpu];
+	readmem(cpu_slab_ptr + OFFSET(kmem_cache_cpu_partial), KVADDR,
+		&partial, sizeof(void *), "kmem_cache_cpu.partial",
+		RETURN_ON_ERROR);
+
+	fprintf(fp, "CPU %d PARTIAL:\n%s", cpu,
+		partial ? "" : "  (empty)\n");
+
+	/*
+	 * kmem_cache_cpu.partial points to the first page of per cpu partial
+	 * list.
+	 */ 
+	while (partial) {
+		si->slab = (ulong)partial;
+		do_slab_slub(si, VERBOSE);
+
+		readmem((ulong)partial + OFFSET(page_next), KVADDR, &partial,
+			sizeof(void *), "page.next", RETURN_ON_ERROR);
+
+	}
+}

 static void
 do_kmem_cache_slub(struct meminfo *si)  
 <at>  <at>  -17337,19 +17369,26  <at>  <at>  do_kmem_cache_slub(struct meminfo *si)
 	per_cpu = (ulong *)GETBUF(sizeof(ulong) * vt->numnodes);

         for (i = 0; i < kt->cpus; i++) {
+		cpu_slab_ptr = ULONG(si->cache_buf + OFFSET(kmem_cache_cpu_slab)) +
+				kt->__per_cpu_offset[i];
+		fprintf(fp, "KMEM_CACHE_CPU    CPU\n%lx%s%3d\n", cpu_slab_ptr,
+			space(VADDR_PRLEN > 8 ? 2 : 10), i);
+
 		cpu_slab_ptr = get_cpu_slab_ptr(si, i, NULL);

 		fprintf(fp, "CPU %d SLAB:\n%s", i, 
 			cpu_slab_ptr ? "" : "  (empty)\n");

-                if (!cpu_slab_ptr)
-                        continue;
+                if (cpu_slab_ptr) {
+                	if ((n = page_to_nid(cpu_slab_ptr)) >= 0)
+				per_cpu[n]++;

-                if ((n = page_to_nid(cpu_slab_ptr)) >= 0)
-			per_cpu[n]++;
+			si->slab = cpu_slab_ptr;
+			do_slab_slub(si, VERBOSE);
+		}

-		si->slab = cpu_slab_ptr;
-		do_slab_slub(si, VERBOSE);
+		if (VALID_MEMBER(kmem_cache_cpu_partial))
+			do_cpu_partial_slub(si, i);

 		if (received_SIGINT())
 			restart(0);
--

-- 
1.8.3.1

Dave Anderson | 17 Jul 18:04 2014
Picon

[PATCH] crash-gcore-command extension module: ARM64 support


Hello Daisuke,

Attached is a patch to introduce support for the ARM64 architecture
for the gcore extension module.   

The patch is fairly straight-forward other than the fact that on
ARM64 machines, the chain of headers included from the crash utility's
"defs.h" looks like this:

  /usr/include/crash/defs.h 
    /usr/include/signal.h 
      /usr/include/sys/ucontext.h 
        /usr/include/sys/procfs.h 

The <sys/procfs.h> file defines several of the ELF-related structures that
are hard-coded in gcore_defs.h, causing compile failures due to duplicate 
structure declarations.

Note that the <sys/ucontext.h> file on the other three architectures does 
not #include <sys/procfs.h> so there are no conflicts.  It would be possible
to move all architectures to include <sys/procfs.h>, but for example, that 
would also bring in the <sys/user.h> definition of the user_regs_struct,
which in turn causes a myriad of register name mismatches in gcore_x86.c.
So for the sake of simplicity, wherever there is an ARM64-only duplicate
structure or definition in gcore_defs.h, I've encapsulated them by:

  #if defined(X86) || defined(X86_64) || defined(ARM)

Also, there are two generic fixes, one where the gcore module fails on
Linux 3.11 and later kernels due to a structure member name change,
and another that changes the getopt() return variable to an "int" instead
of a "char".

Here are the details:

  gcore.mk:

    - Introduce ARM64 as a supported architecture
    - Add libgcore/gcore_arm64 to GCORE_CFILES

  gcore.c:

    - In cmd_gcore() change "c" type to "int" to correctly match
      the return type of getopt(); without it, the while loop
      spins indefinitely on ARM64.
    - In gcore_offset_table_init(), account for the Linux 3.11 
      structure member name-change from ns_proxy.pid_ns to 
      ns_proxy.pid_ns_for_children; without it, the gcore command
      fails during initialization.

  libgcore/gcore_defs.h:

    - Add ARM64 ELF- and REGSET_VIEW-related #defines required for
      each architecture.
    - Account for variable page sizes in ARM64.
    - Restrict the hard-coded ELF_NGREG, elf_siginfo, elf_prstatus, 
      __kernel_old_uid_t and __kernel_old_gid_t, and elf_prsinfo 
      definitions to X86, X86_64 and ARM architectures.
    - Add ARM64 thread_struct_fpsmid_state and thread_struct_tp_value
      offsets to gcore_offset_table.

  libgcore/gcore_coredump.c:

    - In fill_prstatus_note(), account for the ARM64 usage of 
      "user_pt_regs" structure instead of the "user_regs_struct" 
      used by the other architectures.

  libgcore/gcore_arm64.c:

    - Implement ARM64-specific user_regset and user_regset_view
      structures and all required support functions.

Please accept these changes into an new package version.

Thanks,
  Dave
  
Attachment (gcore_arm64.patch): text/x-patch, 12 KiB

Hello Daisuke,

Attached is a patch to introduce support for the ARM64 architecture
for the gcore extension module.   

The patch is fairly straight-forward other than the fact that on
ARM64 machines, the chain of headers included from the crash utility's
"defs.h" looks like this:

  /usr/include/crash/defs.h 
    /usr/include/signal.h 
      /usr/include/sys/ucontext.h 
        /usr/include/sys/procfs.h 

The <sys/procfs.h> file defines several of the ELF-related structures that
are hard-coded in gcore_defs.h, causing compile failures due to duplicate 
structure declarations.

Note that the <sys/ucontext.h> file on the other three architectures does 
not #include <sys/procfs.h> so there are no conflicts.  It would be possible
to move all architectures to include <sys/procfs.h>, but for example, that 
would also bring in the <sys/user.h> definition of the user_regs_struct,
which in turn causes a myriad of register name mismatches in gcore_x86.c.
So for the sake of simplicity, wherever there is an ARM64-only duplicate
structure or definition in gcore_defs.h, I've encapsulated them by:

  #if defined(X86) || defined(X86_64) || defined(ARM)

Also, there are two generic fixes, one where the gcore module fails on
Linux 3.11 and later kernels due to a structure member name change,
and another that changes the getopt() return variable to an "int" instead
of a "char".

Here are the details:

  gcore.mk:

    - Introduce ARM64 as a supported architecture
    - Add libgcore/gcore_arm64 to GCORE_CFILES

  gcore.c:

    - In cmd_gcore() change "c" type to "int" to correctly match
      the return type of getopt(); without it, the while loop
      spins indefinitely on ARM64.
    - In gcore_offset_table_init(), account for the Linux 3.11 
      structure member name-change from ns_proxy.pid_ns to 
      ns_proxy.pid_ns_for_children; without it, the gcore command
      fails during initialization.

  libgcore/gcore_defs.h:

    - Add ARM64 ELF- and REGSET_VIEW-related #defines required for
      each architecture.
    - Account for variable page sizes in ARM64.
    - Restrict the hard-coded ELF_NGREG, elf_siginfo, elf_prstatus, 
      __kernel_old_uid_t and __kernel_old_gid_t, and elf_prsinfo 
      definitions to X86, X86_64 and ARM architectures.
    - Add ARM64 thread_struct_fpsmid_state and thread_struct_tp_value
      offsets to gcore_offset_table.

  libgcore/gcore_coredump.c:

    - In fill_prstatus_note(), account for the ARM64 usage of 
      "user_pt_regs" structure instead of the "user_regs_struct" 
      used by the other architectures.

  libgcore/gcore_arm64.c:

    - Implement ARM64-specific user_regset and user_regset_view
      structures and all required support functions.

Please accept these changes into an new package version.

Thanks,
  Dave
  
Buland Kumar Singh | 9 Jul 21:03 2014
Picon

Negative NR_WRITEBACK counter

Hello Everyone,

I am analysing a kernel crash dump (vmcore) captured from RHEL-5
kernel version (2.6.18-371.4.1.el5) and found that the value of
"NR_WRITEBACK" counter is negative (-126).

$ rpm -q crash
crash-7.0.6-2.el6.x86_64

crash> sys | grep -e RELEASE -e MACHINE -e MEMORY
     RELEASE: 2.6.18-371.4.1.el5
     MACHINE: x86_64  (3000 Mhz)
      MEMORY: 31.5 GB

crash> kmem -z | grep  -e ZONE -e NR_WRITEBACK
NODE: 0  ZONE: 0  ADDR: ffff810000032000  NAME: "DMA"
       NR_WRITEBACK: 0
NODE: 0  ZONE: 1  ADDR: ffff810000032b00  NAME: "DMA32"
       NR_WRITEBACK: 0
NODE: 0  ZONE: 2  ADDR: ffff810000033600  NAME: "Normal"
       NR_WRITEBACK: -126          <<<<
NODE: 0  ZONE: 3  ADDR: ffff810000034100  NAME: "HighMem"

crash> kmem -V | grep -e NR_WRITEBACK
       NR_WRITEBACK: -126          <<<<

crash> vm_stat
vm_stat = $1 =
 {{
    counter = 1106459
  }, {
    counter = 2940354
  }, {
    counter = 6341366
  }, {
    counter = 301750
  }, {
    counter = 245858
  }, {
    counter = 438
  }, {
    counter = -126  // NR_WRITEBACK <<<<
  }, {
    counter = 0
  }, {
    counter = 0
  }, {
    counter = 19687071384
  }, {
    counter = 0
  }, {
    counter = 0
  }, {
    counter = 29247123
  }, {
    counter = 19687071384
  }, {
    counter = 0
  }}

As we're running a 64 bit kernel and the counters are signed long,
so this is very unlikely to be a counter overflow. I need pointers
and suggestions to determine the *cause* of negative counter from
vmcore.

Additional Information:

$ git show ce866b34ae1b7f1ce60234cf65855886ac7e7d30
[..]
diff --git a/drivers/base/node.c b/drivers/base/node.c
index 6fed520..a7b3dcb 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
<at> <at> -49,9 +49,6 <at> <at> static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
        get_page_state_node(&ps, nid);
        __get_zone_counts(&active, &inactive, &free, NODE_DATA(nid));
 
-       /* Check for negative values in these approximate counters */
-       if ((long)ps.nr_writeback < 0)
-               ps.nr_writeback = 0;
 
        n = sprintf(buf, "\n"
                       "Node %d MemTotal:     %8lu kB\n"
[..]

Thank you !

--
BKS
<div><div dir="ltr"><span>Hello Everyone,<br><br>I am analysing a kernel crash dump (vmcore) captured from RHEL-5<br>kernel version (2.6.18-371.4.1.el5) and found that the value of<br>
"NR_WRITEBACK" counter is negative (-126).<br><br>$ rpm -q crash<br>crash-7.0.6-2.el6.x86_64<br><br>crash&gt; sys | grep -e RELEASE -e MACHINE -e MEMORY<br>&nbsp; &nbsp; &nbsp;RELEASE: 2.6.18-371.4.1.el5<br>&nbsp; &nbsp; &nbsp;MACHINE: x86_64 &nbsp;(3000 Mhz)<br>
&nbsp; &nbsp; &nbsp; MEMORY: 31.5 GB<br><br>crash&gt; kmem -z | grep &nbsp;-e ZONE -e NR_WRITEBACK<br>NODE: 0 &nbsp;ZONE: 0 &nbsp;ADDR: ffff810000032000 &nbsp;NAME: "DMA"<br>&nbsp; &nbsp; &nbsp; &nbsp;NR_WRITEBACK: 0<br>NODE: 0 &nbsp;ZONE: 1 &nbsp;ADDR: ffff810000032b00 &nbsp;NAME: "DMA32"<br>
&nbsp; &nbsp; &nbsp; &nbsp;NR_WRITEBACK: 0<br>NODE: 0 &nbsp;ZONE: 2 &nbsp;ADDR: ffff810000033600 &nbsp;NAME: "Normal"<br>&nbsp; &nbsp; &nbsp; &nbsp;NR_WRITEBACK: -126 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;&lt;&lt;&lt;<br>NODE: 0 &nbsp;ZONE: 3 &nbsp;ADDR: ffff810000034100 &nbsp;NAME: "HighMem"<br><br>crash&gt; kmem -V | grep -e NR_WRITEBACK<br>&nbsp; &nbsp; &nbsp; &nbsp;NR_WRITEBACK: -126 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;&lt;&lt;&lt;<br><br>crash&gt; vm_stat<br>vm_stat = $1 =<br>&nbsp;{{<br>&nbsp; &nbsp; counter = 1106459<br>&nbsp; }, {<br>&nbsp; &nbsp; counter = 2940354<br>&nbsp; }, {<br>
&nbsp; &nbsp; counter = 6341366<br>&nbsp; }, {<br>&nbsp; &nbsp; counter = 301750<br>&nbsp; }, {<br>&nbsp; &nbsp; counter = 245858<br>&nbsp; }, {<br>&nbsp; &nbsp; counter = 438<br>&nbsp; }, {<br>&nbsp; &nbsp; counter = -126 &nbsp;// NR_WRITEBACK &lt;&lt;&lt;&lt;<br>&nbsp; }, {<br>&nbsp; &nbsp; counter = 0<br>&nbsp; }, {<br>
&nbsp; &nbsp; counter = 0<br>&nbsp; }, {<br>&nbsp; &nbsp; counter = 19687071384<br>&nbsp; }, {<br>&nbsp; &nbsp; counter = 0<br>&nbsp; }, {<br>&nbsp; &nbsp; counter = 0<br>&nbsp; }, {<br>&nbsp; &nbsp; counter = 29247123<br>&nbsp; }, {<br>&nbsp; &nbsp; counter = 19687071384<br>&nbsp; }, {<br>&nbsp; &nbsp; counter = 0<br>&nbsp; }}<br><br>As we're running a 64 bit kernel and the counters are signed long,<br>so this is very unlikely to be a counter overflow. I need pointers<br>and suggestions to determine the *cause* of negative counter from<br>vmcore.<br><br>Additional Information:<br><br>$ git show ce866b34ae1b7f1ce60234cf65855886ac7e7d30<br>[..]<br>diff --git a/drivers/base/node.c b/drivers/base/node.c<br>index 6fed520..a7b3dcb 100644<br>--- a/drivers/base/node.c<br>+++ b/drivers/base/node.c<br>
 <at>  <at>  -49,9 +49,6  <at>  <at>  static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)<br>&nbsp; &nbsp; &nbsp; &nbsp; get_page_state_node(&amp;ps, nid);<br>&nbsp; &nbsp; &nbsp; &nbsp; __get_zone_counts(&amp;active, &amp;inactive, &amp;free, NODE_DATA(nid));<br>
&nbsp;<br>- &nbsp; &nbsp; &nbsp; /* Check for negative values in these approximate counters */<br>- &nbsp; &nbsp; &nbsp; if ((long)ps.nr_writeback &lt; 0)<br>- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ps.nr_writeback = 0;<br>&nbsp;<br>&nbsp; &nbsp; &nbsp; &nbsp; n = sprintf(buf, "\n"<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;"Node %d MemTotal: &nbsp; &nbsp; %8lu kB\n"<br>
[..]<br><br>Thank you !<span class="sew1hz9tqnvigwn"></span><span class="sew1hz9tqnvigwn"></span><br><br>-- <br>BKS</span></div></div>
Karlsson, Jan | 4 Jul 11:37 2014

Re: crash-utility <at> redhat.com, anderson <at> redhat.com

Hi

I have not seen anything like this before, so I cannot really help you with the problem. You should however be
aware the in this case Crash is built as a 32-bit executable and must be built in that way to work properly. So
you should look for missing 32-bit libraries.

Jan

Jan Karlsson
Senior Software Engineer
System Assurance

Sony Mobile Communications
Tel: +46 703 062 174
jan.karlsson <at> sonymobile.com

sonymobile.com

-----Original Message-----
From: Yu Chen [mailto:chenyu105 <at> gmail.com] 
Sent: den 4 juli 2014 06:40
To: ext-mika.1.westerberg <at> nokia.com; Karlsson, Jan; Fänge, Thomas
Subject: crash-utility <at> redhat.com, anderson <at> redhat.com

Hi all!
I am trying to compile crash-7.0.7  on x86_64 host  for arm.
(x86 binary to analyze ARM dumpfiles)
Here's the failure information:

-bash-4.1$ make target=arm
TARGET: ARM
 CRASH: 7.0.7
   GDB: 7.6
...
checking for gcc... gcc
checking for C compiler default output file name... a.out checking whether the C compiler works... yes
checking whether we are cross compiling... no checking for objcopy... objcopy checking for objdump...
objdump checking for readelf... readelf checking for arm-elf-linux-cc... no checking for
arm-elf-linux-gcc... no checking for arm-elf-linux-c++... no checking for arm-elf-linux-g++... no
checking for arm-elf-linux-cxx... no checking for arm-elf-linux-gxx... no checking for
arm-elf-linux-gcc... no checking for arm-elf-linux-gcj... no

...
checking for library containing waddstr... no
configure: WARNING: no enhanced curses library found; disabling TUI checking for library containing
tgetent... no
configure: error: no termcap library found
make[3]: *** [configure-gdb] Error 1
make[2]: *** [all] Error 2

crash build failed

make[1]: *** [gdb_merge] Error 1
make: *** [all] Error 2

I thought the reason for  above error  message was due to lack of  termcap library. However, the termcap
library could be found on my host machine:

-bash-4.1$ find . -name "*termcap*"
./libtermcap.so.2
./libtermcap.so.2.0.8
-bash-4.1$ pwd
/lib64
-bash-4.1$ uname -a
Linux localhost.localdomain 2.6.32-220.el6.x86_64 #1 SMP Mon Sep 3
07:34:44 EDT 2012 x86_64 x86_64 x86_64 GNU/Linux

After I copyed x86_64 libtermcap.a into /lib64 ,the error message still exist.

I am confused if crash should be cross compiled in this situation?
Or is there any step I  should take before compile crash?

Many  thanks !

--
Crash-utility mailing list
Crash-utility <at> redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility
Dave Anderson | 19 Jun 19:51 2014
Picon

ARM64 support for EPPIC


Hi Luc,

I posted the attached patch as an issue on your code.google.com eppic page.
It allows the eppic.so module to be built, loaded, and run scripts (at least
very simple ones).  I'm presuming that there's no other arch-specific stuff
that needs to be done.

Thanks,
  Dave

qiaonuohan | 13 Jun 13:14 2014

ksm: fix ksm module for RHEL6.5 and later

Hello Dave,

Please check the patch.

-- 
Regards
Qiao Nuohan
From 3d313aaf5d9fedd91e81ac596fe407614dd57de1 Mon Sep 17 00:00:00 2001
From: Qiao Nuohan <qiaonuohan <at> cn.fujitsu.com>
Date: Wed, 11 Jun 2014 10:01:21 +0800
Subject: [PATCH] Fix ksm.c

Because of the following kernel patch, 'root_stable_tree' and 
'struct stable_node' are changed. 

<cut>
ef53d16cded7f89b3843b7a96970dab897843ea5
90bd6fd31c8097ee4ddcb74b7e08363134863de5
4146d2d673e8d6abf9b30a5b5dd8cd95f29632eb
<cut>

Another two change are listed below.

1. add mm_struct's address for the task.
ksm displayed ksm page's messages like below
<cut>
            PAGE: ffffea000451f180
     STABLE_NODE: ffff88004866b6c0
PHYSICAL ADDRESS: 1147c6000
             PID: 1318  MAPPINGS: 7707
             PID: 1297  MAPPINGS: 4965

<cut>

Now, MM item is added to show the mm_struct's address related to task, like
below
<cut>
            PAGE: ffffea000451f180
     STABLE_NODE: ffff88004866b6c0
PHYSICAL ADDRESS: 1147c6000
             PID: 1318  MAPPINGS: 7707  MM: ffff88007f8abe80
             PID: 1297  MAPPINGS: 4965  MM: ffff88007f8aa580

<cut>

2. the task that uses ksm pages may have exited. this patch will change to
show the exited task's "MAPPINGS" and "MM" like below
<cut>
            PAGE: ffffea000292ca40
     STABLE_NODE: ffff88009fe8e9c0
PHYSICAL ADDRESS: a4b29000
             PID: -  MAPPINGS: 1  MM: ffff880115f28000
             PID: -  MAPPINGS: 1  MM: ffff8800cdd7a580
<cut>
task has exited, so PID is "-"

Signed-off-by: Qiao Nuohan <qiaonuohan <at> cn.fujitsu.com>
---
 extensions/ksm.c | 289 ++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 192 insertions(+), 97 deletions(-)

diff --git a/extensions/ksm.c b/extensions/ksm.c
index ce02318..ef97c92 100644
--- a/extensions/ksm.c
+++ b/extensions/ksm.c
 <at>  <at>  -1,6 +1,7  <at>  <at> 
 /*
- * Copyright (C) 2013 FUJITSU LIMITED
+ * Copyright (C) 2013-2014 FUJITSU LIMITED
  * Author: Zhang Yanfei <zhangyanfei <at> cn.fujitsu.com>
+ * Signed-off-by: Qiao Nuohan <qiaonuohan <at> cn.fujitsu.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 <at>  <at>  -22,7 +23,7  <at>  <at>  void cmd_ksm(void);
 char *help_ksm[];

 static struct command_table_entry command_table[] = {
-        { "ksm", cmd_ksm, help_ksm, 0},          
+        { "ksm", cmd_ksm, help_ksm, 0},
         { NULL },
 };

 <at>  <at>  -35,7 +36,8  <at>  <at>  struct ksm_offset_table {
 	long rmap_item_hlist;
 } ksm_offset_table;

-#define KSM_ASSIGN_OFFSET(X)   (ksm_offset_table.X)
+#define KSM_ASSIGN_OFFSET(X) (ksm_offset_table.X)
+#define KSM_INVALID_MEMBER(X) (ksm_offset_table.X == INVALID_OFFSET)
 #define KSM_MEMBER_OFFSET_INIT(X, Y, Z) (KSM_ASSIGN_OFFSET(X) = MEMBER_OFFSET(Y, Z))
 #define KSM_ANON_MEMBER_OFFSET_INIT(X, Y, Z) (KSM_ASSIGN_OFFSET(X) = ANON_MEMBER_OFFSET(Y, Z))
 #define KSM_OFFSET(X)  (OFFSET_verify(ksm_offset_table.X, (char *)__FUNCTION__, __FILE__,
__LINE__, #X))
 <at>  <at>  -50,27 +52,30  <at>  <at>  struct page_ref {
         ulong mm;
         ulong pid;
         int ref;
+	struct page_ref *next;
 };

 static void dump_ksm(struct meminfo *);

 void __attribute__((constructor))
 ksm_init(void) /* Register the command set. */
-{ 
+{
 	if (STRUCT_EXISTS("stable_node")) {
 		KSM_MEMBER_OFFSET_INIT(stable_node_node, "stable_node", "node");
+		if (KSM_INVALID_MEMBER(stable_node_node))
+			KSM_ANON_MEMBER_OFFSET_INIT(stable_node_node, "stable_node", "node");
+
 		KSM_MEMBER_OFFSET_INIT(stable_node_hlist, "stable_node", "hlist");
 		KSM_MEMBER_OFFSET_INIT(stable_node_kpfn, "stable_node", "kpfn");
-		KSM_MEMBER_OFFSET_INIT(stable_node_node, "stable_node", "node");
 		KSM_MEMBER_OFFSET_INIT(rmap_item_mm, "rmap_item", "mm");
 		KSM_MEMBER_OFFSET_INIT(rmap_item_address, "rmap_item", "address");
 		KSM_ANON_MEMBER_OFFSET_INIT(rmap_item_hlist, "rmap_item", "hlist");
 	} else
-		error(FATAL, "ksm_init: stable_node does not exist\n"); 
+		error(FATAL, "ksm_init: stable_node does not exist\n");

        	register_extension(command_table);
 }
- 
+
 void __attribute__((destructor))
 ksm_fini(void) { }

 <at>  <at>  -139,15 +144,17  <at>  <at>  cmd_ksm(void)
 }

 char *help_ksm[] = {
-        "ksm", 
+        "ksm",
         "kernel samepage merging (KSM) information",
-        "[-v] [[-p] address ...]",                   
- 
+        "[-v] [[-p] address ...]",
+
         "  This command displays information about all KSM pages currently",
         "  in use.  For each KSM page, the display includes its stable_node",
-        "  address, its page struct address, its physical address, the TGID/PID", 
-        "  for each task that is using the page, and the number of mappings in",
-        "  the task's address space for the page.",
+        "  address, its page struct address, its physical address, the TGID/PID",
+        "  for each task that is using the page, the number of mappings in the",
+        "  task's address space for the page, and the mm_struct address of the",
+        "  task. If pid is '-', the task has exited and the ksm page has not",
+        "  been removed.",
         " ",
         "       -v  also dump each virtual address in a PID's virtual address",
         "           space that maps the KSM page.",
 <at>  <at>  -159,88 +166,129  <at>  <at>  char *help_ksm[] = {
         "\nEXAMPLE",
         "  Display information about all KSM pages:\n",
         "    %s> ksm",
-//      "    STABLE_NODE     : ffff8806248c2d80",
-//      "    PAGE            : ffffea000ae7f6a8",
-//      "    PHYSICAL ADDRESS: 31db43000",
-        "                PAGE: ffffea000ae7f6a8",
-        "         STABLE_NODE: ffff8806248c2d80",
-        "    PHYSICAL ADDRESS: 31db43000",
-        "                 PID: 2205  MAPPINGS: 2",
+        "                PAGE: ffffea000451f180",
+        "         STABLE_NODE: ffff88004866b6c0",
+        "    PHYSICAL ADDRESS: 1147c6000",
+        "                 PID: 1318  MAPPINGS: 7707  MM: ffff88007f8abe80",
+        "                 PID: 1297  MAPPINGS: 4965  MM: ffff88007f8aa580",
         "",
-//      "    STABLE_NODE     : ffff880624aa57b8",
-//      "    PAGE            : ffffea000ae800f0",
-//      "    PHYSICAL ADDRESS: 31db72000",
-        "                PAGE: ffffea000ae800f0",
-        "         STABLE_NODE: ffff880624aa57b8",
-        "    PHYSICAL ADDRESS: 31db72000",
-        "                 PID: 2205  MAPPINGS: 2",
+        "                PAGE: ffffea0003413c40",
+        "         STABLE_NODE: ffff880117bfbfc0",
+        "    PHYSICAL ADDRESS: d04f1000",
+        "                 PID: 1297  MAPPINGS: 1  MM: ffff88007f8aa580",
+        "                 PID: 1318  MAPPINGS: 1  MM: ffff88007f8abe80",
         "",
-//      "    STABLE_NODE     : ffff8806248c2dd0",
-//      "    PAGE            : ffffea000ae7f8d8",
-//      "    PHYSICAL ADDRESS: 31db4d000",
-        "                PAGE: ffffea000ae7f8d8",
-        "         STABLE_NODE: ffff8806248c2dd0",
-        "    PHYSICAL ADDRESS: 31db4d000",
-        "                 PID: 2205  MAPPINGS: 2",
+        "                PAGE: ffffea00021e9880",
+        "         STABLE_NODE: ffff880054ee1f30",
+        "    PHYSICAL ADDRESS: 87a62000",
+        "                 PID: 1297  MAPPINGS: 2  MM: ffff88007f8aa580",
         "    ...",
         "",
         "  Display all information about the KSM page whose physical",
-        "  address is 0x626e60000:\n",
-        "    %s> ksm -v 626e60000",
-        "                PAGE: ffffea0015882500",
-        "         STABLE_NODE: ffff88028b2af3d0",
-        "    PHYSICAL ADDRESS: 626e60000",
-        "                 PID: 2603  MAPPINGS: 8",
+        "  address is 0xffffea000168cd00:\n",
+        "    %s> ksm -v ffffea000168cd00",
+        "                PAGE: ffffea000168cd00",
+        "         STABLE_NODE: ffff88007153ce10",
+        "    PHYSICAL ADDRESS: 5a334000",
+        "                 PID: 1297  MAPPINGS: 4  MM: ffff88007f8aa580",
         "                 VIRTUAL:",
-        "                 7ff46bcb4000",
-        "                 7ff46bcad000",
-        "                 7ff46bc9f000",
-        "                 7ff46bc7c000",
-        "                 7ff46bc6e000",
-        "                 7ff46bc67000",
-        "                 7ff46bc60000",
-        "                 7ff46bc59000",
+        "                 7f8cb91f9000",
+        "                 7f8cb8f28000",
+        "                 7f8cb7abf000",
+        "                 7f8cb79c7000",
+        "",
+        "                 PID: 1318  MAPPINGS: 4  MM: ffff88007f8abe80",
+        "                 VIRTUAL:",
+        "                 7f7ca0703000",
+        "                 7f7c9f15e000",
+        "                 7f7c9ef8f000",
+        "                 7f7c9e96b000",
         NULL
 };

+/*
+ * find the page_ref whose mm is same as mm
+ */
+static struct page_ref *
+find_match_ref(struct page_ref *ref_list, ulong mm)
+{
+	struct page_ref *next_ref = ref_list;
+
+	while (next_ref) {
+		if (next_ref->mm == mm) {
+			break;
+		} else {
+			next_ref = next_ref->next;
+		}
+	}
+
+	return next_ref;
+}

 /*
- * dump_ksm() displays information of ksm pages.
+ * get the pid of the task that mm_struct belongs to, if not find,
+ * return (ulong)-1
  */
+static ulong
+find_pid(ulong mm)
+{
+	struct task_context *tc;
+	int i;
+	ulong pid = -1;
+
+	tc = FIRST_CONTEXT();
+	for (i = 0; i < RUNNING_TASKS(); i++, tc++) {
+		if (tc->mm_struct == mm) {
+			pid = tc->pid;
+			break;
+		}
+	}
+
+	return pid;
+}
+
 static void
-dump_ksm(struct meminfo *mi)
+add_to_ref_list(struct page_ref **ref_list_ptr, struct page_ref *ref)
 {
-	ulong root_stable_tree, stable_node, kpfn;
+	ref->next = *ref_list_ptr;
+	*ref_list_ptr = ref;
+}
+
+static void
+clean_ref_list(struct page_ref *ref_list)
+{
+	struct page_ref *tmp_ref, *next_ref;
+
+	tmp_ref = ref_list;
+
+	while (tmp_ref) {
+		next_ref = tmp_ref->next;
+		FREEBUF(tmp_ref);
+		tmp_ref = next_ref;
+	}
+}
+
+/*
+ * dump the ksm pages from the stable tree
+ */
+static void
+dump_stable_tree(struct meminfo *mi, struct rb_root *root)
+{
+	ulong stable_node, kpfn;
 	ulong rmap_item, mm, paddr;
-	struct rb_root *root;
 	struct rb_node *node;
 	ulong first, next;
-	struct task_context *tc;
-	int i, ref_size, refs, found;
-	struct page_ref *ref;
+	int found;
+	struct page_ref *ref_list;
 	ulong page, address;

-	if (!symbol_exists("root_stable_tree")) {
-		error(INFO, "cannot determine ksm stable tree address from root_stable_tree\n");
-		return;
-	}
-	root_stable_tree = symbol_value("root_stable_tree");
-	root = (struct rb_root *)root_stable_tree;
-
-	refs = 0;
-	ref_size = sizeof(struct page_ref) * RUNNING_TASKS();
-	ref = (struct page_ref *)GETBUF(ref_size);
-	BZERO(ref, ref_size);
-
 	found = (mi && mi->flags & ADDRESS_SPECIFIED) ? 0 : -1;
+
 	for (node = rb_first(root); node; node = rb_next(node)) {
 		stable_node = (ulong) node - KSM_OFFSET(stable_node_node);
 		if (CRASHDEBUG(1))
 			fprintf(fp, "  stable_node = %lx\n", stable_node);

-		readmem(stable_node + KSM_OFFSET(stable_node_hlist),
-			KVADDR, &first, sizeof(ulong),
-			"stable_node hlist", FAULT_ON_ERROR);
 		readmem(stable_node + KSM_OFFSET(stable_node_kpfn),
 			KVADDR, &kpfn, sizeof(ulong),
 			"stable_node kpfn", FAULT_ON_ERROR);
 <at>  <at>  -259,10 +307,6  <at>  <at>  dump_ksm(struct meminfo *mi)
 		if (found == 0)
 			continue;

-//		fprintf(fp, "STABLE_NODE     : %lx\n", stable_node);
-//		fprintf(fp, "PAGE            : %lx\n", page);
-//		fprintf(fp, "PHYSICAL ADDRESS: %lx\n\n", paddr);
-
 		fprintf(fp, "            PAGE: %lx\n", page);
 		fprintf(fp, "     STABLE_NODE: %lx\n", stable_node);
 		fprintf(fp, "PHYSICAL ADDRESS: %lx\n", paddr);
 <at>  <at>  -272,41 +316,51  <at>  <at>  dump_ksm(struct meminfo *mi)
 			"stable_node hlist", FAULT_ON_ERROR);

 		next = first;
+		ref_list = NULL;
+		struct page_ref *tmp_ref = NULL;
+
 		while (next) {
 			rmap_item = next - KSM_OFFSET(rmap_item_hlist);
 			readmem(rmap_item + KSM_OFFSET(rmap_item_mm),
 				KVADDR, &mm, sizeof(ulong),
 				"rmap_item mm", FAULT_ON_ERROR);

-			for (i = 0; i < refs; i++) {
-				if (ref[i].mm == mm) {
-					ref[i].ref += 1;
-					goto next;
-				}
-			}
-
-			tc = FIRST_CONTEXT();
-			for (i = 0; i < RUNNING_TASKS(); i++, tc++) {
-				if (tc->mm_struct == mm) {
-					ref[refs].mm = mm;
-					ref[refs].pid = tc->pid;
-					ref[refs++].ref = 1;
-					break;
-				}
+			//get the page_ref whose mm is equal to rmap_item's mm
+			tmp_ref = find_match_ref(ref_list, mm);
+			if (tmp_ref) {
+				tmp_ref->ref += 1;
+			} else {
+				//create a new page_ref
+				tmp_ref = (struct page_ref *)GETBUF(
+						sizeof(struct page_ref));
+				tmp_ref->mm = mm;
+				tmp_ref->pid = find_pid(mm);
+				tmp_ref->ref = 1;
+
+				add_to_ref_list(&ref_list, tmp_ref);
 			}

-next:
 			readmem(next + OFFSET(hlist_node_next),
 				KVADDR, &next, sizeof(ulong),
 				"hlist_node next", FAULT_ON_ERROR);
 		};

-		for (i = 0; i < refs; i++) {
-			fprintf(fp, "             PID: %ld ", ref[i].pid);
-			fprintf(fp, " MAPPINGS: %d\n", ref[i].ref);
+		tmp_ref = ref_list;
+		while (tmp_ref) {
+			if (tmp_ref->pid == (ulong)-1) {
+				/*
+				 * the task has exited, but the ksm pages has
+				 * not been cleared yet.
+				 */
+				fprintf(fp, "             PID: - ");
+			} else {
+				fprintf(fp, "             PID: %ld ", tmp_ref->pid);
+			}
+			fprintf(fp, " MAPPINGS: %d ", tmp_ref->ref);
+			fprintf(fp, " MM: %lx\n", tmp_ref->mm);

 			if (!(mi && mi->flags & VERBOSE))
-				continue;
+				goto next_ref;

 			fprintf(fp, "             VIRTUAL:\n");
 			next = first;
 <at>  <at>  -315,7 +369,7  <at>  <at>  next:
 				readmem(rmap_item + KSM_OFFSET(rmap_item_mm),
 					KVADDR, &mm, sizeof(ulong),
 					"rmap_item mm", FAULT_ON_ERROR);
-				if (ref[i].mm == mm) {
+				if (tmp_ref->mm == mm) {
 					readmem(rmap_item + KSM_OFFSET(rmap_item_address),
 						KVADDR, &address, sizeof(ulong),
 						"rmap_item address", FAULT_ON_ERROR);
 <at>  <at>  -327,10 +381,16  <at>  <at>  next:
 					"hlist_node next", FAULT_ON_ERROR);
 			}
 			fprintf(fp, "\n");
+
+next_ref:
+			tmp_ref = tmp_ref->next;
 		}
+
+		//clear all page_ref
+		clean_ref_list(ref_list);
+
 		if (!(mi && mi->flags & VERBOSE))
 			fprintf(fp, "\n");
-		refs = 0;

 		if (found == 1)
 			break;
 <at>  <at>  -339,6 +399,41  <at>  <at>  next:
 	if (found == 0)
 		fprintf(fp, "address 0x%llx cannot specify a ksm stable tree node\n",
 			mi->spec_addr);
+}

-	FREEBUF(ref);
+/*
+ * dump_ksm() displays information of ksm pages.
+ */
+static void
+dump_ksm(struct meminfo *mi)
+{
+	ulong root_stable_tree_ptr;
+	ulong ksm_nr_node_ids_ptr;
+	int ksm_nr_node_ids;
+	struct rb_root *root;
+	int i;
+
+	if (!symbol_exists("root_stable_tree")) {
+		error(INFO, "cannot determine ksm stable tree address from root_stable_tree\n");
+		return;
+	}
+	root_stable_tree_ptr = symbol_value("root_stable_tree");
+
+	if (symbol_exists("ksm_nr_node_ids")) {
+		//root_stable_tree_ptr is an array of stable tree root
+		ksm_nr_node_ids_ptr = symbol_value("ksm_nr_node_ids");
+		readmem(ksm_nr_node_ids_ptr, KVADDR, &ksm_nr_node_ids,
+			sizeof(ksm_nr_node_ids), "ksm_nr_node_ids",
+			FAULT_ON_ERROR);
+
+		readmem(root_stable_tree_ptr, KVADDR, &root, sizeof(ulong),
+			"first stable tree root", FAULT_ON_ERROR);
+		
+		for (i = 0; i < ksm_nr_node_ids; i++) {
+			dump_stable_tree(mi, root + i);
+		}
+	} else {
+		root = (struct rb_root *)root_stable_tree_ptr;
+		dump_stable_tree(mi, root);
+	}
 }
-- 
1.8.5.3

From 3d313aaf5d9fedd91e81ac596fe407614dd57de1 Mon Sep 17 00:00:00 2001
From: Qiao Nuohan <qiaonuohan <at> cn.fujitsu.com>
Date: Wed, 11 Jun 2014 10:01:21 +0800
Subject: [PATCH] Fix ksm.c

Because of the following kernel patch, 'root_stable_tree' and 
'struct stable_node' are changed. 

<cut>
ef53d16cded7f89b3843b7a96970dab897843ea5
90bd6fd31c8097ee4ddcb74b7e08363134863de5
4146d2d673e8d6abf9b30a5b5dd8cd95f29632eb
<cut>

Another two change are listed below.

1. add mm_struct's address for the task.
ksm displayed ksm page's messages like below
<cut>
            PAGE: ffffea000451f180
     STABLE_NODE: ffff88004866b6c0
PHYSICAL ADDRESS: 1147c6000
             PID: 1318  MAPPINGS: 7707
             PID: 1297  MAPPINGS: 4965

<cut>

Now, MM item is added to show the mm_struct's address related to task, like
below
<cut>
            PAGE: ffffea000451f180
     STABLE_NODE: ffff88004866b6c0
PHYSICAL ADDRESS: 1147c6000
             PID: 1318  MAPPINGS: 7707  MM: ffff88007f8abe80
             PID: 1297  MAPPINGS: 4965  MM: ffff88007f8aa580

<cut>

2. the task that uses ksm pages may have exited. this patch will change to
show the exited task's "MAPPINGS" and "MM" like below
<cut>
            PAGE: ffffea000292ca40
     STABLE_NODE: ffff88009fe8e9c0
PHYSICAL ADDRESS: a4b29000
             PID: -  MAPPINGS: 1  MM: ffff880115f28000
             PID: -  MAPPINGS: 1  MM: ffff8800cdd7a580
<cut>
task has exited, so PID is "-"

Signed-off-by: Qiao Nuohan <qiaonuohan <at> cn.fujitsu.com>
---
 extensions/ksm.c | 289 ++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 192 insertions(+), 97 deletions(-)

diff --git a/extensions/ksm.c b/extensions/ksm.c
index ce02318..ef97c92 100644
--- a/extensions/ksm.c
+++ b/extensions/ksm.c
 <at>  <at>  -1,6 +1,7  <at>  <at> 
 /*
- * Copyright (C) 2013 FUJITSU LIMITED
+ * Copyright (C) 2013-2014 FUJITSU LIMITED
  * Author: Zhang Yanfei <zhangyanfei <at> cn.fujitsu.com>
+ * Signed-off-by: Qiao Nuohan <qiaonuohan <at> cn.fujitsu.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 <at>  <at>  -22,7 +23,7  <at>  <at>  void cmd_ksm(void);
 char *help_ksm[];

 static struct command_table_entry command_table[] = {
-        { "ksm", cmd_ksm, help_ksm, 0},          
+        { "ksm", cmd_ksm, help_ksm, 0},
         { NULL },
 };

 <at>  <at>  -35,7 +36,8  <at>  <at>  struct ksm_offset_table {
 	long rmap_item_hlist;
 } ksm_offset_table;

-#define KSM_ASSIGN_OFFSET(X)   (ksm_offset_table.X)
+#define KSM_ASSIGN_OFFSET(X) (ksm_offset_table.X)
+#define KSM_INVALID_MEMBER(X) (ksm_offset_table.X == INVALID_OFFSET)
 #define KSM_MEMBER_OFFSET_INIT(X, Y, Z) (KSM_ASSIGN_OFFSET(X) = MEMBER_OFFSET(Y, Z))
 #define KSM_ANON_MEMBER_OFFSET_INIT(X, Y, Z) (KSM_ASSIGN_OFFSET(X) = ANON_MEMBER_OFFSET(Y, Z))
 #define KSM_OFFSET(X)  (OFFSET_verify(ksm_offset_table.X, (char *)__FUNCTION__, __FILE__,
__LINE__, #X))
 <at>  <at>  -50,27 +52,30  <at>  <at>  struct page_ref {
         ulong mm;
         ulong pid;
         int ref;
+	struct page_ref *next;
 };

 static void dump_ksm(struct meminfo *);

 void __attribute__((constructor))
 ksm_init(void) /* Register the command set. */
-{ 
+{
 	if (STRUCT_EXISTS("stable_node")) {
 		KSM_MEMBER_OFFSET_INIT(stable_node_node, "stable_node", "node");
+		if (KSM_INVALID_MEMBER(stable_node_node))
+			KSM_ANON_MEMBER_OFFSET_INIT(stable_node_node, "stable_node", "node");
+
 		KSM_MEMBER_OFFSET_INIT(stable_node_hlist, "stable_node", "hlist");
 		KSM_MEMBER_OFFSET_INIT(stable_node_kpfn, "stable_node", "kpfn");
-		KSM_MEMBER_OFFSET_INIT(stable_node_node, "stable_node", "node");
 		KSM_MEMBER_OFFSET_INIT(rmap_item_mm, "rmap_item", "mm");
 		KSM_MEMBER_OFFSET_INIT(rmap_item_address, "rmap_item", "address");
 		KSM_ANON_MEMBER_OFFSET_INIT(rmap_item_hlist, "rmap_item", "hlist");
 	} else
-		error(FATAL, "ksm_init: stable_node does not exist\n"); 
+		error(FATAL, "ksm_init: stable_node does not exist\n");

        	register_extension(command_table);
 }
- 
+
 void __attribute__((destructor))
 ksm_fini(void) { }

 <at>  <at>  -139,15 +144,17  <at>  <at>  cmd_ksm(void)
 }

 char *help_ksm[] = {
-        "ksm", 
+        "ksm",
         "kernel samepage merging (KSM) information",
-        "[-v] [[-p] address ...]",                   
- 
+        "[-v] [[-p] address ...]",
+
         "  This command displays information about all KSM pages currently",
         "  in use.  For each KSM page, the display includes its stable_node",
-        "  address, its page struct address, its physical address, the TGID/PID", 
-        "  for each task that is using the page, and the number of mappings in",
-        "  the task's address space for the page.",
+        "  address, its page struct address, its physical address, the TGID/PID",
+        "  for each task that is using the page, the number of mappings in the",
+        "  task's address space for the page, and the mm_struct address of the",
+        "  task. If pid is '-', the task has exited and the ksm page has not",
+        "  been removed.",
         " ",
         "       -v  also dump each virtual address in a PID's virtual address",
         "           space that maps the KSM page.",
 <at>  <at>  -159,88 +166,129  <at>  <at>  char *help_ksm[] = {
         "\nEXAMPLE",
         "  Display information about all KSM pages:\n",
         "    %s> ksm",
-//      "    STABLE_NODE     : ffff8806248c2d80",
-//      "    PAGE            : ffffea000ae7f6a8",
-//      "    PHYSICAL ADDRESS: 31db43000",
-        "                PAGE: ffffea000ae7f6a8",
-        "         STABLE_NODE: ffff8806248c2d80",
-        "    PHYSICAL ADDRESS: 31db43000",
-        "                 PID: 2205  MAPPINGS: 2",
+        "                PAGE: ffffea000451f180",
+        "         STABLE_NODE: ffff88004866b6c0",
+        "    PHYSICAL ADDRESS: 1147c6000",
+        "                 PID: 1318  MAPPINGS: 7707  MM: ffff88007f8abe80",
+        "                 PID: 1297  MAPPINGS: 4965  MM: ffff88007f8aa580",
         "",
-//      "    STABLE_NODE     : ffff880624aa57b8",
-//      "    PAGE            : ffffea000ae800f0",
-//      "    PHYSICAL ADDRESS: 31db72000",
-        "                PAGE: ffffea000ae800f0",
-        "         STABLE_NODE: ffff880624aa57b8",
-        "    PHYSICAL ADDRESS: 31db72000",
-        "                 PID: 2205  MAPPINGS: 2",
+        "                PAGE: ffffea0003413c40",
+        "         STABLE_NODE: ffff880117bfbfc0",
+        "    PHYSICAL ADDRESS: d04f1000",
+        "                 PID: 1297  MAPPINGS: 1  MM: ffff88007f8aa580",
+        "                 PID: 1318  MAPPINGS: 1  MM: ffff88007f8abe80",
         "",
-//      "    STABLE_NODE     : ffff8806248c2dd0",
-//      "    PAGE            : ffffea000ae7f8d8",
-//      "    PHYSICAL ADDRESS: 31db4d000",
-        "                PAGE: ffffea000ae7f8d8",
-        "         STABLE_NODE: ffff8806248c2dd0",
-        "    PHYSICAL ADDRESS: 31db4d000",
-        "                 PID: 2205  MAPPINGS: 2",
+        "                PAGE: ffffea00021e9880",
+        "         STABLE_NODE: ffff880054ee1f30",
+        "    PHYSICAL ADDRESS: 87a62000",
+        "                 PID: 1297  MAPPINGS: 2  MM: ffff88007f8aa580",
         "    ...",
         "",
         "  Display all information about the KSM page whose physical",
-        "  address is 0x626e60000:\n",
-        "    %s> ksm -v 626e60000",
-        "                PAGE: ffffea0015882500",
-        "         STABLE_NODE: ffff88028b2af3d0",
-        "    PHYSICAL ADDRESS: 626e60000",
-        "                 PID: 2603  MAPPINGS: 8",
+        "  address is 0xffffea000168cd00:\n",
+        "    %s> ksm -v ffffea000168cd00",
+        "                PAGE: ffffea000168cd00",
+        "         STABLE_NODE: ffff88007153ce10",
+        "    PHYSICAL ADDRESS: 5a334000",
+        "                 PID: 1297  MAPPINGS: 4  MM: ffff88007f8aa580",
         "                 VIRTUAL:",
-        "                 7ff46bcb4000",
-        "                 7ff46bcad000",
-        "                 7ff46bc9f000",
-        "                 7ff46bc7c000",
-        "                 7ff46bc6e000",
-        "                 7ff46bc67000",
-        "                 7ff46bc60000",
-        "                 7ff46bc59000",
+        "                 7f8cb91f9000",
+        "                 7f8cb8f28000",
+        "                 7f8cb7abf000",
+        "                 7f8cb79c7000",
+        "",
+        "                 PID: 1318  MAPPINGS: 4  MM: ffff88007f8abe80",
+        "                 VIRTUAL:",
+        "                 7f7ca0703000",
+        "                 7f7c9f15e000",
+        "                 7f7c9ef8f000",
+        "                 7f7c9e96b000",
         NULL
 };

+/*
+ * find the page_ref whose mm is same as mm
+ */
+static struct page_ref *
+find_match_ref(struct page_ref *ref_list, ulong mm)
+{
+	struct page_ref *next_ref = ref_list;
+
+	while (next_ref) {
+		if (next_ref->mm == mm) {
+			break;
+		} else {
+			next_ref = next_ref->next;
+		}
+	}
+
+	return next_ref;
+}

 /*
- * dump_ksm() displays information of ksm pages.
+ * get the pid of the task that mm_struct belongs to, if not find,
+ * return (ulong)-1
  */
+static ulong
+find_pid(ulong mm)
+{
+	struct task_context *tc;
+	int i;
+	ulong pid = -1;
+
+	tc = FIRST_CONTEXT();
+	for (i = 0; i < RUNNING_TASKS(); i++, tc++) {
+		if (tc->mm_struct == mm) {
+			pid = tc->pid;
+			break;
+		}
+	}
+
+	return pid;
+}
+
 static void
-dump_ksm(struct meminfo *mi)
+add_to_ref_list(struct page_ref **ref_list_ptr, struct page_ref *ref)
 {
-	ulong root_stable_tree, stable_node, kpfn;
+	ref->next = *ref_list_ptr;
+	*ref_list_ptr = ref;
+}
+
+static void
+clean_ref_list(struct page_ref *ref_list)
+{
+	struct page_ref *tmp_ref, *next_ref;
+
+	tmp_ref = ref_list;
+
+	while (tmp_ref) {
+		next_ref = tmp_ref->next;
+		FREEBUF(tmp_ref);
+		tmp_ref = next_ref;
+	}
+}
+
+/*
+ * dump the ksm pages from the stable tree
+ */
+static void
+dump_stable_tree(struct meminfo *mi, struct rb_root *root)
+{
+	ulong stable_node, kpfn;
 	ulong rmap_item, mm, paddr;
-	struct rb_root *root;
 	struct rb_node *node;
 	ulong first, next;
-	struct task_context *tc;
-	int i, ref_size, refs, found;
-	struct page_ref *ref;
+	int found;
+	struct page_ref *ref_list;
 	ulong page, address;

-	if (!symbol_exists("root_stable_tree")) {
-		error(INFO, "cannot determine ksm stable tree address from root_stable_tree\n");
-		return;
-	}
-	root_stable_tree = symbol_value("root_stable_tree");
-	root = (struct rb_root *)root_stable_tree;
-
-	refs = 0;
-	ref_size = sizeof(struct page_ref) * RUNNING_TASKS();
-	ref = (struct page_ref *)GETBUF(ref_size);
-	BZERO(ref, ref_size);
-
 	found = (mi && mi->flags & ADDRESS_SPECIFIED) ? 0 : -1;
+
 	for (node = rb_first(root); node; node = rb_next(node)) {
 		stable_node = (ulong) node - KSM_OFFSET(stable_node_node);
 		if (CRASHDEBUG(1))
 			fprintf(fp, "  stable_node = %lx\n", stable_node);

-		readmem(stable_node + KSM_OFFSET(stable_node_hlist),
-			KVADDR, &first, sizeof(ulong),
-			"stable_node hlist", FAULT_ON_ERROR);
 		readmem(stable_node + KSM_OFFSET(stable_node_kpfn),
 			KVADDR, &kpfn, sizeof(ulong),
 			"stable_node kpfn", FAULT_ON_ERROR);
 <at>  <at>  -259,10 +307,6  <at>  <at>  dump_ksm(struct meminfo *mi)
 		if (found == 0)
 			continue;

-//		fprintf(fp, "STABLE_NODE     : %lx\n", stable_node);
-//		fprintf(fp, "PAGE            : %lx\n", page);
-//		fprintf(fp, "PHYSICAL ADDRESS: %lx\n\n", paddr);
-
 		fprintf(fp, "            PAGE: %lx\n", page);
 		fprintf(fp, "     STABLE_NODE: %lx\n", stable_node);
 		fprintf(fp, "PHYSICAL ADDRESS: %lx\n", paddr);
 <at>  <at>  -272,41 +316,51  <at>  <at>  dump_ksm(struct meminfo *mi)
 			"stable_node hlist", FAULT_ON_ERROR);

 		next = first;
+		ref_list = NULL;
+		struct page_ref *tmp_ref = NULL;
+
 		while (next) {
 			rmap_item = next - KSM_OFFSET(rmap_item_hlist);
 			readmem(rmap_item + KSM_OFFSET(rmap_item_mm),
 				KVADDR, &mm, sizeof(ulong),
 				"rmap_item mm", FAULT_ON_ERROR);

-			for (i = 0; i < refs; i++) {
-				if (ref[i].mm == mm) {
-					ref[i].ref += 1;
-					goto next;
-				}
-			}
-
-			tc = FIRST_CONTEXT();
-			for (i = 0; i < RUNNING_TASKS(); i++, tc++) {
-				if (tc->mm_struct == mm) {
-					ref[refs].mm = mm;
-					ref[refs].pid = tc->pid;
-					ref[refs++].ref = 1;
-					break;
-				}
+			//get the page_ref whose mm is equal to rmap_item's mm
+			tmp_ref = find_match_ref(ref_list, mm);
+			if (tmp_ref) {
+				tmp_ref->ref += 1;
+			} else {
+				//create a new page_ref
+				tmp_ref = (struct page_ref *)GETBUF(
+						sizeof(struct page_ref));
+				tmp_ref->mm = mm;
+				tmp_ref->pid = find_pid(mm);
+				tmp_ref->ref = 1;
+
+				add_to_ref_list(&ref_list, tmp_ref);
 			}

-next:
 			readmem(next + OFFSET(hlist_node_next),
 				KVADDR, &next, sizeof(ulong),
 				"hlist_node next", FAULT_ON_ERROR);
 		};

-		for (i = 0; i < refs; i++) {
-			fprintf(fp, "             PID: %ld ", ref[i].pid);
-			fprintf(fp, " MAPPINGS: %d\n", ref[i].ref);
+		tmp_ref = ref_list;
+		while (tmp_ref) {
+			if (tmp_ref->pid == (ulong)-1) {
+				/*
+				 * the task has exited, but the ksm pages has
+				 * not been cleared yet.
+				 */
+				fprintf(fp, "             PID: - ");
+			} else {
+				fprintf(fp, "             PID: %ld ", tmp_ref->pid);
+			}
+			fprintf(fp, " MAPPINGS: %d ", tmp_ref->ref);
+			fprintf(fp, " MM: %lx\n", tmp_ref->mm);

 			if (!(mi && mi->flags & VERBOSE))
-				continue;
+				goto next_ref;

 			fprintf(fp, "             VIRTUAL:\n");
 			next = first;
 <at>  <at>  -315,7 +369,7  <at>  <at>  next:
 				readmem(rmap_item + KSM_OFFSET(rmap_item_mm),
 					KVADDR, &mm, sizeof(ulong),
 					"rmap_item mm", FAULT_ON_ERROR);
-				if (ref[i].mm == mm) {
+				if (tmp_ref->mm == mm) {
 					readmem(rmap_item + KSM_OFFSET(rmap_item_address),
 						KVADDR, &address, sizeof(ulong),
 						"rmap_item address", FAULT_ON_ERROR);
 <at>  <at>  -327,10 +381,16  <at>  <at>  next:
 					"hlist_node next", FAULT_ON_ERROR);
 			}
 			fprintf(fp, "\n");
+
+next_ref:
+			tmp_ref = tmp_ref->next;
 		}
+
+		//clear all page_ref
+		clean_ref_list(ref_list);
+
 		if (!(mi && mi->flags & VERBOSE))
 			fprintf(fp, "\n");
-		refs = 0;

 		if (found == 1)
 			break;
 <at>  <at>  -339,6 +399,41  <at>  <at>  next:
 	if (found == 0)
 		fprintf(fp, "address 0x%llx cannot specify a ksm stable tree node\n",
 			mi->spec_addr);
+}

-	FREEBUF(ref);
+/*
+ * dump_ksm() displays information of ksm pages.
+ */
+static void
+dump_ksm(struct meminfo *mi)
+{
+	ulong root_stable_tree_ptr;
+	ulong ksm_nr_node_ids_ptr;
+	int ksm_nr_node_ids;
+	struct rb_root *root;
+	int i;
+
+	if (!symbol_exists("root_stable_tree")) {
+		error(INFO, "cannot determine ksm stable tree address from root_stable_tree\n");
+		return;
+	}
+	root_stable_tree_ptr = symbol_value("root_stable_tree");
+
+	if (symbol_exists("ksm_nr_node_ids")) {
+		//root_stable_tree_ptr is an array of stable tree root
+		ksm_nr_node_ids_ptr = symbol_value("ksm_nr_node_ids");
+		readmem(ksm_nr_node_ids_ptr, KVADDR, &ksm_nr_node_ids,
+			sizeof(ksm_nr_node_ids), "ksm_nr_node_ids",
+			FAULT_ON_ERROR);
+
+		readmem(root_stable_tree_ptr, KVADDR, &root, sizeof(ulong),
+			"first stable tree root", FAULT_ON_ERROR);
+		
+		for (i = 0; i < ksm_nr_node_ids; i++) {
+			dump_stable_tree(mi, root + i);
+		}
+	} else {
+		root = (struct rb_root *)root_stable_tree_ptr;
+		dump_stable_tree(mi, root);
+	}
 }
--

-- 
1.8.5.3

David Mair | 13 Jun 07:07 2014

[PATCH] Fix for some command-line cases an unintended unlink of a file crash didn't create and a leftover temporary

When the crash command line includes two filenames where one is a
compressed kernel and the other is a debuginfo file and they appear in
that order then if the uncompressed temporary version of the kernel is
actually larger than the debuginfo then crash will end with an error but
will also unlink the debuginfo file and will not clean up the (intended
temporary) uncompressed copy of the kernel.

This patch at least fixes the unintended unlink and leaving the
temporary present. It doesn't fix the failure to start but that's
because the wrong files are assumed the debuginfo and kernel. The size
case that led to this discovery is probably rare.

The cause is that evidence of a temporary file to unlink is that there
is a value in pc->namelist and pc->namelist_orig (or pc->namelist_debug
and pc->namelist_orig_debug) but when the file size test in
select_namelist() results in the pc->namelist copy to pc->namelist_debug
the _orig is not copied as well so the implied file to unlink is the one
set in pc->namelist (the debuginfo filename now).

The patch causes a populated namelist_orig value to be swapped with
namelist_debug_orig if the namelist value is copied to namelist_debug.

    Signed-off-by: David Mair <dmair <at> suse.com>
---
 symbols.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/symbols.c b/symbols.c
index 4c6fbf4..e1ed719 100644
--- a/symbols.c
+++ b/symbols.c
 <at>  <at>  -3520,6 +3520,7  <at>  <at>  int
 select_namelist(char *new)
 {
        struct stat stat1, stat2;
+       char *namecp;

        if (pc->server_namelist) {
                pc->namelist_debug = new;
 <at>  <at>  -3533,6 +3534,12  <at>  <at>  select_namelist(char *new)

        if (stat1.st_size > stat2.st_size) {
                pc->namelist_debug = pc->namelist;
+               if (pc->namelist_orig)
+               {
+                       namecp = pc->namelist_debug_orig;
+                       pc->namelist_debug_orig = pc->namelist_orig;
+                       pc->namelist_orig = namecp;
+               }
                pc->namelist = new;
        } else if (stat2.st_size > stat1.st_size)
                pc->namelist_debug = new;

Don Slutz | 11 Jun 19:28 2014
Picon

[PATCH 1/1] xendump: Use off_t not long for 32bit code

This enables crash to handle xen dumps that are larger then 4G
in size in 32bit mode.

Signed-off-by: Don Slutz <dslutz <at> verizon.com>
---
This is the same as was sent as an attachment.  Just a clean top post.

 x86.c     | 10 ++++-----
 x86_64.c  | 10 ++++-----
 xendump.c | 74 +++++++++++++++++++++++++++++++++------------------------------
 xendump.h |  6 +++---
 4 files changed, 52 insertions(+), 48 deletions(-)

diff --git a/x86.c b/x86.c
index 833a11b..608bb88 100644
--- a/x86.c
+++ b/x86.c
 <at>  <at>  -4897,7 +4897,7  <at>  <at>  x86_xendump_p2m_create(struct xendump_data *xd)
 		    "MEMBER_OFFSET(vcpu_guest_context, ctrlreg): %ld\n",
 			ctrlreg_offset);

-	offset = (off_t)xd->xc_core.header.xch_ctxt_offset + 
+	offset = xd->xc_core.header.xch_ctxt_offset +
 		(off_t)ctrlreg_offset;

 	if (lseek(xd->xfd, offset, SEEK_SET) == -1)
 <at>  <at>  -4997,7 +4997,7  <at>  <at>  x86_pvops_xendump_p2m_create(struct xendump_data *xd)
 		    "MEMBER_OFFSET(vcpu_guest_context, ctrlreg): %ld\n",
 			ctrlreg_offset);

-	offset = (off_t)xd->xc_core.header.xch_ctxt_offset + 
+	offset = xd->xc_core.header.xch_ctxt_offset +
 		(off_t)ctrlreg_offset;

 	if (lseek(xd->xfd, offset, SEEK_SET) == -1)
 <at>  <at>  -5369,7 +5369,7  <at>  <at>  x86_xendump_panic_task(struct xendump_data *xd)
 	    INVALID_MEMBER(cpu_user_regs_esp))
 		return NO_TASK;

-        offset = (off_t)xd->xc_core.header.xch_ctxt_offset +
+        offset = xd->xc_core.header.xch_ctxt_offset +
                 (off_t)OFFSET(vcpu_guest_context_user_regs) +
 		(off_t)OFFSET(cpu_user_regs_esp);

 <at>  <at>  -5419,7 +5419,7  <at>  <at>  x86_get_xendump_regs(struct xendump_data *xd, struct bt_info *bt, ulong *eip, ul
             INVALID_MEMBER(cpu_user_regs_esp))
                 goto generic;

-        offset = (off_t)xd->xc_core.header.xch_ctxt_offset +
+        offset = xd->xc_core.header.xch_ctxt_offset +
                 (off_t)OFFSET(vcpu_guest_context_user_regs) +
                 (off_t)OFFSET(cpu_user_regs_esp);
         if (lseek(xd->xfd, offset, SEEK_SET) == -1)
 <at>  <at>  -5427,7 +5427,7  <at>  <at>  x86_get_xendump_regs(struct xendump_data *xd, struct bt_info *bt, ulong *eip, ul
         if (read(xd->xfd, &xesp, sizeof(ulong)) != sizeof(ulong))
                 goto generic;

-        offset = (off_t)xd->xc_core.header.xch_ctxt_offset +
+        offset = xd->xc_core.header.xch_ctxt_offset +
                 (off_t)OFFSET(vcpu_guest_context_user_regs) +
                 (off_t)OFFSET(cpu_user_regs_eip);
         if (lseek(xd->xfd, offset, SEEK_SET) == -1)
diff --git a/x86_64.c b/x86_64.c
index f4a3e8b..a2e4636 100644
--- a/x86_64.c
+++ b/x86_64.c
 <at>  <at>  -6184,7 +6184,7  <at>  <at>  x86_64_xendump_p2m_create(struct xendump_data *xd)
 		    "MEMBER_OFFSET(vcpu_guest_context, ctrlreg): %ld\n",
 			ctrlreg_offset);

-	offset = (off_t)xd->xc_core.header.xch_ctxt_offset + 
+	offset = xd->xc_core.header.xch_ctxt_offset +
 		(off_t)ctrlreg_offset;

 	if (lseek(xd->xfd, offset, SEEK_SET) == -1)
 <at>  <at>  -6270,7 +6270,7  <at>  <at>  x86_64_pvops_xendump_p2m_create(struct xendump_data *xd)
 		    "MEMBER_OFFSET(vcpu_guest_context, ctrlreg): %ld\n",
 			ctrlreg_offset);

-	offset = (off_t)xd->xc_core.header.xch_ctxt_offset + 
+	offset = xd->xc_core.header.xch_ctxt_offset +
 		(off_t)ctrlreg_offset;

 	if (lseek(xd->xfd, offset, SEEK_SET) == -1)
 <at>  <at>  -6601,7 +6601,7  <at>  <at>  x86_64_xendump_panic_task(struct xendump_data *xd)
 	    INVALID_MEMBER(cpu_user_regs_esp))
 		return NO_TASK;

-        offset = (off_t)xd->xc_core.header.xch_ctxt_offset +
+        offset = xd->xc_core.header.xch_ctxt_offset +
                 (off_t)OFFSET(vcpu_guest_context_user_regs) +
 		(off_t)OFFSET(cpu_user_regs_rsp);

 <at>  <at>  -6653,7 +6653,7  <at>  <at>  x86_64_get_xendump_regs(struct xendump_data *xd, struct bt_info *bt, ulong *rip,
             INVALID_MEMBER(cpu_user_regs_rsp))
                 goto generic;

-        offset = (off_t)xd->xc_core.header.xch_ctxt_offset +
+        offset = xd->xc_core.header.xch_ctxt_offset +
                 (off_t)OFFSET(vcpu_guest_context_user_regs) +
                 (off_t)OFFSET(cpu_user_regs_rsp);
         if (lseek(xd->xfd, offset, SEEK_SET) == -1)
 <at>  <at>  -6661,7 +6661,7  <at>  <at>  x86_64_get_xendump_regs(struct xendump_data *xd, struct bt_info *bt, ulong *rip,
         if (read(xd->xfd, &xrsp, sizeof(ulong)) != sizeof(ulong))
                 goto generic;

-        offset = (off_t)xd->xc_core.header.xch_ctxt_offset +
+        offset = xd->xc_core.header.xch_ctxt_offset +
                 (off_t)OFFSET(vcpu_guest_context_user_regs) +
                 (off_t)OFFSET(cpu_user_regs_rip);
         if (lseek(xd->xfd, offset, SEEK_SET) == -1)
diff --git a/xendump.c b/xendump.c
index 6d6b51e..9d78916 100644
--- a/xendump.c
+++ b/xendump.c
 <at>  <at>  -126,9 +126,9  <at>  <at>  xc_core_verify(char *file, char *buf)
 	xd->xc_core.header.xch_magic = xcp->xch_magic;
 	xd->xc_core.header.xch_nr_vcpus = xcp->xch_nr_vcpus;
 	xd->xc_core.header.xch_nr_pages = xcp->xch_nr_pages;
-	xd->xc_core.header.xch_ctxt_offset = (ulong)xcp->xch_ctxt_offset;
-	xd->xc_core.header.xch_index_offset = (ulong)xcp->xch_index_offset;
-	xd->xc_core.header.xch_pages_offset = (ulong)xcp->xch_pages_offset;
+	xd->xc_core.header.xch_ctxt_offset = (off_t)xcp->xch_ctxt_offset;
+	xd->xc_core.header.xch_index_offset = (off_t)xcp->xch_index_offset;
+	xd->xc_core.header.xch_pages_offset = (off_t)xcp->xch_pages_offset;

         xd->flags |= (XENDUMP_LOCAL | XC_CORE_ORIG | XC_CORE_P2M_CREATE);

 <at>  <at>  -187,7 +187,7  <at>  <at>  xc_core_read(void *bufptr, int cnt, ulong addr, physaddr_t paddr)
 	    PFN_NOT_FOUND)
 		return READ_ERROR;

-	offset = (off_t)xd->xc_core.header.xch_pages_offset +
+	offset = xd->xc_core.header.xch_pages_offset +
 		((off_t)(page_index) * (off_t)xd->page_size);

 	if (lseek(xd->xfd, offset, SEEK_SET) == -1) 
 <at>  <at>  -852,7 +852,7  <at>  <at>  read_xendump_hyper(int fd, void *bufptr, int cnt, ulong addr, physaddr_t paddr)
         if ((page_index = xc_core_mfn_to_page_index(pfn)) == PFN_NOT_FOUND)
                 return READ_ERROR;

-        offset = (off_t)xd->xc_core.header.xch_pages_offset +
+        offset = xd->xc_core.header.xch_pages_offset +
                 ((off_t)(page_index) * (off_t)xd->page_size);

         if (lseek(xd->xfd, offset, SEEK_SET) == -1)
 <at>  <at>  -1040,15 +1040,15  <at>  <at>  xendump_memory_dump(FILE *fp)
 	fprintf(fp, "             xch_nr_pages: %d (0x%x)\n",
 		xd->xc_core.header.xch_nr_pages,
 		xd->xc_core.header.xch_nr_pages);
-	fprintf(fp, "          xch_ctxt_offset: %ld (0x%lx)\n", 
-		xd->xc_core.header.xch_ctxt_offset,
-		xd->xc_core.header.xch_ctxt_offset);
-	fprintf(fp, "         xch_index_offset: %ld (0x%lx)\n",
-		xd->xc_core.header.xch_index_offset,
-		xd->xc_core.header.xch_index_offset);
-	fprintf(fp, "         xch_pages_offset: %ld (0x%lx)\n",
-		xd->xc_core.header.xch_pages_offset,
-		xd->xc_core.header.xch_pages_offset);
+	fprintf(fp, "          xch_ctxt_offset: %llu (0x%llx)\n",
+		(ulonglong)xd->xc_core.header.xch_ctxt_offset,
+		(ulonglong)xd->xc_core.header.xch_ctxt_offset);
+	fprintf(fp, "         xch_index_offset: %llu (0x%llx)\n",
+		(ulonglong)xd->xc_core.header.xch_index_offset,
+		(ulonglong)xd->xc_core.header.xch_index_offset);
+	fprintf(fp, "         xch_pages_offset: %llu (0x%llx)\n",
+		(ulonglong)xd->xc_core.header.xch_pages_offset,
+		(ulonglong)xd->xc_core.header.xch_pages_offset);

 	fprintf(fp, "                elf_class: %s\n", xd->xc_core.elf_class == ELFCLASS64 ? "ELFCLASS64" :
 		xd->xc_core.elf_class == ELFCLASS32 ? "ELFCLASS32" : "n/a");
 <at>  <at>  -1285,7 +1285,7  <at>  <at>  xc_core_mfn_to_page(ulong mfn, char *pgbuf)
 	if (xd->flags & XC_CORE_ELF)
 		return xc_core_elf_mfn_to_page(mfn, pgbuf);

-        if (lseek(xd->xfd, (off_t)xd->xc_core.header.xch_index_offset,
+        if (lseek(xd->xfd, xd->xc_core.header.xch_index_offset,
             SEEK_SET) == -1) {
                 error(INFO, "cannot lseek to page index\n");
 		return NULL;
 <at>  <at>  -1325,7 +1325,7  <at>  <at>  xc_core_mfn_to_page(ulong mfn, char *pgbuf)
 		return NULL;
 	}

-        if (lseek(xd->xfd, (off_t)xd->xc_core.header.xch_pages_offset,
+        if (lseek(xd->xfd, xd->xc_core.header.xch_pages_offset,
             SEEK_SET) == -1) {
                 error(INFO, "cannot lseek to xch_pages_offset\n");
 		return NULL;
 <at>  <at>  -1400,7 +1400,7  <at>  <at>  xc_core_elf_mfn_to_page(ulong mfn, char *pgbuf)
 		return NULL;
 	}

-        if (lseek(xd->xfd, (off_t)xd->xc_core.header.xch_pages_offset,
+        if (lseek(xd->xfd, xd->xc_core.header.xch_pages_offset,
             SEEK_SET) == -1)
                 error(FATAL, "cannot lseek to xch_pages_offset\n");

 <at>  <at>  -1434,7 +1434,7  <at>  <at>  xc_core_mfn_to_page_index(ulong mfn)
 	if (xd->flags & XC_CORE_ELF)
 		return xc_core_elf_mfn_to_page_index(mfn);

-        if (lseek(xd->xfd, (off_t)xd->xc_core.header.xch_index_offset,
+        if (lseek(xd->xfd, xd->xc_core.header.xch_index_offset,
             SEEK_SET) == -1) {
                 error(INFO, "cannot lseek to page index\n");
                 return MFN_NOT_FOUND;
 <at>  <at>  -1527,7 +1527,7  <at>  <at>  xc_core_mfns(ulong arg, FILE *ofp)
         ulonglong tmp64[MAX_BATCH_SIZE];
 	size_t size;

-        if (lseek(xd->xfd, (off_t)xd->xc_core.header.xch_index_offset,
+        if (lseek(xd->xfd, xd->xc_core.header.xch_index_offset,
             SEEK_SET) == -1) {
                 error(INFO, "cannot lseek to page index\n");
 		return FALSE;
 <at>  <at>  -1677,7 +1677,7  <at>  <at>  xc_core_pfn_to_page_index(ulong pfn)

 	p2m_idx = xd->xc_core.p2m_frame_index_list[idx];

-	if (lseek(xd->xfd, (off_t)xd->xc_core.header.xch_pages_offset,
+	if (lseek(xd->xfd, xd->xc_core.header.xch_pages_offset,
             SEEK_SET) == -1) {
                 error(INFO, "cannot lseek to xch_pages_offset\n");
                 return PFN_NOT_FOUND;
 <at>  <at>  -1801,7 +1801,7  <at>  <at>  xc_core_pfn_valid(ulong pfn)
 	if (pfn >= (ulong)xd->xc_core.header.xch_nr_pages)
 		return FALSE;

-        offset = (off_t)xd->xc_core.header.xch_index_offset;
+        offset = xd->xc_core.header.xch_index_offset;

 	if (xd->flags & XC_CORE_64BIT_HOST)
 		offset += (off_t)(pfn * sizeof(ulonglong));
 <at>  <at>  -2542,25 +2542,27  <at>  <at>  xc_core_dump_Elf32_Shdr(Elf32_Off offset, int store)
 		return;

 	if (STREQ(name, ".xen_prstatus"))
-		xd->xc_core.header.xch_ctxt_offset = 
-			(unsigned long)shdr.sh_offset;
+		xd->xc_core.header.xch_ctxt_offset =
+			(off_t)shdr.sh_offset;

 	if (STREQ(name, ".xen_shared_info"))
 		xd->xc_core.shared_info_offset = (off_t)shdr.sh_offset;

 	if (STREQ(name, ".xen_pfn")) {
-		xd->xc_core.header.xch_index_offset = shdr.sh_offset;
+		xd->xc_core.header.xch_index_offset =
+			(off_t)shdr.sh_offset;
 		xd->flags |= (XC_CORE_NO_P2M|XC_CORE_PFN_CREATE);
 	}

 	if (STREQ(name, ".xen_p2m")) {
-		xd->xc_core.header.xch_index_offset = shdr.sh_offset;
+		xd->xc_core.header.xch_index_offset =
+			(off_t)shdr.sh_offset;
 		xd->flags |= XC_CORE_P2M_CREATE;
 	}

 	if (STREQ(name, ".xen_pages"))
-		xd->xc_core.header.xch_pages_offset = 
-			(unsigned long)shdr.sh_offset;
+		xd->xc_core.header.xch_pages_offset =
+			(off_t)shdr.sh_offset;

 	if (STREQ(name, ".xen_ia64_mapped_regs"))
 		xd->xc_core.ia64_mapped_regs_offset = 
 <at>  <at>  -2642,25 +2644,27  <at>  <at>  xc_core_dump_Elf64_Shdr(Elf64_Off offset, int store)
 		return;

 	if (STREQ(name, ".xen_prstatus"))
-		xd->xc_core.header.xch_ctxt_offset = 
-			(unsigned long)shdr.sh_offset;
+		xd->xc_core.header.xch_ctxt_offset =
+			(off_t)shdr.sh_offset;

 	if (STREQ(name, ".xen_shared_info"))
 		xd->xc_core.shared_info_offset = (off_t)shdr.sh_offset;

 	if (STREQ(name, ".xen_pfn")) {
-		xd->xc_core.header.xch_index_offset = shdr.sh_offset;
+		xd->xc_core.header.xch_index_offset =
+			(off_t)shdr.sh_offset;
 		xd->flags |= (XC_CORE_NO_P2M|XC_CORE_PFN_CREATE);
 	}

 	if (STREQ(name, ".xen_p2m")) {
-		xd->xc_core.header.xch_index_offset = shdr.sh_offset;
+		xd->xc_core.header.xch_index_offset =
+			(off_t)shdr.sh_offset;
 		xd->flags |= XC_CORE_P2M_CREATE;
 	}

 	if (STREQ(name, ".xen_pages"))
-		xd->xc_core.header.xch_pages_offset = 
-			(unsigned long)shdr.sh_offset;
+		xd->xc_core.header.xch_pages_offset =
+			(off_t)shdr.sh_offset;

 	if (STREQ(name, ".xen_ia64_mapped_regs"))
 		xd->xc_core.ia64_mapped_regs_offset = 
 <at>  <at>  -2814,7 +2818,7  <at>  <at>  xc_core_elf_pfn_init(void)
 		chunk = xd->xc_core.header.xch_nr_pages/INDEX_PFN_COUNT;

 		for (i = c = 0; i < INDEX_PFN_COUNT; i++, c += chunk) {
-			offset = (off_t)xd->xc_core.header.xch_index_offset +
+			offset = xd->xc_core.header.xch_index_offset +
 				(off_t)(c * sizeof(uint64_t));

 	        	if (lseek(xd->xfd, offset, SEEK_SET) == -1)
 <at>  <at>  -2834,7 +2838,7  <at>  <at>  xc_core_elf_pfn_init(void)
 		chunk = xd->xc_core.header.xch_nr_pages/INDEX_PFN_COUNT;
 	
 		for (i = c = 0; i < INDEX_PFN_COUNT; i++, c += chunk) {
-			offset = (off_t)xd->xc_core.header.xch_index_offset +
+			offset = xd->xc_core.header.xch_index_offset +
 				(off_t)(c * sizeof(struct xen_dumpcore_p2m));

 	        	if (lseek(xd->xfd, offset, SEEK_SET) == -1)
diff --git a/xendump.h b/xendump.h
index 9ece4da..17aae37 100644
--- a/xendump.h
+++ b/xendump.h
 <at>  <at>  -42,9 +42,9  <at>  <at>  struct xen_core_header {
     unsigned int xch_magic;
     unsigned int xch_nr_vcpus;
     unsigned int xch_nr_pages;
-    unsigned long xch_ctxt_offset;
-    unsigned long xch_index_offset;
-    unsigned long xch_pages_offset;
+    off_t xch_ctxt_offset;
+    off_t xch_index_offset;
+    off_t xch_pages_offset;
 };

 struct pfn_offset_cache {
--

-- 
1.8.4

Dave Anderson | 10 Jun 15:57 2014
Picon

Re: [PATCH] crash: ARM: support LPAE


----- Original Message -----
> > 
> > Given that the vmcore indentifies itself as a kdump ELF vmcore that contains
> > a VMCOREINFO note, it would seem that the kdump facility "just works" with
> > an ARM PAE kernel as long as the physical memory can be contained within
> > 4GB?
> 
> On our platfrom I have test physical memory beyond 4GB. And it worked fine.
> Maybe my test is not all-around. I will try to do that on qemu, which I failed
> to do last time.

Yeah, it looks like as long as the beginning of the highest physical memory
PT_LOAD segment *begins* before the 4GB mark, then it would work OK.  However,
the 32-bit ELF Elf32_Phdr.p_paddr field is an 32-bit value that cannot contain
a physical address that is 4GB or larger. 

> > But if the system contained physical memory beyond 4GB, then it would
> > require a 64-bit ELF header, and therefore your recent changes to kexec-tools,
> > correct?  In addition, it would require update to the crash utility's netdump.c
> > is_netdump() function to to accept 64-bit ELF headers for EM_ARM vmcores.
> 
> 
> Yes, kexec is ready for LPAE now.
> 
> Maybe I can try to do that. But perhaps I can't test it because
> of lack of entironment.

I believe the 32-bit vs. 64-bit ELF header is configurable, correct?
On RHEL, by default we configure 64-bit ELF headers for 32-bit x86 
machines regardless of their memory size.  So you should be able to
create a vmcore with a 64-bit ELF header on a system that has less
than 4GB of physical memory.

But as I mentioned above, there will need to be at least one fix for
the crash utility, because it will fail at line 258 of netdump.c.
To accept 64-bit ARM headers, there would need to be a additional
case statement like this:

                 case EM_ARM:
                        if (machine_type_mismatch(file, "ARM", NULL,
                            source_query))
                                goto bailout;
                        break;

I'm not sure whether any other fixes would be required?

> 
> > 
> > Also, w/respect to this commit:
> >       
> >   commit 56b700fd6f1e49149880fb1b6ffee0dca5be45fb
> >   Author: Liu Hua <sdu.liu <at> huawei.com>
> >   Date:   Fri Apr 18 07:45:36 2014 +0100
> >   
> >       ARM: 8030/1: ARM : kdump : add arch_crash_save_vmcoreinfo
> >       
> >       For vmcore generated by LPAE enabled kernel, user space
> >       utility such as crash needs additional infomation to
> >       parse.
> >       
> >       So this patch add arch_crash_save_vmcoreinfo as what PAE enabled
> >       i386 linux does.
> >       
> >       Cc: <stable <at> vger.kernel.org>
> >       Reviewed-by: Will Deacon <will.deacon <at> arm.com>
> >       Signed-off-by: Liu Hua <sdu.liu <at> huawei.com>
> >       Signed-off-by: Russell King <rmk+kernel <at> arm.linux.org.uk>
> >   
> >   diff --git a/arch/arm/kernel/machine_kexec.c
> >   b/arch/arm/kernel/machine_kexec.c
> >   index f0d180d..8cf0996 100644
> >   --- a/arch/arm/kernel/machine_kexec.c
> >   +++ b/arch/arm/kernel/machine_kexec.c
> >    <at>  <at>  -184,3 +184,10  <at>  <at>  void machine_kexec(struct kimage *image)
> >    
> >           soft_restart(reboot_entry_phys);
> >    }
> >   +
> >   +void arch_crash_save_vmcoreinfo(void)
> >   +{
> >   +#ifdef CONFIG_ARM_LPAE
> >   +       VMCOREINFO_CONFIG(ARM_LPAE);
> >   +#endif
> >   +}
> >   
> > I note that the sample vmcore you sent me does not have the ARM_LPAE vmcoreinfo
> > item, and that your patch doesn't require/check it.  Was it your intention
> > to use the above as determining factor for setting the "PAE" bit?
> 
> The kernel version I used is 3.13. So it does not contained this infomation.
> At the begining I used this vmcoreinfo, But I found a better way to indentify
> the LPAE enabled kernel. PG_DIR_SIZE of LPAE enabled kernel is larger than
> that of the normal(0x5000 : 0x4000). What do you thank about it?

That was my only concern regarding the patchset, because it presumes that
the difference will be either 0x4000 or 0x5000.  But that's not necessarily
true, at least on older kernels.  For example, here are the values seen
in my small sample set of ARM dumpfiles, showing the kernel release along with
the values of the "swapper_pg_dir" and "_text" symbols, and the difference
between the two:

         RELEASE: 2.6.35-rc3-00272-gd189df4
  swapper_pg_dir: c0004000
           _text: c002c000
                  (28000)

         RELEASE: 2.6.38-rc2-00274-g1f0324c-dirty
  swapper_pg_dir: c0004000
           _text: c0050000
                  (4c000)

         RELEASE: 2.6.36-rc6-next-20101005-00033-g5d269a5-dirty
  swapper_pg_dir: c0004000
           _text: c01d3000
                  (1cf000)

         RELEASE: 3.1.1
  swapper_pg_dir: c0004000
           _text: c0008000
                  (4000)

         RELEASE: 3.1.1
  swapper_pg_dir: c0004000
           _text: c0008000
                  (4000)

         RELEASE: 3.0.8+
  swapper_pg_dir: c0004000
           _text: c0108000
                  (104000)

         RELEASE: 3.13.5     <-- your LPAE kernel
  swapper_pg_dir: 80003000
           _text: 80008000
                  (5000)

         RELEASE: 3.0.8+
  swapper_pg_dir: c0004000
           _text: c0108000
                  (104000)

         RELEASE: 3.1.1
  swapper_pg_dir: c0004000
           _text: c0008000
                  (4000)

         RELEASE: 3.1.1
  swapper_pg_dir: c0004000
           _text: c0008000
                  (4000)

Note that in some earlier kernels, the "_text" symbol is often much
higher.  But I presume that it would be highly unlikely that the difference
would ever be 0x5000 in an older kernel -- so until somebody reports a
problem, it seems OK to do it that way.

However, just in case the layout changes in the future, there should be
a fail-safe check for the VMCOREINFO_CONFIG(ARM_LPAE) in arm_init(),
that does something like this:

    if ((string = pc->read_vmcoreinfo("CONFIG_ARM_LPAE"))) {
            machdep->flags |= PAE;
            free(string);
    } else 
            [check for 0x5000 difference]

There's really no need to check for the "y" contents of the string, because
if the entry exists, then CONFIG_ARM_LPAE is configured. 

> > In any case, thanks for the vmlinux/vmcore pair, which moves us part of the way
> > towards supporting LPAE -- with support for 64-bit ELF headers to be addressed in
> > the future.
> 
> Thanks to your agreement. I will work on this issue continually.

Great -- again, I really appreciate your help.

Thanks,
  Dave

Dave Anderson | 9 Jun 21:32 2014
Picon

[ANNOUNCE] crash 7.0.7 is available


Download from: http://people.redhat.com/anderson
                 or
               https://github.com/crash-utility/crash/releases

The master branch serves as a development branch that will contain all 
patches that are queued for the next release:

  $ git clone git://github.com/crash-utility/crash.git

Changelog:

 - Export the static ELF and compressed kdump vmcoreinfo_read_string()
   functions from netdump.c and kdump.c via a new read_vmcoreinfo()
   method in the global program_context structure.  The function
   get_log_from_vmcoreinfo() will access vmcoreinfo data via the
   new pointer instead of requiring its callers to pass pointers to
   their dumpfile-specific function.
   (anderson <at> redhat.com)

 - Linux 3.15 and later kernels configured with CONFIG_RANDOMIZE_BASE
   can be now be readily identified because of new kernel symbols that
   have been added.  For those kernels, the new "--kaslr=<offset>" 
   and/or "--kaslr=auto" options are not necessary for ELF or compressed
   kdump vmcores, or for live systems that have /proc/kallsyms showing
   the relocated symbol values.  A new KASLR initialization function
   called kaslr_init() is now called by symtab_init() prior to the 
   initial symbol-sorting operation.  If kaslr_init() determines that
   KASLR may be in effect, it will trigger a search for the relevant
   vmlinux symbols during the sorting operation, which in turn will
   cause the relocation value to be automatically calculated.
   (anderson <at> redhat.com)

 - Implemented a new "bt -c cpu(s)" option to display the backtrace
   of the active task on one or more cpus.  The cpus must be specified
   in a comma- and/or dash-separated list; for examples ""3", "1,8,9",
   "1-23", or "1,8,9-14".  Similar to "bt -a", the option is only
   applicable with crash dumps. 
   (atomlin <at> redhat.com)

 - Fix for Linux 3.11 and later ARM kernels, in which all non-panicking
   cpus offline themselves during a kdump procedure.  This causes an 
   invalid cpu count determination during crash session initialization
   from an ARM vmcore.  The patch utilizes the cpu count found in the 
   cpu_active_map if it is greater than the count in the cpu_online_map.
   In addition, the maximum NR_CPUS value for the ARM architecture has 
   been raised from 4 to 32.
   (sdu.liu <at> huawei.com)

 - Fix for the X86_64 "bt" command on Linux 3.3 and later kernels to
   properly display exception frame register contents on NMI stacks.
   Kernel commit 3f3c8b8c4b2a34776c3470142a7c8baafcda6eb0 added 12 more
   values to the NMI exception stack to handle nested NMIs caused by 
   page faults or breakpoints that could occur while handling an NMI 
   exception.  The fix has two parts:

     1. Determine if this kernel has the nested NMI layout and set a
        machine-specific flag (NESTED_NMI) if it does.
     2. When backtracing an NMI stack, use the saved values instead of
        those found at the top of stack.

   Kernel commit 28696f434fef0efa97534b59986ad33b9c4df7f8 changed
   the stack layout again, swapping the location of the "saved" and 
   "copied" registers. This can be detected automatically, because the
   "copied" registers contain either a copy of the "saved" registers, 
   or point to "repeat_nmi". So, if "repeat_nmi" is found as the return
   address, assume that this is the old layout, and adjust the stack 
   pointer again.  Without the patch, incorrect register values are 
   displayed in the exception frame dump in the NMI stack backtrace.
   (ptesarik <at> suse.cz)

 - Fix for the built-in "g" alias, which apparently has not worked 
   correctly since crash-5.1.4.  Without the patch, if the "g" alias
   and the first argument are separated by one space, then the first
   first character of that argument would get stripped prior to being
   passed to the embedded gdb module.
   (anderson <at> redhat.com)

 - Removed the BASELEVEL_REVISION string from defs.h, which serves no
   purpose since the deprecation of the remote daemon, and typically 
   has been out of sync with the crash version.
   (anderson <at> redhat.com)

 - Fix for the "p", "irq", "struct", "union" and "*" commands if a
   cpu specification contains an invalid cpu number.  Without the
   patch, a segmentation violation may be generated.
   (anderson <at> redhat.com)

 - Implemented a new capability for the "ptov" command that takes a
   per-cpu offset and cpu specification argument and translates it
   into the kernel virtual addresses for the cpus specified.
   (anderson <at> redhat.com)

 - Implemented a new "ps -m" option that is a similar, complementary 
   option to "ps -l", but which translates the task timestamp value from 
   a decimal or hexadecimal nanoseconds value into a more human-readable
   string consisting of the number of days, hours, minutes, seconds and 
   milliseconds that have elapsed since the task started executing on a 
   cpu.  More accurately described, it is the time difference between 
   the timestamp copied from the per-cpu runqueue clock when the task 
   last started executing compared to the most current value of the
   per-cpu runqueue clock.  
   (anderson <at> redhat.com, bud.brown <at> redhat.com)

 - In addition, a new "ps -C <cpu-specifier>" option has been added
   that can only be used with "ps -l" and "ps -m", which sorts the 
   global task list into per-cpu blocks; the cpu-specifier uses the 
   standard comma or dash separated list, expressed as "-C 1,3,5", 
   "-C 1-3", "-C 1,3,5-7,10", or "-Call" or "-Ca" for all cpus. 
   (anderson <at> redhat.com)

 - Implemented a new "runq -m" option that is a simliar, complementary
   option to "runq -t", but which displays the amount of time that the 
   active task on each cpu has been running, expressed in a format 
   consisting of days, hours, minutes, seconds and milliseconds.
   (anderson <at> redhat.com)

 - Implemented a new "kmem -h" option that displays the address of 
   each hugepage hstate array entry, its hugepage size, its free and
   total counts, and name string.
   (anderson <at> redhat.com)

 - Implemented a new "ps -S" option that displays a summary consisting
   of the number of tasks in a task state.
   (anderson <at> redhat.com)

 - Fix for the "arguments-input-file" feature to protect against a 
   called command modifying an argument string.  For example, the 
   "struct" command modifies "-l struct_name.member" argument strings,
   and so without the patch, all iterative calls after the first one
   will fail.
   (anderson <at> redhat.com)

 - Fix failure to build from source when compiling the crash utility 
   with gcc-4.9.  Without the patch, the crash utility build generates
   the following error:

    In file included from opncls.c:26:0:
    opncls.c: In function 'bfd_fopen':
    bfd.h:529:65: error: right-hand operand of comma expression has no 
    effect [-Werror=unused-value]
     #define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE)
                                                                    ^
    opncls.c:263:5: note: in expansion of macro 'bfd_set_cacheable'
         bfd_set_cacheable (nbfd, TRUE);

    cc1: all warnings being treated as errors

   (anderson <at> redhat.com, anatol.pomozov <at> gmail.com)

 - Fix for displaying enum values that are greater than 32-bits in 
   size.  Without the patch, the upper 32-bits are clipped off and
   displayed as integer-sized value.  
   (anderson <at> redhat.com)

 - If the kernel (live or dumpfile) has the "kpatch" module installed,
   the tag "[KPATCH]" will be displayed next to the kernel name in the
   initial system banner and by the "sys" command.
   (anderson <at> redhat.com)

 - Fix for the "DEBUG KERNEL:" display in the initial system banner
   and by the "sys" command when using a System.map file with a 
   Linux 3.0 and later debug kernel.  Without the patch, the kernel 
   version is not displayed in parentheses following the debug kernel
   name.
   (anderson <at> redhat.com)

 - If the gdb-<version>.patch file has changed and a rebuild is being
   done from within a previously-existing build tree, "patch -N" the
   gdb sources, and start the rebuild from the gdb-<version> directory
   instead of the gdb-<version>/gdb directory.
   (anderson <at> redhat.com)

 - Fix to prevent a possible segmentation violation generated by the 
   "runq -g" command when run on a very active live system due to an
   active task on a cpu exiting while the command is running.  
   (anderson <at> redhat.com)

 - Fix for the "runq -g" command on Linux 3.15 and later kernels, where
   the cgroup_name() function now utilizes kernfs_name().  Without the 
   patch, the command fails with the error message "runq: invalid 
   structure member offset: cgroup_dentry".          
   (anderson <at> redhat.com)

 - Fix for the "extend" command when running with an x86_64 crash binary 
   that was built with "make target=ARM64" in order to analyze ARM64 
   dumpfiles on an x86_64 host.  Without the patch, if the extend 
   command is used with an extension module built in the same manner,
   it fails with the message "extend: <module>.so: not an ELF format
   object file".
   (Jan.Karlsson <at> sonymobile.com)

 - Introduce support for 32-bit ARM kernels that are configured with 
   CONFIG_ARM_LPAE.  The patch implements the virtual-to-physical
   address translation of 64-bit PTEs used by ARM LPAE kernels.
   (sdu.liu <at> huawei.com, weijitao <at> huawei.com)


Gmane