From 48de27878b6fb3d0c89a50471081bc5551c47671 Mon Sep 17 00:00:00 2001 From: CodeAlex <59381946+CodeAlex52@users.noreply.github.com> Date: Tue, 29 Sep 2026 08:30:00 +0000 Subject: [PATCH 1/2] cpuinfo: parse arm64 CPU identity fields (implementer/variant/part/revision) The arm64 parser only read processor/BogoMIPS/Features/model name. arm64 kernels do not emit a "model name" line, so VendorID, CPUFamily, Model and Stepping were always empty and node_cpu_info lost all CPU identity labels on arm64 hosts. Parse the CPU implementer/variant/part/revision lines into the existing identity fields, following the kernel's arch/arm64/kernel/cpuinfo.c output. Non-arm64 behavior is unchanged. Regression: two-CPU arm64 fixture asserting the identity fields. Closes #875 Signed-off-by: CodeAlex <59381946+CodeAlex52@users.noreply.github.com> --- cpuinfo.go | 8 ++++++++ cpuinfo_test.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/cpuinfo.go b/cpuinfo.go index 7a31a455..b3757bbf 100644 --- a/cpuinfo.go +++ b/cpuinfo.go @@ -243,6 +243,14 @@ func parseCPUInfoARM(info []byte) ([]CPUInfo, error) { featuresLine = line case "model name": cpuinfo[i].ModelName = field[1] + case "CPU implementer": + cpuinfo[i].VendorID = field[1] + case "CPU variant": + cpuinfo[i].CPUFamily = field[1] + case "CPU part": + cpuinfo[i].Model = field[1] + case "CPU revision": + cpuinfo[i].Stepping = field[1] } } fields := strings.SplitN(featuresLine, ": ", 2) diff --git a/cpuinfo_test.go b/cpuinfo_test.go index 9f49eeb3..7e6b9f54 100644 --- a/cpuinfo_test.go +++ b/cpuinfo_test.go @@ -478,3 +478,47 @@ func TestCPUInfoParseLoong64(t *testing.T) { t.Errorf("want CPUFamily '%v', have '%v'", want, have) } } + +const cpuinfoArm64Identity = `processor : 0 +BogoMIPS : 100.00 +Features : fp asimd aes sha1 sha2 crc32 +CPU implementer : 0x41 +CPU variant : 0x1 +CPU part : 0xd40 +CPU revision : 0 + +processor : 1 +BogoMIPS : 100.00 +Features : fp asimd aes sha1 sha2 crc32 +CPU implementer : 0x41 +CPU variant : 0x1 +CPU part : 0xd40 +CPU revision : 0 +` + +func TestParseCPUInfoARM64IdentityFields(t *testing.T) { + parsed, err := parseCPUInfoARM([]byte(cpuinfoArm64Identity)) + if err != nil { + t.Fatalf("parseCPUInfoARM returned an error: %v", err) + } + if len(parsed) != 2 { + t.Fatalf("expected 2 CPUs, got %d", len(parsed)) + } + for i, cpu := range parsed { + // arm64 kernels have no "model name" line; the implementer/variant/ + // part/revision fields are the only CPU identity available and must + // not be dropped by the parser. + if cpu.VendorID != "0x41" { + t.Errorf("cpu %d: VendorID = %q, want %q", i, cpu.VendorID, "0x41") + } + if cpu.CPUFamily != "0x1" { + t.Errorf("cpu %d: CPUFamily = %q, want %q", i, cpu.CPUFamily, "0x1") + } + if cpu.Model != "0xd40" { + t.Errorf("cpu %d: Model = %q, want %q", i, cpu.Model, "0xd40") + } + if cpu.Stepping != "0x0" { + t.Errorf("cpu %d: Stepping = %q, want %q", i, cpu.Stepping, "0x0") + } + } +} From 28016ca10541f0beb9bb8d0611d88e5988ca97ed Mon Sep 17 00:00:00 2001 From: CodeAlex <59381946+CodeAlex52@users.noreply.github.com> Date: Tue, 29 Sep 2026 15:10:32 +0800 Subject: [PATCH 2/2] test: CPU revision is printed in decimal by the kernel --- cpuinfo_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpuinfo_test.go b/cpuinfo_test.go index 7e6b9f54..6f6316e9 100644 --- a/cpuinfo_test.go +++ b/cpuinfo_test.go @@ -517,8 +517,8 @@ func TestParseCPUInfoARM64IdentityFields(t *testing.T) { if cpu.Model != "0xd40" { t.Errorf("cpu %d: Model = %q, want %q", i, cpu.Model, "0xd40") } - if cpu.Stepping != "0x0" { - t.Errorf("cpu %d: Stepping = %q, want %q", i, cpu.Stepping, "0x0") + if cpu.Stepping != "0" { + t.Errorf("cpu %d: Stepping = %q, want %q", i, cpu.Stepping, "0") } } }