Commit 31f8f0a3 authored by Li Yuting's avatar Li Yuting
Browse files

Add kdump support for Phytium S2500

phytium inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I8UDSK


CVE: NA

---------------------------------------------------------

Add kdump support for Phytium S2500

Signed-off-by: default avatarCui Fulong <cuifulong2112@phytium.com.cn>
Signed-off-by: default avatarLi Yuting <liyuting2071@phytium.com.cn>
parent ade50f9f
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!!!");