* [PATCH 00/10] various fixes for kexec crashkernel support
2016-11-23 13:43 [PATCH 00/10] various fixes for kexec crashkernel support Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 01/10] MIPS: do not request resources for crashkernel if one isn't defined Marcin Nowakowski
` (9 subsequent siblings)
10 siblings, 0 replies; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
This set of patches attempts to add support to generic MIPS kernels
for kexec and crashkernel loading, as well as fix some existing
potential issues with KASLR
Patches 1-7 fix various bootmem region definition problems, most importantly
ensuring that a firmware-loaded DTB is not corrupt during kernel relocation
or during bootmem initialisation
Patches 8-9 add some error checking and debug messages for kexec
Patch 10 adds support for loading the device tree blob through kexec
on generic platforms using UHI boot protocol.
I will be publishing supporting patches for kexec (especially for generic
platform dtb support) soon.
* Notes for crashkernel core dumps *
The following patches are required:
https://patchwork.linux-mips.org/patch/14588/
https://patchwork.linux-mips.org/patch/14587/
https://patchwork.linux-mips.org/patch/14586/
For non-generic platforms there is no standard method of passing
boot commandline, hence the required boot arguments (mem, elfcorehdr) need
to be set with CONFIG_CMDLINE (except for Cavium Octeon platforms which
have their own method implemented in soc-specific code as well as in
kexec userspace tool).
Marcin Nowakowski (10):
MIPS: do not request resources for crashkernel if one isn't defined
MIPS: init: ensure reserved memory regions are not added to bootmem
MIPS: init: ensure bootmem does not corrupt reserved memory
MIPS: use early_init_fdt_reserve_self to protect DTB location
MIPS: platform: allow for DTB to be moved during kernel relocation
MIPS: relocate: optionally relocate the DTB
MIPS: fix mem=X@Y commandline processing
MIPS: kexec: do not reserve invalid crashkernel memory on boot
MIPS: kexec: add debug info about the new kexec'ed image
MIPS: generic/kexec: add support for a DTB passed in a separate buffer
arch/mips/generic/Makefile | 1 +
arch/mips/generic/init.c | 13 ++++++
arch/mips/generic/kexec.c | 45 +++++++++++++++++++
arch/mips/include/asm/bootinfo.h | 13 ++++++
arch/mips/kernel/machine_kexec.c | 22 ++++++++++
arch/mips/kernel/prom.c | 7 +++
arch/mips/kernel/relocate.c | 37 +++++++++++++++-
arch/mips/kernel/setup.c | 94 ++++++++++++++++++++++++++++++++++++++--
8 files changed, 228 insertions(+), 4 deletions(-)
create mode 100644 arch/mips/generic/kexec.c
--
2.7.4
^ permalink raw reply [flat|nested] 22+ messages in thread* [PATCH 01/10] MIPS: do not request resources for crashkernel if one isn't defined
2016-11-23 13:43 [PATCH 00/10] various fixes for kexec crashkernel support Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 02/10] MIPS: init: ensure reserved memory regions are not added to bootmem Marcin Nowakowski
` (8 subsequent siblings)
10 siblings, 1 reply; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
When KEXEC is enabled but crashkernel details are not passed through the
kernel commandline unnecessary resources are requested (start==end==0)
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/kernel/setup.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index f66e5ce..0058fea 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -672,6 +672,9 @@ static void __init request_crashkernel(struct resource *res)
{
int ret;
+ if (crashk_res.start == crashk_res.end)
+ return;
+
ret = request_resource(res, &crashk_res);
if (!ret)
pr_info("Reserving %ldMB of memory at %ldMB for crashkernel\n",
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCH 02/10] MIPS: init: ensure reserved memory regions are not added to bootmem
2016-11-23 13:43 [PATCH 00/10] various fixes for kexec crashkernel support Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 01/10] MIPS: do not request resources for crashkernel if one isn't defined Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 03/10] MIPS: init: ensure bootmem does not corrupt reserved memory Marcin Nowakowski
` (7 subsequent siblings)
10 siblings, 1 reply; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
Memories managed through boot_mem_map are generally expected to define
non-crossing areas. However, if part of a larger memory block is marked
as reserved, it would still be added to bootmem allocator as an
available block and could end up being overwritten by the allocator.
Prevent this by explicitly marking the memory as reserved it if exists
in the range used by bootmem allocator.
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/kernel/setup.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 0058fea..8ebad24 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -483,6 +483,10 @@ static void __init bootmem_init(void)
continue;
default:
/* Not usable memory */
+ if (start > min_low_pfn && end < max_low_pfn)
+ reserve_bootmem(boot_mem_map.map[i].addr,
+ boot_mem_map.map[i].size,
+ BOOTMEM_DEFAULT);
continue;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCH 02/10] MIPS: init: ensure reserved memory regions are not added to bootmem
2016-11-23 13:43 ` [PATCH 02/10] MIPS: init: ensure reserved memory regions are not added to bootmem Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
0 siblings, 0 replies; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
Memories managed through boot_mem_map are generally expected to define
non-crossing areas. However, if part of a larger memory block is marked
as reserved, it would still be added to bootmem allocator as an
available block and could end up being overwritten by the allocator.
Prevent this by explicitly marking the memory as reserved it if exists
in the range used by bootmem allocator.
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/kernel/setup.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 0058fea..8ebad24 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -483,6 +483,10 @@ static void __init bootmem_init(void)
continue;
default:
/* Not usable memory */
+ if (start > min_low_pfn && end < max_low_pfn)
+ reserve_bootmem(boot_mem_map.map[i].addr,
+ boot_mem_map.map[i].size,
+ BOOTMEM_DEFAULT);
continue;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 03/10] MIPS: init: ensure bootmem does not corrupt reserved memory
2016-11-23 13:43 [PATCH 00/10] various fixes for kexec crashkernel support Marcin Nowakowski
` (2 preceding siblings ...)
2016-11-23 13:43 ` [PATCH 02/10] MIPS: init: ensure reserved memory regions are not added to bootmem Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 04/10] MIPS: use early_init_fdt_reserve_self to protect DTB location Marcin Nowakowski
` (6 subsequent siblings)
10 siblings, 1 reply; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
Current init code initialises bootmem allocator with all of the low
memory that it assumes is available, but does not check for reserved
memory block, which can lead to corruption of data that may be stored
there.
Move bootmem's allocation map to a location that does not cross any
reserved regions
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/kernel/setup.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 71 insertions(+), 3 deletions(-)
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 8ebad24..64b38d4 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -153,6 +153,35 @@ void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_add
add_memory_region(start, size, BOOT_MEM_RAM);
}
+bool __init memory_region_available(phys_addr_t start, phys_addr_t size)
+{
+ int i;
+ bool in_ram = false, free = true;
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ phys_addr_t start_, end_;
+
+ start_ = boot_mem_map.map[i].addr;
+ end_ = boot_mem_map.map[i].addr + boot_mem_map.map[i].size;
+
+ switch (boot_mem_map.map[i].type) {
+ case BOOT_MEM_RAM:
+ if (start >= start_ && start + size <= end_)
+ in_ram = true;
+ break;
+ case BOOT_MEM_RESERVED:
+ if ((start >= start_ && start < end_) ||
+ (start < start_ && start + size >= start_))
+ free = false;
+ break;
+ default:
+ continue;
+ }
+ }
+
+ return in_ram && free;
+}
+
static void __init print_memory_map(void)
{
int i;
@@ -332,11 +361,19 @@ static void __init bootmem_init(void)
#else /* !CONFIG_SGI_IP27 */
+static unsigned long __init bootmap_bytes(unsigned long pages)
+{
+ unsigned long bytes = DIV_ROUND_UP(pages, 8);
+
+ return ALIGN(bytes, sizeof(long));
+}
+
static void __init bootmem_init(void)
{
unsigned long reserved_end;
unsigned long mapstart = ~0UL;
unsigned long bootmap_size;
+ bool bootmap_valid = false;
int i;
/*
@@ -430,11 +467,42 @@ static void __init bootmem_init(void)
#endif
/*
- * Initialize the boot-time allocator with low memory only.
+ * check that mapstart doesn't overlap with any of
+ * memory regions that have been reserved through eg. DTB
*/
- bootmap_size = init_bootmem_node(NODE_DATA(0), mapstart,
- min_low_pfn, max_low_pfn);
+ bootmap_size = bootmap_bytes(max_low_pfn - min_low_pfn);
+
+ bootmap_valid = memory_region_available(PFN_PHYS(mapstart),
+ bootmap_size);
+ for (i = 0; i < boot_mem_map.nr_map && !bootmap_valid; i++) {
+ unsigned long mapstart_addr;
+
+ switch (boot_mem_map.map[i].type) {
+ case BOOT_MEM_RESERVED:
+ mapstart_addr = PFN_ALIGN(boot_mem_map.map[i].addr +
+ boot_mem_map.map[i].size);
+ if (PHYS_PFN(mapstart_addr) < mapstart)
+ break;
+
+ bootmap_valid = memory_region_available(mapstart_addr,
+ bootmap_size);
+ if (bootmap_valid)
+ mapstart = PHYS_PFN(mapstart_addr);
+ break;
+ default:
+ break;
+ }
+ }
+ if (!bootmap_valid)
+ panic("No memory area to place a bootmap bitmap");
+
+ /*
+ * Initialize the boot-time allocator with low memory only.
+ */
+ if (bootmap_size != init_bootmem_node(NODE_DATA(0), mapstart,
+ min_low_pfn, max_low_pfn))
+ panic("Unexpected memory size required for bootmap");
for (i = 0; i < boot_mem_map.nr_map; i++) {
unsigned long start, end;
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCH 03/10] MIPS: init: ensure bootmem does not corrupt reserved memory
2016-11-23 13:43 ` [PATCH 03/10] MIPS: init: ensure bootmem does not corrupt reserved memory Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
0 siblings, 0 replies; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
Current init code initialises bootmem allocator with all of the low
memory that it assumes is available, but does not check for reserved
memory block, which can lead to corruption of data that may be stored
there.
Move bootmem's allocation map to a location that does not cross any
reserved regions
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/kernel/setup.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 71 insertions(+), 3 deletions(-)
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 8ebad24..64b38d4 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -153,6 +153,35 @@ void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_add
add_memory_region(start, size, BOOT_MEM_RAM);
}
+bool __init memory_region_available(phys_addr_t start, phys_addr_t size)
+{
+ int i;
+ bool in_ram = false, free = true;
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ phys_addr_t start_, end_;
+
+ start_ = boot_mem_map.map[i].addr;
+ end_ = boot_mem_map.map[i].addr + boot_mem_map.map[i].size;
+
+ switch (boot_mem_map.map[i].type) {
+ case BOOT_MEM_RAM:
+ if (start >= start_ && start + size <= end_)
+ in_ram = true;
+ break;
+ case BOOT_MEM_RESERVED:
+ if ((start >= start_ && start < end_) ||
+ (start < start_ && start + size >= start_))
+ free = false;
+ break;
+ default:
+ continue;
+ }
+ }
+
+ return in_ram && free;
+}
+
static void __init print_memory_map(void)
{
int i;
@@ -332,11 +361,19 @@ static void __init bootmem_init(void)
#else /* !CONFIG_SGI_IP27 */
+static unsigned long __init bootmap_bytes(unsigned long pages)
+{
+ unsigned long bytes = DIV_ROUND_UP(pages, 8);
+
+ return ALIGN(bytes, sizeof(long));
+}
+
static void __init bootmem_init(void)
{
unsigned long reserved_end;
unsigned long mapstart = ~0UL;
unsigned long bootmap_size;
+ bool bootmap_valid = false;
int i;
/*
@@ -430,11 +467,42 @@ static void __init bootmem_init(void)
#endif
/*
- * Initialize the boot-time allocator with low memory only.
+ * check that mapstart doesn't overlap with any of
+ * memory regions that have been reserved through eg. DTB
*/
- bootmap_size = init_bootmem_node(NODE_DATA(0), mapstart,
- min_low_pfn, max_low_pfn);
+ bootmap_size = bootmap_bytes(max_low_pfn - min_low_pfn);
+
+ bootmap_valid = memory_region_available(PFN_PHYS(mapstart),
+ bootmap_size);
+ for (i = 0; i < boot_mem_map.nr_map && !bootmap_valid; i++) {
+ unsigned long mapstart_addr;
+
+ switch (boot_mem_map.map[i].type) {
+ case BOOT_MEM_RESERVED:
+ mapstart_addr = PFN_ALIGN(boot_mem_map.map[i].addr +
+ boot_mem_map.map[i].size);
+ if (PHYS_PFN(mapstart_addr) < mapstart)
+ break;
+
+ bootmap_valid = memory_region_available(mapstart_addr,
+ bootmap_size);
+ if (bootmap_valid)
+ mapstart = PHYS_PFN(mapstart_addr);
+ break;
+ default:
+ break;
+ }
+ }
+ if (!bootmap_valid)
+ panic("No memory area to place a bootmap bitmap");
+
+ /*
+ * Initialize the boot-time allocator with low memory only.
+ */
+ if (bootmap_size != init_bootmem_node(NODE_DATA(0), mapstart,
+ min_low_pfn, max_low_pfn))
+ panic("Unexpected memory size required for bootmap");
for (i = 0; i < boot_mem_map.nr_map; i++) {
unsigned long start, end;
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 04/10] MIPS: use early_init_fdt_reserve_self to protect DTB location
2016-11-23 13:43 [PATCH 00/10] various fixes for kexec crashkernel support Marcin Nowakowski
` (3 preceding siblings ...)
2016-11-23 13:43 ` [PATCH 03/10] MIPS: init: ensure bootmem does not corrupt reserved memory Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 05/10] MIPS: platform: allow for DTB to be moved during kernel relocation Marcin Nowakowski
` (5 subsequent siblings)
10 siblings, 1 reply; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
early_init_fdt_reserve_self is used to tell the boot memory allocator
that a memory is occupied by the DTB, so add it in the MIPS init code to
ensure information about the DTB is added to the boot memory array.
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/kernel/prom.c | 7 +++++++
arch/mips/kernel/setup.c | 4 ++++
2 files changed, 11 insertions(+)
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
index 5fcec30..0dbcd15 100644
--- a/arch/mips/kernel/prom.c
+++ b/arch/mips/kernel/prom.c
@@ -49,6 +49,13 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS));
}
+int __init early_init_dt_reserve_memory_arch(phys_addr_t base,
+ phys_addr_t size, bool nomap)
+{
+ add_memory_region(base, size, BOOT_MEM_RESERVED);
+ return 0;
+}
+
void __init __dt_setup_arch(void *bph)
{
if (!early_init_dt_scan(bph))
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 64b38d4..c22f0fd 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -27,6 +27,7 @@
#include <linux/device.h>
#include <linux/dma-contiguous.h>
#include <linux/decompress/generic.h>
+#include <linux/of_fdt.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
@@ -832,6 +833,9 @@ static void __init arch_mem_init(char **cmdline_p)
print_memory_map();
}
+ early_init_fdt_reserve_self();
+ early_init_fdt_scan_reserved_mem();
+
bootmem_init();
#ifdef CONFIG_PROC_VMCORE
if (setup_elfcorehdr && setup_elfcorehdr_size) {
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCH 04/10] MIPS: use early_init_fdt_reserve_self to protect DTB location
2016-11-23 13:43 ` [PATCH 04/10] MIPS: use early_init_fdt_reserve_self to protect DTB location Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
0 siblings, 0 replies; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
early_init_fdt_reserve_self is used to tell the boot memory allocator
that a memory is occupied by the DTB, so add it in the MIPS init code to
ensure information about the DTB is added to the boot memory array.
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/kernel/prom.c | 7 +++++++
arch/mips/kernel/setup.c | 4 ++++
2 files changed, 11 insertions(+)
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
index 5fcec30..0dbcd15 100644
--- a/arch/mips/kernel/prom.c
+++ b/arch/mips/kernel/prom.c
@@ -49,6 +49,13 @@ void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS));
}
+int __init early_init_dt_reserve_memory_arch(phys_addr_t base,
+ phys_addr_t size, bool nomap)
+{
+ add_memory_region(base, size, BOOT_MEM_RESERVED);
+ return 0;
+}
+
void __init __dt_setup_arch(void *bph)
{
if (!early_init_dt_scan(bph))
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index 64b38d4..c22f0fd 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -27,6 +27,7 @@
#include <linux/device.h>
#include <linux/dma-contiguous.h>
#include <linux/decompress/generic.h>
+#include <linux/of_fdt.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
@@ -832,6 +833,9 @@ static void __init arch_mem_init(char **cmdline_p)
print_memory_map();
}
+ early_init_fdt_reserve_self();
+ early_init_fdt_scan_reserved_mem();
+
bootmem_init();
#ifdef CONFIG_PROC_VMCORE
if (setup_elfcorehdr && setup_elfcorehdr_size) {
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 05/10] MIPS: platform: allow for DTB to be moved during kernel relocation
2016-11-23 13:43 [PATCH 00/10] various fixes for kexec crashkernel support Marcin Nowakowski
` (4 preceding siblings ...)
2016-11-23 13:43 ` [PATCH 04/10] MIPS: use early_init_fdt_reserve_self to protect DTB location Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 06/10] MIPS: relocate: optionally relocate the DTB Marcin Nowakowski
` (4 subsequent siblings)
10 siblings, 1 reply; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
Add plat_fdt_relocated(void*) API to allow the kernel relocation code to
update platform's information about the DTB location if the DTB had to
be moved due to being placed in a location used by the relocated kernel.
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/generic/init.c | 13 +++++++++++++
arch/mips/include/asm/bootinfo.h | 13 +++++++++++++
2 files changed, 26 insertions(+)
diff --git a/arch/mips/generic/init.c b/arch/mips/generic/init.c
index d493ccb..4af6192 100644
--- a/arch/mips/generic/init.c
+++ b/arch/mips/generic/init.c
@@ -88,6 +88,19 @@ void __init *plat_get_fdt(void)
return (void *)fdt;
}
+void __init plat_fdt_relocated(void *new_location)
+{
+ /*
+ * reset fdt as the cached value would point to the location
+ * before relocations happened and update the location argument
+ * if it was passed using UHI
+ */
+ fdt = NULL;
+
+ if (fw_arg0 == -2)
+ fw_arg1 = (unsigned long)new_location;
+}
+
void __init plat_mem_setup(void)
{
if (mach && mach->fixup_fdt)
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
index ee9f5f2..e26a093 100644
--- a/arch/mips/include/asm/bootinfo.h
+++ b/arch/mips/include/asm/bootinfo.h
@@ -164,6 +164,19 @@ static inline void plat_swiotlb_setup(void) {}
* Return: Pointer to the flattened device tree blob.
*/
extern void *plat_get_fdt(void);
+
+#ifdef CONFIG_RELOCATABLE
+
+/**
+ * plat_fdt_relocated() - Update platform's information about relocated dtb
+ *
+ * This function provides a platform-independent API to set platform's
+ * information about relocated DTB if it needs to be moved due to kernel
+ * relocation occurring at boot.
+ */
+void plat_fdt_relocated(void *new_location);
+
+#endif /* CONFIG_RELOCATABLE */
#endif /* CONFIG_USE_OF */
#endif /* _ASM_BOOTINFO_H */
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCH 05/10] MIPS: platform: allow for DTB to be moved during kernel relocation
2016-11-23 13:43 ` [PATCH 05/10] MIPS: platform: allow for DTB to be moved during kernel relocation Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
0 siblings, 0 replies; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
Add plat_fdt_relocated(void*) API to allow the kernel relocation code to
update platform's information about the DTB location if the DTB had to
be moved due to being placed in a location used by the relocated kernel.
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/generic/init.c | 13 +++++++++++++
arch/mips/include/asm/bootinfo.h | 13 +++++++++++++
2 files changed, 26 insertions(+)
diff --git a/arch/mips/generic/init.c b/arch/mips/generic/init.c
index d493ccb..4af6192 100644
--- a/arch/mips/generic/init.c
+++ b/arch/mips/generic/init.c
@@ -88,6 +88,19 @@ void __init *plat_get_fdt(void)
return (void *)fdt;
}
+void __init plat_fdt_relocated(void *new_location)
+{
+ /*
+ * reset fdt as the cached value would point to the location
+ * before relocations happened and update the location argument
+ * if it was passed using UHI
+ */
+ fdt = NULL;
+
+ if (fw_arg0 == -2)
+ fw_arg1 = (unsigned long)new_location;
+}
+
void __init plat_mem_setup(void)
{
if (mach && mach->fixup_fdt)
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
index ee9f5f2..e26a093 100644
--- a/arch/mips/include/asm/bootinfo.h
+++ b/arch/mips/include/asm/bootinfo.h
@@ -164,6 +164,19 @@ static inline void plat_swiotlb_setup(void) {}
* Return: Pointer to the flattened device tree blob.
*/
extern void *plat_get_fdt(void);
+
+#ifdef CONFIG_RELOCATABLE
+
+/**
+ * plat_fdt_relocated() - Update platform's information about relocated dtb
+ *
+ * This function provides a platform-independent API to set platform's
+ * information about relocated DTB if it needs to be moved due to kernel
+ * relocation occurring at boot.
+ */
+void plat_fdt_relocated(void *new_location);
+
+#endif /* CONFIG_RELOCATABLE */
#endif /* CONFIG_USE_OF */
#endif /* _ASM_BOOTINFO_H */
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 06/10] MIPS: relocate: optionally relocate the DTB
2016-11-23 13:43 [PATCH 00/10] various fixes for kexec crashkernel support Marcin Nowakowski
` (5 preceding siblings ...)
2016-11-23 13:43 ` [PATCH 05/10] MIPS: platform: allow for DTB to be moved during kernel relocation Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 07/10] MIPS: fix mem=X@Y commandline processing Marcin Nowakowski
` (3 subsequent siblings)
10 siblings, 1 reply; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
If the DTB is located in the target memory area for the relocated kernel
it needs to be relocated as well before kernel relocation takes place.
After copying the DTB use the new plat_fdt_relocated() API from the
relocated kernel to ensure the relocated kernel updates any information
that it may have cached about the location of the DTB.
plat_fdt_relocated is declared as a weak symbol so that platforms that
do not require it do not need to implement the method.
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/kernel/relocate.c | 37 ++++++++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/arch/mips/kernel/relocate.c b/arch/mips/kernel/relocate.c
index 1958910..76108e5 100644
--- a/arch/mips/kernel/relocate.c
+++ b/arch/mips/kernel/relocate.c
@@ -31,6 +31,8 @@ extern u32 _relocation_end[]; /* End relocation table */
extern long __start___ex_table; /* Start exception table */
extern long __stop___ex_table; /* End exception table */
+extern void __weak plat_fdt_relocated(void *new_location);
+
static inline u32 __init get_synci_step(void)
{
u32 res;
@@ -291,12 +293,14 @@ void *__init relocate_kernel(void)
int res = 1;
/* Default to original kernel entry point */
void *kernel_entry = start_kernel;
+ void *fdt = NULL;
/* Get the command line */
fw_init_cmdline();
#if defined(CONFIG_USE_OF)
/* Deal with the device tree */
- early_init_dt_scan(plat_get_fdt());
+ fdt = plat_get_fdt();
+ early_init_dt_scan(fdt);
if (boot_command_line[0]) {
/* Boot command line was passed in device tree */
strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
@@ -316,6 +320,29 @@ void *__init relocate_kernel(void)
arcs_cmdline[0] = '\0';
if (offset) {
+ void (*fdt_relocated_)(void *) = NULL;
+#if defined(CONFIG_USE_OF)
+ unsigned long fdt_phys = virt_to_phys(fdt);
+
+ /*
+ * If built-in dtb is used then it will have been relocated
+ * during kernel _text relocation. If appended DTB is used
+ * then it will not be relocated, but it should remain
+ * intact in the original location. If dtb is loaded by
+ * the bootloader then it may need to be moved if it crosses
+ * the target memory area
+ */
+
+ if (fdt_phys >= virt_to_phys(RELOCATED(&_text)) &&
+ fdt_phys <= virt_to_phys(RELOCATED(&_end))) {
+ void *fdt_relocated =
+ RELOCATED(ALIGN((long)&_end, PAGE_SIZE));
+ memcpy(fdt_relocated, fdt, fdt_totalsize(fdt));
+ fdt = fdt_relocated;
+ fdt_relocated_ = RELOCATED(&plat_fdt_relocated);
+ }
+#endif /* CONFIG_USE_OF */
+
/* Copy the kernel to it's new location */
memcpy(loc_new, &_text, kernel_length);
@@ -338,6 +365,14 @@ void *__init relocate_kernel(void)
*/
memcpy(RELOCATED(&__bss_start), &__bss_start, bss_length);
+ /*
+ * If fdt was stored outside of the kernel image and
+ * had to be moved then update platform's state data
+ * with the new fdt location
+ */
+ if (fdt_relocated_)
+ fdt_relocated_(fdt);
+
/* The current thread is now within the relocated image */
__current_thread_info = RELOCATED(&init_thread_union);
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCH 06/10] MIPS: relocate: optionally relocate the DTB
2016-11-23 13:43 ` [PATCH 06/10] MIPS: relocate: optionally relocate the DTB Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
0 siblings, 0 replies; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
If the DTB is located in the target memory area for the relocated kernel
it needs to be relocated as well before kernel relocation takes place.
After copying the DTB use the new plat_fdt_relocated() API from the
relocated kernel to ensure the relocated kernel updates any information
that it may have cached about the location of the DTB.
plat_fdt_relocated is declared as a weak symbol so that platforms that
do not require it do not need to implement the method.
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/kernel/relocate.c | 37 ++++++++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/arch/mips/kernel/relocate.c b/arch/mips/kernel/relocate.c
index 1958910..76108e5 100644
--- a/arch/mips/kernel/relocate.c
+++ b/arch/mips/kernel/relocate.c
@@ -31,6 +31,8 @@ extern u32 _relocation_end[]; /* End relocation table */
extern long __start___ex_table; /* Start exception table */
extern long __stop___ex_table; /* End exception table */
+extern void __weak plat_fdt_relocated(void *new_location);
+
static inline u32 __init get_synci_step(void)
{
u32 res;
@@ -291,12 +293,14 @@ void *__init relocate_kernel(void)
int res = 1;
/* Default to original kernel entry point */
void *kernel_entry = start_kernel;
+ void *fdt = NULL;
/* Get the command line */
fw_init_cmdline();
#if defined(CONFIG_USE_OF)
/* Deal with the device tree */
- early_init_dt_scan(plat_get_fdt());
+ fdt = plat_get_fdt();
+ early_init_dt_scan(fdt);
if (boot_command_line[0]) {
/* Boot command line was passed in device tree */
strlcpy(arcs_cmdline, boot_command_line, COMMAND_LINE_SIZE);
@@ -316,6 +320,29 @@ void *__init relocate_kernel(void)
arcs_cmdline[0] = '\0';
if (offset) {
+ void (*fdt_relocated_)(void *) = NULL;
+#if defined(CONFIG_USE_OF)
+ unsigned long fdt_phys = virt_to_phys(fdt);
+
+ /*
+ * If built-in dtb is used then it will have been relocated
+ * during kernel _text relocation. If appended DTB is used
+ * then it will not be relocated, but it should remain
+ * intact in the original location. If dtb is loaded by
+ * the bootloader then it may need to be moved if it crosses
+ * the target memory area
+ */
+
+ if (fdt_phys >= virt_to_phys(RELOCATED(&_text)) &&
+ fdt_phys <= virt_to_phys(RELOCATED(&_end))) {
+ void *fdt_relocated =
+ RELOCATED(ALIGN((long)&_end, PAGE_SIZE));
+ memcpy(fdt_relocated, fdt, fdt_totalsize(fdt));
+ fdt = fdt_relocated;
+ fdt_relocated_ = RELOCATED(&plat_fdt_relocated);
+ }
+#endif /* CONFIG_USE_OF */
+
/* Copy the kernel to it's new location */
memcpy(loc_new, &_text, kernel_length);
@@ -338,6 +365,14 @@ void *__init relocate_kernel(void)
*/
memcpy(RELOCATED(&__bss_start), &__bss_start, bss_length);
+ /*
+ * If fdt was stored outside of the kernel image and
+ * had to be moved then update platform's state data
+ * with the new fdt location
+ */
+ if (fdt_relocated_)
+ fdt_relocated_(fdt);
+
/* The current thread is now within the relocated image */
__current_thread_info = RELOCATED(&init_thread_union);
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 07/10] MIPS: fix mem=X@Y commandline processing
2016-11-23 13:43 [PATCH 00/10] various fixes for kexec crashkernel support Marcin Nowakowski
` (6 preceding siblings ...)
2016-11-23 13:43 ` [PATCH 06/10] MIPS: relocate: optionally relocate the DTB Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 08/10] MIPS: kexec: do not reserve invalid crashkernel memory on boot Marcin Nowakowski
` (2 subsequent siblings)
10 siblings, 1 reply; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
When a memory offset is specified through the commandline, add the
memory in range PHYS_OFFSET:Y as reserved memory area.
Otherwise the bootmem allocator is initialised with low page equal to
min_low_pfn = PHYS_OFFSET, and in free_all_bootmem will process pages
starting from min_low_pfn instead of PFN(Y).
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/kernel/setup.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index c22f0fd..ae88866 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -662,6 +662,10 @@ static int __init early_parse_mem(char *p)
start = memparse(p + 1, &p);
add_memory_region(start, size, BOOT_MEM_RAM);
+
+ if (start && start > PHYS_OFFSET)
+ add_memory_region(PHYS_OFFSET, start - PHYS_OFFSET,
+ BOOT_MEM_RESERVED);
return 0;
}
early_param("mem", early_parse_mem);
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCH 07/10] MIPS: fix mem=X@Y commandline processing
2016-11-23 13:43 ` [PATCH 07/10] MIPS: fix mem=X@Y commandline processing Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
0 siblings, 0 replies; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
When a memory offset is specified through the commandline, add the
memory in range PHYS_OFFSET:Y as reserved memory area.
Otherwise the bootmem allocator is initialised with low page equal to
min_low_pfn = PHYS_OFFSET, and in free_all_bootmem will process pages
starting from min_low_pfn instead of PFN(Y).
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/kernel/setup.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index c22f0fd..ae88866 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -662,6 +662,10 @@ static int __init early_parse_mem(char *p)
start = memparse(p + 1, &p);
add_memory_region(start, size, BOOT_MEM_RAM);
+
+ if (start && start > PHYS_OFFSET)
+ add_memory_region(PHYS_OFFSET, start - PHYS_OFFSET,
+ BOOT_MEM_RESERVED);
return 0;
}
early_param("mem", early_parse_mem);
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 08/10] MIPS: kexec: do not reserve invalid crashkernel memory on boot
2016-11-23 13:43 [PATCH 00/10] various fixes for kexec crashkernel support Marcin Nowakowski
` (7 preceding siblings ...)
2016-11-23 13:43 ` [PATCH 07/10] MIPS: fix mem=X@Y commandline processing Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 09/10] MIPS: kexec: add debug info about the new kexec'ed image Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 10/10] MIPS: generic/kexec: add support for a DTB passed in a separate buffer Marcin Nowakowski
10 siblings, 1 reply; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
Do not reserve memory for the crashkernel if the commandline argument
points to a wrong location. This can happen if the location is specified
wrong or if the same commandline is reused when starting the crashkernel
- in the latter case the reserved memory would point to the location
from which the crashkernel is executing.
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/kernel/setup.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index ae88866..01d1dbd 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -741,6 +741,11 @@ static void __init mips_parse_crashkernel(void)
if (ret != 0 || crash_size <= 0)
return;
+ if (!memory_region_available(crash_base, crash_size)) {
+ pr_warn("Invalid memory region reserved for crash kernel\n");
+ return;
+ }
+
crashk_res.start = crash_base;
crashk_res.end = crash_base + crash_size - 1;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCH 08/10] MIPS: kexec: do not reserve invalid crashkernel memory on boot
2016-11-23 13:43 ` [PATCH 08/10] MIPS: kexec: do not reserve invalid crashkernel memory on boot Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
0 siblings, 0 replies; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
Do not reserve memory for the crashkernel if the commandline argument
points to a wrong location. This can happen if the location is specified
wrong or if the same commandline is reused when starting the crashkernel
- in the latter case the reserved memory would point to the location
from which the crashkernel is executing.
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/kernel/setup.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index ae88866..01d1dbd 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -741,6 +741,11 @@ static void __init mips_parse_crashkernel(void)
if (ret != 0 || crash_size <= 0)
return;
+ if (!memory_region_available(crash_base, crash_size)) {
+ pr_warn("Invalid memory region reserved for crash kernel\n");
+ return;
+ }
+
crashk_res.start = crash_base;
crashk_res.end = crash_base + crash_size - 1;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 09/10] MIPS: kexec: add debug info about the new kexec'ed image
2016-11-23 13:43 [PATCH 00/10] various fixes for kexec crashkernel support Marcin Nowakowski
` (8 preceding siblings ...)
2016-11-23 13:43 ` [PATCH 08/10] MIPS: kexec: do not reserve invalid crashkernel memory on boot Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` [PATCH 10/10] MIPS: generic/kexec: add support for a DTB passed in a separate buffer Marcin Nowakowski
10 siblings, 1 reply; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
Print details of the new kexec image loaded.
Based on the original code from
commit 221f2c770e10d ("arm64/kexec: Add pr_debug output")
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/kernel/machine_kexec.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/arch/mips/kernel/machine_kexec.c b/arch/mips/kernel/machine_kexec.c
index 5972520..8b574bc 100644
--- a/arch/mips/kernel/machine_kexec.c
+++ b/arch/mips/kernel/machine_kexec.c
@@ -28,9 +28,31 @@ atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0);
void (*_crash_smp_send_stop)(void) = NULL;
#endif
+static void kexec_image_info(const struct kimage *kimage)
+{
+ unsigned long i;
+
+ pr_debug("kexec kimage info:\n");
+ pr_debug(" type: %d\n", kimage->type);
+ pr_debug(" start: %lx\n", kimage->start);
+ pr_debug(" head: %lx\n", kimage->head);
+ pr_debug(" nr_segments: %lu\n", kimage->nr_segments);
+
+ for (i = 0; i < kimage->nr_segments; i++) {
+ pr_debug(" segment[%lu]: %016lx - %016lx, 0x%lx bytes, %lu pages\n",
+ i,
+ kimage->segment[i].mem,
+ kimage->segment[i].mem + kimage->segment[i].memsz,
+ (unsigned long)kimage->segment[i].memsz,
+ (unsigned long)kimage->segment[i].memsz / PAGE_SIZE);
+ }
+}
+
int
machine_kexec_prepare(struct kimage *kimage)
{
+ kexec_image_info(kimage);
+
if (_machine_kexec_prepare)
return _machine_kexec_prepare(kimage);
return 0;
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCH 09/10] MIPS: kexec: add debug info about the new kexec'ed image
2016-11-23 13:43 ` [PATCH 09/10] MIPS: kexec: add debug info about the new kexec'ed image Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
0 siblings, 0 replies; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
Print details of the new kexec image loaded.
Based on the original code from
commit 221f2c770e10d ("arm64/kexec: Add pr_debug output")
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/kernel/machine_kexec.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/arch/mips/kernel/machine_kexec.c b/arch/mips/kernel/machine_kexec.c
index 5972520..8b574bc 100644
--- a/arch/mips/kernel/machine_kexec.c
+++ b/arch/mips/kernel/machine_kexec.c
@@ -28,9 +28,31 @@ atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0);
void (*_crash_smp_send_stop)(void) = NULL;
#endif
+static void kexec_image_info(const struct kimage *kimage)
+{
+ unsigned long i;
+
+ pr_debug("kexec kimage info:\n");
+ pr_debug(" type: %d\n", kimage->type);
+ pr_debug(" start: %lx\n", kimage->start);
+ pr_debug(" head: %lx\n", kimage->head);
+ pr_debug(" nr_segments: %lu\n", kimage->nr_segments);
+
+ for (i = 0; i < kimage->nr_segments; i++) {
+ pr_debug(" segment[%lu]: %016lx - %016lx, 0x%lx bytes, %lu pages\n",
+ i,
+ kimage->segment[i].mem,
+ kimage->segment[i].mem + kimage->segment[i].memsz,
+ (unsigned long)kimage->segment[i].memsz,
+ (unsigned long)kimage->segment[i].memsz / PAGE_SIZE);
+ }
+}
+
int
machine_kexec_prepare(struct kimage *kimage)
{
+ kexec_image_info(kimage);
+
if (_machine_kexec_prepare)
return _machine_kexec_prepare(kimage);
return 0;
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH 10/10] MIPS: generic/kexec: add support for a DTB passed in a separate buffer
2016-11-23 13:43 [PATCH 00/10] various fixes for kexec crashkernel support Marcin Nowakowski
` (9 preceding siblings ...)
2016-11-23 13:43 ` [PATCH 09/10] MIPS: kexec: add debug info about the new kexec'ed image Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
2016-11-23 13:43 ` Marcin Nowakowski
10 siblings, 1 reply; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/generic/Makefile | 1 +
arch/mips/generic/kexec.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+)
create mode 100644 arch/mips/generic/kexec.c
diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile
index 7c66494..acb9b6d 100644
--- a/arch/mips/generic/Makefile
+++ b/arch/mips/generic/Makefile
@@ -13,3 +13,4 @@ obj-y += irq.o
obj-y += proc.o
obj-$(CONFIG_LEGACY_BOARD_SEAD3) += board-sead3.o
+obj-$(CONFIG_KEXEC) += kexec.o
diff --git a/arch/mips/generic/kexec.c b/arch/mips/generic/kexec.c
new file mode 100644
index 0000000..61f812b
--- /dev/null
+++ b/arch/mips/generic/kexec.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ * Author: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kexec.h>
+#include <linux/libfdt.h>
+#include <linux/uaccess.h>
+
+static int generic_kexec_prepare(struct kimage *image)
+{
+ int i;
+
+ for (i = 0; i < image->nr_segments; i++) {
+ struct fdt_header fdt;
+
+ if (image->segment[i].memsz <= sizeof(fdt))
+ continue;
+
+ if (copy_from_user(&fdt, image->segment[i].buf, sizeof(fdt)))
+ continue;
+
+ if (fdt_check_header(&fdt))
+ continue;
+
+ kexec_args[0] = -2;
+ kexec_args[1] = (unsigned long)
+ phys_to_virt((unsigned long)image->segment[i].mem);
+ break;
+ }
+ return 0;
+}
+
+static int __init register_generic_kexec(void)
+{
+ _machine_kexec_prepare = generic_kexec_prepare;
+ return 0;
+}
+arch_initcall(register_generic_kexec);
+
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PATCH 10/10] MIPS: generic/kexec: add support for a DTB passed in a separate buffer
2016-11-23 13:43 ` [PATCH 10/10] MIPS: generic/kexec: add support for a DTB passed in a separate buffer Marcin Nowakowski
@ 2016-11-23 13:43 ` Marcin Nowakowski
0 siblings, 0 replies; 22+ messages in thread
From: Marcin Nowakowski @ 2016-11-23 13:43 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
Signed-off-by: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
---
arch/mips/generic/Makefile | 1 +
arch/mips/generic/kexec.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+)
create mode 100644 arch/mips/generic/kexec.c
diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile
index 7c66494..acb9b6d 100644
--- a/arch/mips/generic/Makefile
+++ b/arch/mips/generic/Makefile
@@ -13,3 +13,4 @@ obj-y += irq.o
obj-y += proc.o
obj-$(CONFIG_LEGACY_BOARD_SEAD3) += board-sead3.o
+obj-$(CONFIG_KEXEC) += kexec.o
diff --git a/arch/mips/generic/kexec.c b/arch/mips/generic/kexec.c
new file mode 100644
index 0000000..61f812b
--- /dev/null
+++ b/arch/mips/generic/kexec.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 Imagination Technologies
+ * Author: Marcin Nowakowski <marcin.nowakowski@imgtec.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kexec.h>
+#include <linux/libfdt.h>
+#include <linux/uaccess.h>
+
+static int generic_kexec_prepare(struct kimage *image)
+{
+ int i;
+
+ for (i = 0; i < image->nr_segments; i++) {
+ struct fdt_header fdt;
+
+ if (image->segment[i].memsz <= sizeof(fdt))
+ continue;
+
+ if (copy_from_user(&fdt, image->segment[i].buf, sizeof(fdt)))
+ continue;
+
+ if (fdt_check_header(&fdt))
+ continue;
+
+ kexec_args[0] = -2;
+ kexec_args[1] = (unsigned long)
+ phys_to_virt((unsigned long)image->segment[i].mem);
+ break;
+ }
+ return 0;
+}
+
+static int __init register_generic_kexec(void)
+{
+ _machine_kexec_prepare = generic_kexec_prepare;
+ return 0;
+}
+arch_initcall(register_generic_kexec);
+
--
2.7.4
^ permalink raw reply related [flat|nested] 22+ messages in thread