All of lore.kernel.org
 help / color / mirror / Atom feed
* [patch v2 00/10] kdump: Patch series for s390 support (version 2)
@ 2011-07-27 12:55 ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

Hello Vivek,

To make progress and for getting at least the "standard" kdump port upstream
soon, I send you now the updated patch series that contain the s390 kdump port
without stand-alone dump support. The support for stand-alone dump tools
can be added later.

Main changes compared to version 1:
1. We use purgatory code
2. We use pre-allocated ELF core header
3. Registers are saved in old kernel
4. Removed meminfo

The following patches are most interesting for you:
[1-4] Common code changes
[9]   S390 kdump kernel backend
[10]  S390 kdump kexec-tools backend

Patches 5-8 are s390 specific preparation patches for the kdump port.

I hope we will make progress.
Thanks!

Michael

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

* [patch v2 00/10] kdump: Patch series for s390 support (version 2)
@ 2011-07-27 12:55 ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

Hello Vivek,

To make progress and for getting at least the "standard" kdump port upstream
soon, I send you now the updated patch series that contain the s390 kdump port
without stand-alone dump support. The support for stand-alone dump tools
can be added later.

Main changes compared to version 1:
1. We use purgatory code
2. We use pre-allocated ELF core header
3. Registers are saved in old kernel
4. Removed meminfo

The following patches are most interesting for you:
[1-4] Common code changes
[9]   S390 kdump kernel backend
[10]  S390 kdump kexec-tools backend

Patches 5-8 are s390 specific preparation patches for the kdump port.

I hope we will make progress.
Thanks!

Michael

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

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

* [patch v2 01/10] kdump: Add KEXEC_CRASH_CONTROL_MEMORY_LIMIT
  2011-07-27 12:55 ` Michael Holzheu
@ 2011-07-27 12:55   ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

[-- Attachment #1: s390-kdump-common-control-limit.patch --]
[-- Type: text/plain, Size: 1260 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

On s390 there is a different KEXEC_CONTROL_MEMORY_LIMIT for the normal and
the kdump kexec case. Therefore this patch introduces a new macro
KEXEC_CRASH_CONTROL_MEMORY_LIMIT. This is set to
KEXEC_CONTROL_MEMORY_LIMIT for all architectures that do not define
KEXEC_CRASH_CONTROL_MEMORY_LIMIT.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 include/linux/kexec.h |    4 ++++
 kernel/kexec.c        |    2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -33,6 +33,10 @@
 #error KEXEC_ARCH not defined
 #endif
 
+#ifndef KEXEC_CRASH_CONTROL_MEMORY_LIMIT
+#define KEXEC_CRASH_CONTROL_MEMORY_LIMIT KEXEC_CONTROL_MEMORY_LIMIT
+#endif
+
 #define KEXEC_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
 #define KEXEC_CORE_NOTE_NAME "CORE"
 #define KEXEC_CORE_NOTE_NAME_BYTES ALIGN(sizeof(KEXEC_CORE_NOTE_NAME), 4)
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -498,7 +498,7 @@ static struct page *kimage_alloc_crash_c
 	while (hole_end <= crashk_res.end) {
 		unsigned long i;
 
-		if (hole_end > KEXEC_CONTROL_MEMORY_LIMIT)
+		if (hole_end > KEXEC_CRASH_CONTROL_MEMORY_LIMIT)
 			break;
 		if (hole_end > crashk_res.end)
 			break;


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

* [patch v2 01/10] kdump: Add KEXEC_CRASH_CONTROL_MEMORY_LIMIT
@ 2011-07-27 12:55   ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

[-- Attachment #1: s390-kdump-common-control-limit.patch --]
[-- Type: text/plain, Size: 1404 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

On s390 there is a different KEXEC_CONTROL_MEMORY_LIMIT for the normal and
the kdump kexec case. Therefore this patch introduces a new macro
KEXEC_CRASH_CONTROL_MEMORY_LIMIT. This is set to
KEXEC_CONTROL_MEMORY_LIMIT for all architectures that do not define
KEXEC_CRASH_CONTROL_MEMORY_LIMIT.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 include/linux/kexec.h |    4 ++++
 kernel/kexec.c        |    2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -33,6 +33,10 @@
 #error KEXEC_ARCH not defined
 #endif
 
+#ifndef KEXEC_CRASH_CONTROL_MEMORY_LIMIT
+#define KEXEC_CRASH_CONTROL_MEMORY_LIMIT KEXEC_CONTROL_MEMORY_LIMIT
+#endif
+
 #define KEXEC_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
 #define KEXEC_CORE_NOTE_NAME "CORE"
 #define KEXEC_CORE_NOTE_NAME_BYTES ALIGN(sizeof(KEXEC_CORE_NOTE_NAME), 4)
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -498,7 +498,7 @@ static struct page *kimage_alloc_crash_c
 	while (hole_end <= crashk_res.end) {
 		unsigned long i;
 
-		if (hole_end > KEXEC_CONTROL_MEMORY_LIMIT)
+		if (hole_end > KEXEC_CRASH_CONTROL_MEMORY_LIMIT)
 			break;
 		if (hole_end > crashk_res.end)
 			break;


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

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

* [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak
  2011-07-27 12:55 ` Michael Holzheu
@ 2011-07-27 12:55   ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

[-- Attachment #1: s390-kdump-common-load_crash_segment.patch --]
[-- Type: text/plain, Size: 1415 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

On s390 we do not create page tables at all for the crashkernel memory.
This requires a s390 specific version for kimage_load_crash_segment().
Therefore this patch declares this function as "__weak". The s390 version is
very simple. It just copies the kexec segment to real memory without using
page tables:

int kimage_load_crash_segment(struct kimage *image,
                              struct kexec_segment *segment)
{
        return copy_from_user_real((void *) segment->mem, segment->buf,
                                   segment->bufsz);
}

There are two main advantages of not creating page tables for the
crashkernel memory:

a) It saves memory. We have scenarios in mind, where crashkernel
   memory can be very large and saving page table space is important.
b) We protect the crashkernel memory from being overwritten.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 kernel/kexec.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -842,8 +842,8 @@ out:
 	return result;
 }
 
-static int kimage_load_crash_segment(struct kimage *image,
-					struct kexec_segment *segment)
+int __weak kimage_load_crash_segment(struct kimage *image,
+				     struct kexec_segment *segment)
 {
 	/* For crash dumps kernels we simply copy the data from
 	 * user space to it's destination.


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

* [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak
@ 2011-07-27 12:55   ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

[-- Attachment #1: s390-kdump-common-load_crash_segment.patch --]
[-- Type: text/plain, Size: 1559 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

On s390 we do not create page tables at all for the crashkernel memory.
This requires a s390 specific version for kimage_load_crash_segment().
Therefore this patch declares this function as "__weak". The s390 version is
very simple. It just copies the kexec segment to real memory without using
page tables:

int kimage_load_crash_segment(struct kimage *image,
                              struct kexec_segment *segment)
{
        return copy_from_user_real((void *) segment->mem, segment->buf,
                                   segment->bufsz);
}

There are two main advantages of not creating page tables for the
crashkernel memory:

a) It saves memory. We have scenarios in mind, where crashkernel
   memory can be very large and saving page table space is important.
b) We protect the crashkernel memory from being overwritten.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 kernel/kexec.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -842,8 +842,8 @@ out:
 	return result;
 }
 
-static int kimage_load_crash_segment(struct kimage *image,
-					struct kexec_segment *segment)
+int __weak kimage_load_crash_segment(struct kimage *image,
+				     struct kexec_segment *segment)
 {
 	/* For crash dumps kernels we simply copy the data from
 	 * user space to it's destination.


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

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

* [patch v2 03/10] kdump: Add size to elfcorehdr kernel parameter
  2011-07-27 12:55 ` Michael Holzheu
@ 2011-07-27 12:55   ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

[-- Attachment #1: s390-kdump-common-elfcorehdr-parm.patch --]
[-- Type: text/plain, Size: 2558 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

Currently only the address of the pre-allocated ELF header is passed with
the elfcorehdr= kernel parameter. In order to reserve memory for the header
in the 2nd kernel also the size is required. To pass the size with this
patch the syntax of the kernel parameter is extended as follows:

elfcorehdr=[size[KMG]@]offset[KMG]

This change is backward compatible because elfcorehdr=size is still allowed.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 Documentation/kernel-parameters.txt |    6 +++---
 include/linux/crash_dump.h          |    1 +
 kernel/crash_dump.c                 |   11 +++++++++++
 3 files changed, 15 insertions(+), 3 deletions(-)

--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -717,10 +717,10 @@ bytes respectively. Such letter suffixes
 			See Documentation/block/as-iosched.txt and
 			Documentation/block/deadline-iosched.txt for details.
 
-	elfcorehdr=	[IA64,PPC,SH,X86]
+	elfcorehdr=[size[KMG]@]offset[KMG] [IA64,PPC,SH,X86,S390]
 			Specifies physical address of start of kernel core
-			image elf header. Generally kexec loader will
-			pass this option to capture kernel.
+			image elf header and optionally the size. Generally
+			kexec loader will pass this option to capture kernel.
 			See Documentation/kdump/kdump.txt for details.
 
 	enable_mtrr_cleanup [X86]
--- a/include/linux/crash_dump.h
+++ b/include/linux/crash_dump.h
@@ -10,6 +10,7 @@
 #define ELFCORE_ADDR_ERR	(-2ULL)
 
 extern unsigned long long elfcorehdr_addr;
+extern unsigned long long elfcorehdr_size;
 
 extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
 						unsigned long, int);
--- a/kernel/crash_dump.c
+++ b/kernel/crash_dump.c
@@ -20,8 +20,15 @@ unsigned long saved_max_pfn;
 unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
 
 /*
+ * stores the size of elf header of crash image
+ */
+unsigned long long elfcorehdr_size;
+
+/*
  * elfcorehdr= specifies the location of elf core header stored by the crashed
  * kernel. This option will be passed by kexec loader to the capture kernel.
+ *
+ * Syntax: elfcorehdr=[size[KMG]@]offset[KMG]
  */
 static int __init setup_elfcorehdr(char *arg)
 {
@@ -29,6 +36,10 @@ static int __init setup_elfcorehdr(char
 	if (!arg)
 		return -EINVAL;
 	elfcorehdr_addr = memparse(arg, &end);
+	if (*end == '@') {
+		elfcorehdr_size = elfcorehdr_addr;
+		elfcorehdr_addr = memparse(end + 1, &end);
+	}
 	return end > arg ? 0 : -EINVAL;
 }
 early_param("elfcorehdr", setup_elfcorehdr);


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

* [patch v2 03/10] kdump: Add size to elfcorehdr kernel parameter
@ 2011-07-27 12:55   ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

[-- Attachment #1: s390-kdump-common-elfcorehdr-parm.patch --]
[-- Type: text/plain, Size: 2702 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

Currently only the address of the pre-allocated ELF header is passed with
the elfcorehdr= kernel parameter. In order to reserve memory for the header
in the 2nd kernel also the size is required. To pass the size with this
patch the syntax of the kernel parameter is extended as follows:

elfcorehdr=[size[KMG]@]offset[KMG]

This change is backward compatible because elfcorehdr=size is still allowed.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 Documentation/kernel-parameters.txt |    6 +++---
 include/linux/crash_dump.h          |    1 +
 kernel/crash_dump.c                 |   11 +++++++++++
 3 files changed, 15 insertions(+), 3 deletions(-)

--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -717,10 +717,10 @@ bytes respectively. Such letter suffixes
 			See Documentation/block/as-iosched.txt and
 			Documentation/block/deadline-iosched.txt for details.
 
-	elfcorehdr=	[IA64,PPC,SH,X86]
+	elfcorehdr=[size[KMG]@]offset[KMG] [IA64,PPC,SH,X86,S390]
 			Specifies physical address of start of kernel core
-			image elf header. Generally kexec loader will
-			pass this option to capture kernel.
+			image elf header and optionally the size. Generally
+			kexec loader will pass this option to capture kernel.
 			See Documentation/kdump/kdump.txt for details.
 
 	enable_mtrr_cleanup [X86]
--- a/include/linux/crash_dump.h
+++ b/include/linux/crash_dump.h
@@ -10,6 +10,7 @@
 #define ELFCORE_ADDR_ERR	(-2ULL)
 
 extern unsigned long long elfcorehdr_addr;
+extern unsigned long long elfcorehdr_size;
 
 extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
 						unsigned long, int);
--- a/kernel/crash_dump.c
+++ b/kernel/crash_dump.c
@@ -20,8 +20,15 @@ unsigned long saved_max_pfn;
 unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
 
 /*
+ * stores the size of elf header of crash image
+ */
+unsigned long long elfcorehdr_size;
+
+/*
  * elfcorehdr= specifies the location of elf core header stored by the crashed
  * kernel. This option will be passed by kexec loader to the capture kernel.
+ *
+ * Syntax: elfcorehdr=[size[KMG]@]offset[KMG]
  */
 static int __init setup_elfcorehdr(char *arg)
 {
@@ -29,6 +36,10 @@ static int __init setup_elfcorehdr(char
 	if (!arg)
 		return -EINVAL;
 	elfcorehdr_addr = memparse(arg, &end);
+	if (*end == '@') {
+		elfcorehdr_size = elfcorehdr_addr;
+		elfcorehdr_addr = memparse(end + 1, &end);
+	}
 	return end > arg ? 0 : -EINVAL;
 }
 early_param("elfcorehdr", setup_elfcorehdr);


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

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

* [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390
  2011-07-27 12:55 ` Michael Holzheu
@ 2011-07-27 12:55   ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

[-- Attachment #1: s390-kdump-common-shutdown-action.patch --]
[-- Type: text/plain, Size: 974 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

On s390 we have the possibility to configure actions that are executed in
case of a kernel panic. E.g. it is possible to automatically trigger an s390
stand-alone dump. The actions are called via a panic notifier.  We also want
to trigger kdump via the notifier call chain. Therefore this patch disables
for s390 the direct kdump invocation in the panic() function.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 kernel/panic.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -84,9 +84,12 @@ NORET_TYPE void panic(const char * fmt,
 	/*
 	 * If we have crashed and we have a crash kernel loaded let it handle
 	 * everything else.
+	 * For s390 kdump is triggered via the panic notifier call chain.
 	 * Do we want to call this before we try to display a message?
 	 */
+#if !defined(CONFIG_S390)
 	crash_kexec(NULL);
+#endif
 
 	kmsg_dump(KMSG_DUMP_PANIC);
 


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

* [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390
@ 2011-07-27 12:55   ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

[-- Attachment #1: s390-kdump-common-shutdown-action.patch --]
[-- Type: text/plain, Size: 1118 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

On s390 we have the possibility to configure actions that are executed in
case of a kernel panic. E.g. it is possible to automatically trigger an s390
stand-alone dump. The actions are called via a panic notifier.  We also want
to trigger kdump via the notifier call chain. Therefore this patch disables
for s390 the direct kdump invocation in the panic() function.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 kernel/panic.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -84,9 +84,12 @@ NORET_TYPE void panic(const char * fmt,
 	/*
 	 * If we have crashed and we have a crash kernel loaded let it handle
 	 * everything else.
+	 * For s390 kdump is triggered via the panic notifier call chain.
 	 * Do we want to call this before we try to display a message?
 	 */
+#if !defined(CONFIG_S390)
 	crash_kexec(NULL);
+#endif
 
 	kmsg_dump(KMSG_DUMP_PANIC);
 


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

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

* [patch v2 05/10] s390: Add PSW restart shutdown trigger
  2011-07-27 12:55 ` Michael Holzheu
@ 2011-07-27 12:55   ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

[-- Attachment #1: s390-kdump-arch-psw-restart.patch --]
[-- Type: text/plain, Size: 10593 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

With this patch a new S390 shutdown trigger "restart" is added. If under
z/VM "systerm restart" is entered or under the HMC the "PSW restart" button
is pressed, the PSW located at 0 (31 bit) or 0x1a0 (64 bit) bit is loaded.
Now we execute do_restart() that processes the restart action that is
defined under /sys/firmware/shutdown_actions/on_restart. Currently the
following actions are possible: reipl (default), stop, vmcmd, dump, and
dump_reipl.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 arch/s390/include/asm/lowcore.h |   11 +++++++++--
 arch/s390/include/asm/system.h  |    1 +
 arch/s390/kernel/asm-offsets.c  |    1 +
 arch/s390/kernel/entry.S        |   28 ++++++++++++++++++++++++++++
 arch/s390/kernel/entry64.S      |   20 ++++++++++++++++++++
 arch/s390/kernel/ipl.c          |   39 ++++++++++++++++++++++++++++++++++++++-
 arch/s390/kernel/setup.c        |   24 +++++++++++++++++++++++-
 arch/s390/kernel/smp.c          |    8 ++++++++
 arch/s390/mm/maccess.c          |   16 ++++++++++++++++
 9 files changed, 144 insertions(+), 4 deletions(-)

--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -18,6 +18,7 @@ void system_call(void);
 void pgm_check_handler(void);
 void mcck_int_handler(void);
 void io_int_handler(void);
+void psw_restart_int_handler(void);
 
 #ifdef CONFIG_32BIT
 
@@ -150,7 +151,10 @@ struct _lowcore {
 	 */
 	__u32	ipib;				/* 0x0e00 */
 	__u32	ipib_checksum;			/* 0x0e04 */
-	__u8	pad_0x0e08[0x0f00-0x0e08];	/* 0x0e08 */
+
+	/* 64 bit save area */
+	__u64	save_area_64;			/* 0x0e08 */
+	__u8	pad_0x0e10[0x0f00-0x0e10];	/* 0x0e10 */
 
 	/* Extended facility list */
 	__u64	stfle_fac_list[32];		/* 0x0f00 */
@@ -286,7 +290,10 @@ struct _lowcore {
 	 */
 	__u64	ipib;				/* 0x0e00 */
 	__u32	ipib_checksum;			/* 0x0e08 */
-	__u8	pad_0x0e0c[0x0f00-0x0e0c];	/* 0x0e0c */
+
+	/* 64 bit save area */
+	__u64	save_area_64;			/* 0x0e0c */
+	__u8	pad_0x0e14[0x0f00-0x0e14];	/* 0x0e14 */
 
 	/* Extended facility list */
 	__u64	stfle_fac_list[32];		/* 0x0f00 */
--- a/arch/s390/include/asm/system.h
+++ b/arch/s390/include/asm/system.h
@@ -113,6 +113,7 @@ extern void pfault_fini(void);
 
 extern void cmma_init(void);
 extern int memcpy_real(void *, void *, size_t);
+extern void copy_to_absolute_zero(void *dest, void *src, size_t count);
 
 #define finish_arch_switch(prev) do {					     \
 	set_fs(current->thread.mm_segment);				     \
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -142,6 +142,7 @@ int main(void)
 	DEFINE(__LC_FPREGS_SAVE_AREA, offsetof(struct _lowcore, floating_pt_save_area));
 	DEFINE(__LC_GPREGS_SAVE_AREA, offsetof(struct _lowcore, gpregs_save_area));
 	DEFINE(__LC_CREGS_SAVE_AREA, offsetof(struct _lowcore, cregs_save_area));
+	DEFINE(__LC_SAVE_AREA_64, offsetof(struct _lowcore, save_area_64));
 #ifdef CONFIG_32BIT
 	DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, extended_save_area_addr));
 #else /* CONFIG_32BIT */
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -849,6 +849,34 @@ restart_crash:
 restart_go:
 #endif
 
+#
+# PSW restart interrupt handler
+#
+ENTRY(psw_restart_int_handler)
+	st	%r15,__LC_SAVE_AREA_64(%r0)	# save r15
+	basr	%r15,0
+0:	l	%r15,.Lrestart_stack-0b(%r15)	# load restart stack
+	l	%r15,0(%r15)
+	ahi	%r15,-SP_SIZE			# make room for pt_regs
+	stm	%r0,%r14,SP_R0(%r15)		# store gprs %r0-%r14 to stack
+	mvc	SP_R15(4,%r15),__LC_SAVE_AREA_64(%r0)# store saved %r15 to stack
+	mvc	SP_PSW(8,%r15),__LC_RST_OLD_PSW(%r0) # store restart old psw
+	xc	__SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0
+	basr	%r14,0
+1:	l	%r14,.Ldo_restart-1b(%r14)
+	basr	%r14,%r14
+
+	basr	%r14,0				# load disabled wait PSW if
+2:	lpsw	restart_psw_crash-2b(%r14)	# do_restart returns
+	.align 4
+.Ldo_restart:
+	.long	do_restart
+.Lrestart_stack:
+	.long	restart_stack
+	.align 8
+restart_psw_crash:
+	.long	0x000a0000,0x00000000 + restart_psw_crash
+
 	.section .kprobes.text, "ax"
 
 #ifdef CONFIG_CHECK_STACK
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -865,6 +865,26 @@ restart_crash:
 restart_go:
 #endif
 
+#
+# PSW restart interrupt handler
+#
+ENTRY(psw_restart_int_handler)
+	stg	%r15,__LC_SAVE_AREA_64(%r0)	# save r15
+	larl	%r15,restart_stack		# load restart stack
+	lg	%r15,0(%r15)
+	aghi	%r15,-SP_SIZE			# make room for pt_regs
+	stmg	%r0,%r14,SP_R0(%r15)		# store gprs %r0-%r14 to stack
+	mvc	SP_R15(8,%r15),__LC_SAVE_AREA_64(%r0)# store saved %r15 to stack
+	mvc	SP_PSW(16,%r15),__LC_RST_OLD_PSW(%r0)# store restart old psw
+	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0
+	brasl	%r14,do_restart
+
+	larl	%r14,restart_psw_crash		# load disabled wait PSW if
+	lpswe	0(%r14)				# do_restart returns
+	.align 8
+restart_psw_crash:
+	.quad	0x0002000080000000,0x0000000000000000 + restart_psw_crash
+
 	.section .kprobes.text, "ax"
 
 #ifdef CONFIG_CHECK_STACK
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -45,11 +45,13 @@
  * - halt
  * - power off
  * - reipl
+ * - restart
  */
 #define ON_PANIC_STR		"on_panic"
 #define ON_HALT_STR		"on_halt"
 #define ON_POFF_STR		"on_poff"
 #define ON_REIPL_STR		"on_reboot"
+#define ON_RESTART_STR		"on_restart"
 
 struct shutdown_action;
 struct shutdown_trigger {
@@ -1544,17 +1546,20 @@ static char vmcmd_on_reboot[128];
 static char vmcmd_on_panic[128];
 static char vmcmd_on_halt[128];
 static char vmcmd_on_poff[128];
+static char vmcmd_on_restart[128];
 
 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot);
 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic);
 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt);
 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff);
+DEFINE_IPL_ATTR_STR_RW(vmcmd, on_restart, "%s\n", "%s\n", vmcmd_on_restart);
 
 static struct attribute *vmcmd_attrs[] = {
 	&sys_vmcmd_on_reboot_attr.attr,
 	&sys_vmcmd_on_panic_attr.attr,
 	&sys_vmcmd_on_halt_attr.attr,
 	&sys_vmcmd_on_poff_attr.attr,
+	&sys_vmcmd_on_restart_attr.attr,
 	NULL,
 };
 
@@ -1576,6 +1581,8 @@ static void vmcmd_run(struct shutdown_tr
 		cmd = vmcmd_on_halt;
 	else if (strcmp(trigger->name, ON_POFF_STR) == 0)
 		cmd = vmcmd_on_poff;
+	else if (strcmp(trigger->name, ON_RESTART_STR) == 0)
+		cmd = vmcmd_on_restart;
 	else
 		return;
 
@@ -1707,6 +1714,34 @@ static void do_panic(void)
 	stop_run(&on_panic_trigger);
 }
 
+/* on restart */
+
+static struct shutdown_trigger on_restart_trigger = {ON_RESTART_STR,
+	&reipl_action};
+
+static ssize_t on_restart_show(struct kobject *kobj,
+			       struct kobj_attribute *attr, char *page)
+{
+	return sprintf(page, "%s\n", on_restart_trigger.action->name);
+}
+
+static ssize_t on_restart_store(struct kobject *kobj,
+				struct kobj_attribute *attr,
+				const char *buf, size_t len)
+{
+	return set_trigger(buf, &on_restart_trigger, len);
+}
+
+static struct kobj_attribute on_restart_attr =
+	__ATTR(on_restart, 0644, on_restart_show, on_restart_store);
+
+void do_restart(void)
+{
+	smp_send_stop();
+	on_restart_trigger.action->fn(&on_restart_trigger);
+	stop_run(&on_restart_trigger);
+}
+
 /* on halt */
 
 static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action};
@@ -1783,7 +1818,9 @@ static void __init shutdown_triggers_ini
 	if (sysfs_create_file(&shutdown_actions_kset->kobj,
 			      &on_poff_attr.attr))
 		goto fail;
-
+	if (sysfs_create_file(&shutdown_actions_kset->kobj,
+			      &on_restart_attr.attr))
+		goto fail;
 	return;
 fail:
 	panic("shutdown_triggers_init failed\n");
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -346,7 +346,7 @@ setup_lowcore(void)
 	lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
 	lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
 	lc->restart_psw.addr =
-		PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
+		PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
 	if (user_mode != HOME_SPACE_MODE)
 		lc->restart_psw.mask |= PSW_ASC_HOME;
 	lc->external_new_psw.mask = psw_kernel_bits;
@@ -529,6 +529,27 @@ static void __init setup_memory_end(void
 		memory_end = memory_size;
 }
 
+void *restart_stack __attribute__((__section__(".data")));
+
+/*
+ * Setup new PSW and allocate stack for PSW restart interrupt
+ */
+static void __init setup_restart_psw(void)
+{
+	psw_t psw;
+
+	restart_stack = __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0);
+	restart_stack += ASYNC_SIZE;
+
+	/*
+	 * Setup restart PSW for absolute zero lowcore. This is necesary
+	 * if PSW restart is done on an offline CPU that has lowcore zero
+	 */
+	psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
+	psw.addr = PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
+	copy_to_absolute_zero(&S390_lowcore.restart_psw, &psw, sizeof(psw));
+}
+
 static void __init
 setup_memory(void)
 {
@@ -792,6 +813,7 @@ setup_arch(char **cmdline_p)
 	setup_addressing_mode();
 	setup_memory();
 	setup_resources();
+	setup_restart_psw();
 	setup_lowcore();
 
         cpu_init();
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -470,6 +470,11 @@ int __cpuinit start_secondary(void *cpuv
 	ipi_call_unlock();
 	/* Switch on interrupts */
 	local_irq_enable();
+	__ctl_clear_bit(0, 28); /* Disable lowcore protection */
+	S390_lowcore.restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
+	S390_lowcore.restart_psw.addr =
+		PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
+	__ctl_set_bit(0, 28); /* Enable lowcore protection */
 	/* cpu_idle will call schedule for us */
 	cpu_idle();
 	return 0;
@@ -507,6 +512,9 @@ static int __cpuinit smp_alloc_lowcore(i
 	memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512);
 	lowcore->async_stack = async_stack + ASYNC_SIZE;
 	lowcore->panic_stack = panic_stack + PAGE_SIZE;
+	lowcore->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
+	lowcore->restart_psw.addr =
+		PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
 
 #ifndef CONFIG_64BIT
 	if (MACHINE_HAS_IEEE) {
--- a/arch/s390/mm/maccess.c
+++ b/arch/s390/mm/maccess.c
@@ -85,3 +85,19 @@ int memcpy_real(void *dest, void *src, s
 	arch_local_irq_restore(flags);
 	return rc;
 }
+
+/*
+ * Copy memory to absolute zero
+ */
+void copy_to_absolute_zero(void *dest, void *src, size_t count)
+{
+	unsigned long cr0;
+
+	BUG_ON((unsigned long) dest + count >= sizeof(struct _lowcore));
+	preempt_disable();
+	__ctl_store(cr0, 0, 0);
+	__ctl_clear_bit(0, 28); /* disable lowcore protection */
+	memcpy_real(dest + store_prefix(), src, count);
+	__ctl_load(cr0, 0, 0);
+	preempt_enable();
+}


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

* [patch v2 05/10] s390: Add PSW restart shutdown trigger
@ 2011-07-27 12:55   ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

[-- Attachment #1: s390-kdump-arch-psw-restart.patch --]
[-- Type: text/plain, Size: 10737 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

With this patch a new S390 shutdown trigger "restart" is added. If under
z/VM "systerm restart" is entered or under the HMC the "PSW restart" button
is pressed, the PSW located at 0 (31 bit) or 0x1a0 (64 bit) bit is loaded.
Now we execute do_restart() that processes the restart action that is
defined under /sys/firmware/shutdown_actions/on_restart. Currently the
following actions are possible: reipl (default), stop, vmcmd, dump, and
dump_reipl.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 arch/s390/include/asm/lowcore.h |   11 +++++++++--
 arch/s390/include/asm/system.h  |    1 +
 arch/s390/kernel/asm-offsets.c  |    1 +
 arch/s390/kernel/entry.S        |   28 ++++++++++++++++++++++++++++
 arch/s390/kernel/entry64.S      |   20 ++++++++++++++++++++
 arch/s390/kernel/ipl.c          |   39 ++++++++++++++++++++++++++++++++++++++-
 arch/s390/kernel/setup.c        |   24 +++++++++++++++++++++++-
 arch/s390/kernel/smp.c          |    8 ++++++++
 arch/s390/mm/maccess.c          |   16 ++++++++++++++++
 9 files changed, 144 insertions(+), 4 deletions(-)

--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -18,6 +18,7 @@ void system_call(void);
 void pgm_check_handler(void);
 void mcck_int_handler(void);
 void io_int_handler(void);
+void psw_restart_int_handler(void);
 
 #ifdef CONFIG_32BIT
 
@@ -150,7 +151,10 @@ struct _lowcore {
 	 */
 	__u32	ipib;				/* 0x0e00 */
 	__u32	ipib_checksum;			/* 0x0e04 */
-	__u8	pad_0x0e08[0x0f00-0x0e08];	/* 0x0e08 */
+
+	/* 64 bit save area */
+	__u64	save_area_64;			/* 0x0e08 */
+	__u8	pad_0x0e10[0x0f00-0x0e10];	/* 0x0e10 */
 
 	/* Extended facility list */
 	__u64	stfle_fac_list[32];		/* 0x0f00 */
@@ -286,7 +290,10 @@ struct _lowcore {
 	 */
 	__u64	ipib;				/* 0x0e00 */
 	__u32	ipib_checksum;			/* 0x0e08 */
-	__u8	pad_0x0e0c[0x0f00-0x0e0c];	/* 0x0e0c */
+
+	/* 64 bit save area */
+	__u64	save_area_64;			/* 0x0e0c */
+	__u8	pad_0x0e14[0x0f00-0x0e14];	/* 0x0e14 */
 
 	/* Extended facility list */
 	__u64	stfle_fac_list[32];		/* 0x0f00 */
--- a/arch/s390/include/asm/system.h
+++ b/arch/s390/include/asm/system.h
@@ -113,6 +113,7 @@ extern void pfault_fini(void);
 
 extern void cmma_init(void);
 extern int memcpy_real(void *, void *, size_t);
+extern void copy_to_absolute_zero(void *dest, void *src, size_t count);
 
 #define finish_arch_switch(prev) do {					     \
 	set_fs(current->thread.mm_segment);				     \
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -142,6 +142,7 @@ int main(void)
 	DEFINE(__LC_FPREGS_SAVE_AREA, offsetof(struct _lowcore, floating_pt_save_area));
 	DEFINE(__LC_GPREGS_SAVE_AREA, offsetof(struct _lowcore, gpregs_save_area));
 	DEFINE(__LC_CREGS_SAVE_AREA, offsetof(struct _lowcore, cregs_save_area));
+	DEFINE(__LC_SAVE_AREA_64, offsetof(struct _lowcore, save_area_64));
 #ifdef CONFIG_32BIT
 	DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, extended_save_area_addr));
 #else /* CONFIG_32BIT */
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -849,6 +849,34 @@ restart_crash:
 restart_go:
 #endif
 
+#
+# PSW restart interrupt handler
+#
+ENTRY(psw_restart_int_handler)
+	st	%r15,__LC_SAVE_AREA_64(%r0)	# save r15
+	basr	%r15,0
+0:	l	%r15,.Lrestart_stack-0b(%r15)	# load restart stack
+	l	%r15,0(%r15)
+	ahi	%r15,-SP_SIZE			# make room for pt_regs
+	stm	%r0,%r14,SP_R0(%r15)		# store gprs %r0-%r14 to stack
+	mvc	SP_R15(4,%r15),__LC_SAVE_AREA_64(%r0)# store saved %r15 to stack
+	mvc	SP_PSW(8,%r15),__LC_RST_OLD_PSW(%r0) # store restart old psw
+	xc	__SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0
+	basr	%r14,0
+1:	l	%r14,.Ldo_restart-1b(%r14)
+	basr	%r14,%r14
+
+	basr	%r14,0				# load disabled wait PSW if
+2:	lpsw	restart_psw_crash-2b(%r14)	# do_restart returns
+	.align 4
+.Ldo_restart:
+	.long	do_restart
+.Lrestart_stack:
+	.long	restart_stack
+	.align 8
+restart_psw_crash:
+	.long	0x000a0000,0x00000000 + restart_psw_crash
+
 	.section .kprobes.text, "ax"
 
 #ifdef CONFIG_CHECK_STACK
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -865,6 +865,26 @@ restart_crash:
 restart_go:
 #endif
 
+#
+# PSW restart interrupt handler
+#
+ENTRY(psw_restart_int_handler)
+	stg	%r15,__LC_SAVE_AREA_64(%r0)	# save r15
+	larl	%r15,restart_stack		# load restart stack
+	lg	%r15,0(%r15)
+	aghi	%r15,-SP_SIZE			# make room for pt_regs
+	stmg	%r0,%r14,SP_R0(%r15)		# store gprs %r0-%r14 to stack
+	mvc	SP_R15(8,%r15),__LC_SAVE_AREA_64(%r0)# store saved %r15 to stack
+	mvc	SP_PSW(16,%r15),__LC_RST_OLD_PSW(%r0)# store restart old psw
+	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0
+	brasl	%r14,do_restart
+
+	larl	%r14,restart_psw_crash		# load disabled wait PSW if
+	lpswe	0(%r14)				# do_restart returns
+	.align 8
+restart_psw_crash:
+	.quad	0x0002000080000000,0x0000000000000000 + restart_psw_crash
+
 	.section .kprobes.text, "ax"
 
 #ifdef CONFIG_CHECK_STACK
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -45,11 +45,13 @@
  * - halt
  * - power off
  * - reipl
+ * - restart
  */
 #define ON_PANIC_STR		"on_panic"
 #define ON_HALT_STR		"on_halt"
 #define ON_POFF_STR		"on_poff"
 #define ON_REIPL_STR		"on_reboot"
+#define ON_RESTART_STR		"on_restart"
 
 struct shutdown_action;
 struct shutdown_trigger {
@@ -1544,17 +1546,20 @@ static char vmcmd_on_reboot[128];
 static char vmcmd_on_panic[128];
 static char vmcmd_on_halt[128];
 static char vmcmd_on_poff[128];
+static char vmcmd_on_restart[128];
 
 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot);
 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic);
 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt);
 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff);
+DEFINE_IPL_ATTR_STR_RW(vmcmd, on_restart, "%s\n", "%s\n", vmcmd_on_restart);
 
 static struct attribute *vmcmd_attrs[] = {
 	&sys_vmcmd_on_reboot_attr.attr,
 	&sys_vmcmd_on_panic_attr.attr,
 	&sys_vmcmd_on_halt_attr.attr,
 	&sys_vmcmd_on_poff_attr.attr,
+	&sys_vmcmd_on_restart_attr.attr,
 	NULL,
 };
 
@@ -1576,6 +1581,8 @@ static void vmcmd_run(struct shutdown_tr
 		cmd = vmcmd_on_halt;
 	else if (strcmp(trigger->name, ON_POFF_STR) == 0)
 		cmd = vmcmd_on_poff;
+	else if (strcmp(trigger->name, ON_RESTART_STR) == 0)
+		cmd = vmcmd_on_restart;
 	else
 		return;
 
@@ -1707,6 +1714,34 @@ static void do_panic(void)
 	stop_run(&on_panic_trigger);
 }
 
+/* on restart */
+
+static struct shutdown_trigger on_restart_trigger = {ON_RESTART_STR,
+	&reipl_action};
+
+static ssize_t on_restart_show(struct kobject *kobj,
+			       struct kobj_attribute *attr, char *page)
+{
+	return sprintf(page, "%s\n", on_restart_trigger.action->name);
+}
+
+static ssize_t on_restart_store(struct kobject *kobj,
+				struct kobj_attribute *attr,
+				const char *buf, size_t len)
+{
+	return set_trigger(buf, &on_restart_trigger, len);
+}
+
+static struct kobj_attribute on_restart_attr =
+	__ATTR(on_restart, 0644, on_restart_show, on_restart_store);
+
+void do_restart(void)
+{
+	smp_send_stop();
+	on_restart_trigger.action->fn(&on_restart_trigger);
+	stop_run(&on_restart_trigger);
+}
+
 /* on halt */
 
 static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action};
@@ -1783,7 +1818,9 @@ static void __init shutdown_triggers_ini
 	if (sysfs_create_file(&shutdown_actions_kset->kobj,
 			      &on_poff_attr.attr))
 		goto fail;
-
+	if (sysfs_create_file(&shutdown_actions_kset->kobj,
+			      &on_restart_attr.attr))
+		goto fail;
 	return;
 fail:
 	panic("shutdown_triggers_init failed\n");
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -346,7 +346,7 @@ setup_lowcore(void)
 	lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
 	lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
 	lc->restart_psw.addr =
-		PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
+		PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
 	if (user_mode != HOME_SPACE_MODE)
 		lc->restart_psw.mask |= PSW_ASC_HOME;
 	lc->external_new_psw.mask = psw_kernel_bits;
@@ -529,6 +529,27 @@ static void __init setup_memory_end(void
 		memory_end = memory_size;
 }
 
+void *restart_stack __attribute__((__section__(".data")));
+
+/*
+ * Setup new PSW and allocate stack for PSW restart interrupt
+ */
+static void __init setup_restart_psw(void)
+{
+	psw_t psw;
+
+	restart_stack = __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0);
+	restart_stack += ASYNC_SIZE;
+
+	/*
+	 * Setup restart PSW for absolute zero lowcore. This is necesary
+	 * if PSW restart is done on an offline CPU that has lowcore zero
+	 */
+	psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
+	psw.addr = PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
+	copy_to_absolute_zero(&S390_lowcore.restart_psw, &psw, sizeof(psw));
+}
+
 static void __init
 setup_memory(void)
 {
@@ -792,6 +813,7 @@ setup_arch(char **cmdline_p)
 	setup_addressing_mode();
 	setup_memory();
 	setup_resources();
+	setup_restart_psw();
 	setup_lowcore();
 
         cpu_init();
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -470,6 +470,11 @@ int __cpuinit start_secondary(void *cpuv
 	ipi_call_unlock();
 	/* Switch on interrupts */
 	local_irq_enable();
+	__ctl_clear_bit(0, 28); /* Disable lowcore protection */
+	S390_lowcore.restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
+	S390_lowcore.restart_psw.addr =
+		PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
+	__ctl_set_bit(0, 28); /* Enable lowcore protection */
 	/* cpu_idle will call schedule for us */
 	cpu_idle();
 	return 0;
@@ -507,6 +512,9 @@ static int __cpuinit smp_alloc_lowcore(i
 	memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512);
 	lowcore->async_stack = async_stack + ASYNC_SIZE;
 	lowcore->panic_stack = panic_stack + PAGE_SIZE;
+	lowcore->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
+	lowcore->restart_psw.addr =
+		PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
 
 #ifndef CONFIG_64BIT
 	if (MACHINE_HAS_IEEE) {
--- a/arch/s390/mm/maccess.c
+++ b/arch/s390/mm/maccess.c
@@ -85,3 +85,19 @@ int memcpy_real(void *dest, void *src, s
 	arch_local_irq_restore(flags);
 	return rc;
 }
+
+/*
+ * Copy memory to absolute zero
+ */
+void copy_to_absolute_zero(void *dest, void *src, size_t count)
+{
+	unsigned long cr0;
+
+	BUG_ON((unsigned long) dest + count >= sizeof(struct _lowcore));
+	preempt_disable();
+	__ctl_store(cr0, 0, 0);
+	__ctl_clear_bit(0, 28); /* disable lowcore protection */
+	memcpy_real(dest + store_prefix(), src, count);
+	__ctl_load(cr0, 0, 0);
+	preempt_enable();
+}


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

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

* [patch v2 06/10] s390: Export store_status() function
  2011-07-27 12:55 ` Michael Holzheu
@ 2011-07-27 12:55   ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

[-- Attachment #1: s390-kdump-arch-store-status.patch --]
[-- Type: text/plain, Size: 4342 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

For kdump we need a store status function to save the registers for the
current CPU. Therefore this patch exports a function "store_status()".
In addition to that now also floating point registers are saved correctly.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 arch/s390/kernel/reipl64.S |   80 +++++++++++++++++++++++++++++++++------------
 1 file changed, 60 insertions(+), 20 deletions(-)

--- a/arch/s390/kernel/reipl64.S
+++ b/arch/s390/kernel/reipl64.S
@@ -1,5 +1,5 @@
 /*
- *    Copyright IBM Corp 2000,2009
+ *    Copyright IBM Corp 2000,2011
  *    Author(s): Holger Smolinski <Holger.Smolinski@de.ibm.com>,
  *		 Denis Joseph Barrow,
  */
@@ -8,6 +8,64 @@
 #include <asm/asm-offsets.h>
 
 #
+# store_status
+#
+# Prerequisites to run this function:
+# - Prefix register is set to zero
+# - Original prefix register is stored in "dump_prefix_page"
+# - Lowcore protection is off
+#
+ENTRY(store_status)
+	/* Save register one and load save area base */
+	stg	%r1,__LC_SAVE_AREA_64(%r0)
+	lghi	%r1,SAVE_AREA_BASE
+	/* General purpose registers */
+	stmg	%r0,%r15,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	lg	%r2,__LC_SAVE_AREA_64(%r0)
+	stg	%r2,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE+8(%r1)
+	/* Control registers */
+	stctg	%c0,%c15,__LC_CREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	/* Access registers */
+	stam	%a0,%a15,__LC_AREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	/* Floating point registers */
+	std	%f0, 0x00 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f1, 0x08 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f2, 0x10 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f3, 0x18 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f4, 0x20 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f5, 0x28 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f6, 0x30 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f7, 0x38 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f8, 0x40 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f9, 0x48 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f10,0x50 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f11,0x58 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f12,0x60 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f13,0x68 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f14,0x70 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f15,0x78 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	/* Floating point control register */
+	stfpc	__LC_FP_CREG_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	/* CPU timer */
+	stpt	__LC_CPU_TIMER_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	/* Saved prefix register */
+	larl	%r2,dump_prefix_page
+	mvc	__LC_PREFIX_SAVE_AREA-SAVE_AREA_BASE(4,%r1),0(%r2)
+	/* Clock comparator - seven bytes */
+	larl	%r2,.Lclkcmp
+	stckc	0(%r2)
+	mvc	__LC_CLOCK_COMP_SAVE_AREA-SAVE_AREA_BASE + 1(7,%r1),1(%r2)
+	/* Program status word */
+	epsw	%r2,%r3
+	st	%r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 0(%r1)
+	st	%r3,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 4(%r1)
+	larl	%r2,store_status
+	stg	%r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 8(%r1)
+	br	%r14
+.align	8
+.Lclkcmp:	.quad	0x0000000000000000
+
+#
 # do_reipl_asm
 # Parameter: r2 = schid of reipl device
 #
@@ -15,22 +73,7 @@
 ENTRY(do_reipl_asm)
 		basr	%r13,0
 .Lpg0:		lpswe	.Lnewpsw-.Lpg0(%r13)
-.Lpg1:		# do store status of all registers
-
-		stg	%r1,.Lregsave-.Lpg0(%r13)
-		lghi	%r1,0x1000
-		stmg	%r0,%r15,__LC_GPREGS_SAVE_AREA-0x1000(%r1)
-		lg	%r0,.Lregsave-.Lpg0(%r13)
-		stg	%r0,__LC_GPREGS_SAVE_AREA-0x1000+8(%r1)
-		stctg	%c0,%c15,__LC_CREGS_SAVE_AREA-0x1000(%r1)
-		stam	%a0,%a15,__LC_AREGS_SAVE_AREA-0x1000(%r1)
-		lg	%r10,.Ldump_pfx-.Lpg0(%r13)
-		mvc	__LC_PREFIX_SAVE_AREA-0x1000(4,%r1),0(%r10)
-		stfpc	__LC_FP_CREG_SAVE_AREA-0x1000(%r1)
-		stckc	.Lclkcmp-.Lpg0(%r13)
-		mvc	__LC_CLOCK_COMP_SAVE_AREA-0x1000(7,%r1),.Lclkcmp-.Lpg0(%r13)
-		stpt	__LC_CPU_TIMER_SAVE_AREA-0x1000(%r1)
-		stg	%r13, __LC_PSW_SAVE_AREA-0x1000+8(%r1)
+.Lpg1:		brasl	%r14,store_status
 
 		lctlg	%c6,%c6,.Lall-.Lpg0(%r13)
 		lgr	%r1,%r2
@@ -67,10 +110,7 @@ ENTRY(do_reipl_asm)
 		st	%r14,.Ldispsw+12-.Lpg0(%r13)
 		lpswe	.Ldispsw-.Lpg0(%r13)
 		.align	8
-.Lclkcmp:	.quad	0x0000000000000000
 .Lall:		.quad	0x00000000ff000000
-.Ldump_pfx:	.quad	dump_prefix_page
-.Lregsave:	.quad	0x0000000000000000
 		.align	16
 /*
  * These addresses have to be 31 bit otherwise


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

* [patch v2 06/10] s390: Export store_status() function
@ 2011-07-27 12:55   ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

[-- Attachment #1: s390-kdump-arch-store-status.patch --]
[-- Type: text/plain, Size: 4486 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

For kdump we need a store status function to save the registers for the
current CPU. Therefore this patch exports a function "store_status()".
In addition to that now also floating point registers are saved correctly.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 arch/s390/kernel/reipl64.S |   80 +++++++++++++++++++++++++++++++++------------
 1 file changed, 60 insertions(+), 20 deletions(-)

--- a/arch/s390/kernel/reipl64.S
+++ b/arch/s390/kernel/reipl64.S
@@ -1,5 +1,5 @@
 /*
- *    Copyright IBM Corp 2000,2009
+ *    Copyright IBM Corp 2000,2011
  *    Author(s): Holger Smolinski <Holger.Smolinski@de.ibm.com>,
  *		 Denis Joseph Barrow,
  */
@@ -8,6 +8,64 @@
 #include <asm/asm-offsets.h>
 
 #
+# store_status
+#
+# Prerequisites to run this function:
+# - Prefix register is set to zero
+# - Original prefix register is stored in "dump_prefix_page"
+# - Lowcore protection is off
+#
+ENTRY(store_status)
+	/* Save register one and load save area base */
+	stg	%r1,__LC_SAVE_AREA_64(%r0)
+	lghi	%r1,SAVE_AREA_BASE
+	/* General purpose registers */
+	stmg	%r0,%r15,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	lg	%r2,__LC_SAVE_AREA_64(%r0)
+	stg	%r2,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE+8(%r1)
+	/* Control registers */
+	stctg	%c0,%c15,__LC_CREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	/* Access registers */
+	stam	%a0,%a15,__LC_AREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	/* Floating point registers */
+	std	%f0, 0x00 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f1, 0x08 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f2, 0x10 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f3, 0x18 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f4, 0x20 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f5, 0x28 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f6, 0x30 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f7, 0x38 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f8, 0x40 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f9, 0x48 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f10,0x50 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f11,0x58 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f12,0x60 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f13,0x68 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f14,0x70 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	std	%f15,0x78 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	/* Floating point control register */
+	stfpc	__LC_FP_CREG_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	/* CPU timer */
+	stpt	__LC_CPU_TIMER_SAVE_AREA-SAVE_AREA_BASE(%r1)
+	/* Saved prefix register */
+	larl	%r2,dump_prefix_page
+	mvc	__LC_PREFIX_SAVE_AREA-SAVE_AREA_BASE(4,%r1),0(%r2)
+	/* Clock comparator - seven bytes */
+	larl	%r2,.Lclkcmp
+	stckc	0(%r2)
+	mvc	__LC_CLOCK_COMP_SAVE_AREA-SAVE_AREA_BASE + 1(7,%r1),1(%r2)
+	/* Program status word */
+	epsw	%r2,%r3
+	st	%r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 0(%r1)
+	st	%r3,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 4(%r1)
+	larl	%r2,store_status
+	stg	%r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 8(%r1)
+	br	%r14
+.align	8
+.Lclkcmp:	.quad	0x0000000000000000
+
+#
 # do_reipl_asm
 # Parameter: r2 = schid of reipl device
 #
@@ -15,22 +73,7 @@
 ENTRY(do_reipl_asm)
 		basr	%r13,0
 .Lpg0:		lpswe	.Lnewpsw-.Lpg0(%r13)
-.Lpg1:		# do store status of all registers
-
-		stg	%r1,.Lregsave-.Lpg0(%r13)
-		lghi	%r1,0x1000
-		stmg	%r0,%r15,__LC_GPREGS_SAVE_AREA-0x1000(%r1)
-		lg	%r0,.Lregsave-.Lpg0(%r13)
-		stg	%r0,__LC_GPREGS_SAVE_AREA-0x1000+8(%r1)
-		stctg	%c0,%c15,__LC_CREGS_SAVE_AREA-0x1000(%r1)
-		stam	%a0,%a15,__LC_AREGS_SAVE_AREA-0x1000(%r1)
-		lg	%r10,.Ldump_pfx-.Lpg0(%r13)
-		mvc	__LC_PREFIX_SAVE_AREA-0x1000(4,%r1),0(%r10)
-		stfpc	__LC_FP_CREG_SAVE_AREA-0x1000(%r1)
-		stckc	.Lclkcmp-.Lpg0(%r13)
-		mvc	__LC_CLOCK_COMP_SAVE_AREA-0x1000(7,%r1),.Lclkcmp-.Lpg0(%r13)
-		stpt	__LC_CPU_TIMER_SAVE_AREA-0x1000(%r1)
-		stg	%r13, __LC_PSW_SAVE_AREA-0x1000+8(%r1)
+.Lpg1:		brasl	%r14,store_status
 
 		lctlg	%c6,%c6,.Lall-.Lpg0(%r13)
 		lgr	%r1,%r2
@@ -67,10 +110,7 @@ ENTRY(do_reipl_asm)
 		st	%r14,.Ldispsw+12-.Lpg0(%r13)
 		lpswe	.Ldispsw-.Lpg0(%r13)
 		.align	8
-.Lclkcmp:	.quad	0x0000000000000000
 .Lall:		.quad	0x00000000ff000000
-.Ldump_pfx:	.quad	dump_prefix_page
-.Lregsave:	.quad	0x0000000000000000
 		.align	16
 /*
  * These addresses have to be 31 bit otherwise


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

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

* [patch v2 07/10] s390: Use diagnose 308 for system reset
  2011-07-27 12:55 ` Michael Holzheu
@ 2011-07-27 12:55   ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

[-- Attachment #1: s390-kdump-arch-diag308_reset.patch --]
[-- Type: text/plain, Size: 2080 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

The diagnose 308 call is the prefered method for clearing all ongoing I/O.
Therefore if it is available we use it instead of doing a manual reset.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 arch/s390/include/asm/ipl.h |    1 +
 arch/s390/kernel/base.S     |   36 ++++++++++++++++++++++++++++++++++++
 arch/s390/kernel/ipl.c      |    6 ++++++
 3 files changed, 43 insertions(+)

--- a/arch/s390/include/asm/ipl.h
+++ b/arch/s390/include/asm/ipl.h
@@ -167,5 +167,6 @@ enum diag308_rc {
 };
 
 extern int diag308(unsigned long subcode, void *addr);
+extern void diag308_reset(void);
 
 #endif /* _ASM_S390_IPL_H */
--- a/arch/s390/kernel/base.S
+++ b/arch/s390/kernel/base.S
@@ -76,6 +76,42 @@ s390_base_pgm_handler_fn:
 	.quad	0
 	.previous
 
+#
+# Calls diag 308 subcode 1 and continues execution
+#
+# The following conditions must be ensured before calling this function:
+# * Prefix register = 0
+# * Lowcore protection is disabled
+#
+ENTRY(diag308_reset)
+	larl	%r4,.Lctlregs		# Save control registers
+	stctg	%c0,%c15,0(%r4)
+	larl	%r4,.Lrestart_psw	# Setup restart PSW at absolute 0
+	lghi	%r3,0
+	lg	%r4,0(%r4)		# Save PSW
+	sturg	%r4,%r3			# Use sturg, because of large pages
+	lghi	%r1,1
+	diag	%r1,%r1,0x308
+.Lrestart_part2:
+	lhi	%r0,0			# Load r0 with zero
+	lhi	%r1,2			# Use mode 2 = ESAME (dump)
+	sigp	%r1,%r0,0x12		# Switch to ESAME mode
+	sam64				# Switch to 64 bit addressing mode
+	larl	%r4,.Lctlregs		# Restore control registers
+	lctlg	%c0,%c15,0(%r4)
+	br	%r14
+.align 16
+.Lrestart_psw:
+	.long	0x00080000,0x80000000 + .Lrestart_part2
+
+	.section .bss
+.align 8
+.Lctlregs:
+	.rept	16
+	.quad	0
+	.endr
+	.previous
+
 #else /* CONFIG_64BIT */
 
 ENTRY(s390_base_mcck_handler)
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -1996,6 +1996,12 @@ static void do_reset_calls(void)
 {
 	struct reset_call *reset;
 
+#ifdef CONFIG_64BIT
+	if (diag308_set_works) {
+		diag308_reset();
+		return;
+	}
+#endif
 	list_for_each_entry(reset, &rcall, list)
 		reset->fn();
 }


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

* [patch v2 07/10] s390: Use diagnose 308 for system reset
@ 2011-07-27 12:55   ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

[-- Attachment #1: s390-kdump-arch-diag308_reset.patch --]
[-- Type: text/plain, Size: 2224 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

The diagnose 308 call is the prefered method for clearing all ongoing I/O.
Therefore if it is available we use it instead of doing a manual reset.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 arch/s390/include/asm/ipl.h |    1 +
 arch/s390/kernel/base.S     |   36 ++++++++++++++++++++++++++++++++++++
 arch/s390/kernel/ipl.c      |    6 ++++++
 3 files changed, 43 insertions(+)

--- a/arch/s390/include/asm/ipl.h
+++ b/arch/s390/include/asm/ipl.h
@@ -167,5 +167,6 @@ enum diag308_rc {
 };
 
 extern int diag308(unsigned long subcode, void *addr);
+extern void diag308_reset(void);
 
 #endif /* _ASM_S390_IPL_H */
--- a/arch/s390/kernel/base.S
+++ b/arch/s390/kernel/base.S
@@ -76,6 +76,42 @@ s390_base_pgm_handler_fn:
 	.quad	0
 	.previous
 
+#
+# Calls diag 308 subcode 1 and continues execution
+#
+# The following conditions must be ensured before calling this function:
+# * Prefix register = 0
+# * Lowcore protection is disabled
+#
+ENTRY(diag308_reset)
+	larl	%r4,.Lctlregs		# Save control registers
+	stctg	%c0,%c15,0(%r4)
+	larl	%r4,.Lrestart_psw	# Setup restart PSW at absolute 0
+	lghi	%r3,0
+	lg	%r4,0(%r4)		# Save PSW
+	sturg	%r4,%r3			# Use sturg, because of large pages
+	lghi	%r1,1
+	diag	%r1,%r1,0x308
+.Lrestart_part2:
+	lhi	%r0,0			# Load r0 with zero
+	lhi	%r1,2			# Use mode 2 = ESAME (dump)
+	sigp	%r1,%r0,0x12		# Switch to ESAME mode
+	sam64				# Switch to 64 bit addressing mode
+	larl	%r4,.Lctlregs		# Restore control registers
+	lctlg	%c0,%c15,0(%r4)
+	br	%r14
+.align 16
+.Lrestart_psw:
+	.long	0x00080000,0x80000000 + .Lrestart_part2
+
+	.section .bss
+.align 8
+.Lctlregs:
+	.rept	16
+	.quad	0
+	.endr
+	.previous
+
 #else /* CONFIG_64BIT */
 
 ENTRY(s390_base_mcck_handler)
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -1996,6 +1996,12 @@ static void do_reset_calls(void)
 {
 	struct reset_call *reset;
 
+#ifdef CONFIG_64BIT
+	if (diag308_set_works) {
+		diag308_reset();
+		return;
+	}
+#endif
 	list_for_each_entry(reset, &rcall, list)
 		reset->fn();
 }


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

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

* [patch v2 08/10] s390: Add real memory access functions
  2011-07-27 12:55 ` Michael Holzheu
@ 2011-07-27 12:55   ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

[-- Attachment #1: s390-kdump-arch-maccess.patch --]
[-- Type: text/plain, Size: 3600 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

Add access function for real memory needed by s390 kdump backend.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 arch/s390/include/asm/system.h |    2 +
 arch/s390/mm/maccess.c         |   57 +++++++++++++++++++++++++++++++++++++++++
 drivers/s390/char/zcore.c      |   20 +-------------
 3 files changed, 61 insertions(+), 18 deletions(-)

--- a/arch/s390/include/asm/system.h
+++ b/arch/s390/include/asm/system.h
@@ -114,6 +114,8 @@ extern void pfault_fini(void);
 extern void cmma_init(void);
 extern int memcpy_real(void *, void *, size_t);
 extern void copy_to_absolute_zero(void *dest, void *src, size_t count);
+extern int copy_to_user_real(void __user *dest, void *src, size_t count);
+extern int copy_from_user_real(void *dest, void __user *src, size_t count);
 
 #define finish_arch_switch(prev) do {					     \
 	set_fs(current->thread.mm_segment);				     \
--- a/arch/s390/mm/maccess.c
+++ b/arch/s390/mm/maccess.c
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <asm/system.h>
 
 /*
@@ -60,6 +61,9 @@ long probe_kernel_write(void *dst, const
 	return copied < 0 ? -EFAULT : 0;
 }
 
+/*
+ * Copy memory in real mode (kernel to kernel)
+ */
 int memcpy_real(void *dest, void *src, size_t count)
 {
 	register unsigned long _dest asm("2") = (unsigned long) dest;
@@ -101,3 +105,56 @@ void copy_to_absolute_zero(void *dest, v
 	__ctl_load(cr0, 0, 0);
 	preempt_enable();
 }
+
+/*
+ * Copy memory from kernel (real) to user (virtual)
+ */
+int copy_to_user_real(void __user *dest, void *src, size_t count)
+{
+	int offs = 0, size, rc;
+	char *buf;
+
+	buf = (char *) __get_free_page(GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	rc = -EFAULT;
+	while (offs < count) {
+		size = min(PAGE_SIZE, count - offs);
+		if (memcpy_real(buf, src + offs, size))
+			goto out;
+		if (copy_to_user(dest + offs, buf, size))
+			goto out;
+		offs += size;
+	}
+	rc = 0;
+out:
+	free_page((unsigned long) buf);
+	return rc;
+}
+
+/*
+ * Copy memory from user (virtual) to kernel (real)
+ */
+int copy_from_user_real(void *dest, void __user *src, size_t count)
+{
+	int offs = 0, size, rc;
+	char *buf;
+
+	buf = (char *) __get_free_page(GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	rc = -EFAULT;
+	while (offs < count) {
+		size = min(PAGE_SIZE, count - offs);
+		if (copy_from_user(buf, src + offs, size))
+			goto out;
+		if (memcpy_real(dest + offs, buf, size))
+			goto out;
+		offs += size;
+	}
+	rc = 0;
+out:
+	free_page((unsigned long) buf);
+	return rc;
+}
+
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -142,22 +142,6 @@ static int memcpy_hsa_kernel(void *dest,
 	return memcpy_hsa(dest, src, count, TO_KERNEL);
 }
 
-static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
-{
-	static char buf[4096];
-	int offs = 0, size;
-
-	while (offs < count) {
-		size = min(sizeof(buf), count - offs);
-		if (memcpy_real(buf, (void *) src + offs, size))
-			return -EFAULT;
-		if (copy_to_user(dest + offs, buf, size))
-			return -EFAULT;
-		offs += size;
-	}
-	return 0;
-}
-
 static int __init init_cpu_info(enum arch_id arch)
 {
 	struct save_area *sa;
@@ -346,8 +330,8 @@ static ssize_t zcore_read(struct file *f
 
 	/* Copy from real mem */
 	size = count - mem_offs - hdr_count;
-	rc = memcpy_real_user(buf + hdr_count + mem_offs, mem_start + mem_offs,
-			      size);
+	rc = copy_to_user_real(buf + hdr_count + mem_offs,
+			       (void *) mem_start + mem_offs, size);
 	if (rc)
 		goto fail;
 


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

* [patch v2 08/10] s390: Add real memory access functions
@ 2011-07-27 12:55   ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

[-- Attachment #1: s390-kdump-arch-maccess.patch --]
[-- Type: text/plain, Size: 3744 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

Add access function for real memory needed by s390 kdump backend.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 arch/s390/include/asm/system.h |    2 +
 arch/s390/mm/maccess.c         |   57 +++++++++++++++++++++++++++++++++++++++++
 drivers/s390/char/zcore.c      |   20 +-------------
 3 files changed, 61 insertions(+), 18 deletions(-)

--- a/arch/s390/include/asm/system.h
+++ b/arch/s390/include/asm/system.h
@@ -114,6 +114,8 @@ extern void pfault_fini(void);
 extern void cmma_init(void);
 extern int memcpy_real(void *, void *, size_t);
 extern void copy_to_absolute_zero(void *dest, void *src, size_t count);
+extern int copy_to_user_real(void __user *dest, void *src, size_t count);
+extern int copy_from_user_real(void *dest, void __user *src, size_t count);
 
 #define finish_arch_switch(prev) do {					     \
 	set_fs(current->thread.mm_segment);				     \
--- a/arch/s390/mm/maccess.c
+++ b/arch/s390/mm/maccess.c
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/gfp.h>
 #include <asm/system.h>
 
 /*
@@ -60,6 +61,9 @@ long probe_kernel_write(void *dst, const
 	return copied < 0 ? -EFAULT : 0;
 }
 
+/*
+ * Copy memory in real mode (kernel to kernel)
+ */
 int memcpy_real(void *dest, void *src, size_t count)
 {
 	register unsigned long _dest asm("2") = (unsigned long) dest;
@@ -101,3 +105,56 @@ void copy_to_absolute_zero(void *dest, v
 	__ctl_load(cr0, 0, 0);
 	preempt_enable();
 }
+
+/*
+ * Copy memory from kernel (real) to user (virtual)
+ */
+int copy_to_user_real(void __user *dest, void *src, size_t count)
+{
+	int offs = 0, size, rc;
+	char *buf;
+
+	buf = (char *) __get_free_page(GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	rc = -EFAULT;
+	while (offs < count) {
+		size = min(PAGE_SIZE, count - offs);
+		if (memcpy_real(buf, src + offs, size))
+			goto out;
+		if (copy_to_user(dest + offs, buf, size))
+			goto out;
+		offs += size;
+	}
+	rc = 0;
+out:
+	free_page((unsigned long) buf);
+	return rc;
+}
+
+/*
+ * Copy memory from user (virtual) to kernel (real)
+ */
+int copy_from_user_real(void *dest, void __user *src, size_t count)
+{
+	int offs = 0, size, rc;
+	char *buf;
+
+	buf = (char *) __get_free_page(GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	rc = -EFAULT;
+	while (offs < count) {
+		size = min(PAGE_SIZE, count - offs);
+		if (copy_from_user(buf, src + offs, size))
+			goto out;
+		if (memcpy_real(dest + offs, buf, size))
+			goto out;
+		offs += size;
+	}
+	rc = 0;
+out:
+	free_page((unsigned long) buf);
+	return rc;
+}
+
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -142,22 +142,6 @@ static int memcpy_hsa_kernel(void *dest,
 	return memcpy_hsa(dest, src, count, TO_KERNEL);
 }
 
-static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
-{
-	static char buf[4096];
-	int offs = 0, size;
-
-	while (offs < count) {
-		size = min(sizeof(buf), count - offs);
-		if (memcpy_real(buf, (void *) src + offs, size))
-			return -EFAULT;
-		if (copy_to_user(dest + offs, buf, size))
-			return -EFAULT;
-		offs += size;
-	}
-	return 0;
-}
-
 static int __init init_cpu_info(enum arch_id arch)
 {
 	struct save_area *sa;
@@ -346,8 +330,8 @@ static ssize_t zcore_read(struct file *f
 
 	/* Copy from real mem */
 	size = count - mem_offs - hdr_count;
-	rc = memcpy_real_user(buf + hdr_count + mem_offs, mem_start + mem_offs,
-			      size);
+	rc = copy_to_user_real(buf + hdr_count + mem_offs,
+			       (void *) mem_start + mem_offs, size);
 	if (rc)
 		goto fail;
 


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

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

* [patch v2 09/10] s390: kdump backend code
  2011-07-27 12:55 ` Michael Holzheu
@ 2011-07-27 12:55   ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

[-- Attachment #1: s390-kdump-arch-backend.patch --]
[-- Type: text/plain, Size: 29337 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

This patch provides the architecture specific part of the s390 kdump
support.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 arch/s390/Kconfig                |   10 +
 arch/s390/include/asm/ipl.h      |    1 
 arch/s390/include/asm/kexec.h    |    8 -
 arch/s390/include/asm/sclp.h     |    1 
 arch/s390/include/asm/setup.h    |    9 +
 arch/s390/kernel/Makefile        |    1 
 arch/s390/kernel/crash.c         |  206 ++++++++++++++++++++++++++++++++++++++-
 arch/s390/kernel/crash_dump.c    |   39 +++++++
 arch/s390/kernel/head.S          |   16 +++
 arch/s390/kernel/head_kdump.S    |  116 +++++++++++++++++++++
 arch/s390/kernel/ipl.c           |   48 ++++++++-
 arch/s390/kernel/machine_kexec.c |   64 ++++++++++++
 arch/s390/kernel/mem_detect.c    |   69 +++++++++++++
 arch/s390/kernel/setup.c         |  188 +++++++++++++++++++++++++++++++++++
 arch/s390/mm/vmem.c              |    3 
 15 files changed, 772 insertions(+), 7 deletions(-)

--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -567,6 +567,16 @@ config KEXEC
 	  current kernel, and to start another kernel.  It is like a reboot
 	  but is independent of hardware/microcode support.
 
+config CRASH_DUMP
+	bool "kernel crash dumps"
+	depends on 64BIT
+	help
+	  Generate crash dump after being started by kexec.
+	  Crash dump kernels are loaded in the main kernel with kexec-tools
+	  into a specially reserved region and then later executed after
+	  a crash by kdump/kexec.
+	  For more details see Documentation/kdump/kdump.txt
+
 config ZFCPDUMP
 	def_bool n
 	prompt "zfcpdump support"
--- a/arch/s390/include/asm/ipl.h
+++ b/arch/s390/include/asm/ipl.h
@@ -168,5 +168,6 @@ enum diag308_rc {
 
 extern int diag308(unsigned long subcode, void *addr);
 extern void diag308_reset(void);
+extern void store_status(void);
 
 #endif /* _ASM_S390_IPL_H */
--- a/arch/s390/include/asm/kexec.h
+++ b/arch/s390/include/asm/kexec.h
@@ -30,14 +30,14 @@
 /* Not more than 2GB */
 #define KEXEC_CONTROL_MEMORY_LIMIT (1UL<<31)
 
+/* Maximum address we can use for the crash control pages */
+#define KEXEC_CRASH_CONTROL_MEMORY_LIMIT (-1UL)
+
 /* Allocate one page for the pdp and the second for the code */
 #define KEXEC_CONTROL_PAGE_SIZE 4096
 
 /* The native architecture */
 #define KEXEC_ARCH KEXEC_ARCH_S390
 
-/* Provide a dummy definition to avoid build failures. */
-static inline void crash_setup_regs(struct pt_regs *newregs,
-					struct pt_regs *oldregs) { }
-
+extern void crash_setup_regs(struct pt_regs *newregs, struct pt_regs *oldregs);
 #endif /*_S390_KEXEC_H */
--- a/arch/s390/include/asm/sclp.h
+++ b/arch/s390/include/asm/sclp.h
@@ -55,4 +55,5 @@ int sclp_chp_deconfigure(struct chp_id c
 int sclp_chp_read_info(struct sclp_chp_info *info);
 void sclp_get_ipl_info(struct sclp_ipl_info *info);
 
+void _sclp_print_early(const char *);
 #endif /* _ASM_S390_SCLP_H */
--- a/arch/s390/include/asm/setup.h
+++ b/arch/s390/include/asm/setup.h
@@ -30,11 +30,15 @@
 #define IPL_DEVICE        (*(unsigned long *)  (0x10400))
 #define INITRD_START      (*(unsigned long *)  (0x10408))
 #define INITRD_SIZE       (*(unsigned long *)  (0x10410))
+#define OLDMEM_BASE       (*(unsigned long *)  (0x10418))
+#define OLDMEM_SIZE       (*(unsigned long *)  (0x10420))
 #endif /* __s390x__ */
 #define COMMAND_LINE      ((char *)            (0x10480))
 
 #define CHUNK_READ_WRITE 0
 #define CHUNK_READ_ONLY  1
+#define CHUNK_OLDMEM     4
+#define CHUNK_CRASHK     5
 
 struct mem_chunk {
 	unsigned long addr;
@@ -48,6 +52,8 @@ extern int memory_end_set;
 extern unsigned long memory_end;
 
 void detect_memory_layout(struct mem_chunk chunk[]);
+void create_mem_hole(struct mem_chunk memory_chunk[], unsigned long addr,
+		     unsigned long size, int type);
 
 #define PRIMARY_SPACE_MODE	0
 #define ACCESS_REGISTER_MODE	1
@@ -106,6 +112,7 @@ extern unsigned int user_mode;
 #endif /* __s390x__ */
 
 #define ZFCPDUMP_HSA_SIZE	(32UL<<20)
+#define ZFCPDUMP_HSA_SIZE_MAX	(64UL<<20)
 
 /*
  * Console mode. Override with conmode=
@@ -138,6 +145,8 @@ extern char kernel_nss_name[];
 #define IPL_DEVICE        0x10400
 #define INITRD_START      0x10408
 #define INITRD_SIZE       0x10410
+#define OLDMEM_BASE       0x10418
+#define OLDMEM_SIZE       0x10420
 #endif /* __s390x__ */
 #define COMMAND_LINE      0x10480
 
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_FUNCTION_TRACER)	+= $(if $(
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
 obj-$(CONFIG_FTRACE_SYSCALLS)  += ftrace.o
+obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
 
 # Kexec part
 S390_KEXEC_OBJS := machine_kexec.o crash.o
--- a/arch/s390/kernel/crash.c
+++ b/arch/s390/kernel/crash.c
@@ -1,15 +1,217 @@
 /*
  * arch/s390/kernel/crash.c
  *
- * (C) Copyright IBM Corp. 2005
+ * Copyright IBM Corp. 2005,2011
  *
  * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
- *
+ *            Michael Holzheu <holzheu@linux.vnet.ibm.com>
  */
 
 #include <linux/threads.h>
 #include <linux/kexec.h>
 #include <linux/reboot.h>
+#include <linux/elfcore.h>
+#include <asm/ipl.h>
+
+#ifdef CONFIG_CRASH_DUMP
+
+#define ROUNDUP(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
+#define PTR_ADD(x, y) (((char *) (x)) + ((unsigned long) (y)))
+
+#ifndef NT_FPREGSET
+#define NT_FPREGSET 2
+#endif
+
+/*
+ * fpregset ELF Note
+ */
+struct nt_fpregset_64 {
+	u32	fpc;
+	u32	pad;
+	u64	fprs[16];
+} __packed;
+
+/*
+ * Initialize ELF note
+ */
+static void *nt_init(void *buf, Elf64_Word type, void *desc, int d_len,
+		     const char *name)
+{
+	Elf64_Nhdr *note;
+	u64 len;
+
+	note = (Elf64_Nhdr *)buf;
+	note->n_namesz = strlen(name) + 1;
+	note->n_descsz = d_len;
+	note->n_type = type;
+	len = sizeof(Elf64_Nhdr);
+
+	memcpy(buf + len, name, note->n_namesz);
+	len = ROUNDUP(len + note->n_namesz, 4);
+
+	memcpy(buf + len, desc, note->n_descsz);
+	len = ROUNDUP(len + note->n_descsz, 4);
+
+	return PTR_ADD(buf, len);
+}
+
+/*
+ * Initialize prstatus note
+ */
+static void *nt_prstatus(void *ptr, struct save_area *sa)
+{
+	struct elf_prstatus nt_prstatus;
+	static int cpu_nr = 1;
+
+	memset(&nt_prstatus, 0, sizeof(nt_prstatus));
+	memcpy(&nt_prstatus.pr_reg.gprs, sa->gp_regs, sizeof(sa->gp_regs));
+	memcpy(&nt_prstatus.pr_reg.psw, sa->psw, sizeof(sa->psw));
+	memcpy(&nt_prstatus.pr_reg.acrs, sa->acc_regs, sizeof(sa->acc_regs));
+	nt_prstatus.pr_pid = cpu_nr;
+	cpu_nr++;
+
+	return nt_init(ptr, NT_PRSTATUS, &nt_prstatus, sizeof(nt_prstatus),
+			 "CORE");
+}
+
+/*
+ * Initialize fpregset (floating point) note
+ */
+static void *nt_fpregset(void *ptr, struct save_area *sa)
+{
+	struct nt_fpregset_64 nt_fpregset;
+
+	memset(&nt_fpregset, 0, sizeof(nt_fpregset));
+	memcpy(&nt_fpregset.fpc, &sa->fp_ctrl_reg, sizeof(sa->fp_ctrl_reg));
+	memcpy(&nt_fpregset.fprs, &sa->fp_regs, sizeof(sa->fp_regs));
+
+	return nt_init(ptr, NT_FPREGSET, &nt_fpregset, sizeof(nt_fpregset),
+			 "CORE");
+}
+
+/*
+ * Initialize timer note
+ */
+static void *nt_s390_timer(void *ptr, struct save_area *sa)
+{
+	return nt_init(ptr, NT_S390_TIMER, &sa->timer, sizeof(sa->timer),
+			 KEXEC_CORE_NOTE_NAME);
+}
+
+/*
+ * Initialize TOD clock comparator note
+ */
+static void *nt_s390_tod_cmp(void *ptr, struct save_area *sa)
+{
+	return nt_init(ptr, NT_S390_TODCMP, &sa->clk_cmp,
+		       sizeof(sa->clk_cmp), KEXEC_CORE_NOTE_NAME);
+}
+
+/*
+ * Initialize TOD programmable register note
+ */
+static void *nt_s390_tod_preg(void *ptr, struct save_area *sa)
+{
+	return nt_init(ptr, NT_S390_TODPREG, &sa->tod_reg,
+		       sizeof(sa->tod_reg), KEXEC_CORE_NOTE_NAME);
+}
+
+/*
+ * Initialize control register note
+ */
+static void *nt_s390_ctrs(void *ptr, struct save_area *sa)
+{
+	return nt_init(ptr, NT_S390_CTRS, &sa->ctrl_regs,
+		       sizeof(sa->ctrl_regs), KEXEC_CORE_NOTE_NAME);
+}
+
+/*
+ * Initialize prefix register note
+ */
+static void *nt_s390_prefix(void *ptr, struct save_area *sa)
+{
+	return nt_init(ptr, NT_S390_PREFIX, &sa->pref_reg,
+			 sizeof(sa->pref_reg), KEXEC_CORE_NOTE_NAME);
+}
+
+/*
+ * Final empty node
+ */
+static void nt_final(void *ptr)
+{
+	memset(ptr, 0, sizeof(struct elf_note));
+}
+
+/*
+ * Add create ELF notes for CPU
+ */
+static void add_elf_notes(int cpu)
+{
+	struct save_area *sa = (void *) 4608;
+	void *ptr;
+
+	memcpy((void *) (4608UL + sa->pref_reg), sa, sizeof(*sa));
+	ptr = (u64 *) per_cpu_ptr(crash_notes, cpu);
+	ptr = nt_prstatus(ptr, sa);
+	ptr = nt_fpregset(ptr, sa);
+	ptr = nt_s390_timer(ptr, sa);
+	ptr = nt_s390_tod_cmp(ptr, sa);
+	ptr = nt_s390_tod_preg(ptr, sa);
+	ptr = nt_s390_ctrs(ptr, sa);
+	ptr = nt_s390_prefix(ptr, sa);
+	nt_final(ptr);
+}
+
+/*
+ * Store status of next available physical CPU
+ */
+static int store_status_next(int start_cpu, int this_cpu)
+{
+	struct save_area *sa = (void *) 4608;
+	int cpu, rc;
+
+	for (cpu = start_cpu; cpu < 65536; cpu++) {
+		if (cpu == this_cpu)
+			continue;
+		do {
+			rc = raw_sigp(cpu, sigp_stop_and_store_status);
+		} while (rc == sigp_busy);
+		if (rc != sigp_order_code_accepted)
+			continue;
+		if (sa->pref_reg)
+			return cpu;
+	}
+	return -1;
+}
+
+#endif /* CONFIG_CRASH_DUMP */
+
+/*
+ * Initialize CPU ELF notes
+ *
+ * We expect that for current CPU a store status has been done
+ */
+void crash_setup_regs(struct pt_regs *newregs, struct pt_regs *oldregs)
+{
+#ifdef CONFIG_CRASH_DUMP
+	int cpu, this_cpu, phys_cpu = 0, first = 1;
+
+	this_cpu = stap();
+
+	for_each_online_cpu(cpu) {
+		if (first && S390_lowcore.prefixreg_save_area) {
+			add_elf_notes(cpu);
+			first = 0;
+			continue;
+		}
+		phys_cpu = store_status_next(phys_cpu, this_cpu);
+		if (phys_cpu == -1)
+			return;
+		add_elf_notes(cpu);
+		phys_cpu++;
+	}
+#endif
+}
 
 void machine_crash_shutdown(struct pt_regs *regs)
 {
--- /dev/null
+++ b/arch/s390/kernel/crash_dump.c
@@ -0,0 +1,39 @@
+/*
+ * S390 kdump implementation
+ *
+ * Copyright IBM Corp. 2011
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+#include <linux/crash_dump.h>
+#include <asm/lowcore.h>
+
+/*
+ * Copy one page from "oldmem"
+ *
+ * For the kdump reserved memory this functions performs a swap operation:
+ *  - [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE] is mapped to [0 - OLDMEM_SIZE].
+ *  - [0 - OLDMEM_SIZE] is mapped to [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE]
+ */
+ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
+			 size_t csize, unsigned long offset, int userbuf)
+{
+	unsigned long src;
+	int rc;
+
+	if (!csize)
+		return 0;
+
+	src = (pfn << PAGE_SHIFT) + offset;
+	if (src < OLDMEM_SIZE)
+		src += OLDMEM_BASE;
+	else if (src > OLDMEM_BASE &&
+		 src < OLDMEM_BASE + OLDMEM_SIZE)
+		src -= OLDMEM_BASE;
+	if (userbuf)
+		rc = copy_to_user_real((void __user *) buf, (void *) src,
+				       csize);
+	else
+		rc = memcpy_real(buf, (void *) src, csize);
+	return rc < 0 ? rc : csize;
+}
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -449,10 +449,22 @@ ENTRY(start)
 #
 	.org	0x10000
 ENTRY(startup)
+	j	.Lep_startup_normal
+	.org	0x10008
+	.ascii	"S390EP"
+	.byte	0x00,0x01
+#
+# kdump startup-code at 0x10010, running in 64 bit absolute addressing mode
+#
+	.org	0x10010
+ENTRY(startup_kdump)
+	j	.Lep_startup_kdump
+.Lep_startup_normal:
 	basr	%r13,0			# get base
 .LPG0:
 	xc	0x200(256),0x200	# partially clear lowcore
 	xc	0x300(256),0x300
+	xc	0xe00(256),0xe00
 	stck	__LC_LAST_UPDATE_CLOCK
 	spt	5f-.LPG0(%r13)
 	mvc	__LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13)
@@ -534,6 +546,8 @@ ENTRY(startup)
 	.align	8
 5:	.long	0x7fffffff,0xffffffff
 
+#include "head_kdump.S"
+
 #
 # params at 10400 (setup.h)
 #
@@ -541,6 +555,8 @@ ENTRY(startup)
 	.long	0,0			# IPL_DEVICE
 	.long	0,0			# INITRD_START
 	.long	0,0			# INITRD_SIZE
+	.long	0,0			# OLDMEM_BASE
+	.long	0,0			# OLDMEM_SIZE
 
 	.org	COMMAND_LINE
 	.byte	"root=/dev/ram0 ro"
--- /dev/null
+++ b/arch/s390/kernel/head_kdump.S
@@ -0,0 +1,116 @@
+/*
+ * S390 kdump lowlevel functions (new kernel)
+ *
+ * Copyright IBM Corp. 2011
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+#define DATAMOVER_ADDR	0x4000
+#define COPY_PAGE_ADDR	0x6000
+
+#ifdef CONFIG_CRASH_DUMP
+
+#
+# kdump entry (new kernel - not yet relocated)
+#
+# Note: This code has to be position independent
+#
+
+.align 2
+.Lep_startup_kdump:
+	basr	%r13,0
+.Lbase:
+	larl	%r2,.Lbase_addr			# Check, if we have been
+	lg	%r2,0(%r2)			# already relocated:
+	clgr	%r2,%r13			#
+	jne	.Lrelocate			# No : Start data mover
+	lghi	%r2,0				# Yes: Start kdump kernel
+	brasl	%r14,startup_kdump_relocated
+
+.Lrelocate:
+	larl	%r4,startup
+	lg	%r2,0x418(%r4)			# Get kdump base
+	lg	%r3,0x420(%r4)			# Get kdump size
+
+	larl	%r10,.Lcopy_start		# Source of data mover
+	lghi	%r8,DATAMOVER_ADDR		# Target of data mover
+	mvc	0(256,%r8),0(%r10)		# Copy data mover code
+
+	agr	%r8,%r2				# Copy data mover to
+	mvc	0(256,%r8),0(%r10)		# reserved mem
+
+	lghi	%r14,DATAMOVER_ADDR		# Jump to copied data mover
+	basr	%r14,%r14
+.Lbase_addr:
+	.quad	.Lbase
+
+#
+# kdump data mover code (runs at address DATAMOVER_ADDR)
+#
+# r2: kdump base address
+# r3: kdump size
+#
+.Lcopy_start:
+	basr	%r13,0				# Base
+0:
+	lgr	%r11,%r2			# Save kdump base address
+	lgr	%r12,%r2
+	agr	%r12,%r3			# Compute kdump end address
+
+	lghi	%r5,0
+	lghi	%r10,COPY_PAGE_ADDR		# Load copy page address
+1:
+	mvc	0(256,%r10),0(%r5)		# Copy old kernel to tmp
+	mvc	0(256,%r5),0(%r11)		# Copy new kernel to old
+	mvc	0(256,%r11),0(%r10)		# Copy tmp to new
+	aghi	%r11,256
+	aghi	%r5,256
+	clgr	%r11,%r12
+	jl	1b
+
+	lg	%r14,.Lstartup_kdump-0b(%r13)
+	basr	%r14,%r14			# Start relocated kernel
+.Lstartup_kdump:
+	.long	0x00000000,0x00000000 + startup_kdump_relocated
+.Lcopy_end:
+
+#
+# Startup of kdump (relocated new kernel)
+#
+.align 2
+startup_kdump_relocated:
+	basr	%r13,0
+0:
+	mvc	0(8,%r0),.Lrestart_psw-0b(%r13)	# Setup restart PSW
+	mvc	464(16,%r0),.Lpgm_psw-0b(%r13)	# Setup pgm check PSW
+	lhi	%r1,1				# Start new kernel
+	diag	%r1,%r1,0x308			# with diag 308
+
+.Lno_diag308:					# No diag 308
+	sam31					# Switch to 31 bit addr mode
+	sr	%r1,%r1				# Erase register r1
+	sr	%r2,%r2				# Erase register r2
+	sigp	%r1,%r2,0x12			# Switch to 31 bit arch mode
+	lpsw	0				# Start new kernel...
+.align	8
+.Lrestart_psw:
+	.long	0x00080000,0x80000000 + startup
+.Lpgm_psw:
+	.quad	0x0000000180000000,0x0000000000000000 + .Lno_diag308
+#else
+.align 2
+.Lep_startup_kdump:
+#ifdef CONFIG_64BIT
+	larl	%r13,startup_kdump_crash
+	lpswe	0(%r13)
+.align 8
+startup_kdump_crash:
+	.quad	0x0002000080000000,0x0000000000000000 + startup_kdump_crash
+#else
+	basr	%r13,0
+0:	lpsw	startup_kdump_crash-0b(%r13)
+.align 8
+startup_kdump_crash:
+	.long	0x000a0000,0x00000000 + startup_kdump_crash
+#endif /* CONFIG_64BIT */
+#endif /* CONFIG_CRASH_DUMP */
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -16,6 +16,7 @@
 #include <linux/ctype.h>
 #include <linux/fs.h>
 #include <linux/gfp.h>
+#include <linux/crash_dump.h>
 #include <asm/ipl.h>
 #include <asm/smp.h>
 #include <asm/setup.h>
@@ -26,6 +27,7 @@
 #include <asm/sclp.h>
 #include <asm/sigp.h>
 #include <asm/checksum.h>
+#include <asm/lowcore.h>
 
 #define IPL_PARM_BLOCK_VERSION 0
 
@@ -68,6 +70,7 @@ struct shutdown_trigger {
 #define SHUTDOWN_ACTION_VMCMD_STR	"vmcmd"
 #define SHUTDOWN_ACTION_STOP_STR	"stop"
 #define SHUTDOWN_ACTION_DUMP_REIPL_STR	"dump_reipl"
+#define SHUTDOWN_ACTION_KDUMP_STR	"kdump"
 
 struct shutdown_action {
 	char *name;
@@ -1628,11 +1631,42 @@ static void stop_run(struct shutdown_tri
 static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
 					     stop_run, NULL};
 
+/*
+ * kdump shutdown action: Trigger kdump on shutdown.
+ */
+
+#ifdef CONFIG_CRASH_DUMP
+static int kdump_init(void)
+{
+	if (crashk_res.start == 0)
+		return -EOPNOTSUPP;
+	return 0;
+}
+
+static void kdump_run(struct shutdown_trigger *trigger)
+{
+	pfault_fini();
+	s390_reset_system();
+	__arch_local_irq_stnsm(0xfb); /* disable DAT */
+	store_status();
+
+	crash_kexec(NULL);
+	disabled_wait((unsigned long) __builtin_return_address(0));
+}
+
+static struct shutdown_action kdump_action = {SHUTDOWN_ACTION_KDUMP_STR,
+					     kdump_run, kdump_init};
+#endif
+
 /* action list */
 
 static struct shutdown_action *shutdown_actions_list[] = {
 	&ipl_action, &reipl_action, &dump_reipl_action, &dump_action,
-	&vmcmd_action, &stop_action};
+	&vmcmd_action, &stop_action,
+#ifdef CONFIG_CRASH_DUMP
+	&kdump_action
+#endif
+	};
 #define SHUTDOWN_ACTIONS_COUNT (sizeof(shutdown_actions_list) / sizeof(void *))
 
 /*
@@ -1802,6 +1836,16 @@ void (*_machine_power_off)(void) = do_ma
 
 static void __init shutdown_triggers_init(void)
 {
+#ifdef CONFIG_CRASH_DUMP
+	/*
+	 * We set the kdump action for panic and restart, if crashkernel
+	 * memory is defined.
+	 */
+	if (crashk_res.start != 0) {
+		on_restart_trigger.action = &kdump_action;
+		on_panic_trigger.action = &kdump_action;
+	}
+#endif
 	shutdown_actions_kset = kset_create_and_add("shutdown_actions", NULL,
 						    firmware_kobj);
 	if (!shutdown_actions_kset)
@@ -2016,6 +2060,8 @@ void s390_reset_system(void)
 
 	/* Stack for interrupt/machine check handler */
 	lc->panic_stack = S390_lowcore.panic_stack;
+	/* CPU number */
+	lc->cpu_nr = S390_lowcore.cpu_nr;
 
 	/* Save prefix page address for dump case */
 	dump_prefix_page = (u32)(unsigned long) lc;
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -21,12 +21,67 @@
 #include <asm/smp.h>
 #include <asm/reset.h>
 #include <asm/ipl.h>
+#include <asm/cacheflush.h>
+#include <asm/asm-offsets.h>
+#include <asm/checksum.h>
+#include <asm/diag.h>
+#include <asm/sclp.h>
 
 typedef void (*relocate_kernel_t)(kimage_entry_t *, unsigned long);
 
 extern const unsigned char relocate_kernel[];
 extern const unsigned long long relocate_kernel_len;
 
+#ifdef CONFIG_CRASH_DUMP
+
+/*
+ * S390 version: Currently we do not support freeing crashkernel memory
+ */
+void crash_free_reserved_phys_range(unsigned long begin, unsigned long end)
+{
+	return;
+}
+
+/*
+ * S390 version: Just do real copy of segment
+ */
+int kimage_load_crash_segment(struct kimage *image,
+			      struct kexec_segment *segment)
+{
+	return copy_from_user_real((void *) segment->mem, segment->buf,
+				   segment->bufsz);
+}
+
+/*
+ * Start kdump
+ */
+static void __machine_kdump(void *data)
+{
+	struct kimage *image = data;
+	psw_t kdump_psw;
+
+	kdump_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
+	kdump_psw.addr = (unsigned long) image->start;
+	__load_psw(kdump_psw);
+}
+
+#endif
+
+/*
+ * Give back memory to hypervisor before new kdump is loaded
+ */
+static int machine_kexec_prepare_kdump(void)
+{
+#ifdef CONFIG_CRASH_DUMP
+	if (MACHINE_IS_VM)
+		diag10_range(PFN_DOWN(crashk_res.start),
+			     PFN_DOWN(crashk_res.end - crashk_res.start + 1));
+	return 0;
+#else
+	return -EINVAL;
+#endif
+}
+
 int machine_kexec_prepare(struct kimage *image)
 {
 	void *reboot_code_buffer;
@@ -35,6 +90,9 @@ int machine_kexec_prepare(struct kimage
 	if (ipl_flags & IPL_NSS_VALID)
 		return -ENOSYS;
 
+	if (image->type == KEXEC_TYPE_CRASH)
+		return machine_kexec_prepare_kdump();
+
 	/* We don't support anything but the default image type for now. */
 	if (image->type != KEXEC_TYPE_DEFAULT)
 		return -EINVAL;
@@ -72,6 +130,12 @@ static void __machine_kexec(void *data)
 
 void machine_kexec(struct kimage *image)
 {
+#ifdef CONFIG_CRASH_DUMP
+	if (image->type == KEXEC_TYPE_CRASH) {
+		_sclp_print_early("Starting kdump");
+		smp_switch_to_ipl_cpu(__machine_kdump, image);
+	}
+#endif
 	tracer_disable();
 	smp_send_stop();
 	smp_switch_to_ipl_cpu(__machine_kexec, image);
--- a/arch/s390/kernel/mem_detect.c
+++ b/arch/s390/kernel/mem_detect.c
@@ -62,3 +62,72 @@ void detect_memory_layout(struct mem_chu
 	arch_local_irq_restore(flags);
 }
 EXPORT_SYMBOL(detect_memory_layout);
+
+/*
+ * Create memory hole with given address, size, and type
+ */
+void create_mem_hole(struct mem_chunk chunks[], unsigned long addr,
+		     unsigned long size, int type)
+{
+	unsigned long start, end, new_size;
+	int i;
+
+	for (i = 0; i < MEMORY_CHUNKS; i++) {
+		if (chunks[i].size == 0)
+			continue;
+		if (addr + size < chunks[i].addr)
+			continue;
+		if (addr >= chunks[i].addr + chunks[i].size)
+			continue;
+		start = max(addr, chunks[i].addr);
+		end = min(addr + size, chunks[i].addr + chunks[i].size);
+		new_size = end - start;
+		if (new_size == 0)
+			continue;
+		if (start == chunks[i].addr &&
+		    end == chunks[i].addr + chunks[i].size) {
+			/* Remove chunk */
+			chunks[i].type = type;
+		} else if (start == chunks[i].addr) {
+			/* Make chunk smaller at start */
+			if (i >= MEMORY_CHUNKS - 1)
+				panic("Unable to create memory hole");
+			memmove(&chunks[i + 1], &chunks[i],
+				sizeof(struct mem_chunk) *
+				(MEMORY_CHUNKS - (i + 1)));
+			chunks[i + 1].addr = chunks[i].addr + new_size;
+			chunks[i + 1].size = chunks[i].size - new_size;
+			chunks[i].size = new_size;
+			chunks[i].type = type;
+			i += 1;
+		} else if (end == chunks[i].addr + chunks[i].size) {
+			/* Make chunk smaller at end */
+			if (i >= MEMORY_CHUNKS - 1)
+				panic("Unable to create memory hole");
+			memmove(&chunks[i + 1], &chunks[i],
+				sizeof(struct mem_chunk) *
+				(MEMORY_CHUNKS - (i + 1)));
+			chunks[i + 1].addr = start;
+			chunks[i + 1].size = new_size;
+			chunks[i + 1].type = type;
+			chunks[i].size -= new_size;
+			i += 1;
+		} else {
+			/* Create memory hole */
+			if (i >= MEMORY_CHUNKS - 2)
+				panic("Unable to create memory hole");
+			memmove(&chunks[i + 2], &chunks[i],
+				sizeof(struct mem_chunk) *
+				(MEMORY_CHUNKS - (i + 2)));
+			chunks[i + 1].addr = addr;
+			chunks[i + 1].size = size;
+			chunks[i + 1].type = type;
+			chunks[i + 2].addr = addr + size;
+			chunks[i + 2].size =
+				chunks[i].addr + chunks[i].size - (addr + size);
+			chunks[i + 2].type = chunks[i].type;
+			chunks[i].size = addr - chunks[i].addr;
+			i += 2;
+		}
+	}
+}
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -42,6 +42,9 @@
 #include <linux/reboot.h>
 #include <linux/topology.h>
 #include <linux/ftrace.h>
+#include <linux/kexec.h>
+#include <linux/crash_dump.h>
+#include <linux/memory.h>
 
 #include <asm/ipl.h>
 #include <asm/uaccess.h>
@@ -57,6 +60,7 @@
 #include <asm/ebcdic.h>
 #include <asm/compat.h>
 #include <asm/kvm_virtio.h>
+#include <asm/diag.h>
 
 long psw_kernel_bits	= (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY |
 			   PSW_MASK_MCHECK | PSW_DEFAULT_KEY);
@@ -435,6 +439,9 @@ static void __init setup_resources(void)
 	for (i = 0; i < MEMORY_CHUNKS; i++) {
 		if (!memory_chunk[i].size)
 			continue;
+		if (memory_chunk[i].type == CHUNK_OLDMEM ||
+		    memory_chunk[i].type == CHUNK_CRASHK)
+			continue;
 		res = alloc_bootmem_low(sizeof(*res));
 		res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
 		switch (memory_chunk[i].type) {
@@ -479,6 +486,7 @@ static void __init setup_memory_end(void
 	unsigned long max_mem;
 	int i;
 
+
 #ifdef CONFIG_ZFCPDUMP
 	if (ipl_info.type == IPL_TYPE_FCP_DUMP) {
 		memory_end = ZFCPDUMP_HSA_SIZE;
@@ -550,6 +558,171 @@ static void __init setup_restart_psw(voi
 	copy_to_absolute_zero(&S390_lowcore.restart_psw, &psw, sizeof(psw));
 }
 
+#ifdef CONFIG_CRASH_DUMP
+
+/*
+ * Find suitable location for crashkernel memory
+ */
+static unsigned long __init find_crash_base(unsigned long crash_size)
+{
+	unsigned long crash_base;
+	struct mem_chunk *chunk;
+	int i;
+
+	if (is_kdump_kernel() && (crash_size == OLDMEM_SIZE))
+		return OLDMEM_BASE;
+
+	for (i = MEMORY_CHUNKS - 1; i >= 0; i--) {
+		chunk = &memory_chunk[i];
+		if (chunk->size == 0)
+			continue;
+		if (chunk->type != CHUNK_READ_WRITE)
+			continue;
+		if (chunk->size < crash_size)
+			continue;
+		crash_base = max(chunk->addr, crash_size);
+		crash_base = max(crash_base, ZFCPDUMP_HSA_SIZE_MAX);
+		crash_base = max(crash_base, (unsigned long) INITRD_START +
+				 INITRD_SIZE);
+		crash_base = PAGE_ALIGN(crash_base);
+		if (crash_base >= chunk->addr + chunk->size)
+			continue;
+		if (chunk->addr + chunk->size - crash_base < crash_size)
+			continue;
+		crash_base = chunk->size - crash_size;
+		return crash_base;
+	}
+	return 0;
+}
+
+/*
+ * Check if crash_base and crash_size is valid
+ */
+static int __init verify_crash_base(unsigned long crash_base,
+				    unsigned long crash_size)
+{
+	struct mem_chunk *chunk;
+	int i;
+
+	/*
+	 * Because we do the swap to zero, we must have at least 'crash_size'
+	 * bytes free space before crash_base
+	 */
+	if (crash_size > crash_base)
+		return -EINVAL;
+
+	/* First memory chunk must be at least crash_size */
+	if (memory_chunk[0].size < crash_size)
+		return -EINVAL;
+
+	/* Check if we fit into the respective memory chunk */
+	for (i = 0; i < MEMORY_CHUNKS; i++) {
+		chunk = &memory_chunk[i];
+		if (chunk->size == 0)
+			continue;
+		if (crash_base < chunk->addr)
+			continue;
+		if (crash_base >= chunk->addr + chunk->size)
+			continue;
+		/* we have found the memory chunk */
+		if (crash_base + crash_size > chunk->addr + chunk->size)
+			return -EINVAL;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+/*
+ * Reserve kdump memory by creating a memory hole in the mem_chunk array
+ */
+static void __init reserve_kdump_bootmem(unsigned long addr, unsigned long size,
+					 int type)
+{
+	create_mem_hole(memory_chunk, addr, size, type);
+}
+
+/*
+ * When kdump is enabled, we have to ensure that no memory from
+ * the area [0 - crashkernel memory size] is set offline
+ */
+static int kdump_mem_notifier(struct notifier_block *nb,
+			      unsigned long action, void *data)
+{
+	struct memory_notify *arg = data;
+
+	if (arg->start_pfn >= PFN_DOWN(crashk_res.end - crashk_res.start + 1))
+		return NOTIFY_OK;
+	return NOTIFY_BAD;
+}
+
+static struct notifier_block kdump_mem_nb = {
+	.notifier_call = kdump_mem_notifier,
+};
+
+#endif
+
+/*
+ * Make sure that oldmem, where the dump is stored, is protected
+ */
+static void reserve_oldmem(void)
+{
+#ifdef CONFIG_CRASH_DUMP
+	if (!is_kdump_kernel())
+		return;
+
+	reserve_kdump_bootmem(OLDMEM_BASE, OLDMEM_SIZE, CHUNK_OLDMEM);
+	reserve_kdump_bootmem(OLDMEM_SIZE, memory_end - OLDMEM_SIZE,
+			      CHUNK_OLDMEM);
+	if (OLDMEM_BASE + OLDMEM_SIZE == real_memory_size)
+		saved_max_pfn = PFN_DOWN(OLDMEM_BASE) - 1;
+	else
+		saved_max_pfn = PFN_DOWN(real_memory_size) - 1;
+#endif
+}
+
+/*
+ * Reserve memory for kdump kernel to be loaded with kexec
+ */
+static void __init reserve_crashkernel(void)
+{
+#ifdef CONFIG_CRASH_DUMP
+	unsigned long long crash_base, crash_size;
+	int rc;
+
+	rc = parse_crashkernel(boot_command_line, memory_end, &crash_size,
+			       &crash_base);
+	if (rc || crash_size == 0)
+		return;
+	if (register_memory_notifier(&kdump_mem_nb))
+		return;
+	if (!crash_base)
+		crash_base = find_crash_base(crash_size);
+	if (!crash_base) {
+		pr_info("crashkernel reservation failed: %s\n",
+			"No suitable area found");
+		unregister_memory_notifier(&kdump_mem_nb);
+		return;
+	}
+	if (verify_crash_base(crash_base, crash_size)) {
+		pr_info("crashkernel reservation failed: %s\n",
+			"Invalid memory range specified");
+		unregister_memory_notifier(&kdump_mem_nb);
+		return;
+	}
+	if (!is_kdump_kernel() && MACHINE_IS_VM)
+		diag10_range(PFN_DOWN(crash_base), PFN_DOWN(crash_size));
+	crashk_res.start = crash_base;
+	crashk_res.end = crash_base + crash_size - 1;
+	insert_resource(&iomem_resource, &crashk_res);
+	reserve_kdump_bootmem(crashk_res.start,
+			      crashk_res.end - crashk_res.start + 1,
+			      CHUNK_CRASHK);
+	pr_info("Reserving %lluMB of memory at %lluMB "
+		"for crashkernel (System RAM: %luMB)\n",
+		crash_size >> 20, crash_base >> 20, memory_end >> 20);
+#endif
+}
+
 static void __init
 setup_memory(void)
 {
@@ -580,6 +753,14 @@ setup_memory(void)
 		if (PFN_PHYS(start_pfn) + bmap_size > INITRD_START) {
 			start = PFN_PHYS(start_pfn) + bmap_size + PAGE_SIZE;
 
+#ifdef CONFIG_CRASH_DUMP
+			if (is_kdump_kernel()) {
+				/* Move initrd behind kdump oldmem */
+				if (start + INITRD_SIZE > OLDMEM_BASE &&
+				    start < OLDMEM_BASE + OLDMEM_SIZE)
+					start = OLDMEM_BASE + OLDMEM_SIZE;
+			}
+#endif
 			if (start + INITRD_SIZE > memory_end) {
 				pr_err("initrd extends beyond end of "
 				       "memory (0x%08lx > 0x%08lx) "
@@ -644,6 +825,11 @@ setup_memory(void)
 	reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size,
 			BOOTMEM_DEFAULT);
 
+#ifdef CONFIG_CRASH_DUMP
+	if (is_kdump_kernel())
+		reserve_bootmem(elfcorehdr_addr - OLDMEM_BASE,
+				PAGE_ALIGN(elfcorehdr_size), BOOTMEM_DEFAULT);
+#endif
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (INITRD_START && INITRD_SIZE) {
 		if (INITRD_START + INITRD_SIZE <= memory_end) {
@@ -811,6 +997,8 @@ setup_arch(char **cmdline_p)
 	setup_ipl();
 	setup_memory_end();
 	setup_addressing_mode();
+	reserve_oldmem();
+	reserve_crashkernel();
 	setup_memory();
 	setup_resources();
 	setup_restart_psw();
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -335,6 +335,9 @@ void __init vmem_map_init(void)
 	ro_start = ((unsigned long)&_stext) & PAGE_MASK;
 	ro_end = PFN_ALIGN((unsigned long)&_eshared);
 	for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) {
+		if (memory_chunk[i].type == CHUNK_CRASHK ||
+		    memory_chunk[i].type == CHUNK_OLDMEM)
+			continue;
 		start = memory_chunk[i].addr;
 		end = memory_chunk[i].addr + memory_chunk[i].size;
 		if (start >= ro_end || end <= ro_start)


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

* [patch v2 09/10] s390: kdump backend code
@ 2011-07-27 12:55   ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

[-- Attachment #1: s390-kdump-arch-backend.patch --]
[-- Type: text/plain, Size: 29481 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

This patch provides the architecture specific part of the s390 kdump
support.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 arch/s390/Kconfig                |   10 +
 arch/s390/include/asm/ipl.h      |    1 
 arch/s390/include/asm/kexec.h    |    8 -
 arch/s390/include/asm/sclp.h     |    1 
 arch/s390/include/asm/setup.h    |    9 +
 arch/s390/kernel/Makefile        |    1 
 arch/s390/kernel/crash.c         |  206 ++++++++++++++++++++++++++++++++++++++-
 arch/s390/kernel/crash_dump.c    |   39 +++++++
 arch/s390/kernel/head.S          |   16 +++
 arch/s390/kernel/head_kdump.S    |  116 +++++++++++++++++++++
 arch/s390/kernel/ipl.c           |   48 ++++++++-
 arch/s390/kernel/machine_kexec.c |   64 ++++++++++++
 arch/s390/kernel/mem_detect.c    |   69 +++++++++++++
 arch/s390/kernel/setup.c         |  188 +++++++++++++++++++++++++++++++++++
 arch/s390/mm/vmem.c              |    3 
 15 files changed, 772 insertions(+), 7 deletions(-)

--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -567,6 +567,16 @@ config KEXEC
 	  current kernel, and to start another kernel.  It is like a reboot
 	  but is independent of hardware/microcode support.
 
+config CRASH_DUMP
+	bool "kernel crash dumps"
+	depends on 64BIT
+	help
+	  Generate crash dump after being started by kexec.
+	  Crash dump kernels are loaded in the main kernel with kexec-tools
+	  into a specially reserved region and then later executed after
+	  a crash by kdump/kexec.
+	  For more details see Documentation/kdump/kdump.txt
+
 config ZFCPDUMP
 	def_bool n
 	prompt "zfcpdump support"
--- a/arch/s390/include/asm/ipl.h
+++ b/arch/s390/include/asm/ipl.h
@@ -168,5 +168,6 @@ enum diag308_rc {
 
 extern int diag308(unsigned long subcode, void *addr);
 extern void diag308_reset(void);
+extern void store_status(void);
 
 #endif /* _ASM_S390_IPL_H */
--- a/arch/s390/include/asm/kexec.h
+++ b/arch/s390/include/asm/kexec.h
@@ -30,14 +30,14 @@
 /* Not more than 2GB */
 #define KEXEC_CONTROL_MEMORY_LIMIT (1UL<<31)
 
+/* Maximum address we can use for the crash control pages */
+#define KEXEC_CRASH_CONTROL_MEMORY_LIMIT (-1UL)
+
 /* Allocate one page for the pdp and the second for the code */
 #define KEXEC_CONTROL_PAGE_SIZE 4096
 
 /* The native architecture */
 #define KEXEC_ARCH KEXEC_ARCH_S390
 
-/* Provide a dummy definition to avoid build failures. */
-static inline void crash_setup_regs(struct pt_regs *newregs,
-					struct pt_regs *oldregs) { }
-
+extern void crash_setup_regs(struct pt_regs *newregs, struct pt_regs *oldregs);
 #endif /*_S390_KEXEC_H */
--- a/arch/s390/include/asm/sclp.h
+++ b/arch/s390/include/asm/sclp.h
@@ -55,4 +55,5 @@ int sclp_chp_deconfigure(struct chp_id c
 int sclp_chp_read_info(struct sclp_chp_info *info);
 void sclp_get_ipl_info(struct sclp_ipl_info *info);
 
+void _sclp_print_early(const char *);
 #endif /* _ASM_S390_SCLP_H */
--- a/arch/s390/include/asm/setup.h
+++ b/arch/s390/include/asm/setup.h
@@ -30,11 +30,15 @@
 #define IPL_DEVICE        (*(unsigned long *)  (0x10400))
 #define INITRD_START      (*(unsigned long *)  (0x10408))
 #define INITRD_SIZE       (*(unsigned long *)  (0x10410))
+#define OLDMEM_BASE       (*(unsigned long *)  (0x10418))
+#define OLDMEM_SIZE       (*(unsigned long *)  (0x10420))
 #endif /* __s390x__ */
 #define COMMAND_LINE      ((char *)            (0x10480))
 
 #define CHUNK_READ_WRITE 0
 #define CHUNK_READ_ONLY  1
+#define CHUNK_OLDMEM     4
+#define CHUNK_CRASHK     5
 
 struct mem_chunk {
 	unsigned long addr;
@@ -48,6 +52,8 @@ extern int memory_end_set;
 extern unsigned long memory_end;
 
 void detect_memory_layout(struct mem_chunk chunk[]);
+void create_mem_hole(struct mem_chunk memory_chunk[], unsigned long addr,
+		     unsigned long size, int type);
 
 #define PRIMARY_SPACE_MODE	0
 #define ACCESS_REGISTER_MODE	1
@@ -106,6 +112,7 @@ extern unsigned int user_mode;
 #endif /* __s390x__ */
 
 #define ZFCPDUMP_HSA_SIZE	(32UL<<20)
+#define ZFCPDUMP_HSA_SIZE_MAX	(64UL<<20)
 
 /*
  * Console mode. Override with conmode=
@@ -138,6 +145,8 @@ extern char kernel_nss_name[];
 #define IPL_DEVICE        0x10400
 #define INITRD_START      0x10408
 #define INITRD_SIZE       0x10410
+#define OLDMEM_BASE       0x10418
+#define OLDMEM_SIZE       0x10420
 #endif /* __s390x__ */
 #define COMMAND_LINE      0x10480
 
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_FUNCTION_TRACER)	+= $(if $(
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
 obj-$(CONFIG_FTRACE_SYSCALLS)  += ftrace.o
+obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
 
 # Kexec part
 S390_KEXEC_OBJS := machine_kexec.o crash.o
--- a/arch/s390/kernel/crash.c
+++ b/arch/s390/kernel/crash.c
@@ -1,15 +1,217 @@
 /*
  * arch/s390/kernel/crash.c
  *
- * (C) Copyright IBM Corp. 2005
+ * Copyright IBM Corp. 2005,2011
  *
  * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
- *
+ *            Michael Holzheu <holzheu@linux.vnet.ibm.com>
  */
 
 #include <linux/threads.h>
 #include <linux/kexec.h>
 #include <linux/reboot.h>
+#include <linux/elfcore.h>
+#include <asm/ipl.h>
+
+#ifdef CONFIG_CRASH_DUMP
+
+#define ROUNDUP(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
+#define PTR_ADD(x, y) (((char *) (x)) + ((unsigned long) (y)))
+
+#ifndef NT_FPREGSET
+#define NT_FPREGSET 2
+#endif
+
+/*
+ * fpregset ELF Note
+ */
+struct nt_fpregset_64 {
+	u32	fpc;
+	u32	pad;
+	u64	fprs[16];
+} __packed;
+
+/*
+ * Initialize ELF note
+ */
+static void *nt_init(void *buf, Elf64_Word type, void *desc, int d_len,
+		     const char *name)
+{
+	Elf64_Nhdr *note;
+	u64 len;
+
+	note = (Elf64_Nhdr *)buf;
+	note->n_namesz = strlen(name) + 1;
+	note->n_descsz = d_len;
+	note->n_type = type;
+	len = sizeof(Elf64_Nhdr);
+
+	memcpy(buf + len, name, note->n_namesz);
+	len = ROUNDUP(len + note->n_namesz, 4);
+
+	memcpy(buf + len, desc, note->n_descsz);
+	len = ROUNDUP(len + note->n_descsz, 4);
+
+	return PTR_ADD(buf, len);
+}
+
+/*
+ * Initialize prstatus note
+ */
+static void *nt_prstatus(void *ptr, struct save_area *sa)
+{
+	struct elf_prstatus nt_prstatus;
+	static int cpu_nr = 1;
+
+	memset(&nt_prstatus, 0, sizeof(nt_prstatus));
+	memcpy(&nt_prstatus.pr_reg.gprs, sa->gp_regs, sizeof(sa->gp_regs));
+	memcpy(&nt_prstatus.pr_reg.psw, sa->psw, sizeof(sa->psw));
+	memcpy(&nt_prstatus.pr_reg.acrs, sa->acc_regs, sizeof(sa->acc_regs));
+	nt_prstatus.pr_pid = cpu_nr;
+	cpu_nr++;
+
+	return nt_init(ptr, NT_PRSTATUS, &nt_prstatus, sizeof(nt_prstatus),
+			 "CORE");
+}
+
+/*
+ * Initialize fpregset (floating point) note
+ */
+static void *nt_fpregset(void *ptr, struct save_area *sa)
+{
+	struct nt_fpregset_64 nt_fpregset;
+
+	memset(&nt_fpregset, 0, sizeof(nt_fpregset));
+	memcpy(&nt_fpregset.fpc, &sa->fp_ctrl_reg, sizeof(sa->fp_ctrl_reg));
+	memcpy(&nt_fpregset.fprs, &sa->fp_regs, sizeof(sa->fp_regs));
+
+	return nt_init(ptr, NT_FPREGSET, &nt_fpregset, sizeof(nt_fpregset),
+			 "CORE");
+}
+
+/*
+ * Initialize timer note
+ */
+static void *nt_s390_timer(void *ptr, struct save_area *sa)
+{
+	return nt_init(ptr, NT_S390_TIMER, &sa->timer, sizeof(sa->timer),
+			 KEXEC_CORE_NOTE_NAME);
+}
+
+/*
+ * Initialize TOD clock comparator note
+ */
+static void *nt_s390_tod_cmp(void *ptr, struct save_area *sa)
+{
+	return nt_init(ptr, NT_S390_TODCMP, &sa->clk_cmp,
+		       sizeof(sa->clk_cmp), KEXEC_CORE_NOTE_NAME);
+}
+
+/*
+ * Initialize TOD programmable register note
+ */
+static void *nt_s390_tod_preg(void *ptr, struct save_area *sa)
+{
+	return nt_init(ptr, NT_S390_TODPREG, &sa->tod_reg,
+		       sizeof(sa->tod_reg), KEXEC_CORE_NOTE_NAME);
+}
+
+/*
+ * Initialize control register note
+ */
+static void *nt_s390_ctrs(void *ptr, struct save_area *sa)
+{
+	return nt_init(ptr, NT_S390_CTRS, &sa->ctrl_regs,
+		       sizeof(sa->ctrl_regs), KEXEC_CORE_NOTE_NAME);
+}
+
+/*
+ * Initialize prefix register note
+ */
+static void *nt_s390_prefix(void *ptr, struct save_area *sa)
+{
+	return nt_init(ptr, NT_S390_PREFIX, &sa->pref_reg,
+			 sizeof(sa->pref_reg), KEXEC_CORE_NOTE_NAME);
+}
+
+/*
+ * Final empty node
+ */
+static void nt_final(void *ptr)
+{
+	memset(ptr, 0, sizeof(struct elf_note));
+}
+
+/*
+ * Add create ELF notes for CPU
+ */
+static void add_elf_notes(int cpu)
+{
+	struct save_area *sa = (void *) 4608;
+	void *ptr;
+
+	memcpy((void *) (4608UL + sa->pref_reg), sa, sizeof(*sa));
+	ptr = (u64 *) per_cpu_ptr(crash_notes, cpu);
+	ptr = nt_prstatus(ptr, sa);
+	ptr = nt_fpregset(ptr, sa);
+	ptr = nt_s390_timer(ptr, sa);
+	ptr = nt_s390_tod_cmp(ptr, sa);
+	ptr = nt_s390_tod_preg(ptr, sa);
+	ptr = nt_s390_ctrs(ptr, sa);
+	ptr = nt_s390_prefix(ptr, sa);
+	nt_final(ptr);
+}
+
+/*
+ * Store status of next available physical CPU
+ */
+static int store_status_next(int start_cpu, int this_cpu)
+{
+	struct save_area *sa = (void *) 4608;
+	int cpu, rc;
+
+	for (cpu = start_cpu; cpu < 65536; cpu++) {
+		if (cpu == this_cpu)
+			continue;
+		do {
+			rc = raw_sigp(cpu, sigp_stop_and_store_status);
+		} while (rc == sigp_busy);
+		if (rc != sigp_order_code_accepted)
+			continue;
+		if (sa->pref_reg)
+			return cpu;
+	}
+	return -1;
+}
+
+#endif /* CONFIG_CRASH_DUMP */
+
+/*
+ * Initialize CPU ELF notes
+ *
+ * We expect that for current CPU a store status has been done
+ */
+void crash_setup_regs(struct pt_regs *newregs, struct pt_regs *oldregs)
+{
+#ifdef CONFIG_CRASH_DUMP
+	int cpu, this_cpu, phys_cpu = 0, first = 1;
+
+	this_cpu = stap();
+
+	for_each_online_cpu(cpu) {
+		if (first && S390_lowcore.prefixreg_save_area) {
+			add_elf_notes(cpu);
+			first = 0;
+			continue;
+		}
+		phys_cpu = store_status_next(phys_cpu, this_cpu);
+		if (phys_cpu == -1)
+			return;
+		add_elf_notes(cpu);
+		phys_cpu++;
+	}
+#endif
+}
 
 void machine_crash_shutdown(struct pt_regs *regs)
 {
--- /dev/null
+++ b/arch/s390/kernel/crash_dump.c
@@ -0,0 +1,39 @@
+/*
+ * S390 kdump implementation
+ *
+ * Copyright IBM Corp. 2011
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+#include <linux/crash_dump.h>
+#include <asm/lowcore.h>
+
+/*
+ * Copy one page from "oldmem"
+ *
+ * For the kdump reserved memory this functions performs a swap operation:
+ *  - [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE] is mapped to [0 - OLDMEM_SIZE].
+ *  - [0 - OLDMEM_SIZE] is mapped to [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE]
+ */
+ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
+			 size_t csize, unsigned long offset, int userbuf)
+{
+	unsigned long src;
+	int rc;
+
+	if (!csize)
+		return 0;
+
+	src = (pfn << PAGE_SHIFT) + offset;
+	if (src < OLDMEM_SIZE)
+		src += OLDMEM_BASE;
+	else if (src > OLDMEM_BASE &&
+		 src < OLDMEM_BASE + OLDMEM_SIZE)
+		src -= OLDMEM_BASE;
+	if (userbuf)
+		rc = copy_to_user_real((void __user *) buf, (void *) src,
+				       csize);
+	else
+		rc = memcpy_real(buf, (void *) src, csize);
+	return rc < 0 ? rc : csize;
+}
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -449,10 +449,22 @@ ENTRY(start)
 #
 	.org	0x10000
 ENTRY(startup)
+	j	.Lep_startup_normal
+	.org	0x10008
+	.ascii	"S390EP"
+	.byte	0x00,0x01
+#
+# kdump startup-code at 0x10010, running in 64 bit absolute addressing mode
+#
+	.org	0x10010
+ENTRY(startup_kdump)
+	j	.Lep_startup_kdump
+.Lep_startup_normal:
 	basr	%r13,0			# get base
 .LPG0:
 	xc	0x200(256),0x200	# partially clear lowcore
 	xc	0x300(256),0x300
+	xc	0xe00(256),0xe00
 	stck	__LC_LAST_UPDATE_CLOCK
 	spt	5f-.LPG0(%r13)
 	mvc	__LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13)
@@ -534,6 +546,8 @@ ENTRY(startup)
 	.align	8
 5:	.long	0x7fffffff,0xffffffff
 
+#include "head_kdump.S"
+
 #
 # params at 10400 (setup.h)
 #
@@ -541,6 +555,8 @@ ENTRY(startup)
 	.long	0,0			# IPL_DEVICE
 	.long	0,0			# INITRD_START
 	.long	0,0			# INITRD_SIZE
+	.long	0,0			# OLDMEM_BASE
+	.long	0,0			# OLDMEM_SIZE
 
 	.org	COMMAND_LINE
 	.byte	"root=/dev/ram0 ro"
--- /dev/null
+++ b/arch/s390/kernel/head_kdump.S
@@ -0,0 +1,116 @@
+/*
+ * S390 kdump lowlevel functions (new kernel)
+ *
+ * Copyright IBM Corp. 2011
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+#define DATAMOVER_ADDR	0x4000
+#define COPY_PAGE_ADDR	0x6000
+
+#ifdef CONFIG_CRASH_DUMP
+
+#
+# kdump entry (new kernel - not yet relocated)
+#
+# Note: This code has to be position independent
+#
+
+.align 2
+.Lep_startup_kdump:
+	basr	%r13,0
+.Lbase:
+	larl	%r2,.Lbase_addr			# Check, if we have been
+	lg	%r2,0(%r2)			# already relocated:
+	clgr	%r2,%r13			#
+	jne	.Lrelocate			# No : Start data mover
+	lghi	%r2,0				# Yes: Start kdump kernel
+	brasl	%r14,startup_kdump_relocated
+
+.Lrelocate:
+	larl	%r4,startup
+	lg	%r2,0x418(%r4)			# Get kdump base
+	lg	%r3,0x420(%r4)			# Get kdump size
+
+	larl	%r10,.Lcopy_start		# Source of data mover
+	lghi	%r8,DATAMOVER_ADDR		# Target of data mover
+	mvc	0(256,%r8),0(%r10)		# Copy data mover code
+
+	agr	%r8,%r2				# Copy data mover to
+	mvc	0(256,%r8),0(%r10)		# reserved mem
+
+	lghi	%r14,DATAMOVER_ADDR		# Jump to copied data mover
+	basr	%r14,%r14
+.Lbase_addr:
+	.quad	.Lbase
+
+#
+# kdump data mover code (runs at address DATAMOVER_ADDR)
+#
+# r2: kdump base address
+# r3: kdump size
+#
+.Lcopy_start:
+	basr	%r13,0				# Base
+0:
+	lgr	%r11,%r2			# Save kdump base address
+	lgr	%r12,%r2
+	agr	%r12,%r3			# Compute kdump end address
+
+	lghi	%r5,0
+	lghi	%r10,COPY_PAGE_ADDR		# Load copy page address
+1:
+	mvc	0(256,%r10),0(%r5)		# Copy old kernel to tmp
+	mvc	0(256,%r5),0(%r11)		# Copy new kernel to old
+	mvc	0(256,%r11),0(%r10)		# Copy tmp to new
+	aghi	%r11,256
+	aghi	%r5,256
+	clgr	%r11,%r12
+	jl	1b
+
+	lg	%r14,.Lstartup_kdump-0b(%r13)
+	basr	%r14,%r14			# Start relocated kernel
+.Lstartup_kdump:
+	.long	0x00000000,0x00000000 + startup_kdump_relocated
+.Lcopy_end:
+
+#
+# Startup of kdump (relocated new kernel)
+#
+.align 2
+startup_kdump_relocated:
+	basr	%r13,0
+0:
+	mvc	0(8,%r0),.Lrestart_psw-0b(%r13)	# Setup restart PSW
+	mvc	464(16,%r0),.Lpgm_psw-0b(%r13)	# Setup pgm check PSW
+	lhi	%r1,1				# Start new kernel
+	diag	%r1,%r1,0x308			# with diag 308
+
+.Lno_diag308:					# No diag 308
+	sam31					# Switch to 31 bit addr mode
+	sr	%r1,%r1				# Erase register r1
+	sr	%r2,%r2				# Erase register r2
+	sigp	%r1,%r2,0x12			# Switch to 31 bit arch mode
+	lpsw	0				# Start new kernel...
+.align	8
+.Lrestart_psw:
+	.long	0x00080000,0x80000000 + startup
+.Lpgm_psw:
+	.quad	0x0000000180000000,0x0000000000000000 + .Lno_diag308
+#else
+.align 2
+.Lep_startup_kdump:
+#ifdef CONFIG_64BIT
+	larl	%r13,startup_kdump_crash
+	lpswe	0(%r13)
+.align 8
+startup_kdump_crash:
+	.quad	0x0002000080000000,0x0000000000000000 + startup_kdump_crash
+#else
+	basr	%r13,0
+0:	lpsw	startup_kdump_crash-0b(%r13)
+.align 8
+startup_kdump_crash:
+	.long	0x000a0000,0x00000000 + startup_kdump_crash
+#endif /* CONFIG_64BIT */
+#endif /* CONFIG_CRASH_DUMP */
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -16,6 +16,7 @@
 #include <linux/ctype.h>
 #include <linux/fs.h>
 #include <linux/gfp.h>
+#include <linux/crash_dump.h>
 #include <asm/ipl.h>
 #include <asm/smp.h>
 #include <asm/setup.h>
@@ -26,6 +27,7 @@
 #include <asm/sclp.h>
 #include <asm/sigp.h>
 #include <asm/checksum.h>
+#include <asm/lowcore.h>
 
 #define IPL_PARM_BLOCK_VERSION 0
 
@@ -68,6 +70,7 @@ struct shutdown_trigger {
 #define SHUTDOWN_ACTION_VMCMD_STR	"vmcmd"
 #define SHUTDOWN_ACTION_STOP_STR	"stop"
 #define SHUTDOWN_ACTION_DUMP_REIPL_STR	"dump_reipl"
+#define SHUTDOWN_ACTION_KDUMP_STR	"kdump"
 
 struct shutdown_action {
 	char *name;
@@ -1628,11 +1631,42 @@ static void stop_run(struct shutdown_tri
 static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
 					     stop_run, NULL};
 
+/*
+ * kdump shutdown action: Trigger kdump on shutdown.
+ */
+
+#ifdef CONFIG_CRASH_DUMP
+static int kdump_init(void)
+{
+	if (crashk_res.start == 0)
+		return -EOPNOTSUPP;
+	return 0;
+}
+
+static void kdump_run(struct shutdown_trigger *trigger)
+{
+	pfault_fini();
+	s390_reset_system();
+	__arch_local_irq_stnsm(0xfb); /* disable DAT */
+	store_status();
+
+	crash_kexec(NULL);
+	disabled_wait((unsigned long) __builtin_return_address(0));
+}
+
+static struct shutdown_action kdump_action = {SHUTDOWN_ACTION_KDUMP_STR,
+					     kdump_run, kdump_init};
+#endif
+
 /* action list */
 
 static struct shutdown_action *shutdown_actions_list[] = {
 	&ipl_action, &reipl_action, &dump_reipl_action, &dump_action,
-	&vmcmd_action, &stop_action};
+	&vmcmd_action, &stop_action,
+#ifdef CONFIG_CRASH_DUMP
+	&kdump_action
+#endif
+	};
 #define SHUTDOWN_ACTIONS_COUNT (sizeof(shutdown_actions_list) / sizeof(void *))
 
 /*
@@ -1802,6 +1836,16 @@ void (*_machine_power_off)(void) = do_ma
 
 static void __init shutdown_triggers_init(void)
 {
+#ifdef CONFIG_CRASH_DUMP
+	/*
+	 * We set the kdump action for panic and restart, if crashkernel
+	 * memory is defined.
+	 */
+	if (crashk_res.start != 0) {
+		on_restart_trigger.action = &kdump_action;
+		on_panic_trigger.action = &kdump_action;
+	}
+#endif
 	shutdown_actions_kset = kset_create_and_add("shutdown_actions", NULL,
 						    firmware_kobj);
 	if (!shutdown_actions_kset)
@@ -2016,6 +2060,8 @@ void s390_reset_system(void)
 
 	/* Stack for interrupt/machine check handler */
 	lc->panic_stack = S390_lowcore.panic_stack;
+	/* CPU number */
+	lc->cpu_nr = S390_lowcore.cpu_nr;
 
 	/* Save prefix page address for dump case */
 	dump_prefix_page = (u32)(unsigned long) lc;
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -21,12 +21,67 @@
 #include <asm/smp.h>
 #include <asm/reset.h>
 #include <asm/ipl.h>
+#include <asm/cacheflush.h>
+#include <asm/asm-offsets.h>
+#include <asm/checksum.h>
+#include <asm/diag.h>
+#include <asm/sclp.h>
 
 typedef void (*relocate_kernel_t)(kimage_entry_t *, unsigned long);
 
 extern const unsigned char relocate_kernel[];
 extern const unsigned long long relocate_kernel_len;
 
+#ifdef CONFIG_CRASH_DUMP
+
+/*
+ * S390 version: Currently we do not support freeing crashkernel memory
+ */
+void crash_free_reserved_phys_range(unsigned long begin, unsigned long end)
+{
+	return;
+}
+
+/*
+ * S390 version: Just do real copy of segment
+ */
+int kimage_load_crash_segment(struct kimage *image,
+			      struct kexec_segment *segment)
+{
+	return copy_from_user_real((void *) segment->mem, segment->buf,
+				   segment->bufsz);
+}
+
+/*
+ * Start kdump
+ */
+static void __machine_kdump(void *data)
+{
+	struct kimage *image = data;
+	psw_t kdump_psw;
+
+	kdump_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
+	kdump_psw.addr = (unsigned long) image->start;
+	__load_psw(kdump_psw);
+}
+
+#endif
+
+/*
+ * Give back memory to hypervisor before new kdump is loaded
+ */
+static int machine_kexec_prepare_kdump(void)
+{
+#ifdef CONFIG_CRASH_DUMP
+	if (MACHINE_IS_VM)
+		diag10_range(PFN_DOWN(crashk_res.start),
+			     PFN_DOWN(crashk_res.end - crashk_res.start + 1));
+	return 0;
+#else
+	return -EINVAL;
+#endif
+}
+
 int machine_kexec_prepare(struct kimage *image)
 {
 	void *reboot_code_buffer;
@@ -35,6 +90,9 @@ int machine_kexec_prepare(struct kimage
 	if (ipl_flags & IPL_NSS_VALID)
 		return -ENOSYS;
 
+	if (image->type == KEXEC_TYPE_CRASH)
+		return machine_kexec_prepare_kdump();
+
 	/* We don't support anything but the default image type for now. */
 	if (image->type != KEXEC_TYPE_DEFAULT)
 		return -EINVAL;
@@ -72,6 +130,12 @@ static void __machine_kexec(void *data)
 
 void machine_kexec(struct kimage *image)
 {
+#ifdef CONFIG_CRASH_DUMP
+	if (image->type == KEXEC_TYPE_CRASH) {
+		_sclp_print_early("Starting kdump");
+		smp_switch_to_ipl_cpu(__machine_kdump, image);
+	}
+#endif
 	tracer_disable();
 	smp_send_stop();
 	smp_switch_to_ipl_cpu(__machine_kexec, image);
--- a/arch/s390/kernel/mem_detect.c
+++ b/arch/s390/kernel/mem_detect.c
@@ -62,3 +62,72 @@ void detect_memory_layout(struct mem_chu
 	arch_local_irq_restore(flags);
 }
 EXPORT_SYMBOL(detect_memory_layout);
+
+/*
+ * Create memory hole with given address, size, and type
+ */
+void create_mem_hole(struct mem_chunk chunks[], unsigned long addr,
+		     unsigned long size, int type)
+{
+	unsigned long start, end, new_size;
+	int i;
+
+	for (i = 0; i < MEMORY_CHUNKS; i++) {
+		if (chunks[i].size == 0)
+			continue;
+		if (addr + size < chunks[i].addr)
+			continue;
+		if (addr >= chunks[i].addr + chunks[i].size)
+			continue;
+		start = max(addr, chunks[i].addr);
+		end = min(addr + size, chunks[i].addr + chunks[i].size);
+		new_size = end - start;
+		if (new_size == 0)
+			continue;
+		if (start == chunks[i].addr &&
+		    end == chunks[i].addr + chunks[i].size) {
+			/* Remove chunk */
+			chunks[i].type = type;
+		} else if (start == chunks[i].addr) {
+			/* Make chunk smaller at start */
+			if (i >= MEMORY_CHUNKS - 1)
+				panic("Unable to create memory hole");
+			memmove(&chunks[i + 1], &chunks[i],
+				sizeof(struct mem_chunk) *
+				(MEMORY_CHUNKS - (i + 1)));
+			chunks[i + 1].addr = chunks[i].addr + new_size;
+			chunks[i + 1].size = chunks[i].size - new_size;
+			chunks[i].size = new_size;
+			chunks[i].type = type;
+			i += 1;
+		} else if (end == chunks[i].addr + chunks[i].size) {
+			/* Make chunk smaller at end */
+			if (i >= MEMORY_CHUNKS - 1)
+				panic("Unable to create memory hole");
+			memmove(&chunks[i + 1], &chunks[i],
+				sizeof(struct mem_chunk) *
+				(MEMORY_CHUNKS - (i + 1)));
+			chunks[i + 1].addr = start;
+			chunks[i + 1].size = new_size;
+			chunks[i + 1].type = type;
+			chunks[i].size -= new_size;
+			i += 1;
+		} else {
+			/* Create memory hole */
+			if (i >= MEMORY_CHUNKS - 2)
+				panic("Unable to create memory hole");
+			memmove(&chunks[i + 2], &chunks[i],
+				sizeof(struct mem_chunk) *
+				(MEMORY_CHUNKS - (i + 2)));
+			chunks[i + 1].addr = addr;
+			chunks[i + 1].size = size;
+			chunks[i + 1].type = type;
+			chunks[i + 2].addr = addr + size;
+			chunks[i + 2].size =
+				chunks[i].addr + chunks[i].size - (addr + size);
+			chunks[i + 2].type = chunks[i].type;
+			chunks[i].size = addr - chunks[i].addr;
+			i += 2;
+		}
+	}
+}
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -42,6 +42,9 @@
 #include <linux/reboot.h>
 #include <linux/topology.h>
 #include <linux/ftrace.h>
+#include <linux/kexec.h>
+#include <linux/crash_dump.h>
+#include <linux/memory.h>
 
 #include <asm/ipl.h>
 #include <asm/uaccess.h>
@@ -57,6 +60,7 @@
 #include <asm/ebcdic.h>
 #include <asm/compat.h>
 #include <asm/kvm_virtio.h>
+#include <asm/diag.h>
 
 long psw_kernel_bits	= (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY |
 			   PSW_MASK_MCHECK | PSW_DEFAULT_KEY);
@@ -435,6 +439,9 @@ static void __init setup_resources(void)
 	for (i = 0; i < MEMORY_CHUNKS; i++) {
 		if (!memory_chunk[i].size)
 			continue;
+		if (memory_chunk[i].type == CHUNK_OLDMEM ||
+		    memory_chunk[i].type == CHUNK_CRASHK)
+			continue;
 		res = alloc_bootmem_low(sizeof(*res));
 		res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
 		switch (memory_chunk[i].type) {
@@ -479,6 +486,7 @@ static void __init setup_memory_end(void
 	unsigned long max_mem;
 	int i;
 
+
 #ifdef CONFIG_ZFCPDUMP
 	if (ipl_info.type == IPL_TYPE_FCP_DUMP) {
 		memory_end = ZFCPDUMP_HSA_SIZE;
@@ -550,6 +558,171 @@ static void __init setup_restart_psw(voi
 	copy_to_absolute_zero(&S390_lowcore.restart_psw, &psw, sizeof(psw));
 }
 
+#ifdef CONFIG_CRASH_DUMP
+
+/*
+ * Find suitable location for crashkernel memory
+ */
+static unsigned long __init find_crash_base(unsigned long crash_size)
+{
+	unsigned long crash_base;
+	struct mem_chunk *chunk;
+	int i;
+
+	if (is_kdump_kernel() && (crash_size == OLDMEM_SIZE))
+		return OLDMEM_BASE;
+
+	for (i = MEMORY_CHUNKS - 1; i >= 0; i--) {
+		chunk = &memory_chunk[i];
+		if (chunk->size == 0)
+			continue;
+		if (chunk->type != CHUNK_READ_WRITE)
+			continue;
+		if (chunk->size < crash_size)
+			continue;
+		crash_base = max(chunk->addr, crash_size);
+		crash_base = max(crash_base, ZFCPDUMP_HSA_SIZE_MAX);
+		crash_base = max(crash_base, (unsigned long) INITRD_START +
+				 INITRD_SIZE);
+		crash_base = PAGE_ALIGN(crash_base);
+		if (crash_base >= chunk->addr + chunk->size)
+			continue;
+		if (chunk->addr + chunk->size - crash_base < crash_size)
+			continue;
+		crash_base = chunk->size - crash_size;
+		return crash_base;
+	}
+	return 0;
+}
+
+/*
+ * Check if crash_base and crash_size is valid
+ */
+static int __init verify_crash_base(unsigned long crash_base,
+				    unsigned long crash_size)
+{
+	struct mem_chunk *chunk;
+	int i;
+
+	/*
+	 * Because we do the swap to zero, we must have at least 'crash_size'
+	 * bytes free space before crash_base
+	 */
+	if (crash_size > crash_base)
+		return -EINVAL;
+
+	/* First memory chunk must be at least crash_size */
+	if (memory_chunk[0].size < crash_size)
+		return -EINVAL;
+
+	/* Check if we fit into the respective memory chunk */
+	for (i = 0; i < MEMORY_CHUNKS; i++) {
+		chunk = &memory_chunk[i];
+		if (chunk->size == 0)
+			continue;
+		if (crash_base < chunk->addr)
+			continue;
+		if (crash_base >= chunk->addr + chunk->size)
+			continue;
+		/* we have found the memory chunk */
+		if (crash_base + crash_size > chunk->addr + chunk->size)
+			return -EINVAL;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+/*
+ * Reserve kdump memory by creating a memory hole in the mem_chunk array
+ */
+static void __init reserve_kdump_bootmem(unsigned long addr, unsigned long size,
+					 int type)
+{
+	create_mem_hole(memory_chunk, addr, size, type);
+}
+
+/*
+ * When kdump is enabled, we have to ensure that no memory from
+ * the area [0 - crashkernel memory size] is set offline
+ */
+static int kdump_mem_notifier(struct notifier_block *nb,
+			      unsigned long action, void *data)
+{
+	struct memory_notify *arg = data;
+
+	if (arg->start_pfn >= PFN_DOWN(crashk_res.end - crashk_res.start + 1))
+		return NOTIFY_OK;
+	return NOTIFY_BAD;
+}
+
+static struct notifier_block kdump_mem_nb = {
+	.notifier_call = kdump_mem_notifier,
+};
+
+#endif
+
+/*
+ * Make sure that oldmem, where the dump is stored, is protected
+ */
+static void reserve_oldmem(void)
+{
+#ifdef CONFIG_CRASH_DUMP
+	if (!is_kdump_kernel())
+		return;
+
+	reserve_kdump_bootmem(OLDMEM_BASE, OLDMEM_SIZE, CHUNK_OLDMEM);
+	reserve_kdump_bootmem(OLDMEM_SIZE, memory_end - OLDMEM_SIZE,
+			      CHUNK_OLDMEM);
+	if (OLDMEM_BASE + OLDMEM_SIZE == real_memory_size)
+		saved_max_pfn = PFN_DOWN(OLDMEM_BASE) - 1;
+	else
+		saved_max_pfn = PFN_DOWN(real_memory_size) - 1;
+#endif
+}
+
+/*
+ * Reserve memory for kdump kernel to be loaded with kexec
+ */
+static void __init reserve_crashkernel(void)
+{
+#ifdef CONFIG_CRASH_DUMP
+	unsigned long long crash_base, crash_size;
+	int rc;
+
+	rc = parse_crashkernel(boot_command_line, memory_end, &crash_size,
+			       &crash_base);
+	if (rc || crash_size == 0)
+		return;
+	if (register_memory_notifier(&kdump_mem_nb))
+		return;
+	if (!crash_base)
+		crash_base = find_crash_base(crash_size);
+	if (!crash_base) {
+		pr_info("crashkernel reservation failed: %s\n",
+			"No suitable area found");
+		unregister_memory_notifier(&kdump_mem_nb);
+		return;
+	}
+	if (verify_crash_base(crash_base, crash_size)) {
+		pr_info("crashkernel reservation failed: %s\n",
+			"Invalid memory range specified");
+		unregister_memory_notifier(&kdump_mem_nb);
+		return;
+	}
+	if (!is_kdump_kernel() && MACHINE_IS_VM)
+		diag10_range(PFN_DOWN(crash_base), PFN_DOWN(crash_size));
+	crashk_res.start = crash_base;
+	crashk_res.end = crash_base + crash_size - 1;
+	insert_resource(&iomem_resource, &crashk_res);
+	reserve_kdump_bootmem(crashk_res.start,
+			      crashk_res.end - crashk_res.start + 1,
+			      CHUNK_CRASHK);
+	pr_info("Reserving %lluMB of memory at %lluMB "
+		"for crashkernel (System RAM: %luMB)\n",
+		crash_size >> 20, crash_base >> 20, memory_end >> 20);
+#endif
+}
+
 static void __init
 setup_memory(void)
 {
@@ -580,6 +753,14 @@ setup_memory(void)
 		if (PFN_PHYS(start_pfn) + bmap_size > INITRD_START) {
 			start = PFN_PHYS(start_pfn) + bmap_size + PAGE_SIZE;
 
+#ifdef CONFIG_CRASH_DUMP
+			if (is_kdump_kernel()) {
+				/* Move initrd behind kdump oldmem */
+				if (start + INITRD_SIZE > OLDMEM_BASE &&
+				    start < OLDMEM_BASE + OLDMEM_SIZE)
+					start = OLDMEM_BASE + OLDMEM_SIZE;
+			}
+#endif
 			if (start + INITRD_SIZE > memory_end) {
 				pr_err("initrd extends beyond end of "
 				       "memory (0x%08lx > 0x%08lx) "
@@ -644,6 +825,11 @@ setup_memory(void)
 	reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size,
 			BOOTMEM_DEFAULT);
 
+#ifdef CONFIG_CRASH_DUMP
+	if (is_kdump_kernel())
+		reserve_bootmem(elfcorehdr_addr - OLDMEM_BASE,
+				PAGE_ALIGN(elfcorehdr_size), BOOTMEM_DEFAULT);
+#endif
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (INITRD_START && INITRD_SIZE) {
 		if (INITRD_START + INITRD_SIZE <= memory_end) {
@@ -811,6 +997,8 @@ setup_arch(char **cmdline_p)
 	setup_ipl();
 	setup_memory_end();
 	setup_addressing_mode();
+	reserve_oldmem();
+	reserve_crashkernel();
 	setup_memory();
 	setup_resources();
 	setup_restart_psw();
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -335,6 +335,9 @@ void __init vmem_map_init(void)
 	ro_start = ((unsigned long)&_stext) & PAGE_MASK;
 	ro_end = PFN_ALIGN((unsigned long)&_eshared);
 	for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) {
+		if (memory_chunk[i].type == CHUNK_CRASHK ||
+		    memory_chunk[i].type == CHUNK_OLDMEM)
+			continue;
 		start = memory_chunk[i].addr;
 		end = memory_chunk[i].addr + memory_chunk[i].size;
 		if (start >= ro_end || end <= ro_start)


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

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

* [patch v2 10/10] kexec-tools: Add s390 kdump support
  2011-07-27 12:55 ` Michael Holzheu
@ 2011-07-27 12:55   ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

[-- Attachment #1: kexec-tools-s390-kdump.patch --]
[-- Type: text/plain, Size: 15592 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

This patch adds kdump support for s390 to the kexec tool and enables the
"--load-panic" option. When loading the kdump kernel and ramdisk we add the
address of the crashkernel memory to the normal load address.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 include/elf.h                        |    8 +++-
 kexec/arch/s390/Makefile             |    1 
 kexec/arch/s390/crashdump-s390.c     |   59 +++++++++++++++++++++++++++++++
 kexec/arch/s390/kexec-elf-rel-s390.c |   66 ++++++++++++++++++++++++++++++-----
 kexec/arch/s390/kexec-image.c        |   61 ++++++++++++++++++++++----------
 kexec/arch/s390/kexec-s390.c         |   66 ++++++++++++++++++++++++-----------
 kexec/arch/s390/kexec-s390.h         |    7 +++
 purgatory/arch/s390/Makefile         |    4 +-
 purgatory/arch/s390/console-s390.c   |   14 +++++++
 purgatory/arch/s390/purgatory-s390.c |   17 +++++++++
 purgatory/arch/s390/setup-s390.S     |   35 ++++++++++++++++++
 11 files changed, 290 insertions(+), 48 deletions(-)

--- a/include/elf.h
+++ b/include/elf.h
@@ -2304,9 +2304,13 @@ typedef Elf32_Addr Elf32_Conflict;
 #define R_390_TLS_DTPOFF	55	/* Offset in TLS block.	 */
 #define R_390_TLS_TPOFF		56	/* Negated offset in static TLS
 					   block.  */
-
+#define R_390_20		57	/* Direct 20 bit.  */
+#define R_390_GOT20		58	/* 20 bit GOT offset.  */
+#define R_390_GOTPLT20		59	/* 20 bit offset to jump slot.  */
+#define R_390_TLS_GOTIE20	60	/* 20 bit GOT offset for static TLS
+					   block offset.  */
 /* Keep this the last entry.  */
-#define R_390_NUM		57
+#define R_390_NUM		61
 
 /* CRIS relocations.  */
 #define R_CRIS_NONE		0
--- a/kexec/arch/s390/Makefile
+++ b/kexec/arch/s390/Makefile
@@ -4,6 +4,7 @@
 s390_KEXEC_SRCS =  kexec/arch/s390/kexec-s390.c
 s390_KEXEC_SRCS += kexec/arch/s390/kexec-image.c
 s390_KEXEC_SRCS += kexec/arch/s390/kexec-elf-rel-s390.c
+s390_KEXEC_SRCS += kexec/arch/s390/crashdump-s390.c
 
 dist += kexec/arch/s390/Makefile $(s390_KEXEC_SRCS)			\
 	kexec/arch/s390/kexec-s390.h					\
--- /dev/null
+++ b/kexec/arch/s390/crashdump-s390.c
@@ -0,0 +1,59 @@
+/*
+ * kexec/arch/s390/crashdump-s390.c
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <elf.h>
+#include <limits.h>
+#include "../../kexec.h"
+#include "../../kexec-syscall.h"
+#include "../../kexec/crashdump.h"
+#include "kexec-s390.h"
+
+/*
+ * Load additional segments for kdump kernel
+ */
+int load_crashdump_segments(struct kexec_info *info, unsigned long crash_base,
+			    unsigned long crash_end)
+{
+	unsigned long bufsz, elfcorehdr, elfcorehdr_size, addr, crash_size;
+	static struct memory_range crash_memory_range[MAX_MEMORY_RANGES];
+	struct crash_elf_info elf_info;
+	char str[COMMAND_LINESIZE];
+	int ranges;
+	void *tmp;
+
+	crash_size = crash_end - crash_base + 1;
+	memset(&elf_info, 0, sizeof(elf_info));
+
+	elf_info.data = ELFDATA2MSB;
+	elf_info.machine = EM_S390;
+	elf_info.class = ELFCLASS64;
+	elf_info.get_note_info = get_crash_notes_per_cpu;
+
+	if (get_memory_ranges_s390(crash_memory_range, &ranges, 0))
+		    return -1;
+
+	if (crash_create_elf64_headers(info, &elf_info, crash_memory_range,
+				       ranges, &tmp, &bufsz,
+				       ELF_CORE_HEADER_ALIGN))
+		return -1;
+
+	elfcorehdr = add_buffer(info, tmp, bufsz, bufsz, 1024,
+				crash_base, crash_end, -1);
+	elfcorehdr_size = bufsz;
+	elf_rel_build_load(info, &info->rhdr, (const char *) purgatory,
+			   purgatory_size, 0, ULONG_MAX, -1, 0);
+	addr = crash_base + 0x10010;
+	elf_rel_set_symbol(&info->rhdr, "kdump_psw_addr", &addr, sizeof(addr));
+	info->entry = (void *) elf_rel_get_addr(&info->rhdr, "purgatory_start");
+	snprintf(str, sizeof(str), " elfcorehdr=%ld@%ldK\n",
+		 elfcorehdr_size, elfcorehdr / 1024);
+	command_line_add(str);
+	return 0;
+}
--- a/kexec/arch/s390/kexec-elf-rel-s390.c
+++ b/kexec/arch/s390/kexec-elf-rel-s390.c
@@ -1,7 +1,7 @@
 /*
  * kexec/arch/s390/kexec-elf-rel-s390.c
  *
- * (C) Copyright IBM Corp. 2005
+ * Copyright IBM Corp. 2005,2011
  *
  * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
  *
@@ -12,15 +12,65 @@
 #include "../../kexec.h"
 #include "../../kexec-elf.h"
 
-int machine_verify_elf_rel(struct mem_ehdr *UNUSED(ehdr))
+int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 {
-	return 0;
+	if (ehdr->ei_data != ELFDATA2MSB)
+		return 0;
+	if (ehdr->ei_class != ELFCLASS64)
+		return 0;
+	if (ehdr->e_machine != EM_S390)
+		return 0;
+	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
-			   unsigned long UNUSED(r_type),
-			   void *UNUSED(location),
-			   unsigned long UNUSED(address),
-			   unsigned long UNUSED(value))
+void machine_apply_elf_rel(struct mem_ehdr *ehdr,
+			   unsigned long r_type,
+			   void *loc,
+			   unsigned long address,
+			   unsigned long val)
 {
+	switch (r_type) {
+	case R_390_8:		/* Direct 8 bit.   */
+	case R_390_12:		/* Direct 12 bit.  */
+	case R_390_16:		/* Direct 16 bit.  */
+	case R_390_20:		/* Direct 20 bit.  */
+	case R_390_32:		/* Direct 32 bit.  */
+	case R_390_64:		/* Direct 64 bit.  */
+		if (r_type == R_390_8)
+			*(unsigned char *) loc = val;
+		else if (r_type == R_390_12)
+			*(unsigned short *) loc = (val & 0xfff) |
+				(*(unsigned short *) loc & 0xf000);
+		else if (r_type == R_390_16)
+			*(unsigned short *) loc = val;
+		else if (r_type == R_390_20)
+			*(unsigned int *) loc =
+				(*(unsigned int *) loc & 0xf00000ff) |
+				(val & 0xfff) << 16 | (val & 0xff000) >> 4;
+		else if (r_type == R_390_32)
+			*(unsigned int *) loc = val;
+		else if (r_type == R_390_64)
+			*(unsigned long *) loc = val;
+		break;
+	case R_390_PC16:	/* PC relative 16 bit.  */
+	case R_390_PC16DBL:	/* PC relative 16 bit shifted by 1.  */
+	case R_390_PC32DBL:	/* PC relative 32 bit shifted by 1.  */
+	case R_390_PC32:	/* PC relative 32 bit.  */
+	case R_390_PC64:	/* PC relative 64 bit.	*/
+		val -= address;
+		if (r_type == R_390_PC16)
+			*(unsigned short *) loc = val;
+		else if (r_type == R_390_PC16DBL)
+			*(unsigned short *) loc = val >> 1;
+		else if (r_type == R_390_PC32DBL)
+			*(unsigned int *) loc = val >> 1;
+		else if (r_type == R_390_PC32)
+			*(unsigned int *) loc = val;
+		else if (r_type == R_390_PC64)
+			*(unsigned long *) loc = val;
+		break;
+	default:
+		die("Unknown rela relocation: 0x%lx 0x%lx\n", r_type, address);
+		break;
+	}
 }
--- a/kexec/arch/s390/kexec-image.c
+++ b/kexec/arch/s390/kexec-image.c
@@ -18,20 +18,34 @@
 #include <unistd.h>
 #include <getopt.h>
 #include "../../kexec.h"
+#include "../../kexec-syscall.h"
+#include "../../kexec/crashdump.h"
 #include "kexec-s390.h"
+#include "elf.h"
 #include <arch/options.h>
 
+static char command_line[COMMAND_LINESIZE];
+
+int command_line_add(const char *str)
+{
+	if (strlen(command_line) + strlen(str) + 1 > COMMAND_LINESIZE) {
+		fprintf(stderr, "Command line too long.\n");
+		return -1;
+	}
+	strcat(command_line, str);
+	return 0;
+}
+
 int
 image_s390_load(int argc, char **argv, const char *kernel_buf,
 		off_t kernel_size, struct kexec_info *info)
 {
 	void *krnl_buffer;
 	char *rd_buffer;
-	const char *command_line;
 	const char *ramdisk;
-	int command_line_len;
 	off_t ramdisk_len;
 	unsigned int ramdisk_origin;
+	uint64_t crash_base, crash_end;
 	int opt;
 
 	static const struct option options[] =
@@ -44,9 +58,9 @@ image_s390_load(int argc, char **argv, c
 	static const char short_options[] = KEXEC_OPT_STR "";
 
 	ramdisk = NULL;
-	command_line = NULL;
 	ramdisk_len = 0;
 	ramdisk_origin = 0;
+	crash_base = 0;
 
 	while ((opt = getopt_long(argc,argv,short_options,options,0)) != -1) {
 		switch(opt) {
@@ -55,7 +69,8 @@ image_s390_load(int argc, char **argv, c
 			return -1;
 			break;
 		case OPT_APPEND:
-			command_line = optarg;
+			if (command_line_add(optarg))
+				return -1;
 			break;
 		case OPT_RAMDISK:
 			ramdisk = optarg;
@@ -63,18 +78,16 @@ image_s390_load(int argc, char **argv, c
 		}
 	}
 
-	/* Process a given command_line: */
-	if (command_line) {
-		command_line_len = strlen(command_line) + 1; /* Remember the '\0' */
-		if (command_line_len > COMMAND_LINESIZE) {
-		        fprintf(stderr, "Command line too long.\n");
+	if (info->kexec_flags & KEXEC_ON_CRASH) {
+		if (parse_iomem_single("Crash kernel\n", &crash_base,
+				       &crash_end))
 			return -1;
-		}
 	}
 
 	/* Add kernel segment */
 	add_segment(info, kernel_buf + IMAGE_READ_OFFSET,
-		    kernel_size - IMAGE_READ_OFFSET, IMAGE_READ_OFFSET,
+		    kernel_size - IMAGE_READ_OFFSET,
+		    crash_base + IMAGE_READ_OFFSET,
 		    kernel_size - IMAGE_READ_OFFSET);
 
 	/* We do want to change the kernel image */
@@ -88,10 +101,18 @@ image_s390_load(int argc, char **argv, c
 			return -1;
 		}
 		ramdisk_origin = RAMDISK_ORIGIN_ADDR;
-		add_segment(info, rd_buffer, ramdisk_len, RAMDISK_ORIGIN_ADDR, ramdisk_len);
+		add_segment(info, rd_buffer, ramdisk_len,
+			    crash_base + RAMDISK_ORIGIN_ADDR, ramdisk_len);
 	}
 	
-	/* Register the ramdisk in the kernel. */
+	if (info->kexec_flags & KEXEC_ON_CRASH) {
+		if (load_crashdump_segments(info, crash_base, crash_end))
+			return -1;
+	} else {
+		info->entry = (void *) IMAGE_READ_OFFSET;
+	}
+
+	/* Register the ramdisk and crashkernel memory in the kernel. */
 	{
 		unsigned long long *tmp;
 
@@ -100,19 +121,23 @@ image_s390_load(int argc, char **argv, c
 
 		tmp = krnl_buffer + INITRD_SIZE_OFFS;
 		*tmp = (unsigned long long) ramdisk_len;
-	}
 
+		if (info->kexec_flags & KEXEC_ON_CRASH) {
+			tmp = krnl_buffer + OLDMEM_BASE_OFFS;
+			*tmp = crash_base;
+
+			tmp = krnl_buffer + OLDMEM_SIZE_OFFS;
+			*tmp = crash_end - crash_base + 1;
+		}
+	}
 	/*
 	 * We will write a probably given command line.
 	 * First, erase the old area, then setup the new parameters:
 	 */
-	if (command_line) {
+	if (strlen(command_line) != 0) {
 		memset(krnl_buffer + COMMAND_LINE_OFFS, 0, COMMAND_LINESIZE);
 		memcpy(krnl_buffer + COMMAND_LINE_OFFS, command_line, strlen(command_line));
 	}
-
-	info->entry = (void *) IMAGE_READ_OFFSET;
-
 	return 0;
 }
 
--- a/kexec/arch/s390/kexec-s390.c
+++ b/kexec/arch/s390/kexec-s390.c
@@ -1,9 +1,10 @@
 /*
  * kexec/arch/s390/kexec-s390.c
  *
- * (C) Copyright IBM Corp. 2005
+ * Copyright IBM Corp. 2005,2011
  *
  * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
+ *            Michael Holzheu <holzheu@linux.vnet.ibm.com>
  *
  */
 
@@ -19,26 +20,16 @@
 #include "kexec-s390.h"
 #include <arch/options.h>
 
-#define MAX_MEMORY_RANGES 64
 static struct memory_range memory_range[MAX_MEMORY_RANGES];
 
 /*
- * get_memory_ranges:
- *  Return a list of memory ranges by parsing the file returned by
- *  proc_iomem()
- *
- * INPUT:
- *  - Pointer to an array of memory_range structures.
- *  - Pointer to an integer with holds the number of memory ranges.
- *
- * RETURN:
- *  - 0 on normal execution.
- *  - (-1) if something went wrong.
+ * Get memory ranges of type "System RAM" from /proc/iomem. If with_crashk=1
+ * then also type "Crash kernel" is added.
  */
-
-int get_memory_ranges(struct memory_range **range, int *ranges,
-		      unsigned long UNUSED(flags))
+int get_memory_ranges_s390(struct memory_range memory_range[], int *ranges,
+			   int with_crashk)
 {
+	char crash_kernel[] = "Crash kernel\n";
 	char sys_ram[] = "System RAM\n";
 	const char *iomem = proc_iomem();
 	FILE *fp;
@@ -62,7 +53,9 @@ int get_memory_ranges(struct memory_rang
 
 		sscanf(line,"%Lx-%Lx : %n", &start, &end, &cons);
 		str = line+cons;
-		if(memcmp(str,sys_ram,strlen(sys_ram)) == 0) {
+		if((memcmp(str,sys_ram,strlen(sys_ram)) == 0) ||
+		   (with_crashk &&
+		    memcmp(str,crash_kernel,strlen(crash_kernel)) == 0)) {
 			memory_range[current_range].start = start;
 			memory_range[current_range].end = end;
 			memory_range[current_range].type = RANGE_RAM;
@@ -73,9 +66,41 @@ int get_memory_ranges(struct memory_rang
 		}
 	}
 	fclose(fp);
-	*range = memory_range;
 	*ranges = current_range;
+	return 0;
+}
+
+/*
+ * get_memory_ranges:
+ *  Return a list of memory ranges by parsing the file returned by
+ *  proc_iomem()
+ *
+ * INPUT:
+ *  - Pointer to an array of memory_range structures.
+ *  - Pointer to an integer with holds the number of memory ranges.
+ *
+ * RETURN:
+ *  - 0 on normal execution.
+ *  - (-1) if something went wrong.
+ */
 
+int get_memory_ranges(struct memory_range **range, int *ranges,
+		      unsigned long flags)
+{
+	uint64_t start, end;
+
+	if (get_memory_ranges_s390(memory_range, ranges,
+				   flags & KEXEC_ON_CRASH))
+	    	return -1;
+	*range = memory_range;
+	if ((flags & KEXEC_ON_CRASH) && !(flags & KEXEC_PRESERVE_CONTEXT)) {
+		if (parse_iomem_single("Crash kernel\n", &start, &end))
+			return -1;
+		if (start > mem_min)
+			mem_min = start;
+		if (end < mem_max)
+			mem_max = end;
+	}
 	return 0;
 }
 
@@ -112,5 +137,8 @@ void arch_update_purgatory(struct kexec_
 
 int is_crashkernel_mem_reserved(void)
 {
-	return 0; /* kdump is not supported on this platform (yet) */
+	uint64_t start, end;
+
+	return parse_iomem_single("Crash kernel\n", &start, &end) == 0 ?
+		(start != end) : 0;
 }
--- a/kexec/arch/s390/kexec-s390.h
+++ b/kexec/arch/s390/kexec-s390.h
@@ -15,11 +15,18 @@
 #define RAMDISK_ORIGIN_ADDR   0x800000
 #define INITRD_START_OFFS     0x408
 #define INITRD_SIZE_OFFS      0x410
+#define OLDMEM_BASE_OFFS      0x418
+#define OLDMEM_SIZE_OFFS      0x420
 #define COMMAND_LINE_OFFS     0x480
 #define COMMAND_LINESIZE      896
+#define MAX_MEMORY_RANGES     64
 
 extern int image_s390_load(int, char **, const char *, off_t, struct kexec_info *);
 extern int image_s390_probe(const char *, off_t);
 extern void image_s390_usage(void);
+extern int load_crashdump_segments(struct kexec_info *info, unsigned long crash_base, unsigned long crash_end);
+extern int get_memory_ranges_s390(struct memory_range range[], int *ranges,
+				  int with_crashk);
+extern int command_line_add(const char *str);
 
 #endif /* KEXEC_IA64_H */
--- a/purgatory/arch/s390/Makefile
+++ b/purgatory/arch/s390/Makefile
@@ -2,7 +2,9 @@
 # Purgatory s390
 #
 
-s390_PURGATORY_SRCS =
+s390_PURGATORY_SRCS += purgatory/arch/s390/console-s390.c
+s390_PURGATORY_SRCS += purgatory/arch/s390/setup-s390.S
+s390_PURGATORY_SRCS += purgatory/arch/s390/purgatory-s390.c
 
 dist += purgatory/arch/s390/Makefile $(s390_PURGATORY_SRCS)
 
--- /dev/null
+++ b/purgatory/arch/s390/console-s390.c
@@ -0,0 +1,14 @@
+/*
+ * S390 console code (currently not implemented)
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+#include <purgatory.h>
+#include "unused.h"
+
+void putchar(int UNUSED(ch))
+{
+}
--- /dev/null
+++ b/purgatory/arch/s390/purgatory-s390.c
@@ -0,0 +1,17 @@
+/*
+ * S390 purgatory
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+unsigned long kdump_psw_addr = 0;
+
+void setup_arch(void)
+{
+}
+
+void post_verification_setup_arch(void)
+{
+}
--- /dev/null
+++ b/purgatory/arch/s390/setup-s390.S
@@ -0,0 +1,35 @@
+/*
+ * Purgatory setup code
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+	.text
+	.globl purgatory_start
+	.balign 16
+purgatory_start:
+#ifdef __s390x__
+	larl	%r15,lstack
+	brasl	%r14,purgatory
+	larl    %r14,kdump_psw_addr
+	lg	%r4,0(%r14)
+	larl    %r14,kdump_psw
+	stg	%r4,8(%r14)
+	lpswe	0(%r14)
+
+	.section ".data"
+	.balign 16
+kdump_psw:
+	.quad 0x0000000180000000
+	.quad 0x0000000000000000
+
+	.bss
+	.balign 4096
+lstack:
+	.skip 4096
+lstack_end:
+#else
+0:	j	0
+#endif


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

* [patch v2 10/10] kexec-tools: Add s390 kdump support
@ 2011-07-27 12:55   ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-07-27 12:55 UTC (permalink / raw)
  To: vgoyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

[-- Attachment #1: kexec-tools-s390-kdump.patch --]
[-- Type: text/plain, Size: 15736 bytes --]

From: Michael Holzheu <holzheu@linux.vnet.ibm.com>

This patch adds kdump support for s390 to the kexec tool and enables the
"--load-panic" option. When loading the kdump kernel and ramdisk we add the
address of the crashkernel memory to the normal load address.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
---
 include/elf.h                        |    8 +++-
 kexec/arch/s390/Makefile             |    1 
 kexec/arch/s390/crashdump-s390.c     |   59 +++++++++++++++++++++++++++++++
 kexec/arch/s390/kexec-elf-rel-s390.c |   66 ++++++++++++++++++++++++++++++-----
 kexec/arch/s390/kexec-image.c        |   61 ++++++++++++++++++++++----------
 kexec/arch/s390/kexec-s390.c         |   66 ++++++++++++++++++++++++-----------
 kexec/arch/s390/kexec-s390.h         |    7 +++
 purgatory/arch/s390/Makefile         |    4 +-
 purgatory/arch/s390/console-s390.c   |   14 +++++++
 purgatory/arch/s390/purgatory-s390.c |   17 +++++++++
 purgatory/arch/s390/setup-s390.S     |   35 ++++++++++++++++++
 11 files changed, 290 insertions(+), 48 deletions(-)

--- a/include/elf.h
+++ b/include/elf.h
@@ -2304,9 +2304,13 @@ typedef Elf32_Addr Elf32_Conflict;
 #define R_390_TLS_DTPOFF	55	/* Offset in TLS block.	 */
 #define R_390_TLS_TPOFF		56	/* Negated offset in static TLS
 					   block.  */
-
+#define R_390_20		57	/* Direct 20 bit.  */
+#define R_390_GOT20		58	/* 20 bit GOT offset.  */
+#define R_390_GOTPLT20		59	/* 20 bit offset to jump slot.  */
+#define R_390_TLS_GOTIE20	60	/* 20 bit GOT offset for static TLS
+					   block offset.  */
 /* Keep this the last entry.  */
-#define R_390_NUM		57
+#define R_390_NUM		61
 
 /* CRIS relocations.  */
 #define R_CRIS_NONE		0
--- a/kexec/arch/s390/Makefile
+++ b/kexec/arch/s390/Makefile
@@ -4,6 +4,7 @@
 s390_KEXEC_SRCS =  kexec/arch/s390/kexec-s390.c
 s390_KEXEC_SRCS += kexec/arch/s390/kexec-image.c
 s390_KEXEC_SRCS += kexec/arch/s390/kexec-elf-rel-s390.c
+s390_KEXEC_SRCS += kexec/arch/s390/crashdump-s390.c
 
 dist += kexec/arch/s390/Makefile $(s390_KEXEC_SRCS)			\
 	kexec/arch/s390/kexec-s390.h					\
--- /dev/null
+++ b/kexec/arch/s390/crashdump-s390.c
@@ -0,0 +1,59 @@
+/*
+ * kexec/arch/s390/crashdump-s390.c
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <elf.h>
+#include <limits.h>
+#include "../../kexec.h"
+#include "../../kexec-syscall.h"
+#include "../../kexec/crashdump.h"
+#include "kexec-s390.h"
+
+/*
+ * Load additional segments for kdump kernel
+ */
+int load_crashdump_segments(struct kexec_info *info, unsigned long crash_base,
+			    unsigned long crash_end)
+{
+	unsigned long bufsz, elfcorehdr, elfcorehdr_size, addr, crash_size;
+	static struct memory_range crash_memory_range[MAX_MEMORY_RANGES];
+	struct crash_elf_info elf_info;
+	char str[COMMAND_LINESIZE];
+	int ranges;
+	void *tmp;
+
+	crash_size = crash_end - crash_base + 1;
+	memset(&elf_info, 0, sizeof(elf_info));
+
+	elf_info.data = ELFDATA2MSB;
+	elf_info.machine = EM_S390;
+	elf_info.class = ELFCLASS64;
+	elf_info.get_note_info = get_crash_notes_per_cpu;
+
+	if (get_memory_ranges_s390(crash_memory_range, &ranges, 0))
+		    return -1;
+
+	if (crash_create_elf64_headers(info, &elf_info, crash_memory_range,
+				       ranges, &tmp, &bufsz,
+				       ELF_CORE_HEADER_ALIGN))
+		return -1;
+
+	elfcorehdr = add_buffer(info, tmp, bufsz, bufsz, 1024,
+				crash_base, crash_end, -1);
+	elfcorehdr_size = bufsz;
+	elf_rel_build_load(info, &info->rhdr, (const char *) purgatory,
+			   purgatory_size, 0, ULONG_MAX, -1, 0);
+	addr = crash_base + 0x10010;
+	elf_rel_set_symbol(&info->rhdr, "kdump_psw_addr", &addr, sizeof(addr));
+	info->entry = (void *) elf_rel_get_addr(&info->rhdr, "purgatory_start");
+	snprintf(str, sizeof(str), " elfcorehdr=%ld@%ldK\n",
+		 elfcorehdr_size, elfcorehdr / 1024);
+	command_line_add(str);
+	return 0;
+}
--- a/kexec/arch/s390/kexec-elf-rel-s390.c
+++ b/kexec/arch/s390/kexec-elf-rel-s390.c
@@ -1,7 +1,7 @@
 /*
  * kexec/arch/s390/kexec-elf-rel-s390.c
  *
- * (C) Copyright IBM Corp. 2005
+ * Copyright IBM Corp. 2005,2011
  *
  * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
  *
@@ -12,15 +12,65 @@
 #include "../../kexec.h"
 #include "../../kexec-elf.h"
 
-int machine_verify_elf_rel(struct mem_ehdr *UNUSED(ehdr))
+int machine_verify_elf_rel(struct mem_ehdr *ehdr)
 {
-	return 0;
+	if (ehdr->ei_data != ELFDATA2MSB)
+		return 0;
+	if (ehdr->ei_class != ELFCLASS64)
+		return 0;
+	if (ehdr->e_machine != EM_S390)
+		return 0;
+	return 1;
 }
 
-void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr),
-			   unsigned long UNUSED(r_type),
-			   void *UNUSED(location),
-			   unsigned long UNUSED(address),
-			   unsigned long UNUSED(value))
+void machine_apply_elf_rel(struct mem_ehdr *ehdr,
+			   unsigned long r_type,
+			   void *loc,
+			   unsigned long address,
+			   unsigned long val)
 {
+	switch (r_type) {
+	case R_390_8:		/* Direct 8 bit.   */
+	case R_390_12:		/* Direct 12 bit.  */
+	case R_390_16:		/* Direct 16 bit.  */
+	case R_390_20:		/* Direct 20 bit.  */
+	case R_390_32:		/* Direct 32 bit.  */
+	case R_390_64:		/* Direct 64 bit.  */
+		if (r_type == R_390_8)
+			*(unsigned char *) loc = val;
+		else if (r_type == R_390_12)
+			*(unsigned short *) loc = (val & 0xfff) |
+				(*(unsigned short *) loc & 0xf000);
+		else if (r_type == R_390_16)
+			*(unsigned short *) loc = val;
+		else if (r_type == R_390_20)
+			*(unsigned int *) loc =
+				(*(unsigned int *) loc & 0xf00000ff) |
+				(val & 0xfff) << 16 | (val & 0xff000) >> 4;
+		else if (r_type == R_390_32)
+			*(unsigned int *) loc = val;
+		else if (r_type == R_390_64)
+			*(unsigned long *) loc = val;
+		break;
+	case R_390_PC16:	/* PC relative 16 bit.  */
+	case R_390_PC16DBL:	/* PC relative 16 bit shifted by 1.  */
+	case R_390_PC32DBL:	/* PC relative 32 bit shifted by 1.  */
+	case R_390_PC32:	/* PC relative 32 bit.  */
+	case R_390_PC64:	/* PC relative 64 bit.	*/
+		val -= address;
+		if (r_type == R_390_PC16)
+			*(unsigned short *) loc = val;
+		else if (r_type == R_390_PC16DBL)
+			*(unsigned short *) loc = val >> 1;
+		else if (r_type == R_390_PC32DBL)
+			*(unsigned int *) loc = val >> 1;
+		else if (r_type == R_390_PC32)
+			*(unsigned int *) loc = val;
+		else if (r_type == R_390_PC64)
+			*(unsigned long *) loc = val;
+		break;
+	default:
+		die("Unknown rela relocation: 0x%lx 0x%lx\n", r_type, address);
+		break;
+	}
 }
--- a/kexec/arch/s390/kexec-image.c
+++ b/kexec/arch/s390/kexec-image.c
@@ -18,20 +18,34 @@
 #include <unistd.h>
 #include <getopt.h>
 #include "../../kexec.h"
+#include "../../kexec-syscall.h"
+#include "../../kexec/crashdump.h"
 #include "kexec-s390.h"
+#include "elf.h"
 #include <arch/options.h>
 
+static char command_line[COMMAND_LINESIZE];
+
+int command_line_add(const char *str)
+{
+	if (strlen(command_line) + strlen(str) + 1 > COMMAND_LINESIZE) {
+		fprintf(stderr, "Command line too long.\n");
+		return -1;
+	}
+	strcat(command_line, str);
+	return 0;
+}
+
 int
 image_s390_load(int argc, char **argv, const char *kernel_buf,
 		off_t kernel_size, struct kexec_info *info)
 {
 	void *krnl_buffer;
 	char *rd_buffer;
-	const char *command_line;
 	const char *ramdisk;
-	int command_line_len;
 	off_t ramdisk_len;
 	unsigned int ramdisk_origin;
+	uint64_t crash_base, crash_end;
 	int opt;
 
 	static const struct option options[] =
@@ -44,9 +58,9 @@ image_s390_load(int argc, char **argv, c
 	static const char short_options[] = KEXEC_OPT_STR "";
 
 	ramdisk = NULL;
-	command_line = NULL;
 	ramdisk_len = 0;
 	ramdisk_origin = 0;
+	crash_base = 0;
 
 	while ((opt = getopt_long(argc,argv,short_options,options,0)) != -1) {
 		switch(opt) {
@@ -55,7 +69,8 @@ image_s390_load(int argc, char **argv, c
 			return -1;
 			break;
 		case OPT_APPEND:
-			command_line = optarg;
+			if (command_line_add(optarg))
+				return -1;
 			break;
 		case OPT_RAMDISK:
 			ramdisk = optarg;
@@ -63,18 +78,16 @@ image_s390_load(int argc, char **argv, c
 		}
 	}
 
-	/* Process a given command_line: */
-	if (command_line) {
-		command_line_len = strlen(command_line) + 1; /* Remember the '\0' */
-		if (command_line_len > COMMAND_LINESIZE) {
-		        fprintf(stderr, "Command line too long.\n");
+	if (info->kexec_flags & KEXEC_ON_CRASH) {
+		if (parse_iomem_single("Crash kernel\n", &crash_base,
+				       &crash_end))
 			return -1;
-		}
 	}
 
 	/* Add kernel segment */
 	add_segment(info, kernel_buf + IMAGE_READ_OFFSET,
-		    kernel_size - IMAGE_READ_OFFSET, IMAGE_READ_OFFSET,
+		    kernel_size - IMAGE_READ_OFFSET,
+		    crash_base + IMAGE_READ_OFFSET,
 		    kernel_size - IMAGE_READ_OFFSET);
 
 	/* We do want to change the kernel image */
@@ -88,10 +101,18 @@ image_s390_load(int argc, char **argv, c
 			return -1;
 		}
 		ramdisk_origin = RAMDISK_ORIGIN_ADDR;
-		add_segment(info, rd_buffer, ramdisk_len, RAMDISK_ORIGIN_ADDR, ramdisk_len);
+		add_segment(info, rd_buffer, ramdisk_len,
+			    crash_base + RAMDISK_ORIGIN_ADDR, ramdisk_len);
 	}
 	
-	/* Register the ramdisk in the kernel. */
+	if (info->kexec_flags & KEXEC_ON_CRASH) {
+		if (load_crashdump_segments(info, crash_base, crash_end))
+			return -1;
+	} else {
+		info->entry = (void *) IMAGE_READ_OFFSET;
+	}
+
+	/* Register the ramdisk and crashkernel memory in the kernel. */
 	{
 		unsigned long long *tmp;
 
@@ -100,19 +121,23 @@ image_s390_load(int argc, char **argv, c
 
 		tmp = krnl_buffer + INITRD_SIZE_OFFS;
 		*tmp = (unsigned long long) ramdisk_len;
-	}
 
+		if (info->kexec_flags & KEXEC_ON_CRASH) {
+			tmp = krnl_buffer + OLDMEM_BASE_OFFS;
+			*tmp = crash_base;
+
+			tmp = krnl_buffer + OLDMEM_SIZE_OFFS;
+			*tmp = crash_end - crash_base + 1;
+		}
+	}
 	/*
 	 * We will write a probably given command line.
 	 * First, erase the old area, then setup the new parameters:
 	 */
-	if (command_line) {
+	if (strlen(command_line) != 0) {
 		memset(krnl_buffer + COMMAND_LINE_OFFS, 0, COMMAND_LINESIZE);
 		memcpy(krnl_buffer + COMMAND_LINE_OFFS, command_line, strlen(command_line));
 	}
-
-	info->entry = (void *) IMAGE_READ_OFFSET;
-
 	return 0;
 }
 
--- a/kexec/arch/s390/kexec-s390.c
+++ b/kexec/arch/s390/kexec-s390.c
@@ -1,9 +1,10 @@
 /*
  * kexec/arch/s390/kexec-s390.c
  *
- * (C) Copyright IBM Corp. 2005
+ * Copyright IBM Corp. 2005,2011
  *
  * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com>
+ *            Michael Holzheu <holzheu@linux.vnet.ibm.com>
  *
  */
 
@@ -19,26 +20,16 @@
 #include "kexec-s390.h"
 #include <arch/options.h>
 
-#define MAX_MEMORY_RANGES 64
 static struct memory_range memory_range[MAX_MEMORY_RANGES];
 
 /*
- * get_memory_ranges:
- *  Return a list of memory ranges by parsing the file returned by
- *  proc_iomem()
- *
- * INPUT:
- *  - Pointer to an array of memory_range structures.
- *  - Pointer to an integer with holds the number of memory ranges.
- *
- * RETURN:
- *  - 0 on normal execution.
- *  - (-1) if something went wrong.
+ * Get memory ranges of type "System RAM" from /proc/iomem. If with_crashk=1
+ * then also type "Crash kernel" is added.
  */
-
-int get_memory_ranges(struct memory_range **range, int *ranges,
-		      unsigned long UNUSED(flags))
+int get_memory_ranges_s390(struct memory_range memory_range[], int *ranges,
+			   int with_crashk)
 {
+	char crash_kernel[] = "Crash kernel\n";
 	char sys_ram[] = "System RAM\n";
 	const char *iomem = proc_iomem();
 	FILE *fp;
@@ -62,7 +53,9 @@ int get_memory_ranges(struct memory_rang
 
 		sscanf(line,"%Lx-%Lx : %n", &start, &end, &cons);
 		str = line+cons;
-		if(memcmp(str,sys_ram,strlen(sys_ram)) == 0) {
+		if((memcmp(str,sys_ram,strlen(sys_ram)) == 0) ||
+		   (with_crashk &&
+		    memcmp(str,crash_kernel,strlen(crash_kernel)) == 0)) {
 			memory_range[current_range].start = start;
 			memory_range[current_range].end = end;
 			memory_range[current_range].type = RANGE_RAM;
@@ -73,9 +66,41 @@ int get_memory_ranges(struct memory_rang
 		}
 	}
 	fclose(fp);
-	*range = memory_range;
 	*ranges = current_range;
+	return 0;
+}
+
+/*
+ * get_memory_ranges:
+ *  Return a list of memory ranges by parsing the file returned by
+ *  proc_iomem()
+ *
+ * INPUT:
+ *  - Pointer to an array of memory_range structures.
+ *  - Pointer to an integer with holds the number of memory ranges.
+ *
+ * RETURN:
+ *  - 0 on normal execution.
+ *  - (-1) if something went wrong.
+ */
 
+int get_memory_ranges(struct memory_range **range, int *ranges,
+		      unsigned long flags)
+{
+	uint64_t start, end;
+
+	if (get_memory_ranges_s390(memory_range, ranges,
+				   flags & KEXEC_ON_CRASH))
+	    	return -1;
+	*range = memory_range;
+	if ((flags & KEXEC_ON_CRASH) && !(flags & KEXEC_PRESERVE_CONTEXT)) {
+		if (parse_iomem_single("Crash kernel\n", &start, &end))
+			return -1;
+		if (start > mem_min)
+			mem_min = start;
+		if (end < mem_max)
+			mem_max = end;
+	}
 	return 0;
 }
 
@@ -112,5 +137,8 @@ void arch_update_purgatory(struct kexec_
 
 int is_crashkernel_mem_reserved(void)
 {
-	return 0; /* kdump is not supported on this platform (yet) */
+	uint64_t start, end;
+
+	return parse_iomem_single("Crash kernel\n", &start, &end) == 0 ?
+		(start != end) : 0;
 }
--- a/kexec/arch/s390/kexec-s390.h
+++ b/kexec/arch/s390/kexec-s390.h
@@ -15,11 +15,18 @@
 #define RAMDISK_ORIGIN_ADDR   0x800000
 #define INITRD_START_OFFS     0x408
 #define INITRD_SIZE_OFFS      0x410
+#define OLDMEM_BASE_OFFS      0x418
+#define OLDMEM_SIZE_OFFS      0x420
 #define COMMAND_LINE_OFFS     0x480
 #define COMMAND_LINESIZE      896
+#define MAX_MEMORY_RANGES     64
 
 extern int image_s390_load(int, char **, const char *, off_t, struct kexec_info *);
 extern int image_s390_probe(const char *, off_t);
 extern void image_s390_usage(void);
+extern int load_crashdump_segments(struct kexec_info *info, unsigned long crash_base, unsigned long crash_end);
+extern int get_memory_ranges_s390(struct memory_range range[], int *ranges,
+				  int with_crashk);
+extern int command_line_add(const char *str);
 
 #endif /* KEXEC_IA64_H */
--- a/purgatory/arch/s390/Makefile
+++ b/purgatory/arch/s390/Makefile
@@ -2,7 +2,9 @@
 # Purgatory s390
 #
 
-s390_PURGATORY_SRCS =
+s390_PURGATORY_SRCS += purgatory/arch/s390/console-s390.c
+s390_PURGATORY_SRCS += purgatory/arch/s390/setup-s390.S
+s390_PURGATORY_SRCS += purgatory/arch/s390/purgatory-s390.c
 
 dist += purgatory/arch/s390/Makefile $(s390_PURGATORY_SRCS)
 
--- /dev/null
+++ b/purgatory/arch/s390/console-s390.c
@@ -0,0 +1,14 @@
+/*
+ * S390 console code (currently not implemented)
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+#include <purgatory.h>
+#include "unused.h"
+
+void putchar(int UNUSED(ch))
+{
+}
--- /dev/null
+++ b/purgatory/arch/s390/purgatory-s390.c
@@ -0,0 +1,17 @@
+/*
+ * S390 purgatory
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+unsigned long kdump_psw_addr = 0;
+
+void setup_arch(void)
+{
+}
+
+void post_verification_setup_arch(void)
+{
+}
--- /dev/null
+++ b/purgatory/arch/s390/setup-s390.S
@@ -0,0 +1,35 @@
+/*
+ * Purgatory setup code
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
+ */
+
+	.text
+	.globl purgatory_start
+	.balign 16
+purgatory_start:
+#ifdef __s390x__
+	larl	%r15,lstack
+	brasl	%r14,purgatory
+	larl    %r14,kdump_psw_addr
+	lg	%r4,0(%r14)
+	larl    %r14,kdump_psw
+	stg	%r4,8(%r14)
+	lpswe	0(%r14)
+
+	.section ".data"
+	.balign 16
+kdump_psw:
+	.quad 0x0000000180000000
+	.quad 0x0000000000000000
+
+	.bss
+	.balign 4096
+lstack:
+	.skip 4096
+lstack_end:
+#else
+0:	j	0
+#endif


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

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

* Re: [patch v2 01/10] kdump: Add KEXEC_CRASH_CONTROL_MEMORY_LIMIT
  2011-07-27 12:55   ` Michael Holzheu
@ 2011-08-01 20:16     ` Vivek Goyal
  -1 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-01 20:16 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

On Wed, Jul 27, 2011 at 02:55:05PM +0200, Michael Holzheu wrote:
> From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> 
> On s390 there is a different KEXEC_CONTROL_MEMORY_LIMIT for the normal and
> the kdump kexec case. Therefore this patch introduces a new macro
> KEXEC_CRASH_CONTROL_MEMORY_LIMIT. This is set to
> KEXEC_CONTROL_MEMORY_LIMIT for all architectures that do not define
> KEXEC_CRASH_CONTROL_MEMORY_LIMIT.

Hi Michael,

Curious that why limit is different for kexec and kdump cases on s390
only.

Thanks
Vivek

> 
> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> ---
>  include/linux/kexec.h |    4 ++++
>  kernel/kexec.c        |    2 +-
>  2 files changed, 5 insertions(+), 1 deletion(-)
> 
> --- a/include/linux/kexec.h
> +++ b/include/linux/kexec.h
> @@ -33,6 +33,10 @@
>  #error KEXEC_ARCH not defined
>  #endif
>  
> +#ifndef KEXEC_CRASH_CONTROL_MEMORY_LIMIT
> +#define KEXEC_CRASH_CONTROL_MEMORY_LIMIT KEXEC_CONTROL_MEMORY_LIMIT
> +#endif
> +
>  #define KEXEC_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
>  #define KEXEC_CORE_NOTE_NAME "CORE"
>  #define KEXEC_CORE_NOTE_NAME_BYTES ALIGN(sizeof(KEXEC_CORE_NOTE_NAME), 4)
> --- a/kernel/kexec.c
> +++ b/kernel/kexec.c
> @@ -498,7 +498,7 @@ static struct page *kimage_alloc_crash_c
>  	while (hole_end <= crashk_res.end) {
>  		unsigned long i;
>  
> -		if (hole_end > KEXEC_CONTROL_MEMORY_LIMIT)
> +		if (hole_end > KEXEC_CRASH_CONTROL_MEMORY_LIMIT)
>  			break;
>  		if (hole_end > crashk_res.end)
>  			break;

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

* Re: [patch v2 01/10] kdump: Add KEXEC_CRASH_CONTROL_MEMORY_LIMIT
@ 2011-08-01 20:16     ` Vivek Goyal
  0 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-01 20:16 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

On Wed, Jul 27, 2011 at 02:55:05PM +0200, Michael Holzheu wrote:
> From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> 
> On s390 there is a different KEXEC_CONTROL_MEMORY_LIMIT for the normal and
> the kdump kexec case. Therefore this patch introduces a new macro
> KEXEC_CRASH_CONTROL_MEMORY_LIMIT. This is set to
> KEXEC_CONTROL_MEMORY_LIMIT for all architectures that do not define
> KEXEC_CRASH_CONTROL_MEMORY_LIMIT.

Hi Michael,

Curious that why limit is different for kexec and kdump cases on s390
only.

Thanks
Vivek

> 
> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> ---
>  include/linux/kexec.h |    4 ++++
>  kernel/kexec.c        |    2 +-
>  2 files changed, 5 insertions(+), 1 deletion(-)
> 
> --- a/include/linux/kexec.h
> +++ b/include/linux/kexec.h
> @@ -33,6 +33,10 @@
>  #error KEXEC_ARCH not defined
>  #endif
>  
> +#ifndef KEXEC_CRASH_CONTROL_MEMORY_LIMIT
> +#define KEXEC_CRASH_CONTROL_MEMORY_LIMIT KEXEC_CONTROL_MEMORY_LIMIT
> +#endif
> +
>  #define KEXEC_NOTE_HEAD_BYTES ALIGN(sizeof(struct elf_note), 4)
>  #define KEXEC_CORE_NOTE_NAME "CORE"
>  #define KEXEC_CORE_NOTE_NAME_BYTES ALIGN(sizeof(KEXEC_CORE_NOTE_NAME), 4)
> --- a/kernel/kexec.c
> +++ b/kernel/kexec.c
> @@ -498,7 +498,7 @@ static struct page *kimage_alloc_crash_c
>  	while (hole_end <= crashk_res.end) {
>  		unsigned long i;
>  
> -		if (hole_end > KEXEC_CONTROL_MEMORY_LIMIT)
> +		if (hole_end > KEXEC_CRASH_CONTROL_MEMORY_LIMIT)
>  			break;
>  		if (hole_end > crashk_res.end)
>  			break;

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

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

* Re: [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak
  2011-07-27 12:55   ` Michael Holzheu
@ 2011-08-01 20:31     ` Vivek Goyal
  -1 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-01 20:31 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

On Wed, Jul 27, 2011 at 02:55:06PM +0200, Michael Holzheu wrote:
> From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> 
> On s390 we do not create page tables at all for the crashkernel memory.
> This requires a s390 specific version for kimage_load_crash_segment().
> Therefore this patch declares this function as "__weak". The s390 version is
> very simple. It just copies the kexec segment to real memory without using
> page tables:
> 
> int kimage_load_crash_segment(struct kimage *image,
>                               struct kexec_segment *segment)
> {
>         return copy_from_user_real((void *) segment->mem, segment->buf,
>                                    segment->bufsz);
> }
> 
> There are two main advantages of not creating page tables for the
> crashkernel memory:
> 
> a) It saves memory. We have scenarios in mind, where crashkernel
>    memory can be very large and saving page table space is important.
> b) We protect the crashkernel memory from being overwritten.
> 
> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> ---
>  kernel/kexec.c |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> --- a/kernel/kexec.c
> +++ b/kernel/kexec.c
> @@ -842,8 +842,8 @@ out:
>  	return result;
>  }
>  
> -static int kimage_load_crash_segment(struct kimage *image,
> -					struct kexec_segment *segment)
> +int __weak kimage_load_crash_segment(struct kimage *image,
> +				     struct kexec_segment *segment)

A comment here why we are making it weak should help in increasing
the code readability.

Thanks
Vivek

>  {
>  	/* For crash dumps kernels we simply copy the data from
>  	 * user space to it's destination.

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

* Re: [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak
@ 2011-08-01 20:31     ` Vivek Goyal
  0 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-01 20:31 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

On Wed, Jul 27, 2011 at 02:55:06PM +0200, Michael Holzheu wrote:
> From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> 
> On s390 we do not create page tables at all for the crashkernel memory.
> This requires a s390 specific version for kimage_load_crash_segment().
> Therefore this patch declares this function as "__weak". The s390 version is
> very simple. It just copies the kexec segment to real memory without using
> page tables:
> 
> int kimage_load_crash_segment(struct kimage *image,
>                               struct kexec_segment *segment)
> {
>         return copy_from_user_real((void *) segment->mem, segment->buf,
>                                    segment->bufsz);
> }
> 
> There are two main advantages of not creating page tables for the
> crashkernel memory:
> 
> a) It saves memory. We have scenarios in mind, where crashkernel
>    memory can be very large and saving page table space is important.
> b) We protect the crashkernel memory from being overwritten.
> 
> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> ---
>  kernel/kexec.c |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> --- a/kernel/kexec.c
> +++ b/kernel/kexec.c
> @@ -842,8 +842,8 @@ out:
>  	return result;
>  }
>  
> -static int kimage_load_crash_segment(struct kimage *image,
> -					struct kexec_segment *segment)
> +int __weak kimage_load_crash_segment(struct kimage *image,
> +				     struct kexec_segment *segment)

A comment here why we are making it weak should help in increasing
the code readability.

Thanks
Vivek

>  {
>  	/* For crash dumps kernels we simply copy the data from
>  	 * user space to it's destination.

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

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

* Re: [patch v2 03/10] kdump: Add size to elfcorehdr kernel parameter
  2011-07-27 12:55   ` Michael Holzheu
@ 2011-08-01 20:36     ` Vivek Goyal
  -1 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-01 20:36 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

On Wed, Jul 27, 2011 at 02:55:07PM +0200, Michael Holzheu wrote:
> From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> 
> Currently only the address of the pre-allocated ELF header is passed with
> the elfcorehdr= kernel parameter. In order to reserve memory for the header
> in the 2nd kernel also the size is required. To pass the size with this
> patch the syntax of the kernel parameter is extended as follows:
> 
> elfcorehdr=[size[KMG]@]offset[KMG]
> 
> This change is backward compatible because elfcorehdr=size is still allowed.

Generally vmcore parses elfcorehdr to figure out the sizes. kexec-tools
knows about it and relevant memory is excluded from second kernel's map
with the help of memmap= command line option.

Can you please mention that this is only s390 specific requirement as
there are no memmap= equivalent options and somehow dump tools wants
to know how big the elf header size is?

Thanks
Vivek

> 
> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> ---
>  Documentation/kernel-parameters.txt |    6 +++---
>  include/linux/crash_dump.h          |    1 +
>  kernel/crash_dump.c                 |   11 +++++++++++
>  3 files changed, 15 insertions(+), 3 deletions(-)
> 
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -717,10 +717,10 @@ bytes respectively. Such letter suffixes
>  			See Documentation/block/as-iosched.txt and
>  			Documentation/block/deadline-iosched.txt for details.
>  
> -	elfcorehdr=	[IA64,PPC,SH,X86]
> +	elfcorehdr=[size[KMG]@]offset[KMG] [IA64,PPC,SH,X86,S390]
>  			Specifies physical address of start of kernel core
> -			image elf header. Generally kexec loader will
> -			pass this option to capture kernel.
> +			image elf header and optionally the size. Generally
> +			kexec loader will pass this option to capture kernel.
>  			See Documentation/kdump/kdump.txt for details.
>  
>  	enable_mtrr_cleanup [X86]
> --- a/include/linux/crash_dump.h
> +++ b/include/linux/crash_dump.h
> @@ -10,6 +10,7 @@
>  #define ELFCORE_ADDR_ERR	(-2ULL)
>  
>  extern unsigned long long elfcorehdr_addr;
> +extern unsigned long long elfcorehdr_size;
>  
>  extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
>  						unsigned long, int);
> --- a/kernel/crash_dump.c
> +++ b/kernel/crash_dump.c
> @@ -20,8 +20,15 @@ unsigned long saved_max_pfn;
>  unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
>  
>  /*
> + * stores the size of elf header of crash image
> + */
> +unsigned long long elfcorehdr_size;
> +
> +/*
>   * elfcorehdr= specifies the location of elf core header stored by the crashed
>   * kernel. This option will be passed by kexec loader to the capture kernel.
> + *
> + * Syntax: elfcorehdr=[size[KMG]@]offset[KMG]
>   */
>  static int __init setup_elfcorehdr(char *arg)
>  {
> @@ -29,6 +36,10 @@ static int __init setup_elfcorehdr(char
>  	if (!arg)
>  		return -EINVAL;
>  	elfcorehdr_addr = memparse(arg, &end);
> +	if (*end == '@') {
> +		elfcorehdr_size = elfcorehdr_addr;
> +		elfcorehdr_addr = memparse(end + 1, &end);
> +	}
>  	return end > arg ? 0 : -EINVAL;
>  }
>  early_param("elfcorehdr", setup_elfcorehdr);

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

* Re: [patch v2 03/10] kdump: Add size to elfcorehdr kernel parameter
@ 2011-08-01 20:36     ` Vivek Goyal
  0 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-01 20:36 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

On Wed, Jul 27, 2011 at 02:55:07PM +0200, Michael Holzheu wrote:
> From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> 
> Currently only the address of the pre-allocated ELF header is passed with
> the elfcorehdr= kernel parameter. In order to reserve memory for the header
> in the 2nd kernel also the size is required. To pass the size with this
> patch the syntax of the kernel parameter is extended as follows:
> 
> elfcorehdr=[size[KMG]@]offset[KMG]
> 
> This change is backward compatible because elfcorehdr=size is still allowed.

Generally vmcore parses elfcorehdr to figure out the sizes. kexec-tools
knows about it and relevant memory is excluded from second kernel's map
with the help of memmap= command line option.

Can you please mention that this is only s390 specific requirement as
there are no memmap= equivalent options and somehow dump tools wants
to know how big the elf header size is?

Thanks
Vivek

> 
> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> ---
>  Documentation/kernel-parameters.txt |    6 +++---
>  include/linux/crash_dump.h          |    1 +
>  kernel/crash_dump.c                 |   11 +++++++++++
>  3 files changed, 15 insertions(+), 3 deletions(-)
> 
> --- a/Documentation/kernel-parameters.txt
> +++ b/Documentation/kernel-parameters.txt
> @@ -717,10 +717,10 @@ bytes respectively. Such letter suffixes
>  			See Documentation/block/as-iosched.txt and
>  			Documentation/block/deadline-iosched.txt for details.
>  
> -	elfcorehdr=	[IA64,PPC,SH,X86]
> +	elfcorehdr=[size[KMG]@]offset[KMG] [IA64,PPC,SH,X86,S390]
>  			Specifies physical address of start of kernel core
> -			image elf header. Generally kexec loader will
> -			pass this option to capture kernel.
> +			image elf header and optionally the size. Generally
> +			kexec loader will pass this option to capture kernel.
>  			See Documentation/kdump/kdump.txt for details.
>  
>  	enable_mtrr_cleanup [X86]
> --- a/include/linux/crash_dump.h
> +++ b/include/linux/crash_dump.h
> @@ -10,6 +10,7 @@
>  #define ELFCORE_ADDR_ERR	(-2ULL)
>  
>  extern unsigned long long elfcorehdr_addr;
> +extern unsigned long long elfcorehdr_size;
>  
>  extern ssize_t copy_oldmem_page(unsigned long, char *, size_t,
>  						unsigned long, int);
> --- a/kernel/crash_dump.c
> +++ b/kernel/crash_dump.c
> @@ -20,8 +20,15 @@ unsigned long saved_max_pfn;
>  unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
>  
>  /*
> + * stores the size of elf header of crash image
> + */
> +unsigned long long elfcorehdr_size;
> +
> +/*
>   * elfcorehdr= specifies the location of elf core header stored by the crashed
>   * kernel. This option will be passed by kexec loader to the capture kernel.
> + *
> + * Syntax: elfcorehdr=[size[KMG]@]offset[KMG]
>   */
>  static int __init setup_elfcorehdr(char *arg)
>  {
> @@ -29,6 +36,10 @@ static int __init setup_elfcorehdr(char
>  	if (!arg)
>  		return -EINVAL;
>  	elfcorehdr_addr = memparse(arg, &end);
> +	if (*end == '@') {
> +		elfcorehdr_size = elfcorehdr_addr;
> +		elfcorehdr_addr = memparse(end + 1, &end);
> +	}
>  	return end > arg ? 0 : -EINVAL;
>  }
>  early_param("elfcorehdr", setup_elfcorehdr);

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

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

* Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390
  2011-07-27 12:55   ` Michael Holzheu
@ 2011-08-01 20:41     ` Vivek Goyal
  -1 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-01 20:41 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

On Wed, Jul 27, 2011 at 02:55:08PM +0200, Michael Holzheu wrote:
> From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> 
> On s390 we have the possibility to configure actions that are executed in
> case of a kernel panic. E.g. it is possible to automatically trigger an s390
> stand-alone dump. The actions are called via a panic notifier.  We also want
> to trigger kdump via the notifier call chain. Therefore this patch disables
> for s390 the direct kdump invocation in the panic() function.

Doesn't this reduce the reliability of the operation as you are assuming
that panic notifier list is fine and not corrupted.

There might be other generic notifiers registerd on panic notifier list
too. So in your case, are there multiple subsystem registering for panic
notifiers? If not, why not call crash_kexec() directly. Are there any
other actions you want to take on panic then calling crash_kexec()?

Thanks
Vivek

> 
> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> ---
>  kernel/panic.c |    3 +++
>  1 file changed, 3 insertions(+)
> 
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -84,9 +84,12 @@ NORET_TYPE void panic(const char * fmt,
>  	/*
>  	 * If we have crashed and we have a crash kernel loaded let it handle
>  	 * everything else.
> +	 * For s390 kdump is triggered via the panic notifier call chain.
>  	 * Do we want to call this before we try to display a message?
>  	 */
> +#if !defined(CONFIG_S390)
>  	crash_kexec(NULL);
> +#endif
>  
>  	kmsg_dump(KMSG_DUMP_PANIC);
>  

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

* Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390
@ 2011-08-01 20:41     ` Vivek Goyal
  0 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-01 20:41 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

On Wed, Jul 27, 2011 at 02:55:08PM +0200, Michael Holzheu wrote:
> From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> 
> On s390 we have the possibility to configure actions that are executed in
> case of a kernel panic. E.g. it is possible to automatically trigger an s390
> stand-alone dump. The actions are called via a panic notifier.  We also want
> to trigger kdump via the notifier call chain. Therefore this patch disables
> for s390 the direct kdump invocation in the panic() function.

Doesn't this reduce the reliability of the operation as you are assuming
that panic notifier list is fine and not corrupted.

There might be other generic notifiers registerd on panic notifier list
too. So in your case, are there multiple subsystem registering for panic
notifiers? If not, why not call crash_kexec() directly. Are there any
other actions you want to take on panic then calling crash_kexec()?

Thanks
Vivek

> 
> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> ---
>  kernel/panic.c |    3 +++
>  1 file changed, 3 insertions(+)
> 
> --- a/kernel/panic.c
> +++ b/kernel/panic.c
> @@ -84,9 +84,12 @@ NORET_TYPE void panic(const char * fmt,
>  	/*
>  	 * If we have crashed and we have a crash kernel loaded let it handle
>  	 * everything else.
> +	 * For s390 kdump is triggered via the panic notifier call chain.
>  	 * Do we want to call this before we try to display a message?
>  	 */
> +#if !defined(CONFIG_S390)
>  	crash_kexec(NULL);
> +#endif
>  
>  	kmsg_dump(KMSG_DUMP_PANIC);
>  

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

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

* Re: [patch v2 05/10] s390: Add PSW restart shutdown trigger
  2011-07-27 12:55   ` Michael Holzheu
@ 2011-08-01 20:54     ` Vivek Goyal
  -1 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-01 20:54 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

On Wed, Jul 27, 2011 at 02:55:09PM +0200, Michael Holzheu wrote:
> From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> 
> With this patch a new S390 shutdown trigger "restart" is added. If under
> z/VM "systerm restart" is entered or under the HMC the "PSW restart" button
> is pressed, the PSW located at 0 (31 bit) or 0x1a0 (64 bit) bit is loaded.
> Now we execute do_restart() that processes the restart action that is
> defined under /sys/firmware/shutdown_actions/on_restart. Currently the
> following actions are possible: reipl (default), stop, vmcmd, dump, and
> dump_reipl.

i know nothing about s390 but this sounds like a independent
functionality? I mean defining a restart trigger and associated actions
could be done even in current framework without kdump. IIUC, additional
kdump series only adds the ability to use kdump for second kernel instead
of using dump tools in case of "dump" or "dump_reipl" ?

If yes, then this patch probably does not have to be part of this series
and pushed in independetly?

Thanks
Vivek

> 
> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> ---
>  arch/s390/include/asm/lowcore.h |   11 +++++++++--
>  arch/s390/include/asm/system.h  |    1 +
>  arch/s390/kernel/asm-offsets.c  |    1 +
>  arch/s390/kernel/entry.S        |   28 ++++++++++++++++++++++++++++
>  arch/s390/kernel/entry64.S      |   20 ++++++++++++++++++++
>  arch/s390/kernel/ipl.c          |   39 ++++++++++++++++++++++++++++++++++++++-
>  arch/s390/kernel/setup.c        |   24 +++++++++++++++++++++++-
>  arch/s390/kernel/smp.c          |    8 ++++++++
>  arch/s390/mm/maccess.c          |   16 ++++++++++++++++
>  9 files changed, 144 insertions(+), 4 deletions(-)
> 
> --- a/arch/s390/include/asm/lowcore.h
> +++ b/arch/s390/include/asm/lowcore.h
> @@ -18,6 +18,7 @@ void system_call(void);
>  void pgm_check_handler(void);
>  void mcck_int_handler(void);
>  void io_int_handler(void);
> +void psw_restart_int_handler(void);
>  
>  #ifdef CONFIG_32BIT
>  
> @@ -150,7 +151,10 @@ struct _lowcore {
>  	 */
>  	__u32	ipib;				/* 0x0e00 */
>  	__u32	ipib_checksum;			/* 0x0e04 */
> -	__u8	pad_0x0e08[0x0f00-0x0e08];	/* 0x0e08 */
> +
> +	/* 64 bit save area */
> +	__u64	save_area_64;			/* 0x0e08 */
> +	__u8	pad_0x0e10[0x0f00-0x0e10];	/* 0x0e10 */
>  
>  	/* Extended facility list */
>  	__u64	stfle_fac_list[32];		/* 0x0f00 */
> @@ -286,7 +290,10 @@ struct _lowcore {
>  	 */
>  	__u64	ipib;				/* 0x0e00 */
>  	__u32	ipib_checksum;			/* 0x0e08 */
> -	__u8	pad_0x0e0c[0x0f00-0x0e0c];	/* 0x0e0c */
> +
> +	/* 64 bit save area */
> +	__u64	save_area_64;			/* 0x0e0c */
> +	__u8	pad_0x0e14[0x0f00-0x0e14];	/* 0x0e14 */
>  
>  	/* Extended facility list */
>  	__u64	stfle_fac_list[32];		/* 0x0f00 */
> --- a/arch/s390/include/asm/system.h
> +++ b/arch/s390/include/asm/system.h
> @@ -113,6 +113,7 @@ extern void pfault_fini(void);
>  
>  extern void cmma_init(void);
>  extern int memcpy_real(void *, void *, size_t);
> +extern void copy_to_absolute_zero(void *dest, void *src, size_t count);
>  
>  #define finish_arch_switch(prev) do {					     \
>  	set_fs(current->thread.mm_segment);				     \
> --- a/arch/s390/kernel/asm-offsets.c
> +++ b/arch/s390/kernel/asm-offsets.c
> @@ -142,6 +142,7 @@ int main(void)
>  	DEFINE(__LC_FPREGS_SAVE_AREA, offsetof(struct _lowcore, floating_pt_save_area));
>  	DEFINE(__LC_GPREGS_SAVE_AREA, offsetof(struct _lowcore, gpregs_save_area));
>  	DEFINE(__LC_CREGS_SAVE_AREA, offsetof(struct _lowcore, cregs_save_area));
> +	DEFINE(__LC_SAVE_AREA_64, offsetof(struct _lowcore, save_area_64));
>  #ifdef CONFIG_32BIT
>  	DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, extended_save_area_addr));
>  #else /* CONFIG_32BIT */
> --- a/arch/s390/kernel/entry.S
> +++ b/arch/s390/kernel/entry.S
> @@ -849,6 +849,34 @@ restart_crash:
>  restart_go:
>  #endif
>  
> +#
> +# PSW restart interrupt handler
> +#
> +ENTRY(psw_restart_int_handler)
> +	st	%r15,__LC_SAVE_AREA_64(%r0)	# save r15
> +	basr	%r15,0
> +0:	l	%r15,.Lrestart_stack-0b(%r15)	# load restart stack
> +	l	%r15,0(%r15)
> +	ahi	%r15,-SP_SIZE			# make room for pt_regs
> +	stm	%r0,%r14,SP_R0(%r15)		# store gprs %r0-%r14 to stack
> +	mvc	SP_R15(4,%r15),__LC_SAVE_AREA_64(%r0)# store saved %r15 to stack
> +	mvc	SP_PSW(8,%r15),__LC_RST_OLD_PSW(%r0) # store restart old psw
> +	xc	__SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0
> +	basr	%r14,0
> +1:	l	%r14,.Ldo_restart-1b(%r14)
> +	basr	%r14,%r14
> +
> +	basr	%r14,0				# load disabled wait PSW if
> +2:	lpsw	restart_psw_crash-2b(%r14)	# do_restart returns
> +	.align 4
> +.Ldo_restart:
> +	.long	do_restart
> +.Lrestart_stack:
> +	.long	restart_stack
> +	.align 8
> +restart_psw_crash:
> +	.long	0x000a0000,0x00000000 + restart_psw_crash
> +
>  	.section .kprobes.text, "ax"
>  
>  #ifdef CONFIG_CHECK_STACK
> --- a/arch/s390/kernel/entry64.S
> +++ b/arch/s390/kernel/entry64.S
> @@ -865,6 +865,26 @@ restart_crash:
>  restart_go:
>  #endif
>  
> +#
> +# PSW restart interrupt handler
> +#
> +ENTRY(psw_restart_int_handler)
> +	stg	%r15,__LC_SAVE_AREA_64(%r0)	# save r15
> +	larl	%r15,restart_stack		# load restart stack
> +	lg	%r15,0(%r15)
> +	aghi	%r15,-SP_SIZE			# make room for pt_regs
> +	stmg	%r0,%r14,SP_R0(%r15)		# store gprs %r0-%r14 to stack
> +	mvc	SP_R15(8,%r15),__LC_SAVE_AREA_64(%r0)# store saved %r15 to stack
> +	mvc	SP_PSW(16,%r15),__LC_RST_OLD_PSW(%r0)# store restart old psw
> +	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0
> +	brasl	%r14,do_restart
> +
> +	larl	%r14,restart_psw_crash		# load disabled wait PSW if
> +	lpswe	0(%r14)				# do_restart returns
> +	.align 8
> +restart_psw_crash:
> +	.quad	0x0002000080000000,0x0000000000000000 + restart_psw_crash
> +
>  	.section .kprobes.text, "ax"
>  
>  #ifdef CONFIG_CHECK_STACK
> --- a/arch/s390/kernel/ipl.c
> +++ b/arch/s390/kernel/ipl.c
> @@ -45,11 +45,13 @@
>   * - halt
>   * - power off
>   * - reipl
> + * - restart
>   */
>  #define ON_PANIC_STR		"on_panic"
>  #define ON_HALT_STR		"on_halt"
>  #define ON_POFF_STR		"on_poff"
>  #define ON_REIPL_STR		"on_reboot"
> +#define ON_RESTART_STR		"on_restart"
>  
>  struct shutdown_action;
>  struct shutdown_trigger {
> @@ -1544,17 +1546,20 @@ static char vmcmd_on_reboot[128];
>  static char vmcmd_on_panic[128];
>  static char vmcmd_on_halt[128];
>  static char vmcmd_on_poff[128];
> +static char vmcmd_on_restart[128];
>  
>  DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot);
>  DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic);
>  DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt);
>  DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff);
> +DEFINE_IPL_ATTR_STR_RW(vmcmd, on_restart, "%s\n", "%s\n", vmcmd_on_restart);
>  
>  static struct attribute *vmcmd_attrs[] = {
>  	&sys_vmcmd_on_reboot_attr.attr,
>  	&sys_vmcmd_on_panic_attr.attr,
>  	&sys_vmcmd_on_halt_attr.attr,
>  	&sys_vmcmd_on_poff_attr.attr,
> +	&sys_vmcmd_on_restart_attr.attr,
>  	NULL,
>  };
>  
> @@ -1576,6 +1581,8 @@ static void vmcmd_run(struct shutdown_tr
>  		cmd = vmcmd_on_halt;
>  	else if (strcmp(trigger->name, ON_POFF_STR) == 0)
>  		cmd = vmcmd_on_poff;
> +	else if (strcmp(trigger->name, ON_RESTART_STR) == 0)
> +		cmd = vmcmd_on_restart;
>  	else
>  		return;
>  
> @@ -1707,6 +1714,34 @@ static void do_panic(void)
>  	stop_run(&on_panic_trigger);
>  }
>  
> +/* on restart */
> +
> +static struct shutdown_trigger on_restart_trigger = {ON_RESTART_STR,
> +	&reipl_action};
> +
> +static ssize_t on_restart_show(struct kobject *kobj,
> +			       struct kobj_attribute *attr, char *page)
> +{
> +	return sprintf(page, "%s\n", on_restart_trigger.action->name);
> +}
> +
> +static ssize_t on_restart_store(struct kobject *kobj,
> +				struct kobj_attribute *attr,
> +				const char *buf, size_t len)
> +{
> +	return set_trigger(buf, &on_restart_trigger, len);
> +}
> +
> +static struct kobj_attribute on_restart_attr =
> +	__ATTR(on_restart, 0644, on_restart_show, on_restart_store);
> +
> +void do_restart(void)
> +{
> +	smp_send_stop();
> +	on_restart_trigger.action->fn(&on_restart_trigger);
> +	stop_run(&on_restart_trigger);
> +}
> +
>  /* on halt */
>  
>  static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action};
> @@ -1783,7 +1818,9 @@ static void __init shutdown_triggers_ini
>  	if (sysfs_create_file(&shutdown_actions_kset->kobj,
>  			      &on_poff_attr.attr))
>  		goto fail;
> -
> +	if (sysfs_create_file(&shutdown_actions_kset->kobj,
> +			      &on_restart_attr.attr))
> +		goto fail;
>  	return;
>  fail:
>  	panic("shutdown_triggers_init failed\n");
> --- a/arch/s390/kernel/setup.c
> +++ b/arch/s390/kernel/setup.c
> @@ -346,7 +346,7 @@ setup_lowcore(void)
>  	lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
>  	lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
>  	lc->restart_psw.addr =
> -		PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
> +		PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
>  	if (user_mode != HOME_SPACE_MODE)
>  		lc->restart_psw.mask |= PSW_ASC_HOME;
>  	lc->external_new_psw.mask = psw_kernel_bits;
> @@ -529,6 +529,27 @@ static void __init setup_memory_end(void
>  		memory_end = memory_size;
>  }
>  
> +void *restart_stack __attribute__((__section__(".data")));
> +
> +/*
> + * Setup new PSW and allocate stack for PSW restart interrupt
> + */
> +static void __init setup_restart_psw(void)
> +{
> +	psw_t psw;
> +
> +	restart_stack = __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0);
> +	restart_stack += ASYNC_SIZE;
> +
> +	/*
> +	 * Setup restart PSW for absolute zero lowcore. This is necesary
> +	 * if PSW restart is done on an offline CPU that has lowcore zero
> +	 */
> +	psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
> +	psw.addr = PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
> +	copy_to_absolute_zero(&S390_lowcore.restart_psw, &psw, sizeof(psw));
> +}
> +
>  static void __init
>  setup_memory(void)
>  {
> @@ -792,6 +813,7 @@ setup_arch(char **cmdline_p)
>  	setup_addressing_mode();
>  	setup_memory();
>  	setup_resources();
> +	setup_restart_psw();
>  	setup_lowcore();
>  
>          cpu_init();
> --- a/arch/s390/kernel/smp.c
> +++ b/arch/s390/kernel/smp.c
> @@ -470,6 +470,11 @@ int __cpuinit start_secondary(void *cpuv
>  	ipi_call_unlock();
>  	/* Switch on interrupts */
>  	local_irq_enable();
> +	__ctl_clear_bit(0, 28); /* Disable lowcore protection */
> +	S390_lowcore.restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
> +	S390_lowcore.restart_psw.addr =
> +		PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
> +	__ctl_set_bit(0, 28); /* Enable lowcore protection */
>  	/* cpu_idle will call schedule for us */
>  	cpu_idle();
>  	return 0;
> @@ -507,6 +512,9 @@ static int __cpuinit smp_alloc_lowcore(i
>  	memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512);
>  	lowcore->async_stack = async_stack + ASYNC_SIZE;
>  	lowcore->panic_stack = panic_stack + PAGE_SIZE;
> +	lowcore->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
> +	lowcore->restart_psw.addr =
> +		PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
>  
>  #ifndef CONFIG_64BIT
>  	if (MACHINE_HAS_IEEE) {
> --- a/arch/s390/mm/maccess.c
> +++ b/arch/s390/mm/maccess.c
> @@ -85,3 +85,19 @@ int memcpy_real(void *dest, void *src, s
>  	arch_local_irq_restore(flags);
>  	return rc;
>  }
> +
> +/*
> + * Copy memory to absolute zero
> + */
> +void copy_to_absolute_zero(void *dest, void *src, size_t count)
> +{
> +	unsigned long cr0;
> +
> +	BUG_ON((unsigned long) dest + count >= sizeof(struct _lowcore));
> +	preempt_disable();
> +	__ctl_store(cr0, 0, 0);
> +	__ctl_clear_bit(0, 28); /* disable lowcore protection */
> +	memcpy_real(dest + store_prefix(), src, count);
> +	__ctl_load(cr0, 0, 0);
> +	preempt_enable();
> +}

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

* Re: [patch v2 05/10] s390: Add PSW restart shutdown trigger
@ 2011-08-01 20:54     ` Vivek Goyal
  0 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-01 20:54 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

On Wed, Jul 27, 2011 at 02:55:09PM +0200, Michael Holzheu wrote:
> From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> 
> With this patch a new S390 shutdown trigger "restart" is added. If under
> z/VM "systerm restart" is entered or under the HMC the "PSW restart" button
> is pressed, the PSW located at 0 (31 bit) or 0x1a0 (64 bit) bit is loaded.
> Now we execute do_restart() that processes the restart action that is
> defined under /sys/firmware/shutdown_actions/on_restart. Currently the
> following actions are possible: reipl (default), stop, vmcmd, dump, and
> dump_reipl.

i know nothing about s390 but this sounds like a independent
functionality? I mean defining a restart trigger and associated actions
could be done even in current framework without kdump. IIUC, additional
kdump series only adds the ability to use kdump for second kernel instead
of using dump tools in case of "dump" or "dump_reipl" ?

If yes, then this patch probably does not have to be part of this series
and pushed in independetly?

Thanks
Vivek

> 
> Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> ---
>  arch/s390/include/asm/lowcore.h |   11 +++++++++--
>  arch/s390/include/asm/system.h  |    1 +
>  arch/s390/kernel/asm-offsets.c  |    1 +
>  arch/s390/kernel/entry.S        |   28 ++++++++++++++++++++++++++++
>  arch/s390/kernel/entry64.S      |   20 ++++++++++++++++++++
>  arch/s390/kernel/ipl.c          |   39 ++++++++++++++++++++++++++++++++++++++-
>  arch/s390/kernel/setup.c        |   24 +++++++++++++++++++++++-
>  arch/s390/kernel/smp.c          |    8 ++++++++
>  arch/s390/mm/maccess.c          |   16 ++++++++++++++++
>  9 files changed, 144 insertions(+), 4 deletions(-)
> 
> --- a/arch/s390/include/asm/lowcore.h
> +++ b/arch/s390/include/asm/lowcore.h
> @@ -18,6 +18,7 @@ void system_call(void);
>  void pgm_check_handler(void);
>  void mcck_int_handler(void);
>  void io_int_handler(void);
> +void psw_restart_int_handler(void);
>  
>  #ifdef CONFIG_32BIT
>  
> @@ -150,7 +151,10 @@ struct _lowcore {
>  	 */
>  	__u32	ipib;				/* 0x0e00 */
>  	__u32	ipib_checksum;			/* 0x0e04 */
> -	__u8	pad_0x0e08[0x0f00-0x0e08];	/* 0x0e08 */
> +
> +	/* 64 bit save area */
> +	__u64	save_area_64;			/* 0x0e08 */
> +	__u8	pad_0x0e10[0x0f00-0x0e10];	/* 0x0e10 */
>  
>  	/* Extended facility list */
>  	__u64	stfle_fac_list[32];		/* 0x0f00 */
> @@ -286,7 +290,10 @@ struct _lowcore {
>  	 */
>  	__u64	ipib;				/* 0x0e00 */
>  	__u32	ipib_checksum;			/* 0x0e08 */
> -	__u8	pad_0x0e0c[0x0f00-0x0e0c];	/* 0x0e0c */
> +
> +	/* 64 bit save area */
> +	__u64	save_area_64;			/* 0x0e0c */
> +	__u8	pad_0x0e14[0x0f00-0x0e14];	/* 0x0e14 */
>  
>  	/* Extended facility list */
>  	__u64	stfle_fac_list[32];		/* 0x0f00 */
> --- a/arch/s390/include/asm/system.h
> +++ b/arch/s390/include/asm/system.h
> @@ -113,6 +113,7 @@ extern void pfault_fini(void);
>  
>  extern void cmma_init(void);
>  extern int memcpy_real(void *, void *, size_t);
> +extern void copy_to_absolute_zero(void *dest, void *src, size_t count);
>  
>  #define finish_arch_switch(prev) do {					     \
>  	set_fs(current->thread.mm_segment);				     \
> --- a/arch/s390/kernel/asm-offsets.c
> +++ b/arch/s390/kernel/asm-offsets.c
> @@ -142,6 +142,7 @@ int main(void)
>  	DEFINE(__LC_FPREGS_SAVE_AREA, offsetof(struct _lowcore, floating_pt_save_area));
>  	DEFINE(__LC_GPREGS_SAVE_AREA, offsetof(struct _lowcore, gpregs_save_area));
>  	DEFINE(__LC_CREGS_SAVE_AREA, offsetof(struct _lowcore, cregs_save_area));
> +	DEFINE(__LC_SAVE_AREA_64, offsetof(struct _lowcore, save_area_64));
>  #ifdef CONFIG_32BIT
>  	DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, extended_save_area_addr));
>  #else /* CONFIG_32BIT */
> --- a/arch/s390/kernel/entry.S
> +++ b/arch/s390/kernel/entry.S
> @@ -849,6 +849,34 @@ restart_crash:
>  restart_go:
>  #endif
>  
> +#
> +# PSW restart interrupt handler
> +#
> +ENTRY(psw_restart_int_handler)
> +	st	%r15,__LC_SAVE_AREA_64(%r0)	# save r15
> +	basr	%r15,0
> +0:	l	%r15,.Lrestart_stack-0b(%r15)	# load restart stack
> +	l	%r15,0(%r15)
> +	ahi	%r15,-SP_SIZE			# make room for pt_regs
> +	stm	%r0,%r14,SP_R0(%r15)		# store gprs %r0-%r14 to stack
> +	mvc	SP_R15(4,%r15),__LC_SAVE_AREA_64(%r0)# store saved %r15 to stack
> +	mvc	SP_PSW(8,%r15),__LC_RST_OLD_PSW(%r0) # store restart old psw
> +	xc	__SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0
> +	basr	%r14,0
> +1:	l	%r14,.Ldo_restart-1b(%r14)
> +	basr	%r14,%r14
> +
> +	basr	%r14,0				# load disabled wait PSW if
> +2:	lpsw	restart_psw_crash-2b(%r14)	# do_restart returns
> +	.align 4
> +.Ldo_restart:
> +	.long	do_restart
> +.Lrestart_stack:
> +	.long	restart_stack
> +	.align 8
> +restart_psw_crash:
> +	.long	0x000a0000,0x00000000 + restart_psw_crash
> +
>  	.section .kprobes.text, "ax"
>  
>  #ifdef CONFIG_CHECK_STACK
> --- a/arch/s390/kernel/entry64.S
> +++ b/arch/s390/kernel/entry64.S
> @@ -865,6 +865,26 @@ restart_crash:
>  restart_go:
>  #endif
>  
> +#
> +# PSW restart interrupt handler
> +#
> +ENTRY(psw_restart_int_handler)
> +	stg	%r15,__LC_SAVE_AREA_64(%r0)	# save r15
> +	larl	%r15,restart_stack		# load restart stack
> +	lg	%r15,0(%r15)
> +	aghi	%r15,-SP_SIZE			# make room for pt_regs
> +	stmg	%r0,%r14,SP_R0(%r15)		# store gprs %r0-%r14 to stack
> +	mvc	SP_R15(8,%r15),__LC_SAVE_AREA_64(%r0)# store saved %r15 to stack
> +	mvc	SP_PSW(16,%r15),__LC_RST_OLD_PSW(%r0)# store restart old psw
> +	xc	__SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0
> +	brasl	%r14,do_restart
> +
> +	larl	%r14,restart_psw_crash		# load disabled wait PSW if
> +	lpswe	0(%r14)				# do_restart returns
> +	.align 8
> +restart_psw_crash:
> +	.quad	0x0002000080000000,0x0000000000000000 + restart_psw_crash
> +
>  	.section .kprobes.text, "ax"
>  
>  #ifdef CONFIG_CHECK_STACK
> --- a/arch/s390/kernel/ipl.c
> +++ b/arch/s390/kernel/ipl.c
> @@ -45,11 +45,13 @@
>   * - halt
>   * - power off
>   * - reipl
> + * - restart
>   */
>  #define ON_PANIC_STR		"on_panic"
>  #define ON_HALT_STR		"on_halt"
>  #define ON_POFF_STR		"on_poff"
>  #define ON_REIPL_STR		"on_reboot"
> +#define ON_RESTART_STR		"on_restart"
>  
>  struct shutdown_action;
>  struct shutdown_trigger {
> @@ -1544,17 +1546,20 @@ static char vmcmd_on_reboot[128];
>  static char vmcmd_on_panic[128];
>  static char vmcmd_on_halt[128];
>  static char vmcmd_on_poff[128];
> +static char vmcmd_on_restart[128];
>  
>  DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot);
>  DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic);
>  DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt);
>  DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff);
> +DEFINE_IPL_ATTR_STR_RW(vmcmd, on_restart, "%s\n", "%s\n", vmcmd_on_restart);
>  
>  static struct attribute *vmcmd_attrs[] = {
>  	&sys_vmcmd_on_reboot_attr.attr,
>  	&sys_vmcmd_on_panic_attr.attr,
>  	&sys_vmcmd_on_halt_attr.attr,
>  	&sys_vmcmd_on_poff_attr.attr,
> +	&sys_vmcmd_on_restart_attr.attr,
>  	NULL,
>  };
>  
> @@ -1576,6 +1581,8 @@ static void vmcmd_run(struct shutdown_tr
>  		cmd = vmcmd_on_halt;
>  	else if (strcmp(trigger->name, ON_POFF_STR) == 0)
>  		cmd = vmcmd_on_poff;
> +	else if (strcmp(trigger->name, ON_RESTART_STR) == 0)
> +		cmd = vmcmd_on_restart;
>  	else
>  		return;
>  
> @@ -1707,6 +1714,34 @@ static void do_panic(void)
>  	stop_run(&on_panic_trigger);
>  }
>  
> +/* on restart */
> +
> +static struct shutdown_trigger on_restart_trigger = {ON_RESTART_STR,
> +	&reipl_action};
> +
> +static ssize_t on_restart_show(struct kobject *kobj,
> +			       struct kobj_attribute *attr, char *page)
> +{
> +	return sprintf(page, "%s\n", on_restart_trigger.action->name);
> +}
> +
> +static ssize_t on_restart_store(struct kobject *kobj,
> +				struct kobj_attribute *attr,
> +				const char *buf, size_t len)
> +{
> +	return set_trigger(buf, &on_restart_trigger, len);
> +}
> +
> +static struct kobj_attribute on_restart_attr =
> +	__ATTR(on_restart, 0644, on_restart_show, on_restart_store);
> +
> +void do_restart(void)
> +{
> +	smp_send_stop();
> +	on_restart_trigger.action->fn(&on_restart_trigger);
> +	stop_run(&on_restart_trigger);
> +}
> +
>  /* on halt */
>  
>  static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action};
> @@ -1783,7 +1818,9 @@ static void __init shutdown_triggers_ini
>  	if (sysfs_create_file(&shutdown_actions_kset->kobj,
>  			      &on_poff_attr.attr))
>  		goto fail;
> -
> +	if (sysfs_create_file(&shutdown_actions_kset->kobj,
> +			      &on_restart_attr.attr))
> +		goto fail;
>  	return;
>  fail:
>  	panic("shutdown_triggers_init failed\n");
> --- a/arch/s390/kernel/setup.c
> +++ b/arch/s390/kernel/setup.c
> @@ -346,7 +346,7 @@ setup_lowcore(void)
>  	lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
>  	lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
>  	lc->restart_psw.addr =
> -		PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
> +		PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
>  	if (user_mode != HOME_SPACE_MODE)
>  		lc->restart_psw.mask |= PSW_ASC_HOME;
>  	lc->external_new_psw.mask = psw_kernel_bits;
> @@ -529,6 +529,27 @@ static void __init setup_memory_end(void
>  		memory_end = memory_size;
>  }
>  
> +void *restart_stack __attribute__((__section__(".data")));
> +
> +/*
> + * Setup new PSW and allocate stack for PSW restart interrupt
> + */
> +static void __init setup_restart_psw(void)
> +{
> +	psw_t psw;
> +
> +	restart_stack = __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0);
> +	restart_stack += ASYNC_SIZE;
> +
> +	/*
> +	 * Setup restart PSW for absolute zero lowcore. This is necesary
> +	 * if PSW restart is done on an offline CPU that has lowcore zero
> +	 */
> +	psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
> +	psw.addr = PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
> +	copy_to_absolute_zero(&S390_lowcore.restart_psw, &psw, sizeof(psw));
> +}
> +
>  static void __init
>  setup_memory(void)
>  {
> @@ -792,6 +813,7 @@ setup_arch(char **cmdline_p)
>  	setup_addressing_mode();
>  	setup_memory();
>  	setup_resources();
> +	setup_restart_psw();
>  	setup_lowcore();
>  
>          cpu_init();
> --- a/arch/s390/kernel/smp.c
> +++ b/arch/s390/kernel/smp.c
> @@ -470,6 +470,11 @@ int __cpuinit start_secondary(void *cpuv
>  	ipi_call_unlock();
>  	/* Switch on interrupts */
>  	local_irq_enable();
> +	__ctl_clear_bit(0, 28); /* Disable lowcore protection */
> +	S390_lowcore.restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
> +	S390_lowcore.restart_psw.addr =
> +		PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler;
> +	__ctl_set_bit(0, 28); /* Enable lowcore protection */
>  	/* cpu_idle will call schedule for us */
>  	cpu_idle();
>  	return 0;
> @@ -507,6 +512,9 @@ static int __cpuinit smp_alloc_lowcore(i
>  	memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512);
>  	lowcore->async_stack = async_stack + ASYNC_SIZE;
>  	lowcore->panic_stack = panic_stack + PAGE_SIZE;
> +	lowcore->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
> +	lowcore->restart_psw.addr =
> +		PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
>  
>  #ifndef CONFIG_64BIT
>  	if (MACHINE_HAS_IEEE) {
> --- a/arch/s390/mm/maccess.c
> +++ b/arch/s390/mm/maccess.c
> @@ -85,3 +85,19 @@ int memcpy_real(void *dest, void *src, s
>  	arch_local_irq_restore(flags);
>  	return rc;
>  }
> +
> +/*
> + * Copy memory to absolute zero
> + */
> +void copy_to_absolute_zero(void *dest, void *src, size_t count)
> +{
> +	unsigned long cr0;
> +
> +	BUG_ON((unsigned long) dest + count >= sizeof(struct _lowcore));
> +	preempt_disable();
> +	__ctl_store(cr0, 0, 0);
> +	__ctl_clear_bit(0, 28); /* disable lowcore protection */
> +	memcpy_real(dest + store_prefix(), src, count);
> +	__ctl_load(cr0, 0, 0);
> +	preempt_enable();
> +}

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

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

* Re: [patch v2 05/10] s390: Add PSW restart shutdown trigger
  2011-08-01 20:54     ` Vivek Goyal
@ 2011-08-02  8:05       ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-02  8:05 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

Hello Vivek,

On Mon, 2011-08-01 at 16:54 -0400, Vivek Goyal wrote:
> On Wed, Jul 27, 2011 at 02:55:09PM +0200, Michael Holzheu wrote:
> > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > 
> > With this patch a new S390 shutdown trigger "restart" is added. If under
> > z/VM "systerm restart" is entered or under the HMC the "PSW restart" button
> > is pressed, the PSW located at 0 (31 bit) or 0x1a0 (64 bit) bit is loaded.
> > Now we execute do_restart() that processes the restart action that is
> > defined under /sys/firmware/shutdown_actions/on_restart. Currently the
> > following actions are possible: reipl (default), stop, vmcmd, dump, and
> > dump_reipl.
> 
> i know nothing about s390 but this sounds like a independent
> functionality? I mean defining a restart trigger and associated actions
> could be done even in current framework without kdump. IIUC, additional
> kdump series only adds the ability to use kdump for second kernel instead
> of using dump tools in case of "dump" or "dump_reipl" ?
> 
> If yes, then this patch probably does not have to be part of this series
> and pushed in independetly?

Yes, this is correct. We implemented the PSW restart functionality for
kdump, but it can be used independently.

We will integrate this patch upstream independently from this series.

Michael


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

* Re: [patch v2 05/10] s390: Add PSW restart shutdown trigger
@ 2011-08-02  8:05       ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-02  8:05 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

Hello Vivek,

On Mon, 2011-08-01 at 16:54 -0400, Vivek Goyal wrote:
> On Wed, Jul 27, 2011 at 02:55:09PM +0200, Michael Holzheu wrote:
> > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > 
> > With this patch a new S390 shutdown trigger "restart" is added. If under
> > z/VM "systerm restart" is entered or under the HMC the "PSW restart" button
> > is pressed, the PSW located at 0 (31 bit) or 0x1a0 (64 bit) bit is loaded.
> > Now we execute do_restart() that processes the restart action that is
> > defined under /sys/firmware/shutdown_actions/on_restart. Currently the
> > following actions are possible: reipl (default), stop, vmcmd, dump, and
> > dump_reipl.
> 
> i know nothing about s390 but this sounds like a independent
> functionality? I mean defining a restart trigger and associated actions
> could be done even in current framework without kdump. IIUC, additional
> kdump series only adds the ability to use kdump for second kernel instead
> of using dump tools in case of "dump" or "dump_reipl" ?
> 
> If yes, then this patch probably does not have to be part of this series
> and pushed in independetly?

Yes, this is correct. We implemented the PSW restart functionality for
kdump, but it can be used independently.

We will integrate this patch upstream independently from this series.

Michael


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

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

* Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390
  2011-08-01 20:41     ` Vivek Goyal
@ 2011-08-02  8:37       ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-02  8:37 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

Hello Vivek,

On Mon, 2011-08-01 at 16:41 -0400, Vivek Goyal wrote:
> On Wed, Jul 27, 2011 at 02:55:08PM +0200, Michael Holzheu wrote:
> > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > 
> > On s390 we have the possibility to configure actions that are executed in
> > case of a kernel panic. E.g. it is possible to automatically trigger an s390
> > stand-alone dump. The actions are called via a panic notifier.  We also want
> > to trigger kdump via the notifier call chain. Therefore this patch disables
> > for s390 the direct kdump invocation in the panic() function.
> 
> Doesn't this reduce the reliability of the operation as you are assuming
> that panic notifier list is fine and not corrupted.

Yes, this is correct. We have to rely that the notifier list is fine.
Probably there is still room for improvement here.

> There might be other generic notifiers registerd on panic notifier list
> too. So in your case, are there multiple subsystem registering for panic
> notifiers? If not, why not call crash_kexec() directly. Are there any
> other actions you want to take on panic then calling crash_kexec()?

We have added the panic notifier in the past in order to be able to
configure the action that should be done in case of panic using our
shutdown actions infrastructure. We can configure the action using sysfs
and we are able to configure that a stand-alone dump should be started
as action for panic.

Now with the two stage dump approach we would like to keep the
possibility to trigger a stand-alone dump even if kdump is installed.
The stand-alone dumper will be started in case of a kernel panic and
then the procedure we discussed will happen: Jump into kdump and if
program check occurs do stand-alone dump as backup.

Michael


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

* Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390
@ 2011-08-02  8:37       ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-02  8:37 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

Hello Vivek,

On Mon, 2011-08-01 at 16:41 -0400, Vivek Goyal wrote:
> On Wed, Jul 27, 2011 at 02:55:08PM +0200, Michael Holzheu wrote:
> > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > 
> > On s390 we have the possibility to configure actions that are executed in
> > case of a kernel panic. E.g. it is possible to automatically trigger an s390
> > stand-alone dump. The actions are called via a panic notifier.  We also want
> > to trigger kdump via the notifier call chain. Therefore this patch disables
> > for s390 the direct kdump invocation in the panic() function.
> 
> Doesn't this reduce the reliability of the operation as you are assuming
> that panic notifier list is fine and not corrupted.

Yes, this is correct. We have to rely that the notifier list is fine.
Probably there is still room for improvement here.

> There might be other generic notifiers registerd on panic notifier list
> too. So in your case, are there multiple subsystem registering for panic
> notifiers? If not, why not call crash_kexec() directly. Are there any
> other actions you want to take on panic then calling crash_kexec()?

We have added the panic notifier in the past in order to be able to
configure the action that should be done in case of panic using our
shutdown actions infrastructure. We can configure the action using sysfs
and we are able to configure that a stand-alone dump should be started
as action for panic.

Now with the two stage dump approach we would like to keep the
possibility to trigger a stand-alone dump even if kdump is installed.
The stand-alone dumper will be started in case of a kernel panic and
then the procedure we discussed will happen: Jump into kdump and if
program check occurs do stand-alone dump as backup.

Michael


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

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

* Re: [patch v2 03/10] kdump: Add size to elfcorehdr kernel parameter
  2011-08-01 20:36     ` Vivek Goyal
@ 2011-08-02  9:08       ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-02  9:08 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

Hello Vivek,

#On Mon, 2011-08-01 at 16:36 -0400, Vivek Goyal wrote: 
> On Wed, Jul 27, 2011 at 02:55:07PM +0200, Michael Holzheu wrote:
> > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > 
> > Currently only the address of the pre-allocated ELF header is passed with
> > the elfcorehdr= kernel parameter. In order to reserve memory for the header
> > in the 2nd kernel also the size is required. To pass the size with this
> > patch the syntax of the kernel parameter is extended as follows:
> > 
> > elfcorehdr=[size[KMG]@]offset[KMG]
> > 
> > This change is backward compatible because elfcorehdr=size is still allowed.
> 
> Generally vmcore parses elfcorehdr to figure out the sizes. kexec-tools
> knows about it and relevant memory is excluded from second kernel's map
> with the help of memmap= command line option.
> 
> Can you please mention that this is only s390 specific requirement as
> there are no memmap= equivalent options and somehow dump tools wants
> to know how big the elf header size is?

I updated the description: 

Currently only the address of the pre-allocated ELF header is passed with
the elfcorehdr= kernel parameter. In order to reserve memory for the header
in the 2nd kernel also the size is required. Current kdump architecture
backends use different methods to do that, e.g. x86 uses the memmap= kernel
parameter. On s390 there is no easy way to transfer this information.
Therefore the elfcorehdr kernel parameter is extended to also pass the size.
This now can also be used as standard mechanism by all future kdump
architecture backends.

The syntax of the kernel parameter is extended as follows:

elfcorehdr=[size[KMG]@]offset[KMG]

This change is backward compatible because elfcorehdr=size is still allowed.

Ok?

Michael


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

* Re: [patch v2 03/10] kdump: Add size to elfcorehdr kernel parameter
@ 2011-08-02  9:08       ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-02  9:08 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

Hello Vivek,

#On Mon, 2011-08-01 at 16:36 -0400, Vivek Goyal wrote: 
> On Wed, Jul 27, 2011 at 02:55:07PM +0200, Michael Holzheu wrote:
> > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > 
> > Currently only the address of the pre-allocated ELF header is passed with
> > the elfcorehdr= kernel parameter. In order to reserve memory for the header
> > in the 2nd kernel also the size is required. To pass the size with this
> > patch the syntax of the kernel parameter is extended as follows:
> > 
> > elfcorehdr=[size[KMG]@]offset[KMG]
> > 
> > This change is backward compatible because elfcorehdr=size is still allowed.
> 
> Generally vmcore parses elfcorehdr to figure out the sizes. kexec-tools
> knows about it and relevant memory is excluded from second kernel's map
> with the help of memmap= command line option.
> 
> Can you please mention that this is only s390 specific requirement as
> there are no memmap= equivalent options and somehow dump tools wants
> to know how big the elf header size is?

I updated the description: 

Currently only the address of the pre-allocated ELF header is passed with
the elfcorehdr= kernel parameter. In order to reserve memory for the header
in the 2nd kernel also the size is required. Current kdump architecture
backends use different methods to do that, e.g. x86 uses the memmap= kernel
parameter. On s390 there is no easy way to transfer this information.
Therefore the elfcorehdr kernel parameter is extended to also pass the size.
This now can also be used as standard mechanism by all future kdump
architecture backends.

The syntax of the kernel parameter is extended as follows:

elfcorehdr=[size[KMG]@]offset[KMG]

This change is backward compatible because elfcorehdr=size is still allowed.

Ok?

Michael


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

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

* Re: [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak
  2011-08-01 20:31     ` Vivek Goyal
@ 2011-08-02  9:30       ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-02  9:30 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

Hello Vivek,

On Mon, 2011-08-01 at 16:31 -0400, Vivek Goyal wrote:
> On Wed, Jul 27, 2011 at 02:55:06PM +0200, Michael Holzheu wrote:

[snip]

> > --- a/kernel/kexec.c
> > +++ b/kernel/kexec.c
> > @@ -842,8 +842,8 @@ out:
> >  	return result;
> >  }
> >  
> > -static int kimage_load_crash_segment(struct kimage *image,
> > -					struct kexec_segment *segment)
> > +int __weak kimage_load_crash_segment(struct kimage *image,
> > +				     struct kexec_segment *segment)
> 
> A comment here why we are making it weak should help in increasing
> the code readability.

What about the following:

/*
 * Load crash segment into memory. Architecture code can override this
 * function. E.g. this is necessary for architectures that do not
 * create page tables for crashkernel memory.
 */
int __weak kimage_load_crash_segment(struct kimage *image,

Michael


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

* Re: [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak
@ 2011-08-02  9:30       ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-02  9:30 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

Hello Vivek,

On Mon, 2011-08-01 at 16:31 -0400, Vivek Goyal wrote:
> On Wed, Jul 27, 2011 at 02:55:06PM +0200, Michael Holzheu wrote:

[snip]

> > --- a/kernel/kexec.c
> > +++ b/kernel/kexec.c
> > @@ -842,8 +842,8 @@ out:
> >  	return result;
> >  }
> >  
> > -static int kimage_load_crash_segment(struct kimage *image,
> > -					struct kexec_segment *segment)
> > +int __weak kimage_load_crash_segment(struct kimage *image,
> > +				     struct kexec_segment *segment)
> 
> A comment here why we are making it weak should help in increasing
> the code readability.

What about the following:

/*
 * Load crash segment into memory. Architecture code can override this
 * function. E.g. this is necessary for architectures that do not
 * create page tables for crashkernel memory.
 */
int __weak kimage_load_crash_segment(struct kimage *image,

Michael


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

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

* Re: [patch v2 01/10] kdump: Add KEXEC_CRASH_CONTROL_MEMORY_LIMIT
  2011-08-01 20:16     ` Vivek Goyal
@ 2011-08-02  9:51       ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-02  9:51 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

Hello Vivek,

On Mon, 2011-08-01 at 16:16 -0400, Vivek Goyal wrote:
> On Wed, Jul 27, 2011 at 02:55:05PM +0200, Michael Holzheu wrote:
> > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > 
> > On s390 there is a different KEXEC_CONTROL_MEMORY_LIMIT for the normal and
> > the kdump kexec case. Therefore this patch introduces a new macro
> > KEXEC_CRASH_CONTROL_MEMORY_LIMIT. This is set to
> > KEXEC_CONTROL_MEMORY_LIMIT for all architectures that do not define
> > KEXEC_CRASH_CONTROL_MEMORY_LIMIT.
> 
> Hi Michael,
> 
> Curious that why limit is different for kexec and kdump cases on s390
> only.

The standard kexec relocate_kernel code calls a machine instruction that
must run below 2 GiB. For kdump we currently do not use the control page
at all because no segments have to be moved in that case. Perhaps I am
still missing something here?

Michael


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

* Re: [patch v2 01/10] kdump: Add KEXEC_CRASH_CONTROL_MEMORY_LIMIT
@ 2011-08-02  9:51       ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-02  9:51 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

Hello Vivek,

On Mon, 2011-08-01 at 16:16 -0400, Vivek Goyal wrote:
> On Wed, Jul 27, 2011 at 02:55:05PM +0200, Michael Holzheu wrote:
> > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > 
> > On s390 there is a different KEXEC_CONTROL_MEMORY_LIMIT for the normal and
> > the kdump kexec case. Therefore this patch introduces a new macro
> > KEXEC_CRASH_CONTROL_MEMORY_LIMIT. This is set to
> > KEXEC_CONTROL_MEMORY_LIMIT for all architectures that do not define
> > KEXEC_CRASH_CONTROL_MEMORY_LIMIT.
> 
> Hi Michael,
> 
> Curious that why limit is different for kexec and kdump cases on s390
> only.

The standard kexec relocate_kernel code calls a machine instruction that
must run below 2 GiB. For kdump we currently do not use the control page
at all because no segments have to be moved in that case. Perhaps I am
still missing something here?

Michael


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

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

* Re: [patch v2 03/10] kdump: Add size to elfcorehdr kernel parameter
  2011-08-02  9:08       ` Michael Holzheu
@ 2011-08-02 18:55         ` Vivek Goyal
  -1 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-02 18:55 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

On Tue, Aug 02, 2011 at 11:08:07AM +0200, Michael Holzheu wrote:
> Hello Vivek,
> 
> #On Mon, 2011-08-01 at 16:36 -0400, Vivek Goyal wrote: 
> > On Wed, Jul 27, 2011 at 02:55:07PM +0200, Michael Holzheu wrote:
> > > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > > 
> > > Currently only the address of the pre-allocated ELF header is passed with
> > > the elfcorehdr= kernel parameter. In order to reserve memory for the header
> > > in the 2nd kernel also the size is required. To pass the size with this
> > > patch the syntax of the kernel parameter is extended as follows:
> > > 
> > > elfcorehdr=[size[KMG]@]offset[KMG]
> > > 
> > > This change is backward compatible because elfcorehdr=size is still allowed.
> > 
> > Generally vmcore parses elfcorehdr to figure out the sizes. kexec-tools
> > knows about it and relevant memory is excluded from second kernel's map
> > with the help of memmap= command line option.
> > 
> > Can you please mention that this is only s390 specific requirement as
> > there are no memmap= equivalent options and somehow dump tools wants
> > to know how big the elf header size is?
> 
> I updated the description: 
> 
> Currently only the address of the pre-allocated ELF header is passed with
> the elfcorehdr= kernel parameter. In order to reserve memory for the header
> in the 2nd kernel also the size is required. Current kdump architecture
> backends use different methods to do that, e.g. x86 uses the memmap= kernel
> parameter. On s390 there is no easy way to transfer this information.
> Therefore the elfcorehdr kernel parameter is extended to also pass the size.
> This now can also be used as standard mechanism by all future kdump
> architecture backends.
> 
> The syntax of the kernel parameter is extended as follows:
> 
> elfcorehdr=[size[KMG]@]offset[KMG]
> 
> This change is backward compatible because elfcorehdr=size is still allowed.
> 
> Ok?

Yes, this one looks ok.

Thanks
Vivek

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

* Re: [patch v2 03/10] kdump: Add size to elfcorehdr kernel parameter
@ 2011-08-02 18:55         ` Vivek Goyal
  0 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-02 18:55 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

On Tue, Aug 02, 2011 at 11:08:07AM +0200, Michael Holzheu wrote:
> Hello Vivek,
> 
> #On Mon, 2011-08-01 at 16:36 -0400, Vivek Goyal wrote: 
> > On Wed, Jul 27, 2011 at 02:55:07PM +0200, Michael Holzheu wrote:
> > > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > > 
> > > Currently only the address of the pre-allocated ELF header is passed with
> > > the elfcorehdr= kernel parameter. In order to reserve memory for the header
> > > in the 2nd kernel also the size is required. To pass the size with this
> > > patch the syntax of the kernel parameter is extended as follows:
> > > 
> > > elfcorehdr=[size[KMG]@]offset[KMG]
> > > 
> > > This change is backward compatible because elfcorehdr=size is still allowed.
> > 
> > Generally vmcore parses elfcorehdr to figure out the sizes. kexec-tools
> > knows about it and relevant memory is excluded from second kernel's map
> > with the help of memmap= command line option.
> > 
> > Can you please mention that this is only s390 specific requirement as
> > there are no memmap= equivalent options and somehow dump tools wants
> > to know how big the elf header size is?
> 
> I updated the description: 
> 
> Currently only the address of the pre-allocated ELF header is passed with
> the elfcorehdr= kernel parameter. In order to reserve memory for the header
> in the 2nd kernel also the size is required. Current kdump architecture
> backends use different methods to do that, e.g. x86 uses the memmap= kernel
> parameter. On s390 there is no easy way to transfer this information.
> Therefore the elfcorehdr kernel parameter is extended to also pass the size.
> This now can also be used as standard mechanism by all future kdump
> architecture backends.
> 
> The syntax of the kernel parameter is extended as follows:
> 
> elfcorehdr=[size[KMG]@]offset[KMG]
> 
> This change is backward compatible because elfcorehdr=size is still allowed.
> 
> Ok?

Yes, this one looks ok.

Thanks
Vivek

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

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

* Re: [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak
  2011-08-02  9:30       ` Michael Holzheu
@ 2011-08-02 18:55         ` Vivek Goyal
  -1 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-02 18:55 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

On Tue, Aug 02, 2011 at 11:30:03AM +0200, Michael Holzheu wrote:
> Hello Vivek,
> 
> On Mon, 2011-08-01 at 16:31 -0400, Vivek Goyal wrote:
> > On Wed, Jul 27, 2011 at 02:55:06PM +0200, Michael Holzheu wrote:
> 
> [snip]
> 
> > > --- a/kernel/kexec.c
> > > +++ b/kernel/kexec.c
> > > @@ -842,8 +842,8 @@ out:
> > >  	return result;
> > >  }
> > >  
> > > -static int kimage_load_crash_segment(struct kimage *image,
> > > -					struct kexec_segment *segment)
> > > +int __weak kimage_load_crash_segment(struct kimage *image,
> > > +				     struct kexec_segment *segment)
> > 
> > A comment here why we are making it weak should help in increasing
> > the code readability.
> 
> What about the following:
> 
> /*
>  * Load crash segment into memory. Architecture code can override this
>  * function. E.g. this is necessary for architectures that do not
>  * create page tables for crashkernel memory.
>  */
> int __weak kimage_load_crash_segment(struct kimage *image,

This looks better.

Thanks
Vivek

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

* Re: [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak
@ 2011-08-02 18:55         ` Vivek Goyal
  0 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-02 18:55 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

On Tue, Aug 02, 2011 at 11:30:03AM +0200, Michael Holzheu wrote:
> Hello Vivek,
> 
> On Mon, 2011-08-01 at 16:31 -0400, Vivek Goyal wrote:
> > On Wed, Jul 27, 2011 at 02:55:06PM +0200, Michael Holzheu wrote:
> 
> [snip]
> 
> > > --- a/kernel/kexec.c
> > > +++ b/kernel/kexec.c
> > > @@ -842,8 +842,8 @@ out:
> > >  	return result;
> > >  }
> > >  
> > > -static int kimage_load_crash_segment(struct kimage *image,
> > > -					struct kexec_segment *segment)
> > > +int __weak kimage_load_crash_segment(struct kimage *image,
> > > +				     struct kexec_segment *segment)
> > 
> > A comment here why we are making it weak should help in increasing
> > the code readability.
> 
> What about the following:
> 
> /*
>  * Load crash segment into memory. Architecture code can override this
>  * function. E.g. this is necessary for architectures that do not
>  * create page tables for crashkernel memory.
>  */
> int __weak kimage_load_crash_segment(struct kimage *image,

This looks better.

Thanks
Vivek

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

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

* Re: [patch v2 01/10] kdump: Add KEXEC_CRASH_CONTROL_MEMORY_LIMIT
  2011-08-02  9:51       ` Michael Holzheu
@ 2011-08-02 19:16         ` Vivek Goyal
  -1 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-02 19:16 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

On Tue, Aug 02, 2011 at 11:51:04AM +0200, Michael Holzheu wrote:
> Hello Vivek,
> 
> On Mon, 2011-08-01 at 16:16 -0400, Vivek Goyal wrote:
> > On Wed, Jul 27, 2011 at 02:55:05PM +0200, Michael Holzheu wrote:
> > > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > > 
> > > On s390 there is a different KEXEC_CONTROL_MEMORY_LIMIT for the normal and
> > > the kdump kexec case. Therefore this patch introduces a new macro
> > > KEXEC_CRASH_CONTROL_MEMORY_LIMIT. This is set to
> > > KEXEC_CONTROL_MEMORY_LIMIT for all architectures that do not define
> > > KEXEC_CRASH_CONTROL_MEMORY_LIMIT.
> > 
> > Hi Michael,
> > 
> > Curious that why limit is different for kexec and kdump cases on s390
> > only.
> 
> The standard kexec relocate_kernel code calls a machine instruction that
> must run below 2 GiB. For kdump we currently do not use the control page
> at all because no segments have to be moved in that case. Perhaps I am
> still missing something here?

On x86, control page is used for transition to purgatory and second kernel
and common code is used. The only step which is skipped in case of kdump
is the page copying part. As code is common for both the cases the limit
is same.

If you are not using control page at all during s390 kdump (because you
are doing all the setup in dump tools, then probably you can specify
a higher limit so control page.) So in this case you are allocating
control page but not using it?

Thanks
Vivek

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

* Re: [patch v2 01/10] kdump: Add KEXEC_CRASH_CONTROL_MEMORY_LIMIT
@ 2011-08-02 19:16         ` Vivek Goyal
  0 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-02 19:16 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

On Tue, Aug 02, 2011 at 11:51:04AM +0200, Michael Holzheu wrote:
> Hello Vivek,
> 
> On Mon, 2011-08-01 at 16:16 -0400, Vivek Goyal wrote:
> > On Wed, Jul 27, 2011 at 02:55:05PM +0200, Michael Holzheu wrote:
> > > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > > 
> > > On s390 there is a different KEXEC_CONTROL_MEMORY_LIMIT for the normal and
> > > the kdump kexec case. Therefore this patch introduces a new macro
> > > KEXEC_CRASH_CONTROL_MEMORY_LIMIT. This is set to
> > > KEXEC_CONTROL_MEMORY_LIMIT for all architectures that do not define
> > > KEXEC_CRASH_CONTROL_MEMORY_LIMIT.
> > 
> > Hi Michael,
> > 
> > Curious that why limit is different for kexec and kdump cases on s390
> > only.
> 
> The standard kexec relocate_kernel code calls a machine instruction that
> must run below 2 GiB. For kdump we currently do not use the control page
> at all because no segments have to be moved in that case. Perhaps I am
> still missing something here?

On x86, control page is used for transition to purgatory and second kernel
and common code is used. The only step which is skipped in case of kdump
is the page copying part. As code is common for both the cases the limit
is same.

If you are not using control page at all during s390 kdump (because you
are doing all the setup in dump tools, then probably you can specify
a higher limit so control page.) So in this case you are allocating
control page but not using it?

Thanks
Vivek

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

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

* Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390
  2011-08-02  8:37       ` Michael Holzheu
@ 2011-08-02 19:21         ` Vivek Goyal
  -1 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-02 19:21 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

On Tue, Aug 02, 2011 at 10:37:59AM +0200, Michael Holzheu wrote:
> Hello Vivek,
> 
> On Mon, 2011-08-01 at 16:41 -0400, Vivek Goyal wrote:
> > On Wed, Jul 27, 2011 at 02:55:08PM +0200, Michael Holzheu wrote:
> > > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > > 
> > > On s390 we have the possibility to configure actions that are executed in
> > > case of a kernel panic. E.g. it is possible to automatically trigger an s390
> > > stand-alone dump. The actions are called via a panic notifier.  We also want
> > > to trigger kdump via the notifier call chain. Therefore this patch disables
> > > for s390 the direct kdump invocation in the panic() function.
> > 
> > Doesn't this reduce the reliability of the operation as you are assuming
> > that panic notifier list is fine and not corrupted.
> 
> Yes, this is correct. We have to rely that the notifier list is fine.
> Probably there is still room for improvement here.
> 
> > There might be other generic notifiers registerd on panic notifier list
> > too. So in your case, are there multiple subsystem registering for panic
> > notifiers? If not, why not call crash_kexec() directly. Are there any
> > other actions you want to take on panic then calling crash_kexec()?
> 
> We have added the panic notifier in the past in order to be able to
> configure the action that should be done in case of panic using our
> shutdown actions infrastructure. We can configure the action using sysfs
> and we are able to configure that a stand-alone dump should be started
> as action for panic.
> 
> Now with the two stage dump approach we would like to keep the
> possibility to trigger a stand-alone dump even if kdump is installed.
> The stand-alone dumper will be started in case of a kernel panic and
> then the procedure we discussed will happen: Jump into kdump and if
> program check occurs do stand-alone dump as backup.

Frankly speaking this jumping to stand alone kernel by default is not
making any sense to me. Once you have already determined from /sys that
in case of crash a user has set the action to kdump, then we should
simply call crash_kexec() like other architectures and jump to stand
alone kernel only if some piece of code is corrupted and that action
failed.

What's the point of jumping to stand alone kenrel in case of panic()
and then re-enter it back to original kernel using crash_kexec(). Sound
like a very odd design choice to me.

I am now I am repeating this question umpteen time simply because
I never got a good answer except "we have to do it this way".

Thanks
Vivek

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

* Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390
@ 2011-08-02 19:21         ` Vivek Goyal
  0 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-02 19:21 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

On Tue, Aug 02, 2011 at 10:37:59AM +0200, Michael Holzheu wrote:
> Hello Vivek,
> 
> On Mon, 2011-08-01 at 16:41 -0400, Vivek Goyal wrote:
> > On Wed, Jul 27, 2011 at 02:55:08PM +0200, Michael Holzheu wrote:
> > > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > > 
> > > On s390 we have the possibility to configure actions that are executed in
> > > case of a kernel panic. E.g. it is possible to automatically trigger an s390
> > > stand-alone dump. The actions are called via a panic notifier.  We also want
> > > to trigger kdump via the notifier call chain. Therefore this patch disables
> > > for s390 the direct kdump invocation in the panic() function.
> > 
> > Doesn't this reduce the reliability of the operation as you are assuming
> > that panic notifier list is fine and not corrupted.
> 
> Yes, this is correct. We have to rely that the notifier list is fine.
> Probably there is still room for improvement here.
> 
> > There might be other generic notifiers registerd on panic notifier list
> > too. So in your case, are there multiple subsystem registering for panic
> > notifiers? If not, why not call crash_kexec() directly. Are there any
> > other actions you want to take on panic then calling crash_kexec()?
> 
> We have added the panic notifier in the past in order to be able to
> configure the action that should be done in case of panic using our
> shutdown actions infrastructure. We can configure the action using sysfs
> and we are able to configure that a stand-alone dump should be started
> as action for panic.
> 
> Now with the two stage dump approach we would like to keep the
> possibility to trigger a stand-alone dump even if kdump is installed.
> The stand-alone dumper will be started in case of a kernel panic and
> then the procedure we discussed will happen: Jump into kdump and if
> program check occurs do stand-alone dump as backup.

Frankly speaking this jumping to stand alone kernel by default is not
making any sense to me. Once you have already determined from /sys that
in case of crash a user has set the action to kdump, then we should
simply call crash_kexec() like other architectures and jump to stand
alone kernel only if some piece of code is corrupted and that action
failed.

What's the point of jumping to stand alone kenrel in case of panic()
and then re-enter it back to original kernel using crash_kexec(). Sound
like a very odd design choice to me.

I am now I am repeating this question umpteen time simply because
I never got a good answer except "we have to do it this way".

Thanks
Vivek

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

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

* Re: [patch v2 01/10] kdump: Add KEXEC_CRASH_CONTROL_MEMORY_LIMIT
  2011-08-02 19:16         ` Vivek Goyal
@ 2011-08-03  9:27           ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-03  9:27 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

Hello Vivek,

On Tue, 2011-08-02 at 15:16 -0400, Vivek Goyal wrote:
> On Tue, Aug 02, 2011 at 11:51:04AM +0200, Michael Holzheu wrote:
> > Hello Vivek,
> > 
> > On Mon, 2011-08-01 at 16:16 -0400, Vivek Goyal wrote:
> > > On Wed, Jul 27, 2011 at 02:55:05PM +0200, Michael Holzheu wrote:
> > > > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > > > 
> > > > On s390 there is a different KEXEC_CONTROL_MEMORY_LIMIT for the normal and
> > > > the kdump kexec case. Therefore this patch introduces a new macro
> > > > KEXEC_CRASH_CONTROL_MEMORY_LIMIT. This is set to
> > > > KEXEC_CONTROL_MEMORY_LIMIT for all architectures that do not define
> > > > KEXEC_CRASH_CONTROL_MEMORY_LIMIT.
> > > 
> > > Hi Michael,
> > > 
> > > Curious that why limit is different for kexec and kdump cases on s390
> > > only.
> > 
> > The standard kexec relocate_kernel code calls a machine instruction that
> > must run below 2 GiB. For kdump we currently do not use the control page
> > at all because no segments have to be moved in that case. Perhaps I am
> > still missing something here?
> 
> On x86, control page is used for transition to purgatory and second kernel
> and common code is used. The only step which is skipped in case of kdump
> is the page copying part. As code is common for both the cases the limit
> is same.
> If you are not using control page at all during s390 kdump (because you
> are doing all the setup in dump tools, then probably you can specify
> a higher limit so control page.) So in this case you are allocating
> control page but not using it?

Correct, we do not use the control page for kdump, because there is
nothing to do for us. Common code is reserving the control page, we just
don't care about it.

Michael


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

* Re: [patch v2 01/10] kdump: Add KEXEC_CRASH_CONTROL_MEMORY_LIMIT
@ 2011-08-03  9:27           ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-03  9:27 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

Hello Vivek,

On Tue, 2011-08-02 at 15:16 -0400, Vivek Goyal wrote:
> On Tue, Aug 02, 2011 at 11:51:04AM +0200, Michael Holzheu wrote:
> > Hello Vivek,
> > 
> > On Mon, 2011-08-01 at 16:16 -0400, Vivek Goyal wrote:
> > > On Wed, Jul 27, 2011 at 02:55:05PM +0200, Michael Holzheu wrote:
> > > > From: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> > > > 
> > > > On s390 there is a different KEXEC_CONTROL_MEMORY_LIMIT for the normal and
> > > > the kdump kexec case. Therefore this patch introduces a new macro
> > > > KEXEC_CRASH_CONTROL_MEMORY_LIMIT. This is set to
> > > > KEXEC_CONTROL_MEMORY_LIMIT for all architectures that do not define
> > > > KEXEC_CRASH_CONTROL_MEMORY_LIMIT.
> > > 
> > > Hi Michael,
> > > 
> > > Curious that why limit is different for kexec and kdump cases on s390
> > > only.
> > 
> > The standard kexec relocate_kernel code calls a machine instruction that
> > must run below 2 GiB. For kdump we currently do not use the control page
> > at all because no segments have to be moved in that case. Perhaps I am
> > still missing something here?
> 
> On x86, control page is used for transition to purgatory and second kernel
> and common code is used. The only step which is skipped in case of kdump
> is the page copying part. As code is common for both the cases the limit
> is same.
> If you are not using control page at all during s390 kdump (because you
> are doing all the setup in dump tools, then probably you can specify
> a higher limit so control page.) So in this case you are allocating
> control page but not using it?

Correct, we do not use the control page for kdump, because there is
nothing to do for us. Common code is reserving the control page, we just
don't care about it.

Michael


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

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

* Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390
  2011-08-02 19:21         ` Vivek Goyal
@ 2011-08-03  9:50           ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-03  9:50 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

Hello Vivek,

On Tue, 2011-08-02 at 15:21 -0400, Vivek Goyal wrote:
> > We have added the panic notifier in the past in order to be able to
> > configure the action that should be done in case of panic using our
> > shutdown actions infrastructure. We can configure the action using sysfs
> > and we are able to configure that a stand-alone dump should be started
> > as action for panic.
> > 
> > Now with the two stage dump approach we would like to keep the
> > possibility to trigger a stand-alone dump even if kdump is installed.
> > The stand-alone dumper will be started in case of a kernel panic and
> > then the procedure we discussed will happen: Jump into kdump and if
> > program check occurs do stand-alone dump as backup.
> 
> Frankly speaking this jumping to stand alone kernel by default is not
> making any sense to me. Once you have already determined from /sys that
> in case of crash a user has set the action to kdump, then we should
> simply call crash_kexec()

If the user has set the panic action to kdump, we jump directly to
crash_kexec(). This then works like on all other architectures.

Only if the user has specified panic action stand-alone dump, we do the
detour via the stand-alone dump tools.

> like other architectures and jump to stand
> alone kernel only if some piece of code is corrupted and that action
> failed.
> 
> What's the point of jumping to stand alone kenrel in case of panic()
> and then re-enter it back to original kernel using crash_kexec(). Sound
> like a very odd design choice to me.
> 
> I am now I am repeating this question umpteen time simply because
> I never got a good answer except "we have to do it this way".

Sometimes communication is really hard and frustrating.
... but at least we are still communicating.

Ok very last try:

* We can use the same mechanism for manual dump and automatic dump on
panic: IPL the stand-alone dump tools. kdump check and backup
stand-alone dump is implemented only in the stand-alone dump code. If we
would do it like you suggested, we would have to do it twice - in the
kernel and in the stand-alone dump tools:
- kernel: Try kdump and if kdump fails trigger standalone dump tool
- Stand-alone dump tool: Try kdump and if kdump fails do full dump

* Still the panic action is configured via sysfs as the user is already
used to on s390.

* It fits much better into our whole s390 infrastructure. Believe me, we
have discussed that here a long time. I think you do not have a full
overview here. Perhaps you just have to believe that.

Michael



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

* Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390
@ 2011-08-03  9:50           ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-03  9:50 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

Hello Vivek,

On Tue, 2011-08-02 at 15:21 -0400, Vivek Goyal wrote:
> > We have added the panic notifier in the past in order to be able to
> > configure the action that should be done in case of panic using our
> > shutdown actions infrastructure. We can configure the action using sysfs
> > and we are able to configure that a stand-alone dump should be started
> > as action for panic.
> > 
> > Now with the two stage dump approach we would like to keep the
> > possibility to trigger a stand-alone dump even if kdump is installed.
> > The stand-alone dumper will be started in case of a kernel panic and
> > then the procedure we discussed will happen: Jump into kdump and if
> > program check occurs do stand-alone dump as backup.
> 
> Frankly speaking this jumping to stand alone kernel by default is not
> making any sense to me. Once you have already determined from /sys that
> in case of crash a user has set the action to kdump, then we should
> simply call crash_kexec()

If the user has set the panic action to kdump, we jump directly to
crash_kexec(). This then works like on all other architectures.

Only if the user has specified panic action stand-alone dump, we do the
detour via the stand-alone dump tools.

> like other architectures and jump to stand
> alone kernel only if some piece of code is corrupted and that action
> failed.
> 
> What's the point of jumping to stand alone kenrel in case of panic()
> and then re-enter it back to original kernel using crash_kexec(). Sound
> like a very odd design choice to me.
> 
> I am now I am repeating this question umpteen time simply because
> I never got a good answer except "we have to do it this way".

Sometimes communication is really hard and frustrating.
... but at least we are still communicating.

Ok very last try:

* We can use the same mechanism for manual dump and automatic dump on
panic: IPL the stand-alone dump tools. kdump check and backup
stand-alone dump is implemented only in the stand-alone dump code. If we
would do it like you suggested, we would have to do it twice - in the
kernel and in the stand-alone dump tools:
- kernel: Try kdump and if kdump fails trigger standalone dump tool
- Stand-alone dump tool: Try kdump and if kdump fails do full dump

* Still the panic action is configured via sysfs as the user is already
used to on s390.

* It fits much better into our whole s390 infrastructure. Believe me, we
have discussed that here a long time. I think you do not have a full
overview here. Perhaps you just have to believe that.

Michael



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

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

* Re: [patch v2 03/10] kdump: Add size to elfcorehdr kernel parameter
  2011-08-02 18:55         ` Vivek Goyal
@ 2011-08-03 10:40           ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-03 10:40 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

Hello Vivek,

On Tue, 2011-08-02 at 14:55 -0400, Vivek Goyal wrote:
> On Tue, Aug 02, 2011 at 11:08:07AM +0200, Michael Holzheu wrote:
> > Hello Vivek,
> > 
> > > Generally vmcore parses elfcorehdr to figure out the sizes. kexec-tools
> > > knows about it and relevant memory is excluded from second kernel's map
> > > with the help of memmap= command line option.
> > > 
> > > Can you please mention that this is only s390 specific requirement as
> > > there are no memmap= equivalent options and somehow dump tools wants
> > > to know how big the elf header size is?
> > 
> > I updated the description: 
> > 
> > Currently only the address of the pre-allocated ELF header is passed with
> > the elfcorehdr= kernel parameter. In order to reserve memory for the header
> > in the 2nd kernel also the size is required. Current kdump architecture
> > backends use different methods to do that, e.g. x86 uses the memmap= kernel
> > parameter. On s390 there is no easy way to transfer this information.
> > Therefore the elfcorehdr kernel parameter is extended to also pass the size.
> > This now can also be used as standard mechanism by all future kdump
> > architecture backends.
> > 
> > The syntax of the kernel parameter is extended as follows:
> > 
> > elfcorehdr=[size[KMG]@]offset[KMG]
> > 
> > This change is backward compatible because elfcorehdr=size is still allowed.
> > 
> > Ok?
> 
> Yes, this one looks ok.

With that description change: Do I get an "Acked-by" for this patch from
you?

Michael


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

* Re: [patch v2 03/10] kdump: Add size to elfcorehdr kernel parameter
@ 2011-08-03 10:40           ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-03 10:40 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

Hello Vivek,

On Tue, 2011-08-02 at 14:55 -0400, Vivek Goyal wrote:
> On Tue, Aug 02, 2011 at 11:08:07AM +0200, Michael Holzheu wrote:
> > Hello Vivek,
> > 
> > > Generally vmcore parses elfcorehdr to figure out the sizes. kexec-tools
> > > knows about it and relevant memory is excluded from second kernel's map
> > > with the help of memmap= command line option.
> > > 
> > > Can you please mention that this is only s390 specific requirement as
> > > there are no memmap= equivalent options and somehow dump tools wants
> > > to know how big the elf header size is?
> > 
> > I updated the description: 
> > 
> > Currently only the address of the pre-allocated ELF header is passed with
> > the elfcorehdr= kernel parameter. In order to reserve memory for the header
> > in the 2nd kernel also the size is required. Current kdump architecture
> > backends use different methods to do that, e.g. x86 uses the memmap= kernel
> > parameter. On s390 there is no easy way to transfer this information.
> > Therefore the elfcorehdr kernel parameter is extended to also pass the size.
> > This now can also be used as standard mechanism by all future kdump
> > architecture backends.
> > 
> > The syntax of the kernel parameter is extended as follows:
> > 
> > elfcorehdr=[size[KMG]@]offset[KMG]
> > 
> > This change is backward compatible because elfcorehdr=size is still allowed.
> > 
> > Ok?
> 
> Yes, this one looks ok.

With that description change: Do I get an "Acked-by" for this patch from
you?

Michael


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

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

* Re: [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak
  2011-08-02 18:55         ` Vivek Goyal
@ 2011-08-03 10:41           ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-03 10:41 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

On Tue, 2011-08-02 at 14:55 -0400, Vivek Goyal wrote:
> On Tue, Aug 02, 2011 at 11:30:03AM +0200, Michael Holzheu wrote:
> > Hello Vivek,
> > 
> > On Mon, 2011-08-01 at 16:31 -0400, Vivek Goyal wrote:
> > > On Wed, Jul 27, 2011 at 02:55:06PM +0200, Michael Holzheu wrote:
> > 
> > [snip]
> > 
> > > > --- a/kernel/kexec.c
> > > > +++ b/kernel/kexec.c
> > > > @@ -842,8 +842,8 @@ out:
> > > >  	return result;
> > > >  }
> > > >  
> > > > -static int kimage_load_crash_segment(struct kimage *image,
> > > > -					struct kexec_segment *segment)
> > > > +int __weak kimage_load_crash_segment(struct kimage *image,
> > > > +				     struct kexec_segment *segment)
> > > 
> > > A comment here why we are making it weak should help in increasing
> > > the code readability.
> > 
> > What about the following:
> > 
> > /*
> >  * Load crash segment into memory. Architecture code can override this
> >  * function. E.g. this is necessary for architectures that do not
> >  * create page tables for crashkernel memory.
> >  */
> > int __weak kimage_load_crash_segment(struct kimage *image,
> 
> This looks better.

With that comment change: Do I get an "Acked-by" for this patch from
you?

Michael


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

* Re: [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak
@ 2011-08-03 10:41           ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-03 10:41 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

On Tue, 2011-08-02 at 14:55 -0400, Vivek Goyal wrote:
> On Tue, Aug 02, 2011 at 11:30:03AM +0200, Michael Holzheu wrote:
> > Hello Vivek,
> > 
> > On Mon, 2011-08-01 at 16:31 -0400, Vivek Goyal wrote:
> > > On Wed, Jul 27, 2011 at 02:55:06PM +0200, Michael Holzheu wrote:
> > 
> > [snip]
> > 
> > > > --- a/kernel/kexec.c
> > > > +++ b/kernel/kexec.c
> > > > @@ -842,8 +842,8 @@ out:
> > > >  	return result;
> > > >  }
> > > >  
> > > > -static int kimage_load_crash_segment(struct kimage *image,
> > > > -					struct kexec_segment *segment)
> > > > +int __weak kimage_load_crash_segment(struct kimage *image,
> > > > +				     struct kexec_segment *segment)
> > > 
> > > A comment here why we are making it weak should help in increasing
> > > the code readability.
> > 
> > What about the following:
> > 
> > /*
> >  * Load crash segment into memory. Architecture code can override this
> >  * function. E.g. this is necessary for architectures that do not
> >  * create page tables for crashkernel memory.
> >  */
> > int __weak kimage_load_crash_segment(struct kimage *image,
> 
> This looks better.

With that comment change: Do I get an "Acked-by" for this patch from
you?

Michael


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

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

* Re: [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak
  2011-08-03 10:41           ` Michael Holzheu
@ 2011-08-04 20:25             ` Vivek Goyal
  -1 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-04 20:25 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

On Wed, Aug 03, 2011 at 12:41:28PM +0200, Michael Holzheu wrote:
> On Tue, 2011-08-02 at 14:55 -0400, Vivek Goyal wrote:
> > On Tue, Aug 02, 2011 at 11:30:03AM +0200, Michael Holzheu wrote:
> > > Hello Vivek,
> > > 
> > > On Mon, 2011-08-01 at 16:31 -0400, Vivek Goyal wrote:
> > > > On Wed, Jul 27, 2011 at 02:55:06PM +0200, Michael Holzheu wrote:
> > > 
> > > [snip]
> > > 
> > > > > --- a/kernel/kexec.c
> > > > > +++ b/kernel/kexec.c
> > > > > @@ -842,8 +842,8 @@ out:
> > > > >  	return result;
> > > > >  }
> > > > >  
> > > > > -static int kimage_load_crash_segment(struct kimage *image,
> > > > > -					struct kexec_segment *segment)
> > > > > +int __weak kimage_load_crash_segment(struct kimage *image,
> > > > > +				     struct kexec_segment *segment)
> > > > 
> > > > A comment here why we are making it weak should help in increasing
> > > > the code readability.
> > > 
> > > What about the following:
> > > 
> > > /*
> > >  * Load crash segment into memory. Architecture code can override this
> > >  * function. E.g. this is necessary for architectures that do not
> > >  * create page tables for crashkernel memory.
> > >  */
> > > int __weak kimage_load_crash_segment(struct kimage *image,
> > 
> > This looks better.
> 
> With that comment change: Do I get an "Acked-by" for this patch from
> you?

Yes, looks good to me.

Acked-by: Vivek Goyal <vgoyal@redhat.com>

Thanks
Vivek

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

* Re: [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak
@ 2011-08-04 20:25             ` Vivek Goyal
  0 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-04 20:25 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

On Wed, Aug 03, 2011 at 12:41:28PM +0200, Michael Holzheu wrote:
> On Tue, 2011-08-02 at 14:55 -0400, Vivek Goyal wrote:
> > On Tue, Aug 02, 2011 at 11:30:03AM +0200, Michael Holzheu wrote:
> > > Hello Vivek,
> > > 
> > > On Mon, 2011-08-01 at 16:31 -0400, Vivek Goyal wrote:
> > > > On Wed, Jul 27, 2011 at 02:55:06PM +0200, Michael Holzheu wrote:
> > > 
> > > [snip]
> > > 
> > > > > --- a/kernel/kexec.c
> > > > > +++ b/kernel/kexec.c
> > > > > @@ -842,8 +842,8 @@ out:
> > > > >  	return result;
> > > > >  }
> > > > >  
> > > > > -static int kimage_load_crash_segment(struct kimage *image,
> > > > > -					struct kexec_segment *segment)
> > > > > +int __weak kimage_load_crash_segment(struct kimage *image,
> > > > > +				     struct kexec_segment *segment)
> > > > 
> > > > A comment here why we are making it weak should help in increasing
> > > > the code readability.
> > > 
> > > What about the following:
> > > 
> > > /*
> > >  * Load crash segment into memory. Architecture code can override this
> > >  * function. E.g. this is necessary for architectures that do not
> > >  * create page tables for crashkernel memory.
> > >  */
> > > int __weak kimage_load_crash_segment(struct kimage *image,
> > 
> > This looks better.
> 
> With that comment change: Do I get an "Acked-by" for this patch from
> you?

Yes, looks good to me.

Acked-by: Vivek Goyal <vgoyal@redhat.com>

Thanks
Vivek

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

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

* Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390
  2011-08-03  9:50           ` Michael Holzheu
@ 2011-08-04 21:14             ` Vivek Goyal
  -1 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-04 21:14 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

On Wed, Aug 03, 2011 at 11:50:39AM +0200, Michael Holzheu wrote:
> Hello Vivek,
> 
> On Tue, 2011-08-02 at 15:21 -0400, Vivek Goyal wrote:
> > > We have added the panic notifier in the past in order to be able to
> > > configure the action that should be done in case of panic using our
> > > shutdown actions infrastructure. We can configure the action using sysfs
> > > and we are able to configure that a stand-alone dump should be started
> > > as action for panic.
> > > 
> > > Now with the two stage dump approach we would like to keep the
> > > possibility to trigger a stand-alone dump even if kdump is installed.
> > > The stand-alone dumper will be started in case of a kernel panic and
> > > then the procedure we discussed will happen: Jump into kdump and if
> > > program check occurs do stand-alone dump as backup.
> > 
> > Frankly speaking this jumping to stand alone kernel by default is not
> > making any sense to me. Once you have already determined from /sys that
> > in case of crash a user has set the action to kdump, then we should
> > simply call crash_kexec()
> 
> If the user has set the panic action to kdump, we jump directly to
> crash_kexec(). This then works like on all other architectures.

Ok, that's good to know that you will define panic action as kdump also
and in that case we will not jump to dump tools and directly call
crash_kexec()

> 
> Only if the user has specified panic action stand-alone dump, we do the
> detour via the stand-alone dump tools.

If a user decides to load kdump kernel to capture dump, then why does it
still make sense to set panic action as "stand-alone dump tools". One
could argue that user loaded kdump kernel but not necessarily wants
that mechanism to use, in that case dump-tools does not have to jump
to kdump kernel at all. 

> 
> > like other architectures and jump to stand
> > alone kernel only if some piece of code is corrupted and that action
> > failed.
> > 
> > What's the point of jumping to stand alone kenrel in case of panic()
> > and then re-enter it back to original kernel using crash_kexec(). Sound
> > like a very odd design choice to me.
> > 
> > I am now I am repeating this question umpteen time simply because
> > I never got a good answer except "we have to do it this way".
> 
> Sometimes communication is really hard and frustrating.
> ... but at least we are still communicating.
> 
> Ok very last try:
> 
> * We can use the same mechanism for manual dump and automatic dump on
> panic: IPL the stand-alone dump tools.

So manual dump/intervention is only required if automatic dump failed?

> kdump check and backup
> stand-alone dump is implemented only in the stand-alone dump code.

My argument is that why stand alone dump is trying to trigger kdump
at all? Shouldn't it all be part of loading kdump kernel and user
setting panic() action to kdump?

The only valid argument to try to load kdump kernel from dump tools is
the hard hang situation where we never made to panic(). Then either
that hypervisor timer or manual intervention will come into picture
and one might argue that we still will kdump a try.

Fox x86 it is relatively easy as NMI detects hard hang in the context
of first kernel and can easily call crash_kexec() without any additional
information passing.

So if it is about hard hang, i can still understand the need to jump
to crash_kexec() from dump tools. I don't know if it is possible to 
invoke crash_kexec() directly from hypervisor timer without ipling
dump tools or not.

> If we
> would do it like you suggested, we would have to do it twice - in the
> kernel and in the stand-alone dump tools:
> - kernel: Try kdump and if kdump fails trigger standalone dump tool
> - Stand-alone dump tool: Try kdump and if kdump fails do full dump

Are we not already doing above two steps? You just mentioned that 
if user specified "kdump" as panic() action, then you will call
crash_kexec() directly. Will we not jump to dump tools if kdump
fails?

Also if user specified "dump-tools" as action, then your way of things
anyway will try to execute kdump (if kernel is loaded) and if that fails
then we come back to dump tools.

So I think in current scheme of things, you already have both implemented.
> 
> * Still the panic action is configured via sysfs as the user is already
> used to on s390.

I asked the question above why it makes sense to configure panic action
as dump tools if kdump kernel is loaded.

> 
> * It fits much better into our whole s390 infrastructure. Believe me, we
> have discussed that here a long time. I think you do not have a full
> overview here. Perhaps you just have to believe that.

That's what I am talking about. So many times the answer has been "We have
to do it this way".

Sure I do not have full overview here but little explanation sometimes
help in understanding things.

Thanks
Vivek

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

* Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390
@ 2011-08-04 21:14             ` Vivek Goyal
  0 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-04 21:14 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

On Wed, Aug 03, 2011 at 11:50:39AM +0200, Michael Holzheu wrote:
> Hello Vivek,
> 
> On Tue, 2011-08-02 at 15:21 -0400, Vivek Goyal wrote:
> > > We have added the panic notifier in the past in order to be able to
> > > configure the action that should be done in case of panic using our
> > > shutdown actions infrastructure. We can configure the action using sysfs
> > > and we are able to configure that a stand-alone dump should be started
> > > as action for panic.
> > > 
> > > Now with the two stage dump approach we would like to keep the
> > > possibility to trigger a stand-alone dump even if kdump is installed.
> > > The stand-alone dumper will be started in case of a kernel panic and
> > > then the procedure we discussed will happen: Jump into kdump and if
> > > program check occurs do stand-alone dump as backup.
> > 
> > Frankly speaking this jumping to stand alone kernel by default is not
> > making any sense to me. Once you have already determined from /sys that
> > in case of crash a user has set the action to kdump, then we should
> > simply call crash_kexec()
> 
> If the user has set the panic action to kdump, we jump directly to
> crash_kexec(). This then works like on all other architectures.

Ok, that's good to know that you will define panic action as kdump also
and in that case we will not jump to dump tools and directly call
crash_kexec()

> 
> Only if the user has specified panic action stand-alone dump, we do the
> detour via the stand-alone dump tools.

If a user decides to load kdump kernel to capture dump, then why does it
still make sense to set panic action as "stand-alone dump tools". One
could argue that user loaded kdump kernel but not necessarily wants
that mechanism to use, in that case dump-tools does not have to jump
to kdump kernel at all. 

> 
> > like other architectures and jump to stand
> > alone kernel only if some piece of code is corrupted and that action
> > failed.
> > 
> > What's the point of jumping to stand alone kenrel in case of panic()
> > and then re-enter it back to original kernel using crash_kexec(). Sound
> > like a very odd design choice to me.
> > 
> > I am now I am repeating this question umpteen time simply because
> > I never got a good answer except "we have to do it this way".
> 
> Sometimes communication is really hard and frustrating.
> ... but at least we are still communicating.
> 
> Ok very last try:
> 
> * We can use the same mechanism for manual dump and automatic dump on
> panic: IPL the stand-alone dump tools.

So manual dump/intervention is only required if automatic dump failed?

> kdump check and backup
> stand-alone dump is implemented only in the stand-alone dump code.

My argument is that why stand alone dump is trying to trigger kdump
at all? Shouldn't it all be part of loading kdump kernel and user
setting panic() action to kdump?

The only valid argument to try to load kdump kernel from dump tools is
the hard hang situation where we never made to panic(). Then either
that hypervisor timer or manual intervention will come into picture
and one might argue that we still will kdump a try.

Fox x86 it is relatively easy as NMI detects hard hang in the context
of first kernel and can easily call crash_kexec() without any additional
information passing.

So if it is about hard hang, i can still understand the need to jump
to crash_kexec() from dump tools. I don't know if it is possible to 
invoke crash_kexec() directly from hypervisor timer without ipling
dump tools or not.

> If we
> would do it like you suggested, we would have to do it twice - in the
> kernel and in the stand-alone dump tools:
> - kernel: Try kdump and if kdump fails trigger standalone dump tool
> - Stand-alone dump tool: Try kdump and if kdump fails do full dump

Are we not already doing above two steps? You just mentioned that 
if user specified "kdump" as panic() action, then you will call
crash_kexec() directly. Will we not jump to dump tools if kdump
fails?

Also if user specified "dump-tools" as action, then your way of things
anyway will try to execute kdump (if kernel is loaded) and if that fails
then we come back to dump tools.

So I think in current scheme of things, you already have both implemented.
> 
> * Still the panic action is configured via sysfs as the user is already
> used to on s390.

I asked the question above why it makes sense to configure panic action
as dump tools if kdump kernel is loaded.

> 
> * It fits much better into our whole s390 infrastructure. Believe me, we
> have discussed that here a long time. I think you do not have a full
> overview here. Perhaps you just have to believe that.

That's what I am talking about. So many times the answer has been "We have
to do it this way".

Sure I do not have full overview here but little explanation sometimes
help in understanding things.

Thanks
Vivek

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

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

* Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390
  2011-08-04 21:14             ` Vivek Goyal
@ 2011-08-08 17:47               ` Michael Holzheu
  -1 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-08 17:47 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

Hello Vivek,

On Thu, 2011-08-04 at 17:14 -0400, Vivek Goyal wrote:
> On Wed, Aug 03, 2011 at 11:50:39AM +0200, Michael Holzheu wrote:

[snip]
 
> > Only if the user has specified panic action stand-alone dump, we do the
> > detour via the stand-alone dump tools.
> 
> If a user decides to load kdump kernel to capture dump, then why does it
> still make sense to set panic action as "stand-alone dump tools". One
> could argue that user loaded kdump kernel but not necessarily wants
> that mechanism to use, in that case dump-tools does not have to jump
> to kdump kernel at all. 

The user on s390 can currently freely configure the panic action. If we
would always do kdump on panic, when kdump is active, we would have to
ensure in sysfs that the user can't change the setting any more.
Technically we could do that of course.

One use case we had in mind was that the s390 Linux administrator does
not have to learn new things when using kdump. kdump can be used as
extension of the already existing mechanism. Today users configure
stand-alone dump via sysfs. With kdump + trigger via dump tools they
could do it still the same way. And also for manual dump they just IPL
the dump tool as they are used to do it and if kdump is fine, kdump will
be triggered. Nothing new has to be learned.

If users only want to use kdump without stand-alone dump tools as on
other architectures also this is possible. Then the panic action will be
just kdump.

> > 
> > > like other architectures and jump to stand
> > > alone kernel only if some piece of code is corrupted and that action
> > > failed.
> > > 
> > > What's the point of jumping to stand alone kenrel in case of panic()
> > > and then re-enter it back to original kernel using crash_kexec(). Sound
> > > like a very odd design choice to me.
> > > 
> > > I am now I am repeating this question umpteen time simply because
> > > I never got a good answer except "we have to do it this way".
> > 
> > Sometimes communication is really hard and frustrating.
> > ... but at least we are still communicating.
> > 
> > Ok very last try:
> > 
> > * We can use the same mechanism for manual dump and automatic dump on
> > panic: IPL the stand-alone dump tools.
> 
> So manual dump/intervention is only required if automatic dump failed?

Manual intervention is required only if panic code does not make it to
the "IPL stand-alone dump tools" code.

> 
> > kdump check and backup
> > stand-alone dump is implemented only in the stand-alone dump code.
> 
> My argument is that why stand alone dump is trying to trigger kdump
> at all? Shouldn't it all be part of loading kdump kernel and user
> setting panic() action to kdump?

To summarize: Our approach was to do it in the stand-alone dump tools
code for both the manual and the automatic on panic case:

panic ------+                                 +- valid -> kdump
            +-> IPL dump tools -> try kdump --+
hard hang --+                                 +- invalid -> stand-alone dump

Your suggestion looks like the following:

panic --> try kdump +-- valid ---> kdump
                    |
                    +-- invalid -> IPL dump tools --> stand-alone dump

                                            +- valid -> kdump
hard hang --> IPL dump tools -> try kdump --+ 
                                            +- invalid -> stand-alone dump

Is that what you are suggesting? We can do it that way, too. Then
we would not need the #ifdef CONFIG_S390 in panic().

Michael


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

* Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390
@ 2011-08-08 17:47               ` Michael Holzheu
  0 siblings, 0 replies; 66+ messages in thread
From: Michael Holzheu @ 2011-08-08 17:47 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

Hello Vivek,

On Thu, 2011-08-04 at 17:14 -0400, Vivek Goyal wrote:
> On Wed, Aug 03, 2011 at 11:50:39AM +0200, Michael Holzheu wrote:

[snip]
 
> > Only if the user has specified panic action stand-alone dump, we do the
> > detour via the stand-alone dump tools.
> 
> If a user decides to load kdump kernel to capture dump, then why does it
> still make sense to set panic action as "stand-alone dump tools". One
> could argue that user loaded kdump kernel but not necessarily wants
> that mechanism to use, in that case dump-tools does not have to jump
> to kdump kernel at all. 

The user on s390 can currently freely configure the panic action. If we
would always do kdump on panic, when kdump is active, we would have to
ensure in sysfs that the user can't change the setting any more.
Technically we could do that of course.

One use case we had in mind was that the s390 Linux administrator does
not have to learn new things when using kdump. kdump can be used as
extension of the already existing mechanism. Today users configure
stand-alone dump via sysfs. With kdump + trigger via dump tools they
could do it still the same way. And also for manual dump they just IPL
the dump tool as they are used to do it and if kdump is fine, kdump will
be triggered. Nothing new has to be learned.

If users only want to use kdump without stand-alone dump tools as on
other architectures also this is possible. Then the panic action will be
just kdump.

> > 
> > > like other architectures and jump to stand
> > > alone kernel only if some piece of code is corrupted and that action
> > > failed.
> > > 
> > > What's the point of jumping to stand alone kenrel in case of panic()
> > > and then re-enter it back to original kernel using crash_kexec(). Sound
> > > like a very odd design choice to me.
> > > 
> > > I am now I am repeating this question umpteen time simply because
> > > I never got a good answer except "we have to do it this way".
> > 
> > Sometimes communication is really hard and frustrating.
> > ... but at least we are still communicating.
> > 
> > Ok very last try:
> > 
> > * We can use the same mechanism for manual dump and automatic dump on
> > panic: IPL the stand-alone dump tools.
> 
> So manual dump/intervention is only required if automatic dump failed?

Manual intervention is required only if panic code does not make it to
the "IPL stand-alone dump tools" code.

> 
> > kdump check and backup
> > stand-alone dump is implemented only in the stand-alone dump code.
> 
> My argument is that why stand alone dump is trying to trigger kdump
> at all? Shouldn't it all be part of loading kdump kernel and user
> setting panic() action to kdump?

To summarize: Our approach was to do it in the stand-alone dump tools
code for both the manual and the automatic on panic case:

panic ------+                                 +- valid -> kdump
            +-> IPL dump tools -> try kdump --+
hard hang --+                                 +- invalid -> stand-alone dump

Your suggestion looks like the following:

panic --> try kdump +-- valid ---> kdump
                    |
                    +-- invalid -> IPL dump tools --> stand-alone dump

                                            +- valid -> kdump
hard hang --> IPL dump tools -> try kdump --+ 
                                            +- invalid -> stand-alone dump

Is that what you are suggesting? We can do it that way, too. Then
we would not need the #ifdef CONFIG_S390 in panic().

Michael


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

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

* Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390
  2011-08-08 17:47               ` Michael Holzheu
@ 2011-08-09 21:19                 ` Vivek Goyal
  -1 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-09 21:19 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: ebiederm, mahesh, hbabu, oomichi, horms, schwidefsky,
	heiko.carstens, kexec, linux-kernel, linux-s390

On Mon, Aug 08, 2011 at 07:47:39PM +0200, Michael Holzheu wrote:
> Hello Vivek,
> 
> On Thu, 2011-08-04 at 17:14 -0400, Vivek Goyal wrote:
> > On Wed, Aug 03, 2011 at 11:50:39AM +0200, Michael Holzheu wrote:
> 
> [snip]
>  
> > > Only if the user has specified panic action stand-alone dump, we do the
> > > detour via the stand-alone dump tools.
> > 
> > If a user decides to load kdump kernel to capture dump, then why does it
> > still make sense to set panic action as "stand-alone dump tools". One
> > could argue that user loaded kdump kernel but not necessarily wants
> > that mechanism to use, in that case dump-tools does not have to jump
> > to kdump kernel at all. 
> 
> The user on s390 can currently freely configure the panic action. If we
> would always do kdump on panic, when kdump is active, we would have to
> ensure in sysfs that the user can't change the setting any more.
> Technically we could do that of course.
> 
> One use case we had in mind was that the s390 Linux administrator does
> not have to learn new things when using kdump. kdump can be used as
> extension of the already existing mechanism. Today users configure
> stand-alone dump via sysfs. With kdump + trigger via dump tools they
> could do it still the same way. And also for manual dump they just IPL
> the dump tool as they are used to do it and if kdump is fine, kdump will
> be triggered. Nothing new has to be learned.
> 
> If users only want to use kdump without stand-alone dump tools as on
> other architectures also this is possible. Then the panic action will be
> just kdump.

IMHO, it makes sense to introduce a new trigger action "kdump" and let
user configure that instead of masking everything behind dump tools.

In fact, we don't have to even configure it. Like other architectures, 
we can always call crash_kexec() upon panic() if there is a crash
kernel loaded. That way, panic() path remains simple and there are
no arch specific #ifdefs.

> 
> > > 
> > > > like other architectures and jump to stand
> > > > alone kernel only if some piece of code is corrupted and that action
> > > > failed.
> > > > 
> > > > What's the point of jumping to stand alone kenrel in case of panic()
> > > > and then re-enter it back to original kernel using crash_kexec(). Sound
> > > > like a very odd design choice to me.
> > > > 
> > > > I am now I am repeating this question umpteen time simply because
> > > > I never got a good answer except "we have to do it this way".
> > > 
> > > Sometimes communication is really hard and frustrating.
> > > ... but at least we are still communicating.
> > > 
> > > Ok very last try:
> > > 
> > > * We can use the same mechanism for manual dump and automatic dump on
> > > panic: IPL the stand-alone dump tools.
> > 
> > So manual dump/intervention is only required if automatic dump failed?
> 
> Manual intervention is required only if panic code does not make it to
> the "IPL stand-alone dump tools" code.
> 
> > 
> > > kdump check and backup
> > > stand-alone dump is implemented only in the stand-alone dump code.
> > 
> > My argument is that why stand alone dump is trying to trigger kdump
> > at all? Shouldn't it all be part of loading kdump kernel and user
> > setting panic() action to kdump?
> 
> To summarize: Our approach was to do it in the stand-alone dump tools
> code for both the manual and the automatic on panic case:
> 
> panic ------+                                 +- valid -> kdump
>             +-> IPL dump tools -> try kdump --+
> hard hang --+                                 +- invalid -> stand-alone dump
> 
> Your suggestion looks like the following:
> 
> panic --> try kdump +-- valid ---> kdump
>                     |
>                     +-- invalid -> IPL dump tools --> stand-alone dump
> 
>                                             +- valid -> kdump
> hard hang --> IPL dump tools -> try kdump --+ 
>                                             +- invalid -> stand-alone dump

I think thew whole notion of jumping from dump tools to kdump is not
a very good design as it enforces us to pass additional state to dump
tools and also the awkward notion of re-enter the crashed kernel
(crash_kexec() being called from dump tools).

Is there a notion of NMI on s390. What's the x86 NMI equivalent on s390.

> Is that what you are suggesting? We can do it that way, too. Then
> we would not need the #ifdef CONFIG_S390 in panic().

How about keeping it simple in first round.

- Always use kdump for capturing dump is kdump kernel is loaded. If user
  does not want to use kdump, don't load kdump kenrel.

- Use NMI equivalent to handle the hard hang case. In case there is no
  equivalent, how about keeping it simple in first go and always use
  dump-tools to capture full dump and improve upon it in a later patchset.

  (This is no worse then today as today you don't have any filtering
   mechanism).

Thanks
Vivek

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

* Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390
@ 2011-08-09 21:19                 ` Vivek Goyal
  0 siblings, 0 replies; 66+ messages in thread
From: Vivek Goyal @ 2011-08-09 21:19 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: oomichi, linux-s390, mahesh, heiko.carstens, linux-kernel, hbabu,
	horms, ebiederm, schwidefsky, kexec

On Mon, Aug 08, 2011 at 07:47:39PM +0200, Michael Holzheu wrote:
> Hello Vivek,
> 
> On Thu, 2011-08-04 at 17:14 -0400, Vivek Goyal wrote:
> > On Wed, Aug 03, 2011 at 11:50:39AM +0200, Michael Holzheu wrote:
> 
> [snip]
>  
> > > Only if the user has specified panic action stand-alone dump, we do the
> > > detour via the stand-alone dump tools.
> > 
> > If a user decides to load kdump kernel to capture dump, then why does it
> > still make sense to set panic action as "stand-alone dump tools". One
> > could argue that user loaded kdump kernel but not necessarily wants
> > that mechanism to use, in that case dump-tools does not have to jump
> > to kdump kernel at all. 
> 
> The user on s390 can currently freely configure the panic action. If we
> would always do kdump on panic, when kdump is active, we would have to
> ensure in sysfs that the user can't change the setting any more.
> Technically we could do that of course.
> 
> One use case we had in mind was that the s390 Linux administrator does
> not have to learn new things when using kdump. kdump can be used as
> extension of the already existing mechanism. Today users configure
> stand-alone dump via sysfs. With kdump + trigger via dump tools they
> could do it still the same way. And also for manual dump they just IPL
> the dump tool as they are used to do it and if kdump is fine, kdump will
> be triggered. Nothing new has to be learned.
> 
> If users only want to use kdump without stand-alone dump tools as on
> other architectures also this is possible. Then the panic action will be
> just kdump.

IMHO, it makes sense to introduce a new trigger action "kdump" and let
user configure that instead of masking everything behind dump tools.

In fact, we don't have to even configure it. Like other architectures, 
we can always call crash_kexec() upon panic() if there is a crash
kernel loaded. That way, panic() path remains simple and there are
no arch specific #ifdefs.

> 
> > > 
> > > > like other architectures and jump to stand
> > > > alone kernel only if some piece of code is corrupted and that action
> > > > failed.
> > > > 
> > > > What's the point of jumping to stand alone kenrel in case of panic()
> > > > and then re-enter it back to original kernel using crash_kexec(). Sound
> > > > like a very odd design choice to me.
> > > > 
> > > > I am now I am repeating this question umpteen time simply because
> > > > I never got a good answer except "we have to do it this way".
> > > 
> > > Sometimes communication is really hard and frustrating.
> > > ... but at least we are still communicating.
> > > 
> > > Ok very last try:
> > > 
> > > * We can use the same mechanism for manual dump and automatic dump on
> > > panic: IPL the stand-alone dump tools.
> > 
> > So manual dump/intervention is only required if automatic dump failed?
> 
> Manual intervention is required only if panic code does not make it to
> the "IPL stand-alone dump tools" code.
> 
> > 
> > > kdump check and backup
> > > stand-alone dump is implemented only in the stand-alone dump code.
> > 
> > My argument is that why stand alone dump is trying to trigger kdump
> > at all? Shouldn't it all be part of loading kdump kernel and user
> > setting panic() action to kdump?
> 
> To summarize: Our approach was to do it in the stand-alone dump tools
> code for both the manual and the automatic on panic case:
> 
> panic ------+                                 +- valid -> kdump
>             +-> IPL dump tools -> try kdump --+
> hard hang --+                                 +- invalid -> stand-alone dump
> 
> Your suggestion looks like the following:
> 
> panic --> try kdump +-- valid ---> kdump
>                     |
>                     +-- invalid -> IPL dump tools --> stand-alone dump
> 
>                                             +- valid -> kdump
> hard hang --> IPL dump tools -> try kdump --+ 
>                                             +- invalid -> stand-alone dump

I think thew whole notion of jumping from dump tools to kdump is not
a very good design as it enforces us to pass additional state to dump
tools and also the awkward notion of re-enter the crashed kernel
(crash_kexec() being called from dump tools).

Is there a notion of NMI on s390. What's the x86 NMI equivalent on s390.

> Is that what you are suggesting? We can do it that way, too. Then
> we would not need the #ifdef CONFIG_S390 in panic().

How about keeping it simple in first round.

- Always use kdump for capturing dump is kdump kernel is loaded. If user
  does not want to use kdump, don't load kdump kenrel.

- Use NMI equivalent to handle the hard hang case. In case there is no
  equivalent, how about keeping it simple in first go and always use
  dump-tools to capture full dump and improve upon it in a later patchset.

  (This is no worse then today as today you don't have any filtering
   mechanism).

Thanks
Vivek

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

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

end of thread, other threads:[~2011-08-09 21:19 UTC | newest]

Thread overview: 66+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-27 12:55 [patch v2 00/10] kdump: Patch series for s390 support (version 2) Michael Holzheu
2011-07-27 12:55 ` Michael Holzheu
2011-07-27 12:55 ` [patch v2 01/10] kdump: Add KEXEC_CRASH_CONTROL_MEMORY_LIMIT Michael Holzheu
2011-07-27 12:55   ` Michael Holzheu
2011-08-01 20:16   ` Vivek Goyal
2011-08-01 20:16     ` Vivek Goyal
2011-08-02  9:51     ` Michael Holzheu
2011-08-02  9:51       ` Michael Holzheu
2011-08-02 19:16       ` Vivek Goyal
2011-08-02 19:16         ` Vivek Goyal
2011-08-03  9:27         ` Michael Holzheu
2011-08-03  9:27           ` Michael Holzheu
2011-07-27 12:55 ` [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak Michael Holzheu
2011-07-27 12:55   ` Michael Holzheu
2011-08-01 20:31   ` Vivek Goyal
2011-08-01 20:31     ` Vivek Goyal
2011-08-02  9:30     ` Michael Holzheu
2011-08-02  9:30       ` Michael Holzheu
2011-08-02 18:55       ` Vivek Goyal
2011-08-02 18:55         ` Vivek Goyal
2011-08-03 10:41         ` Michael Holzheu
2011-08-03 10:41           ` Michael Holzheu
2011-08-04 20:25           ` Vivek Goyal
2011-08-04 20:25             ` Vivek Goyal
2011-07-27 12:55 ` [patch v2 03/10] kdump: Add size to elfcorehdr kernel parameter Michael Holzheu
2011-07-27 12:55   ` Michael Holzheu
2011-08-01 20:36   ` Vivek Goyal
2011-08-01 20:36     ` Vivek Goyal
2011-08-02  9:08     ` Michael Holzheu
2011-08-02  9:08       ` Michael Holzheu
2011-08-02 18:55       ` Vivek Goyal
2011-08-02 18:55         ` Vivek Goyal
2011-08-03 10:40         ` Michael Holzheu
2011-08-03 10:40           ` Michael Holzheu
2011-07-27 12:55 ` [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390 Michael Holzheu
2011-07-27 12:55   ` Michael Holzheu
2011-08-01 20:41   ` Vivek Goyal
2011-08-01 20:41     ` Vivek Goyal
2011-08-02  8:37     ` Michael Holzheu
2011-08-02  8:37       ` Michael Holzheu
2011-08-02 19:21       ` Vivek Goyal
2011-08-02 19:21         ` Vivek Goyal
2011-08-03  9:50         ` Michael Holzheu
2011-08-03  9:50           ` Michael Holzheu
2011-08-04 21:14           ` Vivek Goyal
2011-08-04 21:14             ` Vivek Goyal
2011-08-08 17:47             ` Michael Holzheu
2011-08-08 17:47               ` Michael Holzheu
2011-08-09 21:19               ` Vivek Goyal
2011-08-09 21:19                 ` Vivek Goyal
2011-07-27 12:55 ` [patch v2 05/10] s390: Add PSW restart shutdown trigger Michael Holzheu
2011-07-27 12:55   ` Michael Holzheu
2011-08-01 20:54   ` Vivek Goyal
2011-08-01 20:54     ` Vivek Goyal
2011-08-02  8:05     ` Michael Holzheu
2011-08-02  8:05       ` Michael Holzheu
2011-07-27 12:55 ` [patch v2 06/10] s390: Export store_status() function Michael Holzheu
2011-07-27 12:55   ` Michael Holzheu
2011-07-27 12:55 ` [patch v2 07/10] s390: Use diagnose 308 for system reset Michael Holzheu
2011-07-27 12:55   ` Michael Holzheu
2011-07-27 12:55 ` [patch v2 08/10] s390: Add real memory access functions Michael Holzheu
2011-07-27 12:55   ` Michael Holzheu
2011-07-27 12:55 ` [patch v2 09/10] s390: kdump backend code Michael Holzheu
2011-07-27 12:55   ` Michael Holzheu
2011-07-27 12:55 ` [patch v2 10/10] kexec-tools: Add s390 kdump support Michael Holzheu
2011-07-27 12:55   ` Michael Holzheu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.