From 4a51a6615f6c029a56648d89251de07bb7c8e2c0 Mon Sep 17 00:00:00 2001 From: Michael Zhao Date: Sat, 28 Jan 2023 19:27:39 +0800 Subject: [PATCH] arch: Fix AArch64 socket setting in CPU topology Before Linux v6.0, AArch64 didn't support "socket" in "cpu-map" (CPU topology) of FDT. We found that clusters can be used in the same way of sockets. That is the way we implemented the socket settings in Cloud Hypervisor. But in fact it was a bug. Linux commit 26a2b7 fixed the mistake. So the cluster nodes can no longer act as sockets. And in a following commit dea8c0, sockets were supported. This patch fixed the way to configure sockets. In each socket, a default cluster was added to contain all the cores, because cluster layer is mandatory in CPU topology on AArch64. This fix will break the socket settings on the guests where the kernel version is lower than v6.0. In that case, if socket number is set to more than 1, the kernel will treat that as FDT mistake and all the CPUs will be put in single cluster of single socket. The patch only impacts the case of using FDT, not ACPI. Signed-off-by: Michael Zhao --- arch/src/aarch64/fdt.rs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/arch/src/aarch64/fdt.rs b/arch/src/aarch64/fdt.rs index 2d6978ec2..365c481e5 100644 --- a/arch/src/aarch64/fdt.rs +++ b/arch/src/aarch64/fdt.rs @@ -191,9 +191,13 @@ fn create_cpu_nodes( let cpu_map_node = fdt.begin_node("cpu-map")?; // Create device tree nodes with regard of above mapping. - for cluster_idx in 0..packages { - let cluster_name = format!("cluster{cluster_idx:x}"); - let cluster_node = fdt.begin_node(&cluster_name)?; + for package_idx in 0..packages { + let package_name = format!("socket{package_idx:x}"); + let package_node = fdt.begin_node(&package_name)?; + + // Cluster is the container of cores, and it is mandatory in the CPU topology. + // Add a default "cluster0" in each socket/package. + let cluster_node = fdt.begin_node("cluster0")?; for core_idx in 0..cores_per_package { let core_name = format!("core{core_idx:x}"); @@ -202,7 +206,7 @@ fn create_cpu_nodes( for thread_idx in 0..threads_per_core { let thread_name = format!("thread{thread_idx:x}"); let thread_node = fdt.begin_node(&thread_name)?; - let cpu_idx = threads_per_core * cores_per_package * cluster_idx + let cpu_idx = threads_per_core * cores_per_package * package_idx + threads_per_core * core_idx + thread_idx; fdt.property_u32("cpu", cpu_idx as u32 + FIRST_VCPU_PHANDLE)?; @@ -212,6 +216,7 @@ fn create_cpu_nodes( fdt.end_node(core_node)?; } fdt.end_node(cluster_node)?; + fdt.end_node(package_node)?; } fdt.end_node(cpu_map_node)?; } else {