Unverified Commit fc0bee18 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!4390 [OLK-6.6] Add kdump support for Phytium S2500

Merge Pull Request from: @liyuting 
 
Kdump support for Phytium S2500

Kernel-issue:
https://gitee.com/open_euler/dashboard?issue_id=I8UDSK

1. Enable kdump service on Phytium S2500.
2. Enable sysrq key by `echo 1 > /proc/sys/kernel/sysrq`
3. Trigger the panic by `echo c > /proc/sysrq-trigger`
4. Kernel panic and automatically reboot.
5. vmcore generate successfully which could be analyse by Crash tools.

Test:
Start the kdump service on the Phytium S2500 and generate the corresponding vmcore successful.

Default config change:
< CONFIG_SYSFS=y
< CONFIG_KEXEC=y or CONFIG_KEXEC_FILE=y
< CONFIG_DEBUG_INFO=y
< CONFIG_CRASH_DUMP=y
< CONFIG_PROC_VMCORE=y
< CONFIG_PROC_KCORE=y
< CONFIG_KEXEC_CORE=y
< CONFIG_CRASH_CORE=y 
 
Link:https://gitee.com/openeuler/kernel/pulls/4390

 

Reviewed-by: default avatarMao HongBo <maohongbo@phytium.com.cn>
Reviewed-by: default avatarZhang Jianhua <chris.zjh@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parents 181ab232 31f8f0a3
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@
#define ARM_CPU_IMP_ARM			0x41
#define ARM_CPU_IMP_APM			0x50
#define ARM_CPU_IMP_CAVIUM		0x43
#define ARM_CPU_IMP_PHYTIUM		0x70
#define ARM_CPU_IMP_BRCM		0x42
#define ARM_CPU_IMP_QCOM		0x51
#define ARM_CPU_IMP_NVIDIA		0x4E
@@ -88,6 +89,7 @@

#define APM_CPU_PART_XGENE		0x000
#define APM_CPU_VAR_POTENZA		0x00
#define PHYTIUM_CPU_PART_2500	0X663

#define CAVIUM_CPU_PART_THUNDERX	0x0A1
#define CAVIUM_CPU_PART_THUNDERX_81XX	0x0A2
@@ -141,6 +143,8 @@
#define MIDR_CORTEX_A72 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
#define MIDR_CORTEX_A73 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A73)
#define MIDR_CORTEX_A75 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A75)
#define MIDR_FT_2500	MIDR_CPU_MODEL(ARM_CPU_IMP_PHYTIUM, PHYTIUM_CPU_PART_2500)

#define MIDR_CORTEX_A35 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A35)
#define MIDR_CORTEX_A55 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A55)
#define MIDR_CORTEX_A76	MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76)
+34 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include <linux/irq_work.h>
#include <linux/kernel_stat.h>
#include <linux/kexec.h>
#include <linux/crash_dump.h>
#include <linux/kvm_host.h>

#include <asm/alternative.h>
@@ -502,6 +503,34 @@ static bool bootcpu_valid __initdata;
static unsigned int cpu_count = 1;

#ifdef CONFIG_ACPI

#ifdef CONFIG_ARCH_PHYTIUM
/*
 * On phytium S2500 multi-socket server, for example 2-socket(2P), there are
 * socekt0 and socket1 on the server:
 * If storage device(like SAS controller and disks to save vmcore into) is
 * installed on socket1 and second kernel brings up 2 CPUs both on socket0 with
 * nr_cpus=2, then vmcore will fail to be saved into the disk as interrupts like
 * SPI and LPI(except SGI) can't communicate across cpu sockets in this server
 * platform.
 * To avoid this issue, Bypass other non-cpu0 to ensure that each cpu0 on each
 * socket can boot up and handle interrupt when booting the second kernel.
 */
static bool __init is_phytium_kdump_cpu_need_bypass(u64 hwid)
{
	if ((read_cpuid_id() & MIDR_CPU_MODEL_MASK) != MIDR_FT_2500)
		return false;

	/*
	 * Bypass other non-cpu0 to ensure second kernel can bring up each cpu0
	 * on each socket
	 */
	if (is_kdump_kernel() && (hwid & 0xffff) != (cpu_logical_map(0) & 0xffff))
		return true;
	return false;
}
#endif

static struct acpi_madt_generic_interrupt cpu_madt_gicc[NR_CPUS];

struct acpi_madt_generic_interrupt *acpi_cpu_get_madt_gicc(int cpu)
@@ -551,6 +580,11 @@ acpi_map_gic_cpu_interface(struct acpi_madt_generic_interrupt *processor)
	if (cpu_count >= NR_CPUS)
		return;

#ifdef CONFIG_ARCH_PHYTIUM
	if (is_phytium_kdump_cpu_need_bypass(hwid))
		return;
#endif

	/* map the logical cpu id to cpu MPIDR */
	set_cpu_logical_map(cpu_count, hwid);

+32 −0
Original line number Diff line number Diff line
@@ -1719,6 +1719,21 @@ static int its_cpumask_select(struct its_device *its_dev,
	cpu = cpumask_any_and(mask_val, cpu_mask);
	cpus = cpus + cpu % skt_cpu_cnt[skt_id];

	if (is_kdump_kernel()) {
		skt = (cpu_logical_map(cpu) >> 16) & 0xff;
		if (skt_id == skt)
			return cpu;

		for (i = 0; i < nr_cpu_ids; i++) {
			skt = (cpu_logical_map(i) >> 16) & 0xff;
			if ((skt >= 0) && (skt < MAX_MARS3_SKT_COUNT)) {
				if (skt_id == skt)
					return i;
			} else if (skt != 0xff)
				pr_err("socket address: %d is out of range.", skt);
		}
	}

	return cpus;
}

@@ -3056,6 +3071,9 @@ static bool enabled_lpis_allowed(void)
	phys_addr_t addr;
	u64 val;

	if (is_kdump_kernel())
		return true;

	/* Check whether the property table is in a reserved region */
	val = gicr_read_propbaser(gic_data_rdist_rd_base() + GICR_PROPBASER);
	addr = val & GENMASK_ULL(51, 12);
@@ -3704,6 +3722,20 @@ static int its_cpumask_first(struct its_device *its_dev,
	if ((cpu > cpus) && (cpu < (cpus + skt_cpu_cnt[skt_id])))
		cpus = cpu;

	if (is_kdump_kernel()) {
		skt = (cpu_logical_map(cpu) >> 16) & 0xff;
		if (skt_id == skt)
			return cpu;
		for (i = 0; i < nr_cpu_ids; i++) {
			skt = (cpu_logical_map(i) >> 16) & 0xff;
			if ((skt >= 0) && (skt < MAX_MARS3_SKT_COUNT)) {
				if (skt_id == skt)
					return i;
			} else if (skt != 0xff)
				pr_err("socket address: %d is out of range.", skt);
		}
	}

	return cpus;
}

+18 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <linux/acpi.h>
#include <linux/cpu.h>
#include <linux/cpu_pm.h>
#include <linux/crash_dump.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
@@ -1566,6 +1567,20 @@ static int gic_cpumask_select(struct irq_data *d, const struct cpumask *mask_val
	cpu = cpumask_any_and(mask_val, cpu_online_mask);
	cpus = cpus + cpu % skt_cpu_cnt[irq_skt];

	if (is_kdump_kernel()) {
		skt = (cpu_logical_map(cpu) >> 16) & 0xff;
		if (irq_skt == skt)
			return cpu;

		for (i = 0; i < nr_cpu_ids; i++) {
			skt = (cpu_logical_map(i) >> 16) & 0xff;
			if ((skt >= 0) && (skt < MAX_MARS3_SOC_COUNT)) {
				if (irq_skt == skt)
					return i;
			} else if (skt != 0xff)
				pr_err("socket address: %d is out of range.", skt);
		}
	}
	return cpus;
}

@@ -2833,6 +2848,9 @@ gic_acpi_init(union acpi_subtable_headers *header, const unsigned long end)

#ifdef CONFIG_ACPI
	mars3_sockets_bitmap = gic_mars3_sockets_bitmap();
	if (is_kdump_kernel())
		mars3_sockets_bitmap = 0x3;

	if (mars3_sockets_bitmap == 0) {
		mars3_sockets_bitmap = 0x1;
		pr_err("No socket, please check cpus MPIDR_AFFINITY_LEVEL!!!");