Skip to content

Commit 9479bb0

Browse files
committed
Merge branch 'topic/kdump-hotplug' into merge-test
2 parents 949e5fd + 849599b commit 9479bb0

File tree

19 files changed

+714
-359
lines changed

19 files changed

+714
-359
lines changed

arch/powerpc/Kconfig

+4
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,10 @@ config ARCH_SELECTS_CRASH_DUMP
686686
depends on CRASH_DUMP
687687
select RELOCATABLE if PPC64 || 44x || PPC_85xx
688688

689+
config ARCH_SUPPORTS_CRASH_HOTPLUG
690+
def_bool y
691+
depends on PPC64
692+
689693
config FA_DUMP
690694
bool "Firmware-assisted dump"
691695
depends on CRASH_DUMP && PPC64 && (PPC_RTAS || PPC_POWERNV)

arch/powerpc/include/asm/kexec.h

+15
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,17 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
135135
ppc_save_regs(newregs);
136136
}
137137

138+
#ifdef CONFIG_CRASH_HOTPLUG
139+
void arch_crash_handle_hotplug_event(struct kimage *image, void *arg);
140+
#define arch_crash_handle_hotplug_event arch_crash_handle_hotplug_event
141+
142+
int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags);
143+
#define arch_crash_hotplug_support arch_crash_hotplug_support
144+
145+
unsigned int arch_crash_get_elfcorehdr_size(void);
146+
#define crash_get_elfcorehdr_size arch_crash_get_elfcorehdr_size
147+
#endif /* CONFIG_CRASH_HOTPLUG */
148+
138149
extern int crashing_cpu;
139150
extern void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *));
140151
extern void crash_ipi_callback(struct pt_regs *regs);
@@ -185,6 +196,10 @@ static inline void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
185196

186197
#endif /* CONFIG_CRASH_DUMP */
187198

199+
#if defined(CONFIG_KEXEC_FILE) || defined(CONFIG_CRASH_DUMP)
200+
int update_cpus_node(void *fdt);
201+
#endif
202+
188203
#ifdef CONFIG_PPC_BOOK3S_64
189204
#include <asm/book3s/64/kexec.h>
190205
#endif

arch/powerpc/include/asm/kexec_ranges.h

+5-15
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,9 @@
77
void sort_memory_ranges(struct crash_mem *mrngs, bool merge);
88
struct crash_mem *realloc_mem_ranges(struct crash_mem **mem_ranges);
99
int add_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size);
10-
int add_tce_mem_ranges(struct crash_mem **mem_ranges);
11-
int add_initrd_mem_range(struct crash_mem **mem_ranges);
12-
#ifdef CONFIG_PPC_64S_HASH_MMU
13-
int add_htab_mem_range(struct crash_mem **mem_ranges);
14-
#else
15-
static inline int add_htab_mem_range(struct crash_mem **mem_ranges)
16-
{
17-
return 0;
18-
}
19-
#endif
20-
int add_kernel_mem_range(struct crash_mem **mem_ranges);
21-
int add_rtas_mem_range(struct crash_mem **mem_ranges);
22-
int add_opal_mem_range(struct crash_mem **mem_ranges);
23-
int add_reserved_mem_ranges(struct crash_mem **mem_ranges);
24-
10+
int remove_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size);
11+
int get_exclude_memory_ranges(struct crash_mem **mem_ranges);
12+
int get_reserved_memory_ranges(struct crash_mem **mem_ranges);
13+
int get_crash_memory_ranges(struct crash_mem **mem_ranges);
14+
int get_usable_memory_ranges(struct crash_mem **mem_ranges);
2515
#endif /* _ASM_POWERPC_KEXEC_RANGES_H */

arch/powerpc/kexec/Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
# Makefile for the linux kernel.
44
#
55

6-
obj-y += core.o core_$(BITS).o
6+
obj-y += core.o core_$(BITS).o ranges.o
77

88
obj-$(CONFIG_PPC32) += relocate_32.o
99

10-
obj-$(CONFIG_KEXEC_FILE) += file_load.o ranges.o file_load_$(BITS).o elf_$(BITS).o
10+
obj-$(CONFIG_KEXEC_FILE) += file_load.o file_load_$(BITS).o elf_$(BITS).o
1111
obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
1212
obj-$(CONFIG_CRASH_DUMP) += crash.o
1313

arch/powerpc/kexec/core_64.c

+91
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/cpu.h>
1818
#include <linux/hardirq.h>
1919
#include <linux/of.h>
20+
#include <linux/libfdt.h>
2021

2122
#include <asm/page.h>
2223
#include <asm/current.h>
@@ -30,6 +31,7 @@
3031
#include <asm/hw_breakpoint.h>
3132
#include <asm/svm.h>
3233
#include <asm/ultravisor.h>
34+
#include <asm/crashdump-ppc64.h>
3335

3436
int machine_kexec_prepare(struct kimage *image)
3537
{
@@ -419,3 +421,92 @@ static int __init export_htab_values(void)
419421
}
420422
late_initcall(export_htab_values);
421423
#endif /* CONFIG_PPC_64S_HASH_MMU */
424+
425+
#if defined(CONFIG_KEXEC_FILE) || defined(CONFIG_CRASH_DUMP)
426+
/**
427+
* add_node_props - Reads node properties from device node structure and add
428+
* them to fdt.
429+
* @fdt: Flattened device tree of the kernel
430+
* @node_offset: offset of the node to add a property at
431+
* @dn: device node pointer
432+
*
433+
* Returns 0 on success, negative errno on error.
434+
*/
435+
static int add_node_props(void *fdt, int node_offset, const struct device_node *dn)
436+
{
437+
int ret = 0;
438+
struct property *pp;
439+
440+
if (!dn)
441+
return -EINVAL;
442+
443+
for_each_property_of_node(dn, pp) {
444+
ret = fdt_setprop(fdt, node_offset, pp->name, pp->value, pp->length);
445+
if (ret < 0) {
446+
pr_err("Unable to add %s property: %s\n", pp->name, fdt_strerror(ret));
447+
return ret;
448+
}
449+
}
450+
return ret;
451+
}
452+
453+
/**
454+
* update_cpus_node - Update cpus node of flattened device tree using of_root
455+
* device node.
456+
* @fdt: Flattened device tree of the kernel.
457+
*
458+
* Returns 0 on success, negative errno on error.
459+
*/
460+
int update_cpus_node(void *fdt)
461+
{
462+
struct device_node *cpus_node, *dn;
463+
int cpus_offset, cpus_subnode_offset, ret = 0;
464+
465+
cpus_offset = fdt_path_offset(fdt, "/cpus");
466+
if (cpus_offset < 0 && cpus_offset != -FDT_ERR_NOTFOUND) {
467+
pr_err("Malformed device tree: error reading /cpus node: %s\n",
468+
fdt_strerror(cpus_offset));
469+
return cpus_offset;
470+
}
471+
472+
if (cpus_offset > 0) {
473+
ret = fdt_del_node(fdt, cpus_offset);
474+
if (ret < 0) {
475+
pr_err("Error deleting /cpus node: %s\n", fdt_strerror(ret));
476+
return -EINVAL;
477+
}
478+
}
479+
480+
/* Add cpus node to fdt */
481+
cpus_offset = fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"), "cpus");
482+
if (cpus_offset < 0) {
483+
pr_err("Error creating /cpus node: %s\n", fdt_strerror(cpus_offset));
484+
return -EINVAL;
485+
}
486+
487+
/* Add cpus node properties */
488+
cpus_node = of_find_node_by_path("/cpus");
489+
ret = add_node_props(fdt, cpus_offset, cpus_node);
490+
of_node_put(cpus_node);
491+
if (ret < 0)
492+
return ret;
493+
494+
/* Loop through all subnodes of cpus and add them to fdt */
495+
for_each_node_by_type(dn, "cpu") {
496+
cpus_subnode_offset = fdt_add_subnode(fdt, cpus_offset, dn->full_name);
497+
if (cpus_subnode_offset < 0) {
498+
pr_err("Unable to add %s subnode: %s\n", dn->full_name,
499+
fdt_strerror(cpus_subnode_offset));
500+
ret = cpus_subnode_offset;
501+
goto out;
502+
}
503+
504+
ret = add_node_props(fdt, cpus_subnode_offset, dn);
505+
if (ret < 0)
506+
goto out;
507+
}
508+
out:
509+
of_node_put(dn);
510+
return ret;
511+
}
512+
#endif /* CONFIG_KEXEC_FILE || CONFIG_CRASH_DUMP */

0 commit comments

Comments
 (0)