public inbox for kexec@lists.infradead.org
 help / color / mirror / Atom feed
* Re: [PATCH v1] makedumpfile: s390x: Add support for s390x crashdump analysis
       [not found] <20101111052840.14598.72719.stgit@mars.in.ibm.com>
@ 2010-11-12  1:28 ` Ken'ichi Ohmichi
  2010-11-12  2:33   ` Ken'ichi Ohmichi
  0 siblings, 1 reply; 5+ messages in thread
From: Ken'ichi Ohmichi @ 2010-11-12  1:28 UTC (permalink / raw)
  To: Mahesh J Salgaonkar
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, Mahesh Salgaonkar,
	kexec-ml, Michael Holzheu, Dave Anderson, Reinhard


Hi Mahesh,

Thank you for the patch.
I reviewed this patch, and I think this is good.

I have one question.

On Thu, 11 Nov 2010 11:04:17 +0530
Mahesh J Salgaonkar <mahesh@linux.vnet.in.ibm.com> wrote:
>
> This patch adds support for processing s390x kernel crashdumps.
> 
> The changes have been tested on s390x system.
> The dump compression and filtering (for all dump levels 1,2,4,8,16 and 31)
> tests are succussfull.

What version of linux kernel are the above tests on ?
I'd like to write the version on README file.


Thanks
Ken'ichi Ohmichi


> Please review this patch and let me know your feedback.
> 
> Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
> Signed-off-by: Michael Holzheu <holzheu@de.ibm.com>
> ---
> 
>  Makefile       |    4 -
>  makedumpfile.h |   52 ++++++++++
>  s390x.c        |  280 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 334 insertions(+), 2 deletions(-)
>  create mode 100644 s390x.c
> 
> diff --git a/Makefile b/Makefile
> index 4dad21e..e79be1c 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -23,8 +23,8 @@ CFLAGS_ARCH += -m64
>  endif
>  
>  SRC	= makedumpfile.c makedumpfile.h diskdump_mod.h
> -SRC_ARCH = arm.c x86.c x86_64.c ia64.c ppc64.c
> -OBJ_ARCH = arm.o x86.o x86_64.o ia64.o ppc64.o
> +SRC_ARCH = arm.c x86.c x86_64.c ia64.c ppc64.c s390x.c
> +OBJ_ARCH = arm.o x86.o x86_64.o ia64.o ppc64.o s390x.o
>  
>  all: makedumpfile
>  
> diff --git a/makedumpfile.h b/makedumpfile.h
> index b703077..c56afd8 100644
> --- a/makedumpfile.h
> +++ b/makedumpfile.h
> @@ -612,6 +612,45 @@ do { \
>  #define _MAX_PHYSMEM_BITS	(44)
>  #endif
>  
> +#ifdef __s390x__
> +#define __PAGE_OFFSET		(info->page_size - 1)
> +#define KERNELBASE		(0)
> +#define KVBASE			(SYMBOL(_stext))
> +#define _SECTION_SIZE_BITS	(28)
> +#define _MAX_PHYSMEM_BITS	(42)
> +
> +/* Bits in the segment/region table address-space-control-element */
> +#define _ASCE_TYPE_MASK		0x0c
> +#define _ASCE_TABLE_LENGTH	0x03	/* region table length  */
> +
> +#define TABLE_LEVEL(x)		(((x) & _ASCE_TYPE_MASK) >> 2)
> +#define TABLE_LENGTH(x)		((x) & _ASCE_TABLE_LENGTH)
> +
> +/* Bits in the region table entry */
> +#define _REGION_ENTRY_ORIGIN	~0xfffUL	/* region table origin*/
> +#define _REGION_ENTRY_TYPE_MASK	0x0c	/* region table type mask */
> +#define _REGION_ENTRY_INVALID	0x20	/* invalid region table entry */
> +#define _REGION_ENTRY_LENGTH	0x03	/* region table length */
> +#define _REGION_OFFSET_MASK	0x7ffUL	/* region/segment table offset mask */
> +
> +#define RSG_TABLE_LEVEL(x)	(((x) & _REGION_ENTRY_TYPE_MASK) >> 2)
> +#define RSG_TABLE_LENGTH(x)	((x) & _REGION_ENTRY_LENGTH)
> +
> +/* Bits in the segment table entry */
> +#define _SEGMENT_ENTRY_ORIGIN	~0x7ffUL
> +#define _SEGMENT_ENTRY_LARGE	0x400
> +#define _SEGMENT_PAGE_SHIFT	31
> +#define _SEGMENT_INDEX_SHIFT	20
> +
> +/* Hardware bits in the page table entry */
> +#define _PAGE_CO		0x100	/* HW Change-bit override */
> +#define _PAGE_ZERO		0x800	/* Bit pos 52 must conatin zero */
> +#define _PAGE_INVALID		0x400	/* HW invalid bit */
> +#define _PAGE_INDEX_SHIFT	12
> +#define _PAGE_OFFSET_MASK	0xffUL	/* page table offset mask */
> +
> +#endif /* __s390x__ */
> +
>  #ifdef __ia64__ /* ia64 */
>  #define REGION_SHIFT		(61)
>  
> @@ -710,6 +749,15 @@ unsigned long long vaddr_to_paddr_ppc64(unsigned long vaddr);
>  #define vaddr_to_paddr(X)	vaddr_to_paddr_ppc64(X)
>  #endif          /* powerpc */
>  
> +#ifdef __s390x__ /* s390x */
> +int get_machdep_info_s390x(void);
> +unsigned long long vaddr_to_paddr_s390x(unsigned long vaddr);
> +#define get_phys_base()		TRUE
> +#define get_machdep_info()	get_machdep_info_s390x()
> +#define get_versiondep_info()	TRUE
> +#define vaddr_to_paddr(X)	vaddr_to_paddr_s390x(X)
> +#endif          /* s390x */
> +
>  #ifdef __ia64__ /* ia64 */
>  int get_phys_base_ia64(void);
>  int get_machdep_info_ia64(void);
> @@ -1274,3 +1322,7 @@ int get_xen_info_ia64(void);
>  #define get_xen_info_arch(X) FALSE
>  #endif	/* powerpc */
>  
> +#ifdef __s390x__ /* s390x */
> +#define kvtop_xen(X)	FALSE
> +#define get_xen_info_arch(X) FALSE
> +#endif	/* s390x */
> diff --git a/s390x.c b/s390x.c
> new file mode 100644
> index 0000000..128e5f0
> --- /dev/null
> +++ b/s390x.c
> @@ -0,0 +1,280 @@
> +/*
> + * s390x.c
> + *
> + * Created by: Michael Holzheu (holzheu@de.ibm.com)
> + * Copyright IBM Corp. 2010
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation (version 2 of the License).
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +#ifdef __s390x__
> +
> +#include "makedumpfile.h"
> +
> +#define TABLE_SIZE		4096
> +
> +/*
> + * Bits in the virtual address
> + *
> + * |<-----  RX  ---------->|
> + * |  RFX  |  RSX  |  RTX  |  SX  | PX |  BX  |
> + * 0        11      22      33     44   52    63
> + *
> + * RX: Region Index
> + *	RFX:	Region first index
> + *	RSX:	Region second index
> + *	RTX:	Region third index
> + * SX: Segment index
> + * PX: Page index
> + * BX: Byte index
> + *
> + * RX part of vaddr is divided into three fields RFX, RSX and RTX each of
> + * 11 bit in size
> + */
> +#define _REGION_INDEX_SHIFT	11
> +#define _PAGE_INDEX_MASK	0xff000UL	/* page index (PX) mask */
> +#define _BYTE_INDEX_MASK	0x00fffUL	/* Byte index (BX) mask */
> +#define _PAGE_BYTE_INDEX_MASK	(_PAGE_INDEX_MASK | _BYTE_INDEX_MASK)
> +
> +/* Region/segment table index */
> +#define rsg_index(x, y)	\
> +		(((x) >> ((_REGION_INDEX_SHIFT * y) + _SEGMENT_INDEX_SHIFT)) \
> +		& _REGION_OFFSET_MASK)
> +/* Page table index */
> +#define pte_index(x)	(((x) >> _PAGE_INDEX_SHIFT) & _PAGE_OFFSET_MASK)
> +
> +#define rsg_offset(x, y)	(rsg_index( x, y) * sizeof(unsigned long))
> +#define pte_offset(x)		(pte_index(x) * sizeof(unsigned long))
> +
> +int
> +get_machdep_info_s390x(void)
> +{
> +	unsigned long vmlist, vmalloc_start;
> +
> +	info->section_size_bits = _SECTION_SIZE_BITS;
> +	info->max_physmem_bits  = _MAX_PHYSMEM_BITS;
> +	info->page_offset = __PAGE_OFFSET;
> +
> +	if (SYMBOL(_stext) == NOT_FOUND_SYMBOL) {
> +		ERRMSG("Can't get the symbol of _stext.\n");
> +		return FALSE;
> +	}
> +	info->kernel_start = SYMBOL(_stext);
> +	DEBUG_MSG("kernel_start : %lx\n", info->kernel_start);
> +
> +	/*
> +	 * For the compatibility, makedumpfile should run without the symbol
> +	 * vmlist and the offset of vm_struct.addr if they are not necessary.
> +	 */
> +	if ((SYMBOL(vmlist) == NOT_FOUND_SYMBOL)
> +	    || (OFFSET(vm_struct.addr) == NOT_FOUND_STRUCTURE)) {
> +		return TRUE;
> +	}
> +	if (!readmem(VADDR, SYMBOL(vmlist), &vmlist, sizeof(vmlist))) {
> +		ERRMSG("Can't get vmlist.\n");
> +		return FALSE;
> +	}
> +	if (!readmem(VADDR, vmlist + OFFSET(vm_struct.addr), &vmalloc_start,
> +	    sizeof(vmalloc_start))) {
> +		ERRMSG("Can't get vmalloc_start.\n");
> +		return FALSE;
> +	}
> +	info->vmalloc_start = vmalloc_start;
> +	DEBUG_MSG("vmalloc_start: %lx\n", vmalloc_start);
> +
> +	return TRUE;
> +}
> +
> +static int
> +is_vmalloc_addr_s390x(unsigned long vaddr)
> +{
> +	return (info->vmalloc_start && vaddr >= info->vmalloc_start);
> +}
> +
> +static int
> +rsg_table_entry_bad(unsigned long entry, int level)
> +{
> +	unsigned long mask = ~_REGION_ENTRY_INVALID
> +				& ~_REGION_ENTRY_TYPE_MASK
> +				& ~_REGION_ENTRY_LENGTH;
> +
> +	if (level)
> +		mask &= ~_REGION_ENTRY_ORIGIN;
> +	else
> +		mask &= ~_SEGMENT_ENTRY_ORIGIN;
> +
> +	return  (entry & mask) != 0;
> +}
> +
> +/* Region or segment table traversal function */
> +static unsigned long
> +_kl_rsg_table_deref_s390x(unsigned long vaddr, unsigned long table,
> +							int len, int level)
> +{
> +	unsigned long offset, entry;
> +
> +	offset = rsg_offset(vaddr, level);
> +
> +	/* check if offset is over the table limit. */
> +	if (offset >= ((len + 1) * TABLE_SIZE)) {
> +		ERRMSG("offset is over the table limit.\n");
> +		return 0;
> +	}
> +
> +	if (!readmem(VADDR, table + offset, &entry, sizeof(entry))) {
> +		if (level)
> +			ERRMSG("Can't read region table %d entry\n", level);
> +		else
> +			ERRMSG("Can't read segment table entry\n");
> +		return 0;
> +	}
> +	/*
> +	 * Check if the segment table entry could be read and doesn't have
> +	 * any of the reserved bits set.
> +	 */
> +	if (rsg_table_entry_bad(entry, level)) {
> +		ERRMSG("Bad region/segment table entry.\n");
> +		return 0;
> +	}
> +	/*
> +	 * Check if the region/segment table entry is with valid
> +	 * level and not invalid.
> +	 */
> +	if ((RSG_TABLE_LEVEL(entry) != level)
> +			&& (entry & _REGION_ENTRY_INVALID)) {
> +		ERRMSG("Invalid region/segment table level or entry.\n");
> +		return 0;
> +	}
> +
> +	return entry;
> +}
> +
> +/* Page table traversal function */
> +static ulong _kl_pg_table_deref_s390x(unsigned long vaddr, unsigned long table)
> +{
> +	unsigned long offset, entry;
> +
> +	offset = pte_offset(vaddr);
> +	readmem(VADDR, table + offset, &entry, sizeof(entry));
> +	/*
> +	 * Check if the page table entry could be read and doesn't have
> +	 * any of the reserved bits set.
> +	 * Check if the page table entry has the invalid bit set.
> +	 */
> +	if (entry &  (_PAGE_CO | _PAGE_ZERO | _PAGE_INVALID)) {
> +		ERRMSG("Invalid page table entry.\n");
> +		return 0;
> +	}
> +
> +	return entry;
> +}
> +
> +/* vtop_s390x() - translate virtual address to physical
> + *	@vaddr: virtual address to translate
> + *
> + * Function converts the @vaddr into physical address using page tables.
> + *
> + * Return:
> + *	Physical address or NOT_PADDR if translation fails.
> + */
> +static unsigned long long
> +vtop_s390x(unsigned long vaddr)
> +{
> +	unsigned long long paddr = NOT_PADDR;
> +	unsigned long table, entry;
> +	int level, len;
> +
> +	if (SYMBOL(swapper_pg_dir) == NOT_FOUND_SYMBOL) {
> +		ERRMSG("Can't get the symbol of swapper_pg_dir.\n");
> +		return NOT_PADDR;
> +	}
> +	table = SYMBOL(swapper_pg_dir);
> +
> +	/* Read the first entry to find the number of page table levels. */
> +	readmem(VADDR, table, &entry, sizeof(entry));
> +	level = TABLE_LEVEL(entry);
> +	len = TABLE_LENGTH(entry);
> +
> +	if ((vaddr >> (_SEGMENT_PAGE_SHIFT + (_REGION_INDEX_SHIFT * level)))) {
> +		ERRMSG("Address too big for the number of page table " \
> +								"levels.\n");
> +		return NOT_PADDR;
> +	}
> +
> +	/*
> +	 * Walk the region and segment tables.
> +	 */
> +	while (level >= 0) {
> +		entry = _kl_rsg_table_deref_s390x(vaddr, table, len, level);
> +		if (!entry) {
> +			return NOT_PADDR;
> +		}
> +		table = entry & _REGION_ENTRY_ORIGIN;
> +		len = RSG_TABLE_LENGTH(entry);
> +		level--;
> +	}
> +
> +	/*
> +	 * Check if this is a large page.
> +	 * if yes, then add the 1MB page offset (PX + BX) and return the value.
> +	 * if no, then get the page table entry using PX index.
> +	 */
> +	if (entry & _SEGMENT_ENTRY_LARGE) {
> +		paddr = table + (vaddr &  _PAGE_BYTE_INDEX_MASK);
> +	} else {
> +		entry = _kl_pg_table_deref_s390x(vaddr,
> +					entry & _SEGMENT_ENTRY_ORIGIN);
> +		if (!entry)
> +			return NOT_PADDR;
> +
> +		/*
> +		 * Isolate the page origin from the page table entry.
> +		 * Add the page offset (BX).
> +		 */
> +		paddr = (entry &  _REGION_ENTRY_ORIGIN)
> +			+ (vaddr & _BYTE_INDEX_MASK);
> +	}
> +
> +	return paddr;
> +}
> +
> +unsigned long long
> +vaddr_to_paddr_s390x(unsigned long vaddr)
> +{
> +	unsigned long long paddr;
> +
> +	paddr = vaddr_to_paddr_general(vaddr);
> +	if (paddr != NOT_PADDR)
> +		return paddr;
> +
> +	if ((SYMBOL(vmlist) == NOT_FOUND_SYMBOL)
> +	    || (OFFSET(vm_struct.addr) == NOT_FOUND_STRUCTURE)) {
> +		ERRMSG("Can't get necessary information for vmalloc "
> +			"translation.\n");
> +		return NOT_PADDR;
> +	}
> +
> +	if (is_vmalloc_addr_s390x(vaddr)) {
> +		paddr = vtop_s390x(vaddr);
> +	}
> +	else {
> +		ERRMSG("Can't convert a virtual address(%lx) to " \
> +		    "physical address.\n", vaddr);
> +		return NOT_PADDR;
> +	}
> +
> +	return paddr;
> +}
> +
> +#endif /* __s390x__ */
> 


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

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

* Re: [PATCH v1] makedumpfile: s390x: Add support for s390x crashdump analysis
  2010-11-12  1:28 ` [PATCH v1] makedumpfile: s390x: Add support for s390x crashdump analysis Ken'ichi Ohmichi
@ 2010-11-12  2:33   ` Ken'ichi Ohmichi
  2010-11-12  7:04     ` Mahesh Jagannath Salgaonkar
  0 siblings, 1 reply; 5+ messages in thread
From: Ken'ichi Ohmichi @ 2010-11-12  2:33 UTC (permalink / raw)
  To: Mahesh Salgaonkar
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec-ml, Michael Holzheu,
	Dave Anderson, Reinhard


Hi Mahesh,

On Fri, 12 Nov 2010 10:28:56 +0900
"Ken'ichi Ohmichi" <oomichi@mxs.nes.nec.co.jp> wrote:
>
> On Thu, 11 Nov 2010 11:04:17 +0530
> Mahesh J Salgaonkar <mahesh@linux.vnet.in.ibm.com> wrote:
> >
> > This patch adds support for processing s390x kernel crashdumps.
> > 
> > The changes have been tested on s390x system.
> > The dump compression and filtering (for all dump levels 1,2,4,8,16 and 31)
> > tests are succussfull.
> 
> What version of linux kernel are the above tests on ?
> I'd like to write the version on README file.

Also, please let me know the memory model (flatmem, discontigmem,
or sparsemem) too.

  # make menuconfig
  -> Processor type and features
     -> Memory model


Thanks
Ken'ichi Ohmichi

> > Please review this patch and let me know your feedback.
> > 
> > Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
> > Signed-off-by: Michael Holzheu <holzheu@de.ibm.com>
> > ---
> > 
> >  Makefile       |    4 -
> >  makedumpfile.h |   52 ++++++++++
> >  s390x.c        |  280 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 334 insertions(+), 2 deletions(-)
> >  create mode 100644 s390x.c
> > 
> > diff --git a/Makefile b/Makefile
> > index 4dad21e..e79be1c 100644
> > --- a/Makefile
> > +++ b/Makefile
> > @@ -23,8 +23,8 @@ CFLAGS_ARCH += -m64
> >  endif
> >  
> >  SRC	= makedumpfile.c makedumpfile.h diskdump_mod.h
> > -SRC_ARCH = arm.c x86.c x86_64.c ia64.c ppc64.c
> > -OBJ_ARCH = arm.o x86.o x86_64.o ia64.o ppc64.o
> > +SRC_ARCH = arm.c x86.c x86_64.c ia64.c ppc64.c s390x.c
> > +OBJ_ARCH = arm.o x86.o x86_64.o ia64.o ppc64.o s390x.o
> >  
> >  all: makedumpfile
> >  
> > diff --git a/makedumpfile.h b/makedumpfile.h
> > index b703077..c56afd8 100644
> > --- a/makedumpfile.h
> > +++ b/makedumpfile.h
> > @@ -612,6 +612,45 @@ do { \
> >  #define _MAX_PHYSMEM_BITS	(44)
> >  #endif
> >  
> > +#ifdef __s390x__
> > +#define __PAGE_OFFSET		(info->page_size - 1)
> > +#define KERNELBASE		(0)
> > +#define KVBASE			(SYMBOL(_stext))
> > +#define _SECTION_SIZE_BITS	(28)
> > +#define _MAX_PHYSMEM_BITS	(42)
> > +
> > +/* Bits in the segment/region table address-space-control-element */
> > +#define _ASCE_TYPE_MASK		0x0c
> > +#define _ASCE_TABLE_LENGTH	0x03	/* region table length  */
> > +
> > +#define TABLE_LEVEL(x)		(((x) & _ASCE_TYPE_MASK) >> 2)
> > +#define TABLE_LENGTH(x)		((x) & _ASCE_TABLE_LENGTH)
> > +
> > +/* Bits in the region table entry */
> > +#define _REGION_ENTRY_ORIGIN	~0xfffUL	/* region table origin*/
> > +#define _REGION_ENTRY_TYPE_MASK	0x0c	/* region table type mask */
> > +#define _REGION_ENTRY_INVALID	0x20	/* invalid region table entry */
> > +#define _REGION_ENTRY_LENGTH	0x03	/* region table length */
> > +#define _REGION_OFFSET_MASK	0x7ffUL	/* region/segment table offset mask */
> > +
> > +#define RSG_TABLE_LEVEL(x)	(((x) & _REGION_ENTRY_TYPE_MASK) >> 2)
> > +#define RSG_TABLE_LENGTH(x)	((x) & _REGION_ENTRY_LENGTH)
> > +
> > +/* Bits in the segment table entry */
> > +#define _SEGMENT_ENTRY_ORIGIN	~0x7ffUL
> > +#define _SEGMENT_ENTRY_LARGE	0x400
> > +#define _SEGMENT_PAGE_SHIFT	31
> > +#define _SEGMENT_INDEX_SHIFT	20
> > +
> > +/* Hardware bits in the page table entry */
> > +#define _PAGE_CO		0x100	/* HW Change-bit override */
> > +#define _PAGE_ZERO		0x800	/* Bit pos 52 must conatin zero */
> > +#define _PAGE_INVALID		0x400	/* HW invalid bit */
> > +#define _PAGE_INDEX_SHIFT	12
> > +#define _PAGE_OFFSET_MASK	0xffUL	/* page table offset mask */
> > +
> > +#endif /* __s390x__ */
> > +
> >  #ifdef __ia64__ /* ia64 */
> >  #define REGION_SHIFT		(61)
> >  
> > @@ -710,6 +749,15 @@ unsigned long long vaddr_to_paddr_ppc64(unsigned long vaddr);
> >  #define vaddr_to_paddr(X)	vaddr_to_paddr_ppc64(X)
> >  #endif          /* powerpc */
> >  
> > +#ifdef __s390x__ /* s390x */
> > +int get_machdep_info_s390x(void);
> > +unsigned long long vaddr_to_paddr_s390x(unsigned long vaddr);
> > +#define get_phys_base()		TRUE
> > +#define get_machdep_info()	get_machdep_info_s390x()
> > +#define get_versiondep_info()	TRUE
> > +#define vaddr_to_paddr(X)	vaddr_to_paddr_s390x(X)
> > +#endif          /* s390x */
> > +
> >  #ifdef __ia64__ /* ia64 */
> >  int get_phys_base_ia64(void);
> >  int get_machdep_info_ia64(void);
> > @@ -1274,3 +1322,7 @@ int get_xen_info_ia64(void);
> >  #define get_xen_info_arch(X) FALSE
> >  #endif	/* powerpc */
> >  
> > +#ifdef __s390x__ /* s390x */
> > +#define kvtop_xen(X)	FALSE
> > +#define get_xen_info_arch(X) FALSE
> > +#endif	/* s390x */
> > diff --git a/s390x.c b/s390x.c
> > new file mode 100644
> > index 0000000..128e5f0
> > --- /dev/null
> > +++ b/s390x.c
> > @@ -0,0 +1,280 @@
> > +/*
> > + * s390x.c
> > + *
> > + * Created by: Michael Holzheu (holzheu@de.ibm.com)
> > + * Copyright IBM Corp. 2010
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation (version 2 of the License).
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> > + * GNU General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU General Public License
> > + * along with this program; if not, write to the Free Software
> > + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> > + */
> > +
> > +#ifdef __s390x__
> > +
> > +#include "makedumpfile.h"
> > +
> > +#define TABLE_SIZE		4096
> > +
> > +/*
> > + * Bits in the virtual address
> > + *
> > + * |<-----  RX  ---------->|
> > + * |  RFX  |  RSX  |  RTX  |  SX  | PX |  BX  |
> > + * 0        11      22      33     44   52    63
> > + *
> > + * RX: Region Index
> > + *	RFX:	Region first index
> > + *	RSX:	Region second index
> > + *	RTX:	Region third index
> > + * SX: Segment index
> > + * PX: Page index
> > + * BX: Byte index
> > + *
> > + * RX part of vaddr is divided into three fields RFX, RSX and RTX each of
> > + * 11 bit in size
> > + */
> > +#define _REGION_INDEX_SHIFT	11
> > +#define _PAGE_INDEX_MASK	0xff000UL	/* page index (PX) mask */
> > +#define _BYTE_INDEX_MASK	0x00fffUL	/* Byte index (BX) mask */
> > +#define _PAGE_BYTE_INDEX_MASK	(_PAGE_INDEX_MASK | _BYTE_INDEX_MASK)
> > +
> > +/* Region/segment table index */
> > +#define rsg_index(x, y)	\
> > +		(((x) >> ((_REGION_INDEX_SHIFT * y) + _SEGMENT_INDEX_SHIFT)) \
> > +		& _REGION_OFFSET_MASK)
> > +/* Page table index */
> > +#define pte_index(x)	(((x) >> _PAGE_INDEX_SHIFT) & _PAGE_OFFSET_MASK)
> > +
> > +#define rsg_offset(x, y)	(rsg_index( x, y) * sizeof(unsigned long))
> > +#define pte_offset(x)		(pte_index(x) * sizeof(unsigned long))
> > +
> > +int
> > +get_machdep_info_s390x(void)
> > +{
> > +	unsigned long vmlist, vmalloc_start;
> > +
> > +	info->section_size_bits = _SECTION_SIZE_BITS;
> > +	info->max_physmem_bits  = _MAX_PHYSMEM_BITS;
> > +	info->page_offset = __PAGE_OFFSET;
> > +
> > +	if (SYMBOL(_stext) == NOT_FOUND_SYMBOL) {
> > +		ERRMSG("Can't get the symbol of _stext.\n");
> > +		return FALSE;
> > +	}
> > +	info->kernel_start = SYMBOL(_stext);
> > +	DEBUG_MSG("kernel_start : %lx\n", info->kernel_start);
> > +
> > +	/*
> > +	 * For the compatibility, makedumpfile should run without the symbol
> > +	 * vmlist and the offset of vm_struct.addr if they are not necessary.
> > +	 */
> > +	if ((SYMBOL(vmlist) == NOT_FOUND_SYMBOL)
> > +	    || (OFFSET(vm_struct.addr) == NOT_FOUND_STRUCTURE)) {
> > +		return TRUE;
> > +	}
> > +	if (!readmem(VADDR, SYMBOL(vmlist), &vmlist, sizeof(vmlist))) {
> > +		ERRMSG("Can't get vmlist.\n");
> > +		return FALSE;
> > +	}
> > +	if (!readmem(VADDR, vmlist + OFFSET(vm_struct.addr), &vmalloc_start,
> > +	    sizeof(vmalloc_start))) {
> > +		ERRMSG("Can't get vmalloc_start.\n");
> > +		return FALSE;
> > +	}
> > +	info->vmalloc_start = vmalloc_start;
> > +	DEBUG_MSG("vmalloc_start: %lx\n", vmalloc_start);
> > +
> > +	return TRUE;
> > +}
> > +
> > +static int
> > +is_vmalloc_addr_s390x(unsigned long vaddr)
> > +{
> > +	return (info->vmalloc_start && vaddr >= info->vmalloc_start);
> > +}
> > +
> > +static int
> > +rsg_table_entry_bad(unsigned long entry, int level)
> > +{
> > +	unsigned long mask = ~_REGION_ENTRY_INVALID
> > +				& ~_REGION_ENTRY_TYPE_MASK
> > +				& ~_REGION_ENTRY_LENGTH;
> > +
> > +	if (level)
> > +		mask &= ~_REGION_ENTRY_ORIGIN;
> > +	else
> > +		mask &= ~_SEGMENT_ENTRY_ORIGIN;
> > +
> > +	return  (entry & mask) != 0;
> > +}
> > +
> > +/* Region or segment table traversal function */
> > +static unsigned long
> > +_kl_rsg_table_deref_s390x(unsigned long vaddr, unsigned long table,
> > +							int len, int level)
> > +{
> > +	unsigned long offset, entry;
> > +
> > +	offset = rsg_offset(vaddr, level);
> > +
> > +	/* check if offset is over the table limit. */
> > +	if (offset >= ((len + 1) * TABLE_SIZE)) {
> > +		ERRMSG("offset is over the table limit.\n");
> > +		return 0;
> > +	}
> > +
> > +	if (!readmem(VADDR, table + offset, &entry, sizeof(entry))) {
> > +		if (level)
> > +			ERRMSG("Can't read region table %d entry\n", level);
> > +		else
> > +			ERRMSG("Can't read segment table entry\n");
> > +		return 0;
> > +	}
> > +	/*
> > +	 * Check if the segment table entry could be read and doesn't have
> > +	 * any of the reserved bits set.
> > +	 */
> > +	if (rsg_table_entry_bad(entry, level)) {
> > +		ERRMSG("Bad region/segment table entry.\n");
> > +		return 0;
> > +	}
> > +	/*
> > +	 * Check if the region/segment table entry is with valid
> > +	 * level and not invalid.
> > +	 */
> > +	if ((RSG_TABLE_LEVEL(entry) != level)
> > +			&& (entry & _REGION_ENTRY_INVALID)) {
> > +		ERRMSG("Invalid region/segment table level or entry.\n");
> > +		return 0;
> > +	}
> > +
> > +	return entry;
> > +}
> > +
> > +/* Page table traversal function */
> > +static ulong _kl_pg_table_deref_s390x(unsigned long vaddr, unsigned long table)
> > +{
> > +	unsigned long offset, entry;
> > +
> > +	offset = pte_offset(vaddr);
> > +	readmem(VADDR, table + offset, &entry, sizeof(entry));
> > +	/*
> > +	 * Check if the page table entry could be read and doesn't have
> > +	 * any of the reserved bits set.
> > +	 * Check if the page table entry has the invalid bit set.
> > +	 */
> > +	if (entry &  (_PAGE_CO | _PAGE_ZERO | _PAGE_INVALID)) {
> > +		ERRMSG("Invalid page table entry.\n");
> > +		return 0;
> > +	}
> > +
> > +	return entry;
> > +}
> > +
> > +/* vtop_s390x() - translate virtual address to physical
> > + *	@vaddr: virtual address to translate
> > + *
> > + * Function converts the @vaddr into physical address using page tables.
> > + *
> > + * Return:
> > + *	Physical address or NOT_PADDR if translation fails.
> > + */
> > +static unsigned long long
> > +vtop_s390x(unsigned long vaddr)
> > +{
> > +	unsigned long long paddr = NOT_PADDR;
> > +	unsigned long table, entry;
> > +	int level, len;
> > +
> > +	if (SYMBOL(swapper_pg_dir) == NOT_FOUND_SYMBOL) {
> > +		ERRMSG("Can't get the symbol of swapper_pg_dir.\n");
> > +		return NOT_PADDR;
> > +	}
> > +	table = SYMBOL(swapper_pg_dir);
> > +
> > +	/* Read the first entry to find the number of page table levels. */
> > +	readmem(VADDR, table, &entry, sizeof(entry));
> > +	level = TABLE_LEVEL(entry);
> > +	len = TABLE_LENGTH(entry);
> > +
> > +	if ((vaddr >> (_SEGMENT_PAGE_SHIFT + (_REGION_INDEX_SHIFT * level)))) {
> > +		ERRMSG("Address too big for the number of page table " \
> > +								"levels.\n");
> > +		return NOT_PADDR;
> > +	}
> > +
> > +	/*
> > +	 * Walk the region and segment tables.
> > +	 */
> > +	while (level >= 0) {
> > +		entry = _kl_rsg_table_deref_s390x(vaddr, table, len, level);
> > +		if (!entry) {
> > +			return NOT_PADDR;
> > +		}
> > +		table = entry & _REGION_ENTRY_ORIGIN;
> > +		len = RSG_TABLE_LENGTH(entry);
> > +		level--;
> > +	}
> > +
> > +	/*
> > +	 * Check if this is a large page.
> > +	 * if yes, then add the 1MB page offset (PX + BX) and return the value.
> > +	 * if no, then get the page table entry using PX index.
> > +	 */
> > +	if (entry & _SEGMENT_ENTRY_LARGE) {
> > +		paddr = table + (vaddr &  _PAGE_BYTE_INDEX_MASK);
> > +	} else {
> > +		entry = _kl_pg_table_deref_s390x(vaddr,
> > +					entry & _SEGMENT_ENTRY_ORIGIN);
> > +		if (!entry)
> > +			return NOT_PADDR;
> > +
> > +		/*
> > +		 * Isolate the page origin from the page table entry.
> > +		 * Add the page offset (BX).
> > +		 */
> > +		paddr = (entry &  _REGION_ENTRY_ORIGIN)
> > +			+ (vaddr & _BYTE_INDEX_MASK);
> > +	}
> > +
> > +	return paddr;
> > +}
> > +
> > +unsigned long long
> > +vaddr_to_paddr_s390x(unsigned long vaddr)
> > +{
> > +	unsigned long long paddr;
> > +
> > +	paddr = vaddr_to_paddr_general(vaddr);
> > +	if (paddr != NOT_PADDR)
> > +		return paddr;
> > +
> > +	if ((SYMBOL(vmlist) == NOT_FOUND_SYMBOL)
> > +	    || (OFFSET(vm_struct.addr) == NOT_FOUND_STRUCTURE)) {
> > +		ERRMSG("Can't get necessary information for vmalloc "
> > +			"translation.\n");
> > +		return NOT_PADDR;
> > +	}
> > +
> > +	if (is_vmalloc_addr_s390x(vaddr)) {
> > +		paddr = vtop_s390x(vaddr);
> > +	}
> > +	else {
> > +		ERRMSG("Can't convert a virtual address(%lx) to " \
> > +		    "physical address.\n", vaddr);
> > +		return NOT_PADDR;
> > +	}
> > +
> > +	return paddr;
> > +}
> > +
> > +#endif /* __s390x__ */
> > 
> 
> 
> _______________________________________________
> kexec mailing list
> kexec@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/kexec

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

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

* Re: [PATCH v1] makedumpfile: s390x: Add support for s390x crashdump analysis
  2010-11-12  2:33   ` Ken'ichi Ohmichi
@ 2010-11-12  7:04     ` Mahesh Jagannath Salgaonkar
  2010-11-15  3:54       ` Ken'ichi Ohmichi
  0 siblings, 1 reply; 5+ messages in thread
From: Mahesh Jagannath Salgaonkar @ 2010-11-12  7:04 UTC (permalink / raw)
  To: Ken'ichi Ohmichi
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec-ml, Michael Holzheu,
	Dave Anderson, Reinhard

Hi Ken'ichi,

On 11/12/2010 08:03 AM, Ken'ichi Ohmichi wrote:
> 
> Hi Mahesh,
> 
> On Fri, 12 Nov 2010 10:28:56 +0900
> "Ken'ichi Ohmichi" <oomichi@mxs.nes.nec.co.jp> wrote:
>>
>> On Thu, 11 Nov 2010 11:04:17 +0530
>> Mahesh J Salgaonkar <mahesh@linux.vnet.in.ibm.com> wrote:
>>>
>>> This patch adds support for processing s390x kernel crashdumps.
>>>
>>> The changes have been tested on s390x system.
>>> The dump compression and filtering (for all dump levels 1,2,4,8,16 and 31)
>>> tests are succussfull.
>>
>> What version of linux kernel are the above tests on ?
>> I'd like to write the version on README file.
> 
> Also, please let me know the memory model (flatmem, discontigmem,
> or sparsemem) too.
> 
>   # make menuconfig
>   -> Processor type and features
>      -> Memory model
> 

I have tested this on RHEL6.0 GA kernel version 2.6.32-71.el6.s390x.

The memory model is 'Sparse Memory'

Thanks,
-Mahesh.

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

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

* Re: [PATCH v1] makedumpfile: s390x: Add support for s390x crashdump analysis
  2010-11-12  7:04     ` Mahesh Jagannath Salgaonkar
@ 2010-11-15  3:54       ` Ken'ichi Ohmichi
  2010-11-16  6:33         ` Mahesh Jagannath Salgaonkar
  0 siblings, 1 reply; 5+ messages in thread
From: Ken'ichi Ohmichi @ 2010-11-15  3:54 UTC (permalink / raw)
  To: Mahesh Jagannath Salgaonkar
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec-ml, Michael Holzheu,
	Dave Anderson, Reinhard


Hi Mahesh,

On Fri, 12 Nov 2010 12:34:53 +0530
Mahesh Jagannath Salgaonkar <mahesh@linux.vnet.ibm.com> wrote:
> >>>
> >>> This patch adds support for processing s390x kernel crashdumps.
> >>>
> >>> The changes have been tested on s390x system.
> >>> The dump compression and filtering (for all dump levels 1,2,4,8,16 and 31)
> >>> tests are succussfull.
> >>
> >> What version of linux kernel are the above tests on ?
> >> I'd like to write the version on README file.
> > 
> > Also, please let me know the memory model (flatmem, discontigmem,
> > or sparsemem) too.
> > 
> >   # make menuconfig
> >   -> Processor type and features
> >      -> Memory model
> > 
> 
> I have tested this on RHEL6.0 GA kernel version 2.6.32-71.el6.s390x.
> 
> The memory model is 'Sparse Memory'

Thank you.
Your patch has been merged to git tree.


Thanks
Ken'ichi Ohmichi

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

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

* Re: [PATCH v1] makedumpfile: s390x: Add support for s390x crashdump analysis
  2010-11-15  3:54       ` Ken'ichi Ohmichi
@ 2010-11-16  6:33         ` Mahesh Jagannath Salgaonkar
  0 siblings, 0 replies; 5+ messages in thread
From: Mahesh Jagannath Salgaonkar @ 2010-11-16  6:33 UTC (permalink / raw)
  To: Ken'ichi Ohmichi
  Cc: V Srivatsa, Ananth N Mavinakayanahalli, kexec-ml, Michael Holzheu,
	Dave Anderson, Reinhard

Hi Ken'ichi,

On 11/15/2010 09:24 AM, Ken'ichi Ohmichi wrote:
> 
> Hi Mahesh,
> 
> On Fri, 12 Nov 2010 12:34:53 +0530
> Mahesh Jagannath Salgaonkar <mahesh@linux.vnet.ibm.com> wrote:
>>>>>
>>>>> This patch adds support for processing s390x kernel crashdumps.
>>>>>
>>>>> The changes have been tested on s390x system.
>>>>> The dump compression and filtering (for all dump levels 1,2,4,8,16 and 31)
>>>>> tests are succussfull.
>>>>
>>>> What version of linux kernel are the above tests on ?
>>>> I'd like to write the version on README file.
>>>
>>> Also, please let me know the memory model (flatmem, discontigmem,
>>> or sparsemem) too.
>>>
>>>   # make menuconfig
>>>   -> Processor type and features
>>>      -> Memory model
>>>
>>
>> I have tested this on RHEL6.0 GA kernel version 2.6.32-71.el6.s390x.
>>
>> The memory model is 'Sparse Memory'
> 
> Thank you.
> Your patch has been merged to git tree.
I pulled in your latest changes and tested on s390x system, works fine.

Thanks for your help.
-Mahesh.

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

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

end of thread, other threads:[~2010-11-16  6:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20101111052840.14598.72719.stgit@mars.in.ibm.com>
2010-11-12  1:28 ` [PATCH v1] makedumpfile: s390x: Add support for s390x crashdump analysis Ken'ichi Ohmichi
2010-11-12  2:33   ` Ken'ichi Ohmichi
2010-11-12  7:04     ` Mahesh Jagannath Salgaonkar
2010-11-15  3:54       ` Ken'ichi Ohmichi
2010-11-16  6:33         ` Mahesh Jagannath Salgaonkar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox