Discussion:
[PATCH v4 01/11] crashdump/arm: Add get_crash_kernel_load_range() function
Eric DeVolder
2017-02-14 21:09:13 UTC
Permalink
From: Daniel Kiper <***@oracle.com>

Implement get_crash_kernel_load_range() in support of
print crash kernel region size option.

Signed-off-by: Daniel Kiper <***@oracle.com>
Signed-off-by: Eric DeVolder <***@oracle.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
v4: Incorporated feedback:
- no changes for this arch
v3: Incorporated feedback:
- changes for coding convention and formatting
- restructured to introduce get_crash_kernel_load_range() for each
architecture, and then a single function in kexec/kexec.c to call
the per-architecture get_crash_kernel_load_range() and print the
result.
- print_crashkernel_region_size() changed to get_crash_kernel_load_range()
v2: Incorporated feedback:
- no changes for this arch
v1: Posted to kexec-tools mailing list
---
kexec/arch/arm/crashdump-arm.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/kexec/arch/arm/crashdump-arm.c b/kexec/arch/arm/crashdump-arm.c
index 4a89b5e..ac76e0a 100644
--- a/kexec/arch/arm/crashdump-arm.c
+++ b/kexec/arch/arm/crashdump-arm.c
@@ -413,3 +413,8 @@ int is_crashkernel_mem_reserved(void)

return crash_kernel_mem.start != crash_kernel_mem.end;
}
+
+int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
+{
+ return parse_iomem_single("Crash kernel\n", start, end);
+}
--
2.7.4
Eric DeVolder
2017-02-14 21:09:18 UTC
Permalink
From: Daniel Kiper <***@oracle.com>

Implement get_crash_kernel_load_range() in support of
print crash kernel region size option.

Signed-off-by: Daniel Kiper <***@oracle.com>
Signed-off-by: Eric DeVolder <***@oracle.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
v4: Incorporated feedback:
- no changes for this arch
v3: Incorporated feedback:
- changes for coding convention and formatting
- restructured to introduce get_crash_kernel_load_range() for each
architecture, and then a single function in kexec/kexec.c to call
the per-architecture get_crash_kernel_load_range() and print the
result.
- print_crashkernel_region_size() changed to get_crash_kernel_load_range()
v2: Incorporated feedback:
- no changes for this arch
v1: Posted to kexec-tools mailing list
---
kexec/arch/mips/crashdump-mips.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/kexec/arch/mips/crashdump-mips.c b/kexec/arch/mips/crashdump-mips.c
index d6cff5a..9c33599 100644
--- a/kexec/arch/mips/crashdump-mips.c
+++ b/kexec/arch/mips/crashdump-mips.c
@@ -385,3 +385,7 @@ int is_crashkernel_mem_reserved(void)
(start != end) : 0;
}

+int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
+{
+ return parse_iomem_single("Crash kernel\n", start, end);
+}
--
2.7.4
Eric DeVolder
2017-02-14 21:09:21 UTC
Permalink
From: Daniel Kiper <***@oracle.com>

Implement get_crash_kernel_load_range() in support of
print crash kernel region size option.

Signed-off-by: Daniel Kiper <***@oracle.com>
Signed-off-by: Eric DeVolder <***@oracle.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
v4: Incorporated feedback:
- no changes for this arch
v3: Incorporated feedback:
- changes for coding convention and formatting
- restructured to introduce get_crash_kernel_load_range() for each
architecture, and then a single function in kexec/kexec.c to call
the per-architecture get_crash_kernel_load_range() and print the
result.
- print_crashkernel_region_size() changed to get_crash_kernel_load_range()
v2: Incorporated feedback:
- no changes for this arch
v1: Posted to kexec-tools mailing list
---
kexec/arch/s390/kexec-s390.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/kexec/arch/s390/kexec-s390.c b/kexec/arch/s390/kexec-s390.c
index 074575e..f863483 100644
--- a/kexec/arch/s390/kexec-s390.c
+++ b/kexec/arch/s390/kexec-s390.c
@@ -262,3 +262,8 @@ int is_crashkernel_mem_reserved(void)
return parse_iomem_single("Crash kernel\n", &start, &end) == 0 ?
(start != end) : 0;
}
+
+int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
+{
+ return parse_iomem_single("Crash kernel\n", start, end);
+}
--
2.7.4
Eric DeVolder
2017-02-14 21:09:22 UTC
Permalink
From: Daniel Kiper <***@oracle.com>

Implement get_crash_kernel_load_range() in support of
print crash kernel region size option.

Signed-off-by: Daniel Kiper <***@oracle.com>
Signed-off-by: Eric DeVolder <***@oracle.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
v4: Incorporated feedback:
- no changes for this arch
v3: Incorporated feedback:
- changes for coding convention and formatting
- restructured to introduce get_crash_kernel_load_range() for each
architecture, and then a single function in kexec/kexec.c to call
the per-architecture get_crash_kernel_load_range() and print the
result.
- print_crashkernel_region_size() changed to get_crash_kernel_load_range()
v2: Incorporated feedback:
- no changes for this arch
v1: Posted to kexec-tools mailing list
---
kexec/arch/sh/crashdump-sh.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/kexec/arch/sh/crashdump-sh.c b/kexec/arch/sh/crashdump-sh.c
index 9e6af6b..aa25dea 100644
--- a/kexec/arch/sh/crashdump-sh.c
+++ b/kexec/arch/sh/crashdump-sh.c
@@ -178,3 +178,8 @@ int is_crashkernel_mem_reserved(void)
return parse_iomem_single("Crash kernel\n", &start, &end) == 0 ?
(start != end) : 0;
}
+
+int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
+{
+ return parse_iomem_single("Crash kernel\n", start, end);
+}
--
2.7.4
Eric DeVolder
2017-02-14 21:09:15 UTC
Permalink
From: Daniel Kiper <***@oracle.com>

Provide stub get_crash_kernel_load_range() in support of
print crash kernel region size option.

Signed-off-by: Daniel Kiper <***@oracle.com>
Signed-off-by: Eric DeVolder <***@oracle.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
v4: Incorporated feedback:
- Changed commit description to make it clear that
get_crash_kernel_load_range() is a stub
v3: Incorporated feedback:
- changes for coding convention and formatting
- restructured to introduce get_crash_kernel_load_range() for each
architecture, and then a single function in kexec/kexec.c to call
the per-architecture get_crash_kernel_load_range() and print the
result.
v2: Incorporated feedback:
- unsupported architectures, print appropriate message
v1: Posted to kexec-tools mailing list
---
kexec/arch/cris/kexec-cris.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/kexec/arch/cris/kexec-cris.c b/kexec/arch/cris/kexec-cris.c
index 4ac2f89..3b69709 100644
--- a/kexec/arch/cris/kexec-cris.c
+++ b/kexec/arch/cris/kexec-cris.c
@@ -77,6 +77,12 @@ int is_crashkernel_mem_reserved(void)
return 0;
}

+int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
+{
+ /* Crash kernel region size is not exposed by the system */
+ return -1;
+}
+
unsigned long virt_to_phys(unsigned long addr)
{
return (addr) & 0x7fffffff;
--
2.7.4
Eric DeVolder
2017-02-14 21:09:19 UTC
Permalink
From: Daniel Kiper <***@oracle.com>

Implement get_crash_kernel_load_range() in support of
print crash kernel region size option.

Signed-off-by: Daniel Kiper <***@oracle.com>
Signed-off-by: Eric DeVolder <***@oracle.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
v4: Incorporated feedback:
- changes for coding convention and formatting
v3: Incorporated feedback:
- changes for coding convention and formatting
- restructured to introduce get_crash_kernel_load_range() for each
architecture, and then a single function in kexec/kexec.c to call
the per-architecture get_crash_kernel_load_range() and print the
result.
- changed print_crashkernel_region_size() to get_crash_kernel_load_range()
- introduced get_devtree_value()
v2: Incorporated feedback:
- utilize the is_crashkernel_mem_reserved() function common in all archs
- utilize device-tree values to print size
v1: Posted to kexec-tools mailing list
---
kexec/arch/ppc/crashdump-powerpc.c | 27 ++++++++++++++++++++++++++-
kexec/arch/ppc/kexec-ppc.c | 28 ++++++++++++++++++++++++++++
kexec/arch/ppc/kexec-ppc.h | 1 +
3 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/kexec/arch/ppc/crashdump-powerpc.c b/kexec/arch/ppc/crashdump-powerpc.c
index 3dc35eb..186005c 100644
--- a/kexec/arch/ppc/crashdump-powerpc.c
+++ b/kexec/arch/ppc/crashdump-powerpc.c
@@ -16,6 +16,9 @@
#include "kexec-ppc.h"
#include "crashdump-powerpc.h"

+#define DEVTREE_CRASHKERNEL_BASE "/proc/device-tree/chosen/linux,crashkernel-base"
+#define DEVTREE_CRASHKERNEL_SIZE "/proc/device-tree/chosen/linux,crashkernel-size"
+
#ifdef CONFIG_PPC64
static struct crash_elf_info elf_info64 = {
class: ELFCLASS64,
@@ -397,11 +400,33 @@ void add_usable_mem_rgns(unsigned long long base, unsigned long long size)
usablemem_rgns.size, base, size);
}

+int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
+{
+ unsigned long long value;
+ int ret = 0;
+
+ if (!get_devtree_value(DEVTREE_CRASHKERNEL_BASE, &value))
+ *start = value;
+ else {
+ *start = 0;
+ ret = -1;
+ }
+
+ if (!get_devtree_value(DEVTREE_CRASHKERNEL_SIZE, &value))
+ *end = *start + value - 1;
+ else {
+ *end = 0;
+ ret = -1;
+ }
+
+ return ret;
+}
+
int is_crashkernel_mem_reserved(void)
{
int fd;

- fd = open("/proc/device-tree/chosen/linux,crashkernel-base", O_RDONLY);
+ fd = open(DEVTREE_CRASHKERNEL_BASE, O_RDONLY);
if (fd < 0)
return 0;
close(fd);
diff --git a/kexec/arch/ppc/kexec-ppc.c b/kexec/arch/ppc/kexec-ppc.c
index d046110..bea1bc2 100644
--- a/kexec/arch/ppc/kexec-ppc.c
+++ b/kexec/arch/ppc/kexec-ppc.c
@@ -423,6 +423,34 @@ err_out:
return -1;
}

+int get_devtree_value(const char *fname, unsigned long long *pvalue)
+{
+ /* Return 0 if fname/value valid, -1 otherwise */
+ FILE *file;
+ char buf[MAXBYTES];
+ int ret = 0, n = -1;
+ unsigned long long value = 0;
+
+ if ((file = fopen(fname, "r"))) {
+ n = fread(buf, 1, MAXBYTES, file);
+ fclose(file);
+ }
+
+ if (n == sizeof(uint32_t))
+ value = ((uint32_t *)buf)[0];
+ else if (n == sizeof(uint64_t))
+ value = ((uint64_t *)buf)[0];
+ else {
+ fprintf(stderr, "%s node has invalid size: %d\n", fname, n);
+ ret = -1;
+ }
+
+ if (pvalue)
+ *pvalue = value;
+
+ return ret;
+}
+
/* Get devtree details and create exclude_range array
* Also create usablemem_ranges for KEXEC_ON_CRASH
*/
diff --git a/kexec/arch/ppc/kexec-ppc.h b/kexec/arch/ppc/kexec-ppc.h
index 904cf48..f8fd678 100644
--- a/kexec/arch/ppc/kexec-ppc.h
+++ b/kexec/arch/ppc/kexec-ppc.h
@@ -75,6 +75,7 @@ extern unsigned long dt_address_cells, dt_size_cells;
extern int init_memory_region_info(void);
extern int read_memory_region_limits(int fd, unsigned long long *start,
unsigned long long *end);
+extern int get_devtree_value(const char *fname, unsigned long long *pvalue);
#define COMMAND_LINE_SIZE 512 /* from kernel */
/*fs2dt*/
void reserve(unsigned long long where, unsigned long long length);
--
2.7.4
Daniel Kiper
2017-02-14 22:29:29 UTC
Permalink
Post by Eric DeVolder
Implement get_crash_kernel_load_range() in support of
print crash kernel region size option.
---
- changes for coding convention and formatting
- changes for coding convention and formatting
- restructured to introduce get_crash_kernel_load_range() for each
architecture, and then a single function in kexec/kexec.c to call
the per-architecture get_crash_kernel_load_range() and print the
result.
- changed print_crashkernel_region_size() to get_crash_kernel_load_range()
- introduced get_devtree_value()
- utilize the is_crashkernel_mem_reserved() function common in all archs
- utilize device-tree values to print size
v1: Posted to kexec-tools mailing list
---
kexec/arch/ppc/crashdump-powerpc.c | 27 ++++++++++++++++++++++++++-
kexec/arch/ppc/kexec-ppc.c | 28 ++++++++++++++++++++++++++++
kexec/arch/ppc/kexec-ppc.h | 1 +
3 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/kexec/arch/ppc/crashdump-powerpc.c b/kexec/arch/ppc/crashdump-powerpc.c
index 3dc35eb..186005c 100644
--- a/kexec/arch/ppc/crashdump-powerpc.c
+++ b/kexec/arch/ppc/crashdump-powerpc.c
@@ -16,6 +16,9 @@
#include "kexec-ppc.h"
#include "crashdump-powerpc.h"
+#define DEVTREE_CRASHKERNEL_BASE "/proc/device-tree/chosen/linux,crashkernel-base"
+#define DEVTREE_CRASHKERNEL_SIZE "/proc/device-tree/chosen/linux,crashkernel-size"
+
#ifdef CONFIG_PPC64
static struct crash_elf_info elf_info64 = {
class: ELFCLASS64,
@@ -397,11 +400,33 @@ void add_usable_mem_rgns(unsigned long long base, unsigned long long size)
usablemem_rgns.size, base, size);
}
+int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
+{
+ unsigned long long value;
+ int ret = 0;
+
+ if (!get_devtree_value(DEVTREE_CRASHKERNEL_BASE, &value))
+ *start = value;
+ else {
+ *start = 0;
I have a feeling that this is not needed. If it is true then we can also
drop curly brackets and leave just ret assignment only.
Post by Eric DeVolder
+ ret = -1;
+ }
+
+ if (!get_devtree_value(DEVTREE_CRASHKERNEL_SIZE, &value))
+ *end = *start + value - 1;
+ else {
+ *end = 0;
Ditto.

IIRC, same thing applies to ppc64.

Daniel
Eric DeVolder
2017-02-14 21:09:14 UTC
Permalink
Provide stub get_crash_kernel_load_range() in support of
print crash kernel region size option.

Signed-off-by: Eric DeVolder <***@oracle.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
v4: Incorporated feedback:
- Changed commit description to make it clear that
get_crash_kernel_load_range() is a stub
v3: Incorporated feedback:
- changes for coding convention and formatting
- restructured to introduce get_crash_kernel_load_range() for each
architecture, and then a single function in kexec/kexec.c to call
the per-architecture get_crash_kernel_load_range() and print the
result.
v2: Incorporated feedback:
- unsupported architectures, print appropriate message
v1: Posted to kexec-tools mailing list
---
kexec/arch/arm64/crashdump-arm64.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c
index d2272c8..b0e4713 100644
--- a/kexec/arch/arm64/crashdump-arm64.c
+++ b/kexec/arch/arm64/crashdump-arm64.c
@@ -19,3 +19,9 @@ int is_crashkernel_mem_reserved(void)
{
return 0;
}
+
+int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
+{
+ /* Crash kernel region size is not exposed by the system */
+ return -1;
+}
--
2.7.4
Eric DeVolder
2017-02-14 21:09:16 UTC
Permalink
From: Daniel Kiper <***@oracle.com>

Implement get_crash_kernel_load_range() in support of
print crash kernel region size option.

Signed-off-by: Daniel Kiper <***@oracle.com>
Signed-off-by: Eric DeVolder <***@oracle.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
v4: Incorporated feedback:
- no changes for this arch
v3: Incorporated feedback:
- changes for coding convention and formatting
- restructured to introduce get_crash_kernel_load_range() for each
architecture, and then a single function in kexec/kexec.c to call
the per-architecture get_crash_kernel_load_range() and print the
result.
- print_crashkernel_region_size() changed to get_crash_kernel_load_range()
v2: Incorporated feedback:
- no changes for this arch
v1: Posted to kexec-tools mailing list
---
kexec/arch/ia64/crashdump-ia64.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/kexec/arch/ia64/crashdump-ia64.c b/kexec/arch/ia64/crashdump-ia64.c
index 726c9f4..755ee5e 100644
--- a/kexec/arch/ia64/crashdump-ia64.c
+++ b/kexec/arch/ia64/crashdump-ia64.c
@@ -286,3 +286,8 @@ int is_crashkernel_mem_reserved(void)
return parse_iomem_single("Crash kernel\n", &start,
&end) == 0 ? (start != end) : 0;
}
+
+int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
+{
+ return parse_iomem_single("Crash kernel\n", start, end);
+}
--
2.7.4
Eric DeVolder
2017-02-14 21:09:17 UTC
Permalink
From: Daniel Kiper <***@oracle.com>

Provide stub get_crash_kernel_load_range() in support of
print crash kernel region size option.

Signed-off-by: Daniel Kiper <***@oracle.com>
Signed-off-by: Eric DeVolder <***@oracle.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
v4: Incorporated feedback:
- Changed commit description to make it clear that
get_crash_kernel_load_range() is a stub
v3: Incorporated feedback:
- changes for coding convention and formatting
- restructured to introduce get_crash_kernel_load_range() for each
architecture, and then a single function in kexec/kexec.c to call
the per-architecture get_crash_kernel_load_range() and print the
result.
v2: Incorporated feedback:
- unsupported architectures, print appropriate message
v1: Posted to kexec-tools mailing list
---
kexec/arch/m68k/kexec-m68k.c | 6 ++++++
1 file changed, 6 insertions(+)

diff --git a/kexec/arch/m68k/kexec-m68k.c b/kexec/arch/m68k/kexec-m68k.c
index 372aa37..cb54927 100644
--- a/kexec/arch/m68k/kexec-m68k.c
+++ b/kexec/arch/m68k/kexec-m68k.c
@@ -89,6 +89,12 @@ int is_crashkernel_mem_reserved(void)
return 0;
}

+int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
+{
+ /* Crash kernel region size is not exposed by the system */
+ return -1;
+}
+
unsigned long virt_to_phys(unsigned long addr)
{
return addr + m68k_memoffset;
--
2.7.4
Eric DeVolder
2017-02-14 21:09:23 UTC
Permalink
From: Daniel Kiper <***@oracle.com>

Crash kernel region size is available via sysfs on Linux running on
bare metal. However, this does not work when Linux runs as Xen dom0.
In this case Xen crash kernel region size should be established using
__HYPERVISOR_kexec_op hypercall (Linux kernel kexec functionality does
not make a lot of sense in Xen dom0). Sadly hypercalls are not easily
accessible using shell scripts or something like that. Potentially we
can check "xl dmesg" output for crashkernel option but this is not nice.
So, let's add this functionality, for Linux running on bare metal and
as Xen dom0, to kexec-tools. This way kdump scripts may establish crash
kernel region size in one way regardless of platform. All burden of
platform detection lies on kexec-tools.

Figure (and unit) displayed by this new kexec-tools functionality is
the same as one taken from /sys/kernel/kexec_crash_size.

Signed-off-by: Daniel Kiper <***@oracle.com>
Signed-off-by: Eric DeVolder <***@oracle.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
v4: Incorporated feedback:
- changes for coding convention and formatting
- Changed commit description to make it clear that
get_crash_kernel_load_range() is a stub on some archs
v3: Incorporated feedback:
- changes for coding convention and formatting
- restructured to introduce get_crash_kernel_load_range() for each
architecture, and then a single function in kexec/kexec.c to call
the per-architecture get_crash_kernel_load_range() and print the
result.
v2: Incorporated feedback:
- utilize the is_crashkernel_mem_reserved() function common in all archs
- for ppc and ppc64, utilize device-tree values to print size
- for unsupported architectures, print appropriate message
v1: Posted to kexec-tools mailing list
---
kexec/kexec.8 | 3 +++
kexec/kexec.c | 19 +++++++++++++++++++
kexec/kexec.h | 4 +++-
3 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/kexec/kexec.8 b/kexec/kexec.8
index f4b39a6..e0131b4 100644
--- a/kexec/kexec.8
+++ b/kexec/kexec.8
@@ -179,6 +179,9 @@ Load a helper image to jump back to original kernel.
.TP
.BI \-\-reuseinitrd
Reuse initrd from first boot.
+.TP
+.BI \-\-print-ckr-size
+Print crash kernel region size, if available.


.SH SUPPORTED KERNEL FILE TYPES AND OPTIONS
diff --git a/kexec/kexec.c b/kexec/kexec.c
index a2ba79d..eccd988 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -995,6 +995,7 @@ void usage(void)
" --mem-max=<addr> Specify the highest memory address to\n"
" load code into.\n"
" --reuseinitrd Reuse initrd from first boot.\n"
+ " --print-ckr-size Print crash kernel region size.\n"
" --load-preserve-context Load the new kernel and preserve\n"
" context of current kernel during kexec.\n"
" --load-jump-back-helper Load a helper image to jump back\n"
@@ -1218,6 +1219,21 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
return ret;
}

+static void print_crashkernel_region_size(void)
+{
+ uint64_t start = 0, end = 0;
+
+ if (is_crashkernel_mem_reserved() &&
+ get_crash_kernel_load_range(&start, &end)) {
+ fprintf(stderr, "get_crash_kernel_load_range() failed.\n");
+ return;
+ }
+
+ if (start != end)
+ printf("%lu\n", end - start + 1);
+ else
+ printf("0\n");
+}

int main(int argc, char *argv[])
{
@@ -1375,6 +1391,9 @@ int main(int argc, char *argv[])
case OPT_STATUS:
do_status = 1;
break;
+ case OPT_PRINT_CKR_SIZE:
+ print_crashkernel_region_size();
+ return 0;
default:
break;
}
diff --git a/kexec/kexec.h b/kexec/kexec.h
index 2b06f59..52bef9b 100644
--- a/kexec/kexec.h
+++ b/kexec/kexec.h
@@ -226,7 +226,8 @@ extern int file_types;
#define OPT_LOAD_PRESERVE_CONTEXT 259
#define OPT_LOAD_JUMP_BACK_HELPER 260
#define OPT_ENTRY 261
-#define OPT_MAX 262
+#define OPT_PRINT_CKR_SIZE 262
+#define OPT_MAX 263
#define KEXEC_OPTIONS \
{ "help", 0, 0, OPT_HELP }, \
{ "version", 0, 0, OPT_VERSION }, \
@@ -247,6 +248,7 @@ extern int file_types;
{ "kexec-file-syscall", 0, 0, OPT_KEXEC_FILE_SYSCALL }, \
{ "debug", 0, 0, OPT_DEBUG }, \
{ "status", 0, 0, OPT_STATUS }, \
+ { "print-ckr-size", 0, 0, OPT_PRINT_CKR_SIZE }, \

#define KEXEC_OPT_STR "h?vdfxyluet:psS"
--
2.7.4
Daniel Kiper
2017-02-14 22:34:21 UTC
Permalink
Post by Eric DeVolder
Crash kernel region size is available via sysfs on Linux running on
bare metal. However, this does not work when Linux runs as Xen dom0.
In this case Xen crash kernel region size should be established using
__HYPERVISOR_kexec_op hypercall (Linux kernel kexec functionality does
not make a lot of sense in Xen dom0). Sadly hypercalls are not easily
accessible using shell scripts or something like that. Potentially we
can check "xl dmesg" output for crashkernel option but this is not nice.
So, let's add this functionality, for Linux running on bare metal and
as Xen dom0, to kexec-tools. This way kdump scripts may establish crash
kernel region size in one way regardless of platform. All burden of
platform detection lies on kexec-tools.
Figure (and unit) displayed by this new kexec-tools functionality is
the same as one taken from /sys/kernel/kexec_crash_size.
---
- changes for coding convention and formatting
- Changed commit description to make it clear that
get_crash_kernel_load_range() is a stub on some archs
- changes for coding convention and formatting
- restructured to introduce get_crash_kernel_load_range() for each
architecture, and then a single function in kexec/kexec.c to call
the per-architecture get_crash_kernel_load_range() and print the
result.
- utilize the is_crashkernel_mem_reserved() function common in all archs
- for ppc and ppc64, utilize device-tree values to print size
- for unsupported architectures, print appropriate message
v1: Posted to kexec-tools mailing list
---
kexec/kexec.8 | 3 +++
kexec/kexec.c | 19 +++++++++++++++++++
kexec/kexec.h | 4 +++-
3 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/kexec/kexec.8 b/kexec/kexec.8
index f4b39a6..e0131b4 100644
--- a/kexec/kexec.8
+++ b/kexec/kexec.8
@@ -179,6 +179,9 @@ Load a helper image to jump back to original kernel.
.TP
.BI \-\-reuseinitrd
Reuse initrd from first boot.
+.TP
+.BI \-\-print-ckr-size
+Print crash kernel region size, if available.
.SH SUPPORTED KERNEL FILE TYPES AND OPTIONS
diff --git a/kexec/kexec.c b/kexec/kexec.c
index a2ba79d..eccd988 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -995,6 +995,7 @@ void usage(void)
" --mem-max=<addr> Specify the highest memory address to\n"
" load code into.\n"
" --reuseinitrd Reuse initrd from first boot.\n"
+ " --print-ckr-size Print crash kernel region size.\n"
" --load-preserve-context Load the new kernel and preserve\n"
" context of current kernel during kexec.\n"
" --load-jump-back-helper Load a helper image to jump back\n"
@@ -1218,6 +1219,21 @@ static int do_kexec_file_load(int fileind, int argc, char **argv,
return ret;
}
+static void print_crashkernel_region_size(void)
+{
+ uint64_t start = 0, end = 0;
+
+ if (is_crashkernel_mem_reserved() &&
+ get_crash_kernel_load_range(&start, &end)) {
get_crash_kernel_load_range() call should start in the same
column as is_crashkernel_mem_reserved() call starts.

So, we should have:

if (is_crashkernel_mem_reserved() &&
get_crash_kernel_load_range(&start, &end)) {
Post by Eric DeVolder
+ fprintf(stderr, "get_crash_kernel_load_range() failed.\n");
+ return;
Please just only two tabs.

Daniel

Eric DeVolder
2017-02-14 21:09:20 UTC
Permalink
From: Daniel Kiper <***@oracle.com>

Implement get_crash_kernel_load_range() in support of
print crash kernel region size option.

Signed-off-by: Daniel Kiper <***@oracle.com>
Signed-off-by: Eric DeVolder <***@oracle.com>
Reviewed-by: Daniel Kiper <***@oracle.com>
---
v4: Incorporated feedback:
- changes for coding convention and formatting
v3: Incorporated feedback:
- changes for coding convention and formatting
- restructured to introduce get_crash_kernel_load_range() for each
architecture, and then a single function in kexec/kexec.c to call
the per-architecture get_crash_kernel_load_range() and print the
result.
- changed print_crashkernel_region_size() to get_crash_kernel_load_range()
- introduced get_devtree_value()
v2: Incorporated feedback:
- utilize the is_crashkernel_mem_reserved() function common in all archs
- utilize device-tree values to print size
v1: Posted to kexec-tools mailing list
---
kexec/arch/ppc64/crashdump-ppc64.c | 27 ++++++++++++++++++++++++++-
kexec/arch/ppc64/kexec-ppc64.c | 28 ++++++++++++++++++++++++++++
kexec/arch/ppc64/kexec-ppc64.h | 2 ++
3 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/kexec/arch/ppc64/crashdump-ppc64.c b/kexec/arch/ppc64/crashdump-ppc64.c
index f62b159..3d7565d 100644
--- a/kexec/arch/ppc64/crashdump-ppc64.c
+++ b/kexec/arch/ppc64/crashdump-ppc64.c
@@ -36,6 +36,9 @@
#include "../../fs2dt.h"
#include "crashdump-ppc64.h"

+#define DEVTREE_CRASHKERNEL_BASE "/proc/device-tree/chosen/linux,crashkernel-base"
+#define DEVTREE_CRASHKERNEL_SIZE "/proc/device-tree/chosen/linux,crashkernel-size"
+
static struct crash_elf_info elf_info64 =
{
class: ELFCLASS64,
@@ -526,11 +529,33 @@ void add_usable_mem_rgns(unsigned long long base, unsigned long long size)
usablemem_rgns.size, base, size);
}

+int get_crash_kernel_load_range(uint64_t *start, uint64_t *end)
+{
+ unsigned long long value;
+ int ret = 0;
+
+ if (!get_devtree_value(DEVTREE_CRASHKERNEL_BASE, &value))
+ *start = value;
+ else {
+ *start = 0;
+ ret = -1;
+ }
+
+ if (!get_devtree_value(DEVTREE_CRASHKERNEL_SIZE, &value))
+ *end = *start + value - 1;
+ else {
+ *end = 0;
+ ret = -1;
+ }
+
+ return ret;
+}
+
int is_crashkernel_mem_reserved(void)
{
int fd;

- fd = open("/proc/device-tree/chosen/linux,crashkernel-base", O_RDONLY);
+ fd = open(DEVTREE_CRASHKERNEL_BASE, O_RDONLY);
if (fd < 0)
return 0;
close(fd);
diff --git a/kexec/arch/ppc64/kexec-ppc64.c b/kexec/arch/ppc64/kexec-ppc64.c
index 09ee025..85c9868 100644
--- a/kexec/arch/ppc64/kexec-ppc64.c
+++ b/kexec/arch/ppc64/kexec-ppc64.c
@@ -356,6 +356,34 @@ void scan_reserved_ranges(unsigned long kexec_flags, int *range_index)
*range_index = i;
}

+int get_devtree_value(const char *fname, unsigned long long *pvalue)
+{
+ /* Return 0 if fname/value valid, -1 otherwise */
+ FILE *file;
+ char buf[MAXBYTES];
+ int ret = 0, n = -1;
+ unsigned long long value = 0;
+
+ if ((file = fopen(fname, "r"))) {
+ n = fread(buf, 1, MAXBYTES, file);
+ fclose(file);
+ }
+
+ if (n == sizeof(uint32_t))
+ value = ((uint32_t *)buf)[0];
+ else if (n == sizeof(uint64_t))
+ value = ((uint64_t *)buf)[0];
+ else {
+ fprintf(stderr, "%s node has invalid size: %d\n", fname, n);
+ ret = -1;
+ }
+
+ if (pvalue)
+ *pvalue = value;
+
+ return ret;
+}
+
/* Get devtree details and create exclude_range array
* Also create usablemem_ranges for KEXEC_ON_CRASH
*/
diff --git a/kexec/arch/ppc64/kexec-ppc64.h b/kexec/arch/ppc64/kexec-ppc64.h
index 89ee942..633ae77 100644
--- a/kexec/arch/ppc64/kexec-ppc64.h
+++ b/kexec/arch/ppc64/kexec-ppc64.h
@@ -14,6 +14,8 @@
#define HAVE_DYNAMIC_MEMORY
#define NEED_RESERVE_DTB

+extern int get_devtree_value(const char *fname, unsigned long long *pvalue);
+
int setup_memory_ranges(unsigned long kexec_flags);

int elf_ppc64_probe(const char *buf, off_t len);
--
2.7.4
Loading...