Skip to contentSkip to conversation

kdump: Patch series for s390 support (version 2)

PATCH Superseded Michael Holzheu 2 participants 33 messages Jul 27, 2011 – Aug 9, 2011

Subsystems (7)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

v2 cover kdump: Patch series for s390 support (version 2)

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

#1 lore raw

PATCH v2 1/10 kdump: Add KEXEC_CRASH_CONTROL_MEMORY_LIMIT

From: Michael Holzheu <[email protected]>

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.

---
 include/linux/kexec.h |    4 ++++
 kernel/kexec.c        |    2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)
include/linux/kexec.h +4 -0
@@ -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)
kernel/kexec.c +1 -1
@@ -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;
#2 lore raw

Re: [patch v2 01/10] kdump: Add KEXEC_CRASH_CONTROL_MEMORY_LIMIT

Quoted 7 lines · Michael Holzheu

From: Michael Holzheu <[email protected]>

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

Quoted 31 lines
---
 include/linux/kexec.h |    4 ++++
 kernel/kexec.c        |    2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)
include/linux/kexec.h +4 -0
@@ -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)
kernel/kexec.c +1 -1
@@ -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;
#3 lore raw

Re: [patch v2 01/10] kdump: Add KEXEC_CRASH_CONTROL_MEMORY_LIMIT

Hello Vivek,

Quoted 9 lines · Vivek Goyal
Quoted 7 lines · Michael Holzheu

From: Michael Holzheu <[email protected]>

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.

Quoted 4 lines

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

#4 lore raw

Re: [patch v2 01/10] kdump: Add KEXEC_CRASH_CONTROL_MEMORY_LIMIT

Quoted 14 lines · Michael Holzheu

Hello Vivek,

Quoted 11 lines · Vivek Goyal
Quoted 7 lines · Michael Holzheu

From: Michael Holzheu <[email protected]>

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,

Quoted 7 lines
Quoted 2 lines

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

#5 lore raw

Re: [patch v2 01/10] kdump: Add KEXEC_CRASH_CONTROL_MEMORY_LIMIT

Hello Vivek,

Quoted 23 lines · Vivek Goyal
Quoted 14 lines · Michael Holzheu

Hello Vivek,

Quoted 11 lines · Vivek Goyal
Quoted 7 lines · Michael Holzheu

From: Michael Holzheu <[email protected]>

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,

Quoted 7 lines
Quoted 2 lines

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?

Quoted 8 lines

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

#6 lore raw

PATCH v2 2/10 kdump: Make kimage_load_crash_segment() weak

In reply to Michael Holzheu

From: Michael Holzheu <[email protected]>

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.

---
 kernel/kexec.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/kexec.c +2 -2
@@ -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.
#7 lore raw

Re: [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak

Quoted 30 lines · Michael Holzheu

From: Michael Holzheu <[email protected]>

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.

---
 kernel/kexec.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

kernel/kexec.c out: · line 846

Quoted 7 lines
kernel/kexec.c +2 -2
@@ -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

Quoted 3 lines
kernel/kexec.c +0 -0
 {
 	/* For crash dumps kernels we simply copy the data from
 	 * user space to it's destination.
#8 lore raw

Re: [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak

Hello Vivek,

Quoted 1 line · Vivek Goyal

On Wed, Jul 27, 2011 at 02:55:06PM +0200, Michael Holzheu wrote:

[snip]

Quoted 6 lines
Quoted 6 lines
kernel/kexec.c +0 -0
@@ -842,8 +842,8 @@ out:
 	return result;
 }
 
Quoted 7 lines

kernel/kexec.c out: · line 846

Quoted 4 lines
kernel/kexec.c +2 -2
-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

#9 lore raw

Re: [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak

Quoted 21 lines · Michael Holzheu

Hello Vivek,

Quoted 1 line · Vivek Goyal

On Wed, Jul 27, 2011 at 02:55:06PM +0200, Michael Holzheu wrote:

[snip]

Quoted 6 lines
Quoted 6 lines
kernel/kexec.c +0 -0
@@ -842,8 +842,8 @@ out:
 	return result;
 }
 
Quoted 7 lines

kernel/kexec.c out: · line 846

Quoted 4 lines
kernel/kexec.c +2 -2
-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.

Quoted 8 lines

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

#10 lore raw

Re: [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak

Quoted 24 lines · Vivek Goyal
Quoted 23 lines · Michael Holzheu

Hello Vivek,

Quoted 1 line · Vivek Goyal

On Wed, Jul 27, 2011 at 02:55:06PM +0200, Michael Holzheu wrote:

[snip]

Quoted 6 lines
Quoted 6 lines
kernel/kexec.c +0 -0
@@ -842,8 +842,8 @@ out:
 	return result;
 }
 
Quoted 7 lines

kernel/kexec.c out: · line 846

Quoted 4 lines
kernel/kexec.c +2 -2
-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:

Quoted 8 lines
Quoted 6 lines

/*
* 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

Acked-by
#11 lore raw

Re: [patch v2 02/10] kdump: Make kimage_load_crash_segment() weak

Quoted 32 lines · Michael Holzheu
Quoted 31 lines · Vivek Goyal
Quoted 29 lines · Michael Holzheu

Hello Vivek,

Quoted 1 line · Vivek Goyal

On Wed, Jul 27, 2011 at 02:55:06PM +0200, Michael Holzheu wrote:

[snip]

Quoted 6 lines
Quoted 6 lines
kernel/kexec.c +0 -0
@@ -842,8 +842,8 @@ out:
 	return result;
 }
 
Quoted 7 lines

kernel/kexec.c out: · line 846

Quoted 4 lines
kernel/kexec.c +2 -2
-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,

Quoted 4 lines
Quoted 1 line

This looks better.

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

Yes, looks good to me.

Thanks
Vivek

#12 lore raw

PATCH v2 3/10 kdump: Add size to elfcorehdr kernel parameter

In reply to Michael Holzheu

From: Michael Holzheu <[email protected]>

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.

---
 Documentation/kernel-parameters.txt |    6 +++---
 include/linux/crash_dump.h          |    1 +
 kernel/crash_dump.c                 |   11 +++++++++++
 3 files changed, 15 insertions(+), 3 deletions(-)
Documentation/kernel-parameters.txt +3 -3
@@ -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]
include/linux/crash_dump.h +1 -0
@@ -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);
kernel/crash_dump.c +11 -0
@@ -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);
#13 lore raw

Re: [patch v2 03/10] kdump: Add size to elfcorehdr kernel parameter

Quoted 10 lines · Michael Holzheu

From: Michael Holzheu <[email protected]>

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

Quoted 63 lines
---
 Documentation/kernel-parameters.txt |    6 +++---
 include/linux/crash_dump.h          |    1 +
 kernel/crash_dump.c                 |   11 +++++++++++
 3 files changed, 15 insertions(+), 3 deletions(-)
Documentation/kernel-parameters.txt +3 -3
@@ -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]
include/linux/crash_dump.h +1 -0
@@ -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);
kernel/crash_dump.c +11 -0
@@ -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);
#14 lore raw

Re: [patch v2 03/10] kdump: Add size to elfcorehdr kernel parameter

Hello Vivek,

Quoted 12 lines · Vivek Goyal
Quoted 10 lines · Michael Holzheu

From: Michael Holzheu <[email protected]>

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.

Quoted 7 lines

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

#15 lore raw

Re: [patch v2 03/10] kdump: Add size to elfcorehdr kernel parameter

Quoted 34 lines · Michael Holzheu

Hello Vivek,

Quoted 12 lines · Vivek Goyal
Quoted 10 lines · Michael Holzheu

From: Michael Holzheu <[email protected]>

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.

Quoted 7 lines

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.

Quoted 7 lines

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

#16 lore raw

Re: [patch v2 03/10] kdump: Add size to elfcorehdr kernel parameter

Hello Vivek,

Quoted 24 lines · Vivek Goyal
Quoted 23 lines · Michael Holzheu

Hello Vivek,

Quoted 7 lines

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:

Quoted 7 lines
Quoted 5 lines

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

#17 lore raw

PATCH v2 4/10 kdump: Trigger kdump via panic notifier chain on s390

In reply to Michael Holzheu

From: Michael Holzheu <[email protected]>

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.

---
 kernel/panic.c |    3 +++
 1 file changed, 3 insertions(+)
kernel/panic.c +3 -0
@@ -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);
 
#18 lore raw

Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390

Quoted 7 lines · Michael Holzheu

From: Michael Holzheu <[email protected]>

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

Quoted 21 lines
---
 kernel/panic.c |    3 +++
 1 file changed, 3 insertions(+)
kernel/panic.c +3 -0
@@ -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);
 
#19 lore raw

Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390

Hello Vivek,

Quoted 11 lines · Vivek Goyal
Quoted 7 lines · Michael Holzheu

From: Michael Holzheu <[email protected]>

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.

Quoted 4 lines

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

#20 lore raw

Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390

Quoted 29 lines · Michael Holzheu

Hello Vivek,

Quoted 11 lines · Vivek Goyal
Quoted 7 lines · Michael Holzheu

From: Michael Holzheu <[email protected]>

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.

Quoted 4 lines

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.

Quoted 5 lines

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

#21 lore raw

Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390

Hello Vivek,

Quoted 12 lines · Vivek Goyal
Quoted 11 lines

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.

Quoted 4 lines

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.

Quoted 10 lines

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

#22 lore raw

Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390

Quoted 15 lines · Michael Holzheu

Hello Vivek,

Quoted 12 lines · Vivek Goyal
Quoted 11 lines

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.

Quoted 7 lines
Quoted 4 lines

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()

Quoted 3 lines

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.

Quoted 12 lines
Quoted 11 lines

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".

Quoted 7 lines

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?

Quoted 2 lines

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.

Quoted 5 lines

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.

Quoted 3 lines

* 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.

Quoted 4 lines

* 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

#23 lore raw

Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390

Hello Vivek,

Quoted 1 line · Vivek Goyal

On Wed, Aug 03, 2011 at 11:50:39AM +0200, Michael Holzheu wrote:

[snip]

Quoted 8 lines
Quoted 2 lines

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.

Quoted 15 lines
Quoted 15 lines
Quoted 11 lines

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.

Quoted 6 lines
Quoted 4 lines

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.

Quoted 7 lines
Quoted 3 lines

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

#24 lore raw

Re: [patch v2 04/10] kdump: Trigger kdump via panic notifier chain on s390

Quoted 29 lines · Michael Holzheu

Hello Vivek,

Quoted 1 line · Vivek Goyal

On Wed, Aug 03, 2011 at 11:50:39AM +0200, Michael Holzheu wrote:

[snip]

Quoted 8 lines
Quoted 2 lines

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.

Quoted 3 lines

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.

Quoted 43 lines
Quoted 16 lines
Quoted 16 lines
Quoted 6 lines

like other architectures and jump to stand
alone kernel only if some piece of code is corrupted and that action failed.

Quoted 6 lines

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.

Quoted 6 lines
Quoted 4 lines

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.

Quoted 7 lines
Quoted 3 lines

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:

Quoted 7 lines

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.

Quoted 2 lines

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

#25 lore raw

PATCH v2 5/10 s390: Add PSW restart shutdown trigger

In reply to Michael Holzheu

From: Michael Holzheu <[email protected]>

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.

---
 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(-)
arch/s390/include/asm/lowcore.h +9 -2
@@ -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 */
arch/s390/include/asm/system.h +1 -0
@@ -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);				     \
arch/s390/kernel/asm-offsets.c +1 -0
@@ -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 */
arch/s390/kernel/entry.S +28 -0
@@ -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
arch/s390/kernel/entry64.S +20 -0
@@ -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
arch/s390/kernel/ipl.c +38 -1
@@ -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");
arch/s390/kernel/setup.c +23 -1
@@ -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();
arch/s390/kernel/smp.c +8 -0
@@ -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) {
arch/s390/mm/maccess.c +16 -0
@@ -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();
+}
#26 lore raw

Re: [patch v2 05/10] s390: Add PSW restart shutdown trigger

Quoted 9 lines · Michael Holzheu

From: Michael Holzheu <[email protected]>

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

Quoted 319 lines
---
 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(-)
arch/s390/include/asm/lowcore.h +9 -2
@@ -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 */
arch/s390/include/asm/system.h +1 -0
@@ -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);				     \
arch/s390/kernel/asm-offsets.c +1 -0
@@ -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 */
arch/s390/kernel/entry.S +28 -0
@@ -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
arch/s390/kernel/entry64.S +20 -0
@@ -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
arch/s390/kernel/ipl.c +38 -1
@@ -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");
arch/s390/kernel/setup.c +23 -1
@@ -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();
arch/s390/kernel/smp.c +8 -0
@@ -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) {
arch/s390/mm/maccess.c +16 -0
@@ -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();
+}
#27 lore raw

Re: [patch v2 05/10] s390: Add PSW restart shutdown trigger

Hello Vivek,

Quoted 11 lines · Vivek Goyal
Quoted 9 lines · Michael Holzheu

From: Michael Holzheu <[email protected]>

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.

Quoted 8 lines

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

#28 lore raw

PATCH v2 6/10 s390: Export store_status() function

In reply to Michael Holzheu

From: Michael Holzheu <[email protected]>

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.

---
 arch/s390/kernel/reipl64.S |   80 +++++++++++++++++++++++++++++++++------------
 1 file changed, 60 insertions(+), 20 deletions(-)
arch/s390/kernel/reipl64.S +60 -20
@@ -1,5 +1,5 @@
 /*
- *    Copyright IBM Corp 2000,2009
+ *    Copyright IBM Corp 2000,2011
  *    Author(s): Holger Smolinski <[email protected]>,
  *		 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
#29 lore raw

PATCH v2 7/10 s390: Use diagnose 308 for system reset

In reply to Michael Holzheu

From: Michael Holzheu <[email protected]>

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.

---
 arch/s390/include/asm/ipl.h |    1 +
 arch/s390/kernel/base.S     |   36 ++++++++++++++++++++++++++++++++++++
 arch/s390/kernel/ipl.c      |    6 ++++++
 3 files changed, 43 insertions(+)
arch/s390/include/asm/ipl.h +1 -0
@@ -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 */
arch/s390/kernel/base.S +36 -0
@@ -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)
arch/s390/kernel/ipl.c +6 -0
@@ -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();
 }
#30 lore raw

PATCH v2 8/10 s390: Add real memory access functions

In reply to Michael Holzheu

From: Michael Holzheu <[email protected]>

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

---
 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(-)
arch/s390/include/asm/system.h +2 -0
@@ -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);				     \
arch/s390/mm/maccess.c +57 -0

72 lines not on this page · raw message

drivers/s390/char/zcore.c +2 -18
@@ -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;
 
#31 lore raw

PATCH v2 9/10 s390: kdump backend code

In reply to Michael Holzheu

From: Michael Holzheu <[email protected]>

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

---
 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(-)
arch/s390/Kconfig +10 -0
@@ -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"
arch/s390/include/asm/ipl.h +1 -0
@@ -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 */
arch/s390/include/asm/kexec.h +4 -4
@@ -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 */
arch/s390/include/asm/sclp.h +1 -0
@@ -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 */
arch/s390/include/asm/setup.h +9 -0
@@ -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
 
arch/s390/kernel/Makefile +1 -0
@@ -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
arch/s390/kernel/crash.c +204 -2

219 lines not on this page · raw message

arch/s390/kernel/crash_dump.c new file +39 -0
@@ -0,0 +1,39 @@
+/*
+ * S390 kdump implementation
+ *
+ * Copyright IBM Corp. 2011
+ * Author(s): Michael Holzheu <[email protected]>
+ */
+
+#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;
+}
arch/s390/kernel/head.S +16 -0
@@ -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"
arch/s390/kernel/head_kdump.S new file +116 -0

116 lines not on this page · raw message

arch/s390/kernel/ipl.c +47 -1

88 lines not on this page · raw message

arch/s390/kernel/machine_kexec.c +64 -0

88 lines not on this page · raw message

arch/s390/kernel/mem_detect.c +69 -0

72 lines not on this page · raw message

arch/s390/kernel/setup.c +188 -0

236 lines not on this page · raw message

arch/s390/mm/vmem.c +3 -0
@@ -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)
#32 lore raw

PATCH v2 10/10 kexec-tools: Add s390 kdump support

In reply to Michael Holzheu

From: Michael Holzheu <[email protected]>

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.

---
 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(-)
include/elf.h +6 -2
@@ -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
kexec/arch/s390/Makefile +1 -0
@@ -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					\
kexec/arch/s390/crashdump-s390.c new file +59 -0

59 lines not on this page · raw message

kexec/arch/s390/kexec-elf-rel-s390.c +58 -8

80 lines not on this page · raw message

kexec/arch/s390/kexec-image.c +43 -18

126 lines not on this page · raw message

kexec/arch/s390/kexec-s390.c +47 -19

103 lines not on this page · raw message

kexec/arch/s390/kexec-s390.h +7 -0
@@ -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 */
purgatory/arch/s390/Makefile +3 -1
@@ -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)
 
purgatory/arch/s390/console-s390.c new file +14 -0
@@ -0,0 +1,14 @@
+/*
+ * S390 console code (currently not implemented)
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Author(s): Michael Holzheu <[email protected]>
+ */
+
+#include <purgatory.h>
+#include "unused.h"
+
+void putchar(int UNUSED(ch))
+{
+}
purgatory/arch/s390/purgatory-s390.c new file +17 -0
@@ -0,0 +1,17 @@
+/*
+ * S390 purgatory
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Author(s): Michael Holzheu <[email protected]>
+ */
+
+unsigned long kdump_psw_addr = 0;
+
+void setup_arch(void)
+{
+}
+
+void post_verification_setup_arch(void)
+{
+}
purgatory/arch/s390/setup-s390.S new file +35 -0
@@ -0,0 +1,35 @@
+/*
+ * Purgatory setup code
+ *
+ * Copyright IBM Corp. 2011
+ *
+ * Author(s): Michael Holzheu <[email protected]>
+ */
+
+	.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