Skip to content

Commit

Permalink
Automatic merge of 'next' into merge (2024-05-13 23:14)
Browse files Browse the repository at this point in the history
  • Loading branch information
mpe committed May 13, 2024
2 parents 1ef514a + e789d44 commit 4727911
Show file tree
Hide file tree
Showing 34 changed files with 1,102 additions and 501 deletions.
7 changes: 7 additions & 0 deletions Documentation/ABI/testing/sysfs-kernel-fadump
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,10 @@ Description: read only
memory add/remove events because elfcorehdr is now prepared in
the second/fadump kernel.
User: kexec-tools

What: /sys/kernel/fadump/bootargs_append
Date: May 2024
Contact: linuxppc-dev@lists.ozlabs.org
Description: read/write
This is a special sysfs file available to setup additional
parameters to be passed to capture kernel.
8 changes: 4 additions & 4 deletions Documentation/virt/kvm/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4300,7 +4300,7 @@ operating system that uses the PIT for timing (e.g. Linux 2.4.x).
4.100 KVM_PPC_CONFIGURE_V3_MMU
------------------------------

:Capability: KVM_CAP_PPC_RADIX_MMU or KVM_CAP_PPC_HASH_MMU_V3
:Capability: KVM_CAP_PPC_MMU_RADIX or KVM_CAP_PPC_MMU_HASH_V3
:Architectures: ppc
:Type: vm ioctl
:Parameters: struct kvm_ppc_mmuv3_cfg (in)
Expand Down Expand Up @@ -4334,7 +4334,7 @@ the Power ISA V3.00, Book III section 5.7.6.1.
4.101 KVM_PPC_GET_RMMU_INFO
---------------------------

:Capability: KVM_CAP_PPC_RADIX_MMU
:Capability: KVM_CAP_PPC_MMU_RADIX
:Architectures: ppc
:Type: vm ioctl
:Parameters: struct kvm_ppc_rmmu_info (out)
Expand Down Expand Up @@ -8095,7 +8095,7 @@ capability via KVM_ENABLE_CAP ioctl on the vcpu fd. Note that this
will disable the use of APIC hardware virtualization even if supported
by the CPU, as it's incompatible with SynIC auto-EOI behavior.

8.3 KVM_CAP_PPC_RADIX_MMU
8.3 KVM_CAP_PPC_MMU_RADIX
-------------------------

:Architectures: ppc
Expand All @@ -8105,7 +8105,7 @@ available, means that the kernel can support guests using the
radix MMU defined in Power ISA V3.00 (as implemented in the POWER9
processor).

8.4 KVM_CAP_PPC_HASH_MMU_V3
8.4 KVM_CAP_PPC_MMU_HASH_V3
---------------------------

:Architectures: ppc
Expand Down
4 changes: 4 additions & 0 deletions arch/powerpc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -686,6 +686,10 @@ config ARCH_SELECTS_CRASH_DUMP
depends on CRASH_DUMP
select RELOCATABLE if PPC64 || 44x || PPC_85xx

config ARCH_SUPPORTS_CRASH_HOTPLUG
def_bool y
depends on PPC64

config FA_DUMP
bool "Firmware-assisted dump"
depends on CRASH_DUMP && PPC64 && (PPC_RTAS || PPC_POWERNV)
Expand Down
5 changes: 4 additions & 1 deletion arch/powerpc/include/asm/fadump-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ struct fw_dump {
unsigned long cpu_notes_buf_vaddr;
unsigned long cpu_notes_buf_size;

unsigned long param_area;

/*
* Maximum size supported by firmware to copy from source to
* destination address per entry.
Expand All @@ -138,6 +140,7 @@ struct fw_dump {
unsigned long dump_active:1;
unsigned long dump_registered:1;
unsigned long nocma:1;
unsigned long param_area_supported:1;

struct fadump_ops *ops;
};
Expand All @@ -156,14 +159,14 @@ struct fadump_ops {
struct seq_file *m);
void (*fadump_trigger)(struct fadump_crash_info_header *fdh,
const char *msg);
int (*fadump_max_boot_mem_rgns)(void);
};

/* Helper functions */
s32 __init fadump_setup_cpu_notes_buf(u32 num_cpus);
void fadump_free_cpu_notes_buf(void);
u32 *__init fadump_regs_to_elf_notes(u32 *buf, struct pt_regs *regs);
void __init fadump_update_elfcore_header(char *bufp);
bool is_fadump_boot_mem_contiguous(void);
bool is_fadump_reserved_mem_contiguous(void);

#else /* !CONFIG_PRESERVE_FA_DUMP */
Expand Down
2 changes: 2 additions & 0 deletions arch/powerpc/include/asm/fadump.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ extern int is_fadump_active(void);
extern int should_fadump_crash(void);
extern void crash_fadump(struct pt_regs *, const char *);
extern void fadump_cleanup(void);
extern void fadump_append_bootargs(void);

#else /* CONFIG_FA_DUMP */
static inline int is_fadump_active(void) { return 0; }
static inline int should_fadump_crash(void) { return 0; }
static inline void crash_fadump(struct pt_regs *regs, const char *str) { }
static inline void fadump_cleanup(void) { }
static inline void fadump_append_bootargs(void) { }
#endif /* !CONFIG_FA_DUMP */

#if defined(CONFIG_FA_DUMP) || defined(CONFIG_PRESERVE_FA_DUMP)
Expand Down
15 changes: 15 additions & 0 deletions arch/powerpc/include/asm/kexec.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,17 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
ppc_save_regs(newregs);
}

#ifdef CONFIG_CRASH_HOTPLUG
void arch_crash_handle_hotplug_event(struct kimage *image, void *arg);
#define arch_crash_handle_hotplug_event arch_crash_handle_hotplug_event

int arch_crash_hotplug_support(struct kimage *image, unsigned long kexec_flags);
#define arch_crash_hotplug_support arch_crash_hotplug_support

unsigned int arch_crash_get_elfcorehdr_size(void);
#define crash_get_elfcorehdr_size arch_crash_get_elfcorehdr_size
#endif /* CONFIG_CRASH_HOTPLUG */

extern int crashing_cpu;
extern void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *));
extern void crash_ipi_callback(struct pt_regs *regs);
Expand Down Expand Up @@ -185,6 +196,10 @@ static inline void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))

#endif /* CONFIG_CRASH_DUMP */

#if defined(CONFIG_KEXEC_FILE) || defined(CONFIG_CRASH_DUMP)
int update_cpus_node(void *fdt);
#endif

#ifdef CONFIG_PPC_BOOK3S_64
#include <asm/book3s/64/kexec.h>
#endif
Expand Down
20 changes: 5 additions & 15 deletions arch/powerpc/include/asm/kexec_ranges.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,9 @@
void sort_memory_ranges(struct crash_mem *mrngs, bool merge);
struct crash_mem *realloc_mem_ranges(struct crash_mem **mem_ranges);
int add_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size);
int add_tce_mem_ranges(struct crash_mem **mem_ranges);
int add_initrd_mem_range(struct crash_mem **mem_ranges);
#ifdef CONFIG_PPC_64S_HASH_MMU
int add_htab_mem_range(struct crash_mem **mem_ranges);
#else
static inline int add_htab_mem_range(struct crash_mem **mem_ranges)
{
return 0;
}
#endif
int add_kernel_mem_range(struct crash_mem **mem_ranges);
int add_rtas_mem_range(struct crash_mem **mem_ranges);
int add_opal_mem_range(struct crash_mem **mem_ranges);
int add_reserved_mem_ranges(struct crash_mem **mem_ranges);

int remove_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size);
int get_exclude_memory_ranges(struct crash_mem **mem_ranges);
int get_reserved_memory_ranges(struct crash_mem **mem_ranges);
int get_crash_memory_ranges(struct crash_mem **mem_ranges);
int get_usable_memory_ranges(struct crash_mem **mem_ranges);
#endif /* _ASM_POWERPC_KEXEC_RANGES_H */
149 changes: 125 additions & 24 deletions arch/powerpc/kernel/fadump.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,41 @@ static int __init fadump_cma_init(void)
static int __init fadump_cma_init(void) { return 1; }
#endif /* CONFIG_CMA */

/*
* Additional parameters meant for capture kernel are placed in a dedicated area.
* If this is capture kernel boot, append these parameters to bootargs.
*/
void __init fadump_append_bootargs(void)
{
char *append_args;
size_t len;

if (!fw_dump.dump_active || !fw_dump.param_area_supported || !fw_dump.param_area)
return;

if (fw_dump.param_area >= fw_dump.boot_mem_top) {
if (memblock_reserve(fw_dump.param_area, COMMAND_LINE_SIZE)) {
pr_warn("WARNING: Can't use additional parameters area!\n");
fw_dump.param_area = 0;
return;
}
}

append_args = (char *)fw_dump.param_area;
len = strlen(boot_command_line);

/*
* Too late to fail even if cmdline size exceeds. Truncate additional parameters
* to cmdline size and proceed anyway.
*/
if (len + strlen(append_args) >= COMMAND_LINE_SIZE - 1)
pr_warn("WARNING: Appending parameters exceeds cmdline size. Truncating!\n");

pr_debug("Cmdline: %s\n", boot_command_line);
snprintf(boot_command_line + len, COMMAND_LINE_SIZE - len, " %s", append_args);
pr_info("Updated cmdline: %s\n", boot_command_line);
}

/* Scan the Firmware Assisted dump configuration details. */
int __init early_init_dt_scan_fw_dump(unsigned long node, const char *uname,
int depth, void *data)
Expand Down Expand Up @@ -220,28 +255,6 @@ static bool is_fadump_mem_area_contiguous(u64 d_start, u64 d_end)
return ret;
}

/*
* Returns true, if there are no holes in boot memory area,
* false otherwise.
*/
bool is_fadump_boot_mem_contiguous(void)
{
unsigned long d_start, d_end;
bool ret = false;
int i;

for (i = 0; i < fw_dump.boot_mem_regs_cnt; i++) {
d_start = fw_dump.boot_mem_addr[i];
d_end = d_start + fw_dump.boot_mem_sz[i];

ret = is_fadump_mem_area_contiguous(d_start, d_end);
if (!ret)
break;
}

return ret;
}

/*
* Returns true, if there are no holes in reserved memory area,
* false otherwise.
Expand Down Expand Up @@ -381,10 +394,11 @@ static unsigned long __init get_fadump_area_size(void)
static int __init add_boot_mem_region(unsigned long rstart,
unsigned long rsize)
{
int max_boot_mem_rgns = fw_dump.ops->fadump_max_boot_mem_rgns();
int i = fw_dump.boot_mem_regs_cnt++;

if (fw_dump.boot_mem_regs_cnt > FADUMP_MAX_MEM_REGS) {
fw_dump.boot_mem_regs_cnt = FADUMP_MAX_MEM_REGS;
if (fw_dump.boot_mem_regs_cnt > max_boot_mem_rgns) {
fw_dump.boot_mem_regs_cnt = max_boot_mem_rgns;
return 0;
}

Expand Down Expand Up @@ -1452,6 +1466,43 @@ static ssize_t registered_show(struct kobject *kobj,
return sprintf(buf, "%d\n", fw_dump.dump_registered);
}

static ssize_t bootargs_append_show(struct kobject *kobj,
struct kobj_attribute *attr,
char *buf)
{
return sprintf(buf, "%s\n", (char *)__va(fw_dump.param_area));
}

static ssize_t bootargs_append_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
char *params;

if (!fw_dump.fadump_enabled || fw_dump.dump_active)
return -EPERM;

if (count >= COMMAND_LINE_SIZE)
return -EINVAL;

/*
* Fail here instead of handling this scenario with
* some silly workaround in capture kernel.
*/
if (saved_command_line_len + count >= COMMAND_LINE_SIZE) {
pr_err("Appending parameters exceeds cmdline size!\n");
return -ENOSPC;
}

params = __va(fw_dump.param_area);
strscpy_pad(params, buf, COMMAND_LINE_SIZE);
/* Remove newline character at the end. */
if (params[count-1] == '\n')
params[count-1] = '\0';

return count;
}

static ssize_t registered_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
Expand Down Expand Up @@ -1511,6 +1562,7 @@ static struct kobj_attribute enable_attr = __ATTR_RO(enabled);
static struct kobj_attribute register_attr = __ATTR_RW(registered);
static struct kobj_attribute mem_reserved_attr = __ATTR_RO(mem_reserved);
static struct kobj_attribute hotplug_ready_attr = __ATTR_RO(hotplug_ready);
static struct kobj_attribute bootargs_append_attr = __ATTR_RW(bootargs_append);

static struct attribute *fadump_attrs[] = {
&enable_attr.attr,
Expand Down Expand Up @@ -1684,6 +1736,54 @@ static void __init fadump_process(void)
fadump_invalidate_release_mem();
}

/*
* Reserve memory to store additional parameters to be passed
* for fadump/capture kernel.
*/
static void fadump_setup_param_area(void)
{
phys_addr_t range_start, range_end;

if (!fw_dump.param_area_supported || fw_dump.dump_active)
return;

/* This memory can't be used by PFW or bootloader as it is shared across kernels */
if (radix_enabled()) {
/*
* Anywhere in the upper half should be good enough as all memory
* is accessible in real mode.
*/
range_start = memblock_end_of_DRAM() / 2;
range_end = memblock_end_of_DRAM();
} else {
/*
* Passing additional parameters is supported for hash MMU only
* if the first memory block size is 768MB or higher.
*/
if (ppc64_rma_size < 0x30000000)
return;

/*
* 640 MB to 768 MB is not used by PFW/bootloader. So, try reserving
* memory for passing additional parameters in this range to avoid
* being stomped on by PFW/bootloader.
*/
range_start = 0x2A000000;
range_end = range_start + 0x4000000;
}

fw_dump.param_area = memblock_phys_alloc_range(COMMAND_LINE_SIZE,
COMMAND_LINE_SIZE,
range_start,
range_end);
if (!fw_dump.param_area || sysfs_create_file(fadump_kobj, &bootargs_append_attr.attr)) {
pr_warn("WARNING: Could not setup area to pass additional parameters!\n");
return;
}

memset(phys_to_virt(fw_dump.param_area), 0, COMMAND_LINE_SIZE);
}

/*
* Prepare for firmware-assisted dump.
*/
Expand All @@ -1707,6 +1807,7 @@ int __init setup_fadump(void)
}
/* Initialize the kernel dump memory structure and register with f/w */
else if (fw_dump.reserve_dump_area_size) {
fadump_setup_param_area();
fw_dump.ops->fadump_init_mem_struct(&fw_dump);
register_fadump();
}
Expand Down
3 changes: 3 additions & 0 deletions arch/powerpc/kernel/prom.c
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,9 @@ void __init early_init_devtree(void *params)
*/
of_scan_flat_dt(early_init_dt_scan_chosen_ppc, boot_command_line);

/* Append additional parameters passed for fadump capture kernel */
fadump_append_bootargs();

/* Scan memory nodes and rebuild MEMBLOCKs */
early_init_dt_scan_root();
early_init_dt_scan_memory_ppc();
Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/kexec/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
# Makefile for the linux kernel.
#

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

obj-$(CONFIG_PPC32) += relocate_32.o

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

Expand Down
Loading

0 comments on commit 4727911

Please sign in to comment.