* [PATCH v2 0/3] arm64: handle "reserved" entries in /proc/iomem
@ 2019-01-11 9:59 AKASHI Takahiro
2019-01-11 9:59 ` [PATCH v2 1/3] kexec: add variant helper functions for handling memory regions AKASHI Takahiro
` (4 more replies)
0 siblings, 5 replies; 11+ messages in thread
From: AKASHI Takahiro @ 2019-01-11 9:59 UTC (permalink / raw)
To: horms, james.morse, bhsharma; +Cc: AKASHI Takahiro, kexec
# @James, @Bhupesh
# Could you kindly test this patch, please?
# I'm not quite confident that I correctly merged my patch with,
# particularly, Bhupesh's recent change.
In recent arm64 kernels, /proc/iomem has an extended file format like:
40000000-5871ffff : System RAM
41800000-426affff : Kernel code
426b0000-42aaffff : reserved
42ab0000-42c64fff : Kernel data
54400000-583fffff : Crash kernel
58590000-585effff : reserved
58700000-5871ffff : reserved
58720000-58b5ffff : reserved
58b60000-5be3ffff : System RAM
58b61000-58b61fff : reserved
59a77000-59a77fff : reserved
5be40000-5becffff : reserved
5bed0000-5bedffff : System RAM
5bee0000-5bffffff : reserved
5c000000-5fffffff : System RAM
5da00000-5e9fffff : reserved
5ec00000-5edfffff : reserved
5ef6a000-5ef6afff : reserved
5ef6b000-5efcafff : reserved
5efcd000-5efcffff : reserved
5efd0000-5effffff : reserved
5f000000-5fffffff : reserved
where "reserved" entries can be an APCI table, UEFI related code or data,
and they are expected to be preserved across kexec'ing.
With this patch[1], kexec/kdump will be allowed to handle them properly.
[1] https://git.linaro.org/people/takahiro.akashi/kexec-tools.git arm64/resv_mem
AKASHI Takahiro (3):
kexec: add variant helper functions for handling memory regions
arm64: kexec: allocate memory space avoiding reserved regions
arm64: kdump: deal with a lot of resource entries in /proc/iomem
kexec/arch/arm64/crashdump-arm64.c | 25 ++---
kexec/arch/arm64/kexec-arm64.c | 146 +++++++++++++++++------------
kexec/mem_regions.c | 42 +++++++++
kexec/mem_regions.h | 7 ++
4 files changed, 146 insertions(+), 74 deletions(-)
--
2.19.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 1/3] kexec: add variant helper functions for handling memory regions
2019-01-11 9:59 [PATCH v2 0/3] arm64: handle "reserved" entries in /proc/iomem AKASHI Takahiro
@ 2019-01-11 9:59 ` AKASHI Takahiro
2019-01-11 9:59 ` [PATCH v2 2/3] arm64: kexec: allocate memory space avoiding reserved regions AKASHI Takahiro
` (3 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: AKASHI Takahiro @ 2019-01-11 9:59 UTC (permalink / raw)
To: horms, james.morse, bhsharma; +Cc: AKASHI Takahiro, kexec
mem_regions_alloc_and_add() and mem_regions_alloc_and_exclude() are
functionally equivalent to, respectively, mem_regions_add() and
mem_regions_exclude() except the formers will re-allocate memory
dynamically when no more entries are available in 'ranges' array.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
kexec/mem_regions.c | 42 ++++++++++++++++++++++++++++++++++++++++++
kexec/mem_regions.h | 7 +++++++
2 files changed, 49 insertions(+)
diff --git a/kexec/mem_regions.c b/kexec/mem_regions.c
index 50c8abccb93a..ad7d3f13fd84 100644
--- a/kexec/mem_regions.c
+++ b/kexec/mem_regions.c
@@ -125,3 +125,45 @@ int mem_regions_exclude(struct memory_ranges *ranges,
}
return 0;
}
+
+#define KEXEC_MEMORY_RANGES 16
+
+int mem_regions_alloc_and_add(struct memory_ranges *ranges,
+ unsigned long long base,
+ unsigned long long length, int type)
+{
+ void *new_ranges;
+
+ if (ranges->size >= ranges->max_size) {
+ new_ranges = realloc(ranges->ranges,
+ sizeof(struct memory_range) *
+ (ranges->max_size + KEXEC_MEMORY_RANGES));
+ if (!new_ranges)
+ return -1;
+
+ ranges->ranges = new_ranges;
+ ranges->max_size += KEXEC_MEMORY_RANGES;
+ }
+
+ return mem_regions_add(ranges, base, length, type);
+}
+
+int mem_regions_alloc_and_exclude(struct memory_ranges *ranges,
+ const struct memory_range *range)
+{
+ void *new_ranges;
+
+ /* for safety, we should have at least one free entry in ranges */
+ if (ranges->size >= ranges->max_size) {
+ new_ranges = realloc(ranges->ranges,
+ sizeof(struct memory_range) *
+ (ranges->max_size + KEXEC_MEMORY_RANGES));
+ if (!new_ranges)
+ return -1;
+
+ ranges->ranges = new_ranges;
+ ranges->max_size += KEXEC_MEMORY_RANGES;
+ }
+
+ return mem_regions_exclude(ranges, range);
+}
diff --git a/kexec/mem_regions.h b/kexec/mem_regions.h
index ae9e972b0206..e306d67e3261 100644
--- a/kexec/mem_regions.h
+++ b/kexec/mem_regions.h
@@ -12,4 +12,11 @@ int mem_regions_exclude(struct memory_ranges *ranges,
int mem_regions_add(struct memory_ranges *ranges, unsigned long long base,
unsigned long long length, int type);
+int mem_regions_alloc_and_exclude(struct memory_ranges *ranges,
+ const struct memory_range *range);
+
+int mem_regions_alloc_and_add(struct memory_ranges *ranges,
+ unsigned long long base,
+ unsigned long long length, int type);
+
#endif
--
2.19.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 2/3] arm64: kexec: allocate memory space avoiding reserved regions
2019-01-11 9:59 [PATCH v2 0/3] arm64: handle "reserved" entries in /proc/iomem AKASHI Takahiro
2019-01-11 9:59 ` [PATCH v2 1/3] kexec: add variant helper functions for handling memory regions AKASHI Takahiro
@ 2019-01-11 9:59 ` AKASHI Takahiro
2019-12-13 20:04 ` Masayoshi Mizuma
2019-01-11 9:59 ` [PATCH v2 3/3] arm64: kdump: deal with a lot of resource entries in /proc/iomem AKASHI Takahiro
` (2 subsequent siblings)
4 siblings, 1 reply; 11+ messages in thread
From: AKASHI Takahiro @ 2019-01-11 9:59 UTC (permalink / raw)
To: horms, james.morse, bhsharma; +Cc: AKASHI Takahiro, kexec
On UEFI/ACPI-only system, some memory regions, including but not limited
to UEFI memory map and ACPI tables, must be preserved across kexec'ing.
Otherwise, they can be corrupted and result in early failure in booting
a new kernel.
In recent kernels, /proc/iomem now has an extended file format like:
40000000-5871ffff : System RAM
41800000-426affff : Kernel code
426b0000-42aaffff : reserved
42ab0000-42c64fff : Kernel data
54400000-583fffff : Crash kernel
58590000-585effff : reserved
58700000-5871ffff : reserved
58720000-58b5ffff : reserved
58b60000-5be3ffff : System RAM
58b61000-58b61fff : reserved
59a77000-59a77fff : reserved
5be40000-5becffff : reserved
5bed0000-5bedffff : System RAM
5bee0000-5bffffff : reserved
5c000000-5fffffff : System RAM
5da00000-5e9fffff : reserved
5ec00000-5edfffff : reserved
5ef6a000-5ef6afff : reserved
5ef6b000-5efcafff : reserved
5efcd000-5efcffff : reserved
5efd0000-5effffff : reserved
5f000000-5fffffff : reserved
where the "reserved" entries at the top level or under System RAM (and
its descendant resources) are ones of such kind and should not be regarded
as usable memory ranges where several free spaces for loading kexec data
will be allocated.
With this patch, get_memory_ranges() will handle this format of file
correctly. Note that, for safety, unknown regions, in addition to
"reserved" ones, will also be excluded.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
kexec/arch/arm64/kexec-arm64.c | 146 ++++++++++++++++++++-------------
1 file changed, 87 insertions(+), 59 deletions(-)
diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
index 1cde75d1a771..2e923b54f5b1 100644
--- a/kexec/arch/arm64/kexec-arm64.c
+++ b/kexec/arch/arm64/kexec-arm64.c
@@ -10,7 +10,9 @@
#include <inttypes.h>
#include <libfdt.h>
#include <limits.h>
+#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/stat.h>
#include <linux/elf-em.h>
#include <elf.h>
@@ -29,6 +31,7 @@
#include "fs2dt.h"
#include "iomem.h"
#include "kexec-syscall.h"
+#include "mem_regions.h"
#include "arch/options.h"
#define ROOT_NODE_ADDR_CELLS_DEFAULT 1
@@ -899,19 +902,33 @@ int get_phys_base_from_pt_load(unsigned long *phys_offset)
return 0;
}
+static bool to_be_excluded(char *str)
+{
+ if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) ||
+ !strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) ||
+ !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) ||
+ !strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)))
+ return false;
+ else
+ return true;
+}
+
/**
- * get_memory_ranges_iomem_cb - Helper for get_memory_ranges_iomem.
+ * get_memory_ranges - Try to get the memory ranges from
+ * /proc/iomem.
*/
-
-static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
- unsigned long long base, unsigned long long length)
+int get_memory_ranges(struct memory_range **range, int *ranges,
+ unsigned long kexec_flags)
{
- int ret;
unsigned long phys_offset = UINT64_MAX;
- struct memory_range *r;
-
- if (nr >= KEXEC_SEGMENT_MAX)
- return -1;
+ FILE *fp;
+ const char *iomem = proc_iomem();
+ char line[MAX_LINE], *str;
+ unsigned long long start, end;
+ int n, consumed;
+ struct memory_ranges memranges;
+ struct memory_range *last, excl_range;
+ int ret;
if (!try_read_phys_offset_from_kcore) {
/* Since kernel version 4.19, 'kcore' contains
@@ -945,17 +962,65 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
try_read_phys_offset_from_kcore = true;
}
- r = (struct memory_range *)data + nr;
+ fp = fopen(iomem, "r");
+ if (!fp)
+ die("Cannot open %s\n", iomem);
+
+ memranges.ranges = NULL;
+ memranges.size = memranges.max_size = 0;
+
+ while (fgets(line, sizeof(line), fp) != 0) {
+ n = sscanf(line, "%llx-%llx : %n", &start, &end, &consumed);
+ if (n != 2)
+ continue;
+ str = line + consumed;
+
+ if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM))) {
+ ret = mem_regions_alloc_and_add(&memranges,
+ start, end - start + 1, RANGE_RAM);
+ if (ret) {
+ fprintf(stderr,
+ "Cannot allocate memory for ranges\n");
+ return -ENOMEM;
+ }
- if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)))
- r->type = RANGE_RAM;
- else if (!strncmp(str, IOMEM_RESERVED, strlen(IOMEM_RESERVED)))
- r->type = RANGE_RESERVED;
- else
- return 1;
+ dbgprintf("%s:+[%d] %016llx - %016llx\n", __func__,
+ memranges.size - 1,
+ memranges.ranges[memranges.size - 1].start,
+ memranges.ranges[memranges.size - 1].end);
+ } else if (to_be_excluded(str)) {
+ if (!memranges.size)
+ continue;
+
+ /*
+ * Note: mem_regions_exclude() doesn't guarantee
+ * that the ranges are sorted out, but as long as
+ * we cope with /proc/iomem, we only operate on
+ * the last entry and so it is safe.
+ */
- r->start = base;
- r->end = base + length - 1;
+ /* The last System RAM range */
+ last = &memranges.ranges[memranges.size - 1];
+
+ if (last->end < start)
+ /* New resource outside of System RAM */
+ continue;
+ if (end < last->start)
+ /* Already excluded by parent resource */
+ continue;
+
+ excl_range.start = start;
+ excl_range.end = end;
+ mem_regions_alloc_and_exclude(&memranges, &excl_range);
+ dbgprintf("%s:- %016llx - %016llx\n",
+ __func__, start, end);
+ }
+ }
+
+ fclose(fp);
+
+ *range = memranges.ranges;
+ *ranges = memranges.size;
/* As a fallback option, we can try determining the PHYS_OFFSET
* value from the '/proc/iomem' entries as well.
@@ -976,52 +1041,15 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
* between the user-space and kernel space 'PHYS_OFFSET'
* value.
*/
- set_phys_offset(r->start, "iomem");
+ if (memranges.size)
+ set_phys_offset(memranges.ranges[0].start, "iomem");
- dbgprintf("%s: %016llx - %016llx : %s", __func__, r->start,
- r->end, str);
+ dbgprint_mem_range("System RAM ranges;",
+ memranges.ranges, memranges.size);
return 0;
}
-/**
- * get_memory_ranges_iomem - Try to get the memory ranges from
- * /proc/iomem.
- */
-
-static int get_memory_ranges_iomem(struct memory_range *array,
- unsigned int *count)
-{
- *count = kexec_iomem_for_each_line(NULL,
- get_memory_ranges_iomem_cb, array);
-
- if (!*count) {
- dbgprintf("%s: failed: No RAM found.\n", __func__);
- return EFAILED;
- }
-
- return 0;
-}
-
-/**
- * get_memory_ranges - Try to get the memory ranges some how.
- */
-
-int get_memory_ranges(struct memory_range **range, int *ranges,
- unsigned long kexec_flags)
-{
- static struct memory_range array[KEXEC_SEGMENT_MAX];
- unsigned int count;
- int result;
-
- result = get_memory_ranges_iomem(array, &count);
-
- *range = result ? NULL : array;
- *ranges = result ? 0 : count;
-
- return result;
-}
-
int arch_compat_trampoline(struct kexec_info *info)
{
return 0;
--
2.19.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v2 3/3] arm64: kdump: deal with a lot of resource entries in /proc/iomem
2019-01-11 9:59 [PATCH v2 0/3] arm64: handle "reserved" entries in /proc/iomem AKASHI Takahiro
2019-01-11 9:59 ` [PATCH v2 1/3] kexec: add variant helper functions for handling memory regions AKASHI Takahiro
2019-01-11 9:59 ` [PATCH v2 2/3] arm64: kexec: allocate memory space avoiding reserved regions AKASHI Takahiro
@ 2019-01-11 9:59 ` AKASHI Takahiro
2019-01-13 11:36 ` [PATCH v2 0/3] arm64: handle "reserved" " Bhupesh Sharma
2019-12-13 19:53 ` Masayoshi Mizuma
4 siblings, 0 replies; 11+ messages in thread
From: AKASHI Takahiro @ 2019-01-11 9:59 UTC (permalink / raw)
To: horms, james.morse, bhsharma; +Cc: AKASHI Takahiro, kexec
As described in the commit ("arm64: kexec: allocate memory space avoiding
reserved regions"), /proc/iomem now has a lot of "reserved" entries, and
it's not just enough to have a fixed size of memory range array.
With this patch, kdump is allowed to handle arbitrary number of memory
ranges, using mem_regions_alloc_and_xxx() functions.
Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
kexec/arch/arm64/crashdump-arm64.c | 25 ++++++++++---------------
1 file changed, 10 insertions(+), 15 deletions(-)
diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c
index 4fd7aa8fd43c..38d1a0f3000d 100644
--- a/kexec/arch/arm64/crashdump-arm64.c
+++ b/kexec/arch/arm64/crashdump-arm64.c
@@ -23,13 +23,8 @@
#include "kexec-elf.h"
#include "mem_regions.h"
-/* memory ranges on crashed kernel */
-static struct memory_range system_memory_ranges[CRASH_MAX_MEMORY_RANGES];
-static struct memory_ranges system_memory_rgns = {
- .size = 0,
- .max_size = CRASH_MAX_MEMORY_RANGES,
- .ranges = system_memory_ranges,
-};
+/* memory ranges of crashed kernel */
+static struct memory_ranges system_memory_rgns;
/* memory range reserved for crashkernel */
struct memory_range crash_reserved_mem;
@@ -82,7 +77,7 @@ static uint64_t get_kernel_page_offset(void)
*
* This function is called once for each memory region found in /proc/iomem.
* It locates system RAM and crashkernel reserved memory and places these to
- * variables, respectively, system_memory_ranges and crash_reserved_mem.
+ * variables, respectively, system_memory_rgns and usablemem_rgns.
*/
static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr),
@@ -90,11 +85,11 @@ static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr),
unsigned long long length)
{
if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0)
- return mem_regions_add(&usablemem_rgns,
- base, length, RANGE_RAM);
+ return mem_regions_alloc_and_add(&usablemem_rgns,
+ base, length, RANGE_RAM);
else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0)
- return mem_regions_add(&system_memory_rgns,
- base, length, RANGE_RAM);
+ return mem_regions_alloc_and_add(&system_memory_rgns,
+ base, length, RANGE_RAM);
else if (strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) == 0)
elf_info.kern_paddr_start = base;
else if (strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) == 0)
@@ -135,9 +130,9 @@ static int crash_get_memory_ranges(void)
dbgprint_mem_range("Reserved memory range", &crash_reserved_mem, 1);
- if (mem_regions_exclude(&system_memory_rgns, &crash_reserved_mem)) {
- fprintf(stderr,
- "Error: Number of crash memory ranges excedeed the max limit\n");
+ if (mem_regions_alloc_and_exclude(&system_memory_rgns,
+ &crash_reserved_mem)) {
+ fprintf(stderr, "Cannot allocate memory for ranges\n");
return -ENOMEM;
}
--
2.19.1
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH v2 0/3] arm64: handle "reserved" entries in /proc/iomem
2019-01-11 9:59 [PATCH v2 0/3] arm64: handle "reserved" entries in /proc/iomem AKASHI Takahiro
` (2 preceding siblings ...)
2019-01-11 9:59 ` [PATCH v2 3/3] arm64: kdump: deal with a lot of resource entries in /proc/iomem AKASHI Takahiro
@ 2019-01-13 11:36 ` Bhupesh Sharma
2019-12-13 19:53 ` Masayoshi Mizuma
4 siblings, 0 replies; 11+ messages in thread
From: Bhupesh Sharma @ 2019-01-13 11:36 UTC (permalink / raw)
To: AKASHI Takahiro; +Cc: kexec mailing list, Simon Horman, James Morse
Hi Akashi,
On Fri, Jan 11, 2019 at 3:29 PM AKASHI Takahiro
<takahiro.akashi@linaro.org> wrote:
>
> # @James, @Bhupesh
> # Could you kindly test this patch, please?
> # I'm not quite confident that I correctly merged my patch with,
> # particularly, Bhupesh's recent change.
I will give this a go at my end and come back with results/comments in
a day or two.
> In recent arm64 kernels, /proc/iomem has an extended file format like:
> 40000000-5871ffff : System RAM
> 41800000-426affff : Kernel code
> 426b0000-42aaffff : reserved
> 42ab0000-42c64fff : Kernel data
> 54400000-583fffff : Crash kernel
> 58590000-585effff : reserved
> 58700000-5871ffff : reserved
> 58720000-58b5ffff : reserved
> 58b60000-5be3ffff : System RAM
> 58b61000-58b61fff : reserved
> 59a77000-59a77fff : reserved
> 5be40000-5becffff : reserved
> 5bed0000-5bedffff : System RAM
> 5bee0000-5bffffff : reserved
> 5c000000-5fffffff : System RAM
> 5da00000-5e9fffff : reserved
> 5ec00000-5edfffff : reserved
> 5ef6a000-5ef6afff : reserved
> 5ef6b000-5efcafff : reserved
> 5efcd000-5efcffff : reserved
> 5efd0000-5effffff : reserved
> 5f000000-5fffffff : reserved
>
> where "reserved" entries can be an APCI table, UEFI related code or data,
> and they are expected to be preserved across kexec'ing.
> With this patch[1], kexec/kdump will be allowed to handle them properly.
>
> [1] https://git.linaro.org/people/takahiro.akashi/kexec-tools.git arm64/resv_mem
>
> AKASHI Takahiro (3):
> kexec: add variant helper functions for handling memory regions
> arm64: kexec: allocate memory space avoiding reserved regions
> arm64: kdump: deal with a lot of resource entries in /proc/iomem
>
> kexec/arch/arm64/crashdump-arm64.c | 25 ++---
> kexec/arch/arm64/kexec-arm64.c | 146 +++++++++++++++++------------
> kexec/mem_regions.c | 42 +++++++++
> kexec/mem_regions.h | 7 ++
> 4 files changed, 146 insertions(+), 74 deletions(-)
>
> --
> 2.19.1
>
Thanks,
Bhupesh
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 0/3] arm64: handle "reserved" entries in /proc/iomem
2019-01-11 9:59 [PATCH v2 0/3] arm64: handle "reserved" entries in /proc/iomem AKASHI Takahiro
` (3 preceding siblings ...)
2019-01-13 11:36 ` [PATCH v2 0/3] arm64: handle "reserved" " Bhupesh Sharma
@ 2019-12-13 19:53 ` Masayoshi Mizuma
4 siblings, 0 replies; 11+ messages in thread
From: Masayoshi Mizuma @ 2019-12-13 19:53 UTC (permalink / raw)
To: AKASHI Takahiro; +Cc: kexec, Bhupesh Sharma, Simon Horman, James Morse
Hello,
(I'm sorry if I break the mail thread...)
As Bhupesh said at:
http://lists.infradead.org/pipermail/kexec/2019-December/024142.html
Please feel free to add:
Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
Thanks!
Masa
On Fri, Jan 11, 2019 at 06:59:43PM +0900, AKASHI Takahiro wrote:
> # @James, @Bhupesh
> # Could you kindly test this patch, please?
> # I'm not quite confident that I correctly merged my patch with,
> # particularly, Bhupesh's recent change.
>
> In recent arm64 kernels, /proc/iomem has an extended file format like:
> 40000000-5871ffff : System RAM
> 41800000-426affff : Kernel code
> 426b0000-42aaffff : reserved
> 42ab0000-42c64fff : Kernel data
> 54400000-583fffff : Crash kernel
> 58590000-585effff : reserved
> 58700000-5871ffff : reserved
> 58720000-58b5ffff : reserved
> 58b60000-5be3ffff : System RAM
> 58b61000-58b61fff : reserved
> 59a77000-59a77fff : reserved
> 5be40000-5becffff : reserved
> 5bed0000-5bedffff : System RAM
> 5bee0000-5bffffff : reserved
> 5c000000-5fffffff : System RAM
> 5da00000-5e9fffff : reserved
> 5ec00000-5edfffff : reserved
> 5ef6a000-5ef6afff : reserved
> 5ef6b000-5efcafff : reserved
> 5efcd000-5efcffff : reserved
> 5efd0000-5effffff : reserved
> 5f000000-5fffffff : reserved
>
> where "reserved" entries can be an APCI table, UEFI related code or data,
> and they are expected to be preserved across kexec'ing.
> With this patch[1], kexec/kdump will be allowed to handle them properly.
>
> [1] https://git.linaro.org/people/takahiro.akashi/kexec-tools.git arm64/resv_mem
>
> AKASHI Takahiro (3):
> kexec: add variant helper functions for handling memory regions
> arm64: kexec: allocate memory space avoiding reserved regions
> arm64: kdump: deal with a lot of resource entries in /proc/iomem
>
> kexec/arch/arm64/crashdump-arm64.c | 25 ++---
> kexec/arch/arm64/kexec-arm64.c | 146 +++++++++++++++++------------
> kexec/mem_regions.c | 42 +++++++++
> kexec/mem_regions.h | 7 ++
> 4 files changed, 146 insertions(+), 74 deletions(-)
>
> --
> 2.19.1
>
>
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/3] arm64: kexec: allocate memory space avoiding reserved regions
2019-01-11 9:59 ` [PATCH v2 2/3] arm64: kexec: allocate memory space avoiding reserved regions AKASHI Takahiro
@ 2019-12-13 20:04 ` Masayoshi Mizuma
2019-12-16 5:52 ` Bhupesh Sharma
0 siblings, 1 reply; 11+ messages in thread
From: Masayoshi Mizuma @ 2019-12-13 20:04 UTC (permalink / raw)
To: AKASHI Takahiro; +Cc: kexec, Bhupesh Sharma, Simon Horman, James Morse
some nits as below:
On Fri, Jan 11, 2019 at 06:59:45PM +0900, AKASHI Takahiro wrote:
> On UEFI/ACPI-only system, some memory regions, including but not limited
> to UEFI memory map and ACPI tables, must be preserved across kexec'ing.
> Otherwise, they can be corrupted and result in early failure in booting
> a new kernel.
>
> In recent kernels, /proc/iomem now has an extended file format like:
> 40000000-5871ffff : System RAM
> 41800000-426affff : Kernel code
> 426b0000-42aaffff : reserved
> 42ab0000-42c64fff : Kernel data
> 54400000-583fffff : Crash kernel
> 58590000-585effff : reserved
> 58700000-5871ffff : reserved
> 58720000-58b5ffff : reserved
> 58b60000-5be3ffff : System RAM
> 58b61000-58b61fff : reserved
> 59a77000-59a77fff : reserved
> 5be40000-5becffff : reserved
> 5bed0000-5bedffff : System RAM
> 5bee0000-5bffffff : reserved
> 5c000000-5fffffff : System RAM
> 5da00000-5e9fffff : reserved
> 5ec00000-5edfffff : reserved
> 5ef6a000-5ef6afff : reserved
> 5ef6b000-5efcafff : reserved
> 5efcd000-5efcffff : reserved
> 5efd0000-5effffff : reserved
> 5f000000-5fffffff : reserved
>
> where the "reserved" entries at the top level or under System RAM (and
> its descendant resources) are ones of such kind and should not be regarded
> as usable memory ranges where several free spaces for loading kexec data
> will be allocated.
>
> With this patch, get_memory_ranges() will handle this format of file
> correctly. Note that, for safety, unknown regions, in addition to
> "reserved" ones, will also be excluded.
>
> Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
> ---
> kexec/arch/arm64/kexec-arm64.c | 146 ++++++++++++++++++++-------------
> 1 file changed, 87 insertions(+), 59 deletions(-)
>
> diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
> index 1cde75d1a771..2e923b54f5b1 100644
> --- a/kexec/arch/arm64/kexec-arm64.c
> +++ b/kexec/arch/arm64/kexec-arm64.c
> @@ -10,7 +10,9 @@
> #include <inttypes.h>
> #include <libfdt.h>
> #include <limits.h>
> +#include <stdio.h>
> #include <stdlib.h>
> +#include <string.h>
> #include <sys/stat.h>
> #include <linux/elf-em.h>
> #include <elf.h>
> @@ -29,6 +31,7 @@
> #include "fs2dt.h"
> #include "iomem.h"
> #include "kexec-syscall.h"
> +#include "mem_regions.h"
> #include "arch/options.h"
>
> #define ROOT_NODE_ADDR_CELLS_DEFAULT 1
> @@ -899,19 +902,33 @@ int get_phys_base_from_pt_load(unsigned long *phys_offset)
> return 0;
> }
>
> +static bool to_be_excluded(char *str)
> +{
> + if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) ||
> + !strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) ||
> + !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) ||
> + !strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)))
> + return false;
> + else
> + return true;
> +}
> +
> /**
> - * get_memory_ranges_iomem_cb - Helper for get_memory_ranges_iomem.
> + * get_memory_ranges - Try to get the memory ranges from
> + * /proc/iomem.
> */
> -
> -static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
> - unsigned long long base, unsigned long long length)
> +int get_memory_ranges(struct memory_range **range, int *ranges,
> + unsigned long kexec_flags)
> {
> - int ret;
> unsigned long phys_offset = UINT64_MAX;
> - struct memory_range *r;
> -
> - if (nr >= KEXEC_SEGMENT_MAX)
> - return -1;
> + FILE *fp;
> + const char *iomem = proc_iomem();
> + char line[MAX_LINE], *str;
> + unsigned long long start, end;
> + int n, consumed;
> + struct memory_ranges memranges;
> + struct memory_range *last, excl_range;
> + int ret;
>
> if (!try_read_phys_offset_from_kcore) {
> /* Since kernel version 4.19, 'kcore' contains
> @@ -945,17 +962,65 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
> try_read_phys_offset_from_kcore = true;
> }
>
> - r = (struct memory_range *)data + nr;
> + fp = fopen(iomem, "r");
> + if (!fp)
> + die("Cannot open %s\n", iomem);
> +
> + memranges.ranges = NULL;
> + memranges.size = memranges.max_size = 0;
> +
> + while (fgets(line, sizeof(line), fp) != 0) {
> + n = sscanf(line, "%llx-%llx : %n", &start, &end, &consumed);
> + if (n != 2)
> + continue;
> + str = line + consumed;
> +
> + if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM))) {
> + ret = mem_regions_alloc_and_add(&memranges,
> + start, end - start + 1, RANGE_RAM);
> + if (ret) {
> + fprintf(stderr,
> + "Cannot allocate memory for ranges\n");
fclose(fp);
> + return -ENOMEM;
> + }
>
> - if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)))
> - r->type = RANGE_RAM;
> - else if (!strncmp(str, IOMEM_RESERVED, strlen(IOMEM_RESERVED)))
> - r->type = RANGE_RESERVED;
> - else
> - return 1;
> + dbgprintf("%s:+[%d] %016llx - %016llx\n", __func__,
> + memranges.size - 1,
> + memranges.ranges[memranges.size - 1].start,
> + memranges.ranges[memranges.size - 1].end);
> + } else if (to_be_excluded(str)) {
> + if (!memranges.size)
> + continue;
> +
> + /*
> + * Note: mem_regions_exclude() doesn't guarantee
> + * that the ranges are sorted out, but as long as
> + * we cope with /proc/iomem, we only operate on
> + * the last entry and so it is safe.
> + */
>
> - r->start = base;
> - r->end = base + length - 1;
> + /* The last System RAM range */
> + last = &memranges.ranges[memranges.size - 1];
> +
> + if (last->end < start)
> + /* New resource outside of System RAM */
> + continue;
> + if (end < last->start)
> + /* Already excluded by parent resource */
> + continue;
> +
> + excl_range.start = start;
> + excl_range.end = end;
> + mem_regions_alloc_and_exclude(&memranges, &excl_range);
ret = mem_regions_alloc_and_exclude(&memranges, &excl_range);
if (ret) {
fprintf(stderr,
"Cannot allocate memory for ranges (exclude)\n");
fclose(fp);
return -ENOMEM;
}
Thanks,
Masa
> + dbgprintf("%s:- %016llx - %016llx\n",
> + __func__, start, end);
> + }
> + }
> +
> + fclose(fp);
> +
> + *range = memranges.ranges;
> + *ranges = memranges.size;
>
> /* As a fallback option, we can try determining the PHYS_OFFSET
> * value from the '/proc/iomem' entries as well.
> @@ -976,52 +1041,15 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
> * between the user-space and kernel space 'PHYS_OFFSET'
> * value.
> */
> - set_phys_offset(r->start, "iomem");
> + if (memranges.size)
> + set_phys_offset(memranges.ranges[0].start, "iomem");
>
> - dbgprintf("%s: %016llx - %016llx : %s", __func__, r->start,
> - r->end, str);
> + dbgprint_mem_range("System RAM ranges;",
> + memranges.ranges, memranges.size);
>
> return 0;
> }
>
> -/**
> - * get_memory_ranges_iomem - Try to get the memory ranges from
> - * /proc/iomem.
> - */
> -
> -static int get_memory_ranges_iomem(struct memory_range *array,
> - unsigned int *count)
> -{
> - *count = kexec_iomem_for_each_line(NULL,
> - get_memory_ranges_iomem_cb, array);
> -
> - if (!*count) {
> - dbgprintf("%s: failed: No RAM found.\n", __func__);
> - return EFAILED;
> - }
> -
> - return 0;
> -}
> -
> -/**
> - * get_memory_ranges - Try to get the memory ranges some how.
> - */
> -
> -int get_memory_ranges(struct memory_range **range, int *ranges,
> - unsigned long kexec_flags)
> -{
> - static struct memory_range array[KEXEC_SEGMENT_MAX];
> - unsigned int count;
> - int result;
> -
> - result = get_memory_ranges_iomem(array, &count);
> -
> - *range = result ? NULL : array;
> - *ranges = result ? 0 : count;
> -
> - return result;
> -}
> -
> int arch_compat_trampoline(struct kexec_info *info)
> {
> return 0;
> --
> 2.19.1
>
>
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/3] arm64: kexec: allocate memory space avoiding reserved regions
2019-12-13 20:04 ` Masayoshi Mizuma
@ 2019-12-16 5:52 ` Bhupesh Sharma
2019-12-16 14:16 ` Masayoshi Mizuma
0 siblings, 1 reply; 11+ messages in thread
From: Bhupesh Sharma @ 2019-12-16 5:52 UTC (permalink / raw)
To: Masayoshi Mizuma
Cc: AKASHI Takahiro, Simon Horman, James Morse, kexec mailing list
Thanks Masa,
On Sat, Dec 14, 2019 at 1:34 AM Masayoshi Mizuma <msys.mizuma@gmail.com> wrote:
>
> some nits as below:
>
> On Fri, Jan 11, 2019 at 06:59:45PM +0900, AKASHI Takahiro wrote:
> > On UEFI/ACPI-only system, some memory regions, including but not limited
> > to UEFI memory map and ACPI tables, must be preserved across kexec'ing.
> > Otherwise, they can be corrupted and result in early failure in booting
> > a new kernel.
> >
> > In recent kernels, /proc/iomem now has an extended file format like:
> > 40000000-5871ffff : System RAM
> > 41800000-426affff : Kernel code
> > 426b0000-42aaffff : reserved
> > 42ab0000-42c64fff : Kernel data
> > 54400000-583fffff : Crash kernel
> > 58590000-585effff : reserved
> > 58700000-5871ffff : reserved
> > 58720000-58b5ffff : reserved
> > 58b60000-5be3ffff : System RAM
> > 58b61000-58b61fff : reserved
> > 59a77000-59a77fff : reserved
> > 5be40000-5becffff : reserved
> > 5bed0000-5bedffff : System RAM
> > 5bee0000-5bffffff : reserved
> > 5c000000-5fffffff : System RAM
> > 5da00000-5e9fffff : reserved
> > 5ec00000-5edfffff : reserved
> > 5ef6a000-5ef6afff : reserved
> > 5ef6b000-5efcafff : reserved
> > 5efcd000-5efcffff : reserved
> > 5efd0000-5effffff : reserved
> > 5f000000-5fffffff : reserved
> >
> > where the "reserved" entries at the top level or under System RAM (and
> > its descendant resources) are ones of such kind and should not be regarded
> > as usable memory ranges where several free spaces for loading kexec data
> > will be allocated.
> >
> > With this patch, get_memory_ranges() will handle this format of file
> > correctly. Note that, for safety, unknown regions, in addition to
> > "reserved" ones, will also be excluded.
> >
> > Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
> > ---
> > kexec/arch/arm64/kexec-arm64.c | 146 ++++++++++++++++++++-------------
> > 1 file changed, 87 insertions(+), 59 deletions(-)
> >
> > diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
> > index 1cde75d1a771..2e923b54f5b1 100644
> > --- a/kexec/arch/arm64/kexec-arm64.c
> > +++ b/kexec/arch/arm64/kexec-arm64.c
> > @@ -10,7 +10,9 @@
> > #include <inttypes.h>
> > #include <libfdt.h>
> > #include <limits.h>
> > +#include <stdio.h>
> > #include <stdlib.h>
> > +#include <string.h>
> > #include <sys/stat.h>
> > #include <linux/elf-em.h>
> > #include <elf.h>
> > @@ -29,6 +31,7 @@
> > #include "fs2dt.h"
> > #include "iomem.h"
> > #include "kexec-syscall.h"
> > +#include "mem_regions.h"
> > #include "arch/options.h"
> >
> > #define ROOT_NODE_ADDR_CELLS_DEFAULT 1
> > @@ -899,19 +902,33 @@ int get_phys_base_from_pt_load(unsigned long *phys_offset)
> > return 0;
> > }
> >
> > +static bool to_be_excluded(char *str)
> > +{
> > + if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) ||
> > + !strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) ||
> > + !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) ||
> > + !strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)))
> > + return false;
> > + else
> > + return true;
> > +}
> > +
> > /**
> > - * get_memory_ranges_iomem_cb - Helper for get_memory_ranges_iomem.
> > + * get_memory_ranges - Try to get the memory ranges from
> > + * /proc/iomem.
> > */
> > -
> > -static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
> > - unsigned long long base, unsigned long long length)
> > +int get_memory_ranges(struct memory_range **range, int *ranges,
> > + unsigned long kexec_flags)
> > {
> > - int ret;
> > unsigned long phys_offset = UINT64_MAX;
> > - struct memory_range *r;
> > -
> > - if (nr >= KEXEC_SEGMENT_MAX)
> > - return -1;
> > + FILE *fp;
> > + const char *iomem = proc_iomem();
> > + char line[MAX_LINE], *str;
> > + unsigned long long start, end;
> > + int n, consumed;
> > + struct memory_ranges memranges;
> > + struct memory_range *last, excl_range;
> > + int ret;
> >
> > if (!try_read_phys_offset_from_kcore) {
> > /* Since kernel version 4.19, 'kcore' contains
> > @@ -945,17 +962,65 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
> > try_read_phys_offset_from_kcore = true;
> > }
> >
> > - r = (struct memory_range *)data + nr;
> > + fp = fopen(iomem, "r");
> > + if (!fp)
> > + die("Cannot open %s\n", iomem);
> > +
> > + memranges.ranges = NULL;
> > + memranges.size = memranges.max_size = 0;
> > +
> > + while (fgets(line, sizeof(line), fp) != 0) {
> > + n = sscanf(line, "%llx-%llx : %n", &start, &end, &consumed);
> > + if (n != 2)
> > + continue;
> > + str = line + consumed;
> > +
> > + if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM))) {
> > + ret = mem_regions_alloc_and_add(&memranges,
> > + start, end - start + 1, RANGE_RAM);
> > + if (ret) {
> > + fprintf(stderr,
> > + "Cannot allocate memory for ranges\n");
>
> fclose(fp);
>
> > + return -ENOMEM;
> > + }
> >
> > - if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)))
> > - r->type = RANGE_RAM;
> > - else if (!strncmp(str, IOMEM_RESERVED, strlen(IOMEM_RESERVED)))
> > - r->type = RANGE_RESERVED;
> > - else
> > - return 1;
> > + dbgprintf("%s:+[%d] %016llx - %016llx\n", __func__,
> > + memranges.size - 1,
> > + memranges.ranges[memranges.size - 1].start,
> > + memranges.ranges[memranges.size - 1].end);
> > + } else if (to_be_excluded(str)) {
> > + if (!memranges.size)
> > + continue;
> > +
> > + /*
> > + * Note: mem_regions_exclude() doesn't guarantee
> > + * that the ranges are sorted out, but as long as
> > + * we cope with /proc/iomem, we only operate on
> > + * the last entry and so it is safe.
> > + */
> >
> > - r->start = base;
> > - r->end = base + length - 1;
> > + /* The last System RAM range */
> > + last = &memranges.ranges[memranges.size - 1];
> > +
> > + if (last->end < start)
> > + /* New resource outside of System RAM */
> > + continue;
> > + if (end < last->start)
> > + /* Already excluded by parent resource */
> > + continue;
> > +
> > + excl_range.start = start;
> > + excl_range.end = end;
>
> > + mem_regions_alloc_and_exclude(&memranges, &excl_range);
> ret = mem_regions_alloc_and_exclude(&memranges, &excl_range);
> if (ret) {
> fprintf(stderr,
> "Cannot allocate memory for ranges (exclude)\n");
> fclose(fp);
> return -ENOMEM;
> }
Since this is an old thread, it would be useful for people looking at
the same, if you can add some comments/details about why you think
this nit is needed.
Also if Akashi agrees with the same, it would be better if he could
send a rebased version of the patchset (with your comments addressed),
so that the same can be picked for upstream kexec-tools cleanly.
@Akashi- Hi Akashi, Please let us know your views.
Thanks,
Bhupesh
> + dbgprintf("%s:- %016llx - %016llx\n",
> > + __func__, start, end);
> > + }
> > + }
> > +
> > + fclose(fp);
> > +
> > + *range = memranges.ranges;
> > + *ranges = memranges.size;
> >
> > /* As a fallback option, we can try determining the PHYS_OFFSET
> > * value from the '/proc/iomem' entries as well.
> > @@ -976,52 +1041,15 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
> > * between the user-space and kernel space 'PHYS_OFFSET'
> > * value.
> > */
> > - set_phys_offset(r->start, "iomem");
> > + if (memranges.size)
> > + set_phys_offset(memranges.ranges[0].start, "iomem");
> >
> > - dbgprintf("%s: %016llx - %016llx : %s", __func__, r->start,
> > - r->end, str);
> > + dbgprint_mem_range("System RAM ranges;",
> > + memranges.ranges, memranges.size);
> >
> > return 0;
> > }
> >
> > -/**
> > - * get_memory_ranges_iomem - Try to get the memory ranges from
> > - * /proc/iomem.
> > - */
> > -
> > -static int get_memory_ranges_iomem(struct memory_range *array,
> > - unsigned int *count)
> > -{
> > - *count = kexec_iomem_for_each_line(NULL,
> > - get_memory_ranges_iomem_cb, array);
> > -
> > - if (!*count) {
> > - dbgprintf("%s: failed: No RAM found.\n", __func__);
> > - return EFAILED;
> > - }
> > -
> > - return 0;
> > -}
> > -
> > -/**
> > - * get_memory_ranges - Try to get the memory ranges some how.
> > - */
> > -
> > -int get_memory_ranges(struct memory_range **range, int *ranges,
> > - unsigned long kexec_flags)
> > -{
> > - static struct memory_range array[KEXEC_SEGMENT_MAX];
> > - unsigned int count;
> > - int result;
> > -
> > - result = get_memory_ranges_iomem(array, &count);
> > -
> > - *range = result ? NULL : array;
> > - *ranges = result ? 0 : count;
> > -
> > - return result;
> > -}
> > -
> > int arch_compat_trampoline(struct kexec_info *info)
> > {
> > return 0;
> > --
> > 2.19.1
> >
> >
>
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/3] arm64: kexec: allocate memory space avoiding reserved regions
2019-12-16 5:52 ` Bhupesh Sharma
@ 2019-12-16 14:16 ` Masayoshi Mizuma
2019-12-18 2:48 ` AKASHI Takahiro
0 siblings, 1 reply; 11+ messages in thread
From: Masayoshi Mizuma @ 2019-12-16 14:16 UTC (permalink / raw)
To: Bhupesh Sharma
Cc: AKASHI Takahiro, Simon Horman, James Morse, kexec mailing list
On Mon, Dec 16, 2019 at 11:22:56AM +0530, Bhupesh Sharma wrote:
> Thanks Masa,
>
> On Sat, Dec 14, 2019 at 1:34 AM Masayoshi Mizuma <msys.mizuma@gmail.com> wrote:
> >
> > some nits as below:
> >
> > On Fri, Jan 11, 2019 at 06:59:45PM +0900, AKASHI Takahiro wrote:
> > > On UEFI/ACPI-only system, some memory regions, including but not limited
> > > to UEFI memory map and ACPI tables, must be preserved across kexec'ing.
> > > Otherwise, they can be corrupted and result in early failure in booting
> > > a new kernel.
> > >
> > > In recent kernels, /proc/iomem now has an extended file format like:
> > > 40000000-5871ffff : System RAM
> > > 41800000-426affff : Kernel code
> > > 426b0000-42aaffff : reserved
> > > 42ab0000-42c64fff : Kernel data
> > > 54400000-583fffff : Crash kernel
> > > 58590000-585effff : reserved
> > > 58700000-5871ffff : reserved
> > > 58720000-58b5ffff : reserved
> > > 58b60000-5be3ffff : System RAM
> > > 58b61000-58b61fff : reserved
> > > 59a77000-59a77fff : reserved
> > > 5be40000-5becffff : reserved
> > > 5bed0000-5bedffff : System RAM
> > > 5bee0000-5bffffff : reserved
> > > 5c000000-5fffffff : System RAM
> > > 5da00000-5e9fffff : reserved
> > > 5ec00000-5edfffff : reserved
> > > 5ef6a000-5ef6afff : reserved
> > > 5ef6b000-5efcafff : reserved
> > > 5efcd000-5efcffff : reserved
> > > 5efd0000-5effffff : reserved
> > > 5f000000-5fffffff : reserved
> > >
> > > where the "reserved" entries at the top level or under System RAM (and
> > > its descendant resources) are ones of such kind and should not be regarded
> > > as usable memory ranges where several free spaces for loading kexec data
> > > will be allocated.
> > >
> > > With this patch, get_memory_ranges() will handle this format of file
> > > correctly. Note that, for safety, unknown regions, in addition to
> > > "reserved" ones, will also be excluded.
> > >
> > > Signed-off-by: AKASHI Takahiro <takahiro.akashi at linaro.org>
> > > ---
> > > kexec/arch/arm64/kexec-arm64.c | 146 ++++++++++++++++++++-------------
> > > 1 file changed, 87 insertions(+), 59 deletions(-)
> > >
> > > diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
> > > index 1cde75d1a771..2e923b54f5b1 100644
> > > --- a/kexec/arch/arm64/kexec-arm64.c
> > > +++ b/kexec/arch/arm64/kexec-arm64.c
> > > @@ -10,7 +10,9 @@
> > > #include <inttypes.h>
> > > #include <libfdt.h>
> > > #include <limits.h>
> > > +#include <stdio.h>
> > > #include <stdlib.h>
> > > +#include <string.h>
> > > #include <sys/stat.h>
> > > #include <linux/elf-em.h>
> > > #include <elf.h>
> > > @@ -29,6 +31,7 @@
> > > #include "fs2dt.h"
> > > #include "iomem.h"
> > > #include "kexec-syscall.h"
> > > +#include "mem_regions.h"
> > > #include "arch/options.h"
> > >
> > > #define ROOT_NODE_ADDR_CELLS_DEFAULT 1
> > > @@ -899,19 +902,33 @@ int get_phys_base_from_pt_load(unsigned long *phys_offset)
> > > return 0;
> > > }
> > >
> > > +static bool to_be_excluded(char *str)
> > > +{
> > > + if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) ||
> > > + !strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) ||
> > > + !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) ||
> > > + !strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)))
> > > + return false;
> > > + else
> > > + return true;
> > > +}
> > > +
> > > /**
> > > - * get_memory_ranges_iomem_cb - Helper for get_memory_ranges_iomem.
> > > + * get_memory_ranges - Try to get the memory ranges from
> > > + * /proc/iomem.
> > > */
> > > -
> > > -static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
> > > - unsigned long long base, unsigned long long length)
> > > +int get_memory_ranges(struct memory_range **range, int *ranges,
> > > + unsigned long kexec_flags)
> > > {
> > > - int ret;
> > > unsigned long phys_offset = UINT64_MAX;
> > > - struct memory_range *r;
> > > -
> > > - if (nr >= KEXEC_SEGMENT_MAX)
> > > - return -1;
> > > + FILE *fp;
> > > + const char *iomem = proc_iomem();
> > > + char line[MAX_LINE], *str;
> > > + unsigned long long start, end;
> > > + int n, consumed;
> > > + struct memory_ranges memranges;
> > > + struct memory_range *last, excl_range;
> > > + int ret;
> > >
> > > if (!try_read_phys_offset_from_kcore) {
> > > /* Since kernel version 4.19, 'kcore' contains
> > > @@ -945,17 +962,65 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
> > > try_read_phys_offset_from_kcore = true;
> > > }
> > >
> > > - r = (struct memory_range *)data + nr;
> > > + fp = fopen(iomem, "r");
> > > + if (!fp)
> > > + die("Cannot open %s\n", iomem);
> > > +
> > > + memranges.ranges = NULL;
> > > + memranges.size = memranges.max_size = 0;
> > > +
> > > + while (fgets(line, sizeof(line), fp) != 0) {
> > > + n = sscanf(line, "%llx-%llx : %n", &start, &end, &consumed);
> > > + if (n != 2)
> > > + continue;
> > > + str = line + consumed;
> > > +
> > > + if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM))) {
> > > + ret = mem_regions_alloc_and_add(&memranges,
> > > + start, end - start + 1, RANGE_RAM);
> > > + if (ret) {
> > > + fprintf(stderr,
> > > + "Cannot allocate memory for ranges\n");
> >
> > fclose(fp);
> >
> > > + return -ENOMEM;
> > > + }
> > >
> > > - if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)))
> > > - r->type = RANGE_RAM;
> > > - else if (!strncmp(str, IOMEM_RESERVED, strlen(IOMEM_RESERVED)))
> > > - r->type = RANGE_RESERVED;
> > > - else
> > > - return 1;
> > > + dbgprintf("%s:+[%d] %016llx - %016llx\n", __func__,
> > > + memranges.size - 1,
> > > + memranges.ranges[memranges.size - 1].start,
> > > + memranges.ranges[memranges.size - 1].end);
> > > + } else if (to_be_excluded(str)) {
> > > + if (!memranges.size)
> > > + continue;
> > > +
> > > + /*
> > > + * Note: mem_regions_exclude() doesn't guarantee
> > > + * that the ranges are sorted out, but as long as
> > > + * we cope with /proc/iomem, we only operate on
> > > + * the last entry and so it is safe.
> > > + */
> > >
> > > - r->start = base;
> > > - r->end = base + length - 1;
> > > + /* The last System RAM range */
> > > + last = &memranges.ranges[memranges.size - 1];
> > > +
> > > + if (last->end < start)
> > > + /* New resource outside of System RAM */
> > > + continue;
> > > + if (end < last->start)
> > > + /* Already excluded by parent resource */
> > > + continue;
> > > +
> > > + excl_range.start = start;
> > > + excl_range.end = end;
> >
> > > + mem_regions_alloc_and_exclude(&memranges, &excl_range);
> > ret = mem_regions_alloc_and_exclude(&memranges, &excl_range);
> > if (ret) {
> > fprintf(stderr,
> > "Cannot allocate memory for ranges (exclude)\n");
> > fclose(fp);
> > return -ENOMEM;
> > }
>
> Since this is an old thread, it would be useful for people looking at
> the same, if you can add some comments/details about why you think
> this nit is needed.
Thank you for your follow up and I'm sorry I didn't explain it.
mem_regions_alloc_and_exclude() may fail in case realloc() or
mem_region_exclude() fail, so it would be better to add the error
handling.
>
> Also if Akashi agrees with the same, it would be better if he could
> send a rebased version of the patchset (with your comments addressed),
> so that the same can be picked for upstream kexec-tools cleanly.
Sounds great!
- Masa
>
> @Akashi- Hi Akashi, Please let us know your views.
>
> Thanks,
> Bhupesh
>
> > + dbgprintf("%s:- %016llx - %016llx\n",
> > > + __func__, start, end);
> > > + }
> > > + }
> > > +
> > > + fclose(fp);
> > > +
> > > + *range = memranges.ranges;
> > > + *ranges = memranges.size;
> > >
> > > /* As a fallback option, we can try determining the PHYS_OFFSET
> > > * value from the '/proc/iomem' entries as well.
> > > @@ -976,52 +1041,15 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
> > > * between the user-space and kernel space 'PHYS_OFFSET'
> > > * value.
> > > */
> > > - set_phys_offset(r->start, "iomem");
> > > + if (memranges.size)
> > > + set_phys_offset(memranges.ranges[0].start, "iomem");
> > >
> > > - dbgprintf("%s: %016llx - %016llx : %s", __func__, r->start,
> > > - r->end, str);
> > > + dbgprint_mem_range("System RAM ranges;",
> > > + memranges.ranges, memranges.size);
> > >
> > > return 0;
> > > }
> > >
> > > -/**
> > > - * get_memory_ranges_iomem - Try to get the memory ranges from
> > > - * /proc/iomem.
> > > - */
> > > -
> > > -static int get_memory_ranges_iomem(struct memory_range *array,
> > > - unsigned int *count)
> > > -{
> > > - *count = kexec_iomem_for_each_line(NULL,
> > > - get_memory_ranges_iomem_cb, array);
> > > -
> > > - if (!*count) {
> > > - dbgprintf("%s: failed: No RAM found.\n", __func__);
> > > - return EFAILED;
> > > - }
> > > -
> > > - return 0;
> > > -}
> > > -
> > > -/**
> > > - * get_memory_ranges - Try to get the memory ranges some how.
> > > - */
> > > -
> > > -int get_memory_ranges(struct memory_range **range, int *ranges,
> > > - unsigned long kexec_flags)
> > > -{
> > > - static struct memory_range array[KEXEC_SEGMENT_MAX];
> > > - unsigned int count;
> > > - int result;
> > > -
> > > - result = get_memory_ranges_iomem(array, &count);
> > > -
> > > - *range = result ? NULL : array;
> > > - *ranges = result ? 0 : count;
> > > -
> > > - return result;
> > > -}
> > > -
> > > int arch_compat_trampoline(struct kexec_info *info)
> > > {
> > > return 0;
> > > --
> > > 2.19.1
> > >
> > >
> >
>
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/3] arm64: kexec: allocate memory space avoiding reserved regions
2019-12-16 14:16 ` Masayoshi Mizuma
@ 2019-12-18 2:48 ` AKASHI Takahiro
2019-12-18 15:08 ` Masayoshi Mizuma
0 siblings, 1 reply; 11+ messages in thread
From: AKASHI Takahiro @ 2019-12-18 2:48 UTC (permalink / raw)
To: Masayoshi Mizuma
Cc: kexec mailing list, Bhupesh Sharma, Simon Horman, James Morse
On Mon, Dec 16, 2019 at 09:16:06AM -0500, Masayoshi Mizuma wrote:
> On Mon, Dec 16, 2019 at 11:22:56AM +0530, Bhupesh Sharma wrote:
> > Thanks Masa,
[...]
> > Since this is an old thread, it would be useful for people looking at
> > the same, if you can add some comments/details about why you think
> > this nit is needed.
>
> Thank you for your follow up and I'm sorry I didn't explain it.
> mem_regions_alloc_and_exclude() may fail in case realloc() or
> mem_region_exclude() fail, so it would be better to add the error
> handling.
>
> >
> > Also if Akashi agrees with the same, it would be better if he could
> > send a rebased version of the patchset (with your comments addressed),
> > so that the same can be picked for upstream kexec-tools cleanly.
>
> Sounds great!
I have almost forgotten the background of this patch.
If you see that it is still useful, please feel free to re-post it.
Thanks,
-Takahiro Akashi
> - Masa
>
> >
> > @Akashi- Hi Akashi, Please let us know your views.
> >
> > Thanks,
> > Bhupesh
> >
> > > + dbgprintf("%s:- %016llx - %016llx\n",
> > > > + __func__, start, end);
> > > > + }
> > > > + }
> > > > +
> > > > + fclose(fp);
> > > > +
> > > > + *range = memranges.ranges;
> > > > + *ranges = memranges.size;
> > > >
> > > > /* As a fallback option, we can try determining the PHYS_OFFSET
> > > > * value from the '/proc/iomem' entries as well.
> > > > @@ -976,52 +1041,15 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
> > > > * between the user-space and kernel space 'PHYS_OFFSET'
> > > > * value.
> > > > */
> > > > - set_phys_offset(r->start, "iomem");
> > > > + if (memranges.size)
> > > > + set_phys_offset(memranges.ranges[0].start, "iomem");
> > > >
> > > > - dbgprintf("%s: %016llx - %016llx : %s", __func__, r->start,
> > > > - r->end, str);
> > > > + dbgprint_mem_range("System RAM ranges;",
> > > > + memranges.ranges, memranges.size);
> > > >
> > > > return 0;
> > > > }
> > > >
> > > > -/**
> > > > - * get_memory_ranges_iomem - Try to get the memory ranges from
> > > > - * /proc/iomem.
> > > > - */
> > > > -
> > > > -static int get_memory_ranges_iomem(struct memory_range *array,
> > > > - unsigned int *count)
> > > > -{
> > > > - *count = kexec_iomem_for_each_line(NULL,
> > > > - get_memory_ranges_iomem_cb, array);
> > > > -
> > > > - if (!*count) {
> > > > - dbgprintf("%s: failed: No RAM found.\n", __func__);
> > > > - return EFAILED;
> > > > - }
> > > > -
> > > > - return 0;
> > > > -}
> > > > -
> > > > -/**
> > > > - * get_memory_ranges - Try to get the memory ranges some how.
> > > > - */
> > > > -
> > > > -int get_memory_ranges(struct memory_range **range, int *ranges,
> > > > - unsigned long kexec_flags)
> > > > -{
> > > > - static struct memory_range array[KEXEC_SEGMENT_MAX];
> > > > - unsigned int count;
> > > > - int result;
> > > > -
> > > > - result = get_memory_ranges_iomem(array, &count);
> > > > -
> > > > - *range = result ? NULL : array;
> > > > - *ranges = result ? 0 : count;
> > > > -
> > > > - return result;
> > > > -}
> > > > -
> > > > int arch_compat_trampoline(struct kexec_info *info)
> > > > {
> > > > return 0;
> > > > --
> > > > 2.19.1
> > > >
> > > >
> > >
> >
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v2 2/3] arm64: kexec: allocate memory space avoiding reserved regions
2019-12-18 2:48 ` AKASHI Takahiro
@ 2019-12-18 15:08 ` Masayoshi Mizuma
0 siblings, 0 replies; 11+ messages in thread
From: Masayoshi Mizuma @ 2019-12-18 15:08 UTC (permalink / raw)
To: AKASHI Takahiro
Cc: kexec mailing list, Bhupesh Sharma, Simon Horman, James Morse
On Wed, Dec 18, 2019 at 11:48:50AM +0900, AKASHI Takahiro wrote:
> On Mon, Dec 16, 2019 at 09:16:06AM -0500, Masayoshi Mizuma wrote:
> > On Mon, Dec 16, 2019 at 11:22:56AM +0530, Bhupesh Sharma wrote:
> > > Thanks Masa,
>
> [...]
>
> > > Since this is an old thread, it would be useful for people looking at
> > > the same, if you can add some comments/details about why you think
> > > this nit is needed.
> >
> > Thank you for your follow up and I'm sorry I didn't explain it.
> > mem_regions_alloc_and_exclude() may fail in case realloc() or
> > mem_region_exclude() fail, so it would be better to add the error
> > handling.
> >
> > >
> > > Also if Akashi agrees with the same, it would be better if he could
> > > send a rebased version of the patchset (with your comments addressed),
> > > so that the same can be picked for upstream kexec-tools cleanly.
> >
> > Sounds great!
>
> I have almost forgotten the background of this patch.
> If you see that it is still useful, please feel free to re-post it.
Thanks! I'll repost the patchset as v3.
- Masa
>
> Thanks,
> -Takahiro Akashi
>
> > - Masa
> >
> > >
> > > @Akashi- Hi Akashi, Please let us know your views.
> > >
> > > Thanks,
> > > Bhupesh
> > >
> > > > + dbgprintf("%s:- %016llx - %016llx\n",
> > > > > + __func__, start, end);
> > > > > + }
> > > > > + }
> > > > > +
> > > > > + fclose(fp);
> > > > > +
> > > > > + *range = memranges.ranges;
> > > > > + *ranges = memranges.size;
> > > > >
> > > > > /* As a fallback option, we can try determining the PHYS_OFFSET
> > > > > * value from the '/proc/iomem' entries as well.
> > > > > @@ -976,52 +1041,15 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str,
> > > > > * between the user-space and kernel space 'PHYS_OFFSET'
> > > > > * value.
> > > > > */
> > > > > - set_phys_offset(r->start, "iomem");
> > > > > + if (memranges.size)
> > > > > + set_phys_offset(memranges.ranges[0].start, "iomem");
> > > > >
> > > > > - dbgprintf("%s: %016llx - %016llx : %s", __func__, r->start,
> > > > > - r->end, str);
> > > > > + dbgprint_mem_range("System RAM ranges;",
> > > > > + memranges.ranges, memranges.size);
> > > > >
> > > > > return 0;
> > > > > }
> > > > >
> > > > > -/**
> > > > > - * get_memory_ranges_iomem - Try to get the memory ranges from
> > > > > - * /proc/iomem.
> > > > > - */
> > > > > -
> > > > > -static int get_memory_ranges_iomem(struct memory_range *array,
> > > > > - unsigned int *count)
> > > > > -{
> > > > > - *count = kexec_iomem_for_each_line(NULL,
> > > > > - get_memory_ranges_iomem_cb, array);
> > > > > -
> > > > > - if (!*count) {
> > > > > - dbgprintf("%s: failed: No RAM found.\n", __func__);
> > > > > - return EFAILED;
> > > > > - }
> > > > > -
> > > > > - return 0;
> > > > > -}
> > > > > -
> > > > > -/**
> > > > > - * get_memory_ranges - Try to get the memory ranges some how.
> > > > > - */
> > > > > -
> > > > > -int get_memory_ranges(struct memory_range **range, int *ranges,
> > > > > - unsigned long kexec_flags)
> > > > > -{
> > > > > - static struct memory_range array[KEXEC_SEGMENT_MAX];
> > > > > - unsigned int count;
> > > > > - int result;
> > > > > -
> > > > > - result = get_memory_ranges_iomem(array, &count);
> > > > > -
> > > > > - *range = result ? NULL : array;
> > > > > - *ranges = result ? 0 : count;
> > > > > -
> > > > > - return result;
> > > > > -}
> > > > > -
> > > > > int arch_compat_trampoline(struct kexec_info *info)
> > > > > {
> > > > > return 0;
> > > > > --
> > > > > 2.19.1
> > > > >
> > > > >
> > > >
> > >
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2019-12-18 15:08 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-01-11 9:59 [PATCH v2 0/3] arm64: handle "reserved" entries in /proc/iomem AKASHI Takahiro
2019-01-11 9:59 ` [PATCH v2 1/3] kexec: add variant helper functions for handling memory regions AKASHI Takahiro
2019-01-11 9:59 ` [PATCH v2 2/3] arm64: kexec: allocate memory space avoiding reserved regions AKASHI Takahiro
2019-12-13 20:04 ` Masayoshi Mizuma
2019-12-16 5:52 ` Bhupesh Sharma
2019-12-16 14:16 ` Masayoshi Mizuma
2019-12-18 2:48 ` AKASHI Takahiro
2019-12-18 15:08 ` Masayoshi Mizuma
2019-01-11 9:59 ` [PATCH v2 3/3] arm64: kdump: deal with a lot of resource entries in /proc/iomem AKASHI Takahiro
2019-01-13 11:36 ` [PATCH v2 0/3] arm64: handle "reserved" " Bhupesh Sharma
2019-12-13 19:53 ` Masayoshi Mizuma
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox