Commit 00b006d8 authored by Mao HongBo's avatar Mao HongBo Committed by Zheng Zengkai
Browse files

Phytium/S2500: kdump: Avoid vmcore saving failure across multi-socket

phytium inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I41AUQ



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

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.

Signed-off-by: default avatarMao HongBo <maohongbo@phytium.com.cn>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
Reviewed-by: default avatarHanjun Guo <guohanjun@huawei.com>
Acked-by: default avatarXie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: default avatarZheng Zengkai <zhengzengkai@huawei.com>
parent 0683413f
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@

#include <linux/kvm_host.h>
#include <linux/perf/arm_pmu.h>
#include <linux/crash_dump.h>

#include <asm/alternative.h>
#include <asm/atomic.h>
@@ -702,6 +703,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)
@@ -748,6 +777,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);