From 33f6839ddf5a89bbfc358f1942fa47e31225167b Mon Sep 17 00:00:00 2001 From: Jay Chung Date: Thu, 9 Jul 2026 16:46:42 +0000 Subject: [PATCH] feat(test): add Graviton5 (Neoverse V3) CPU feature baselines Register Graviton5 so the aarch64 CPU feature tests recognise it: - utils_cpuid.py: add the ARM_NEOVERSE_V3 CpuModel and map MIDR part 0xd84 (r0p1) to it. - test_cpu_features_aarch64.py: G5_FEATS = G4_FEATS | {afp, ecv} and the ARM_NEOVERSE_V3 match cases for the default and SVE/PAC templates. wfxt (FEAT_WFxT) reaches the guest from the 6.1 guest kernel, so add it to the guest baseline when the guest kernel is >= 6.1. - test_cpu_features_host_vs_guest.py: add the ARM_NEOVERSE_V3 case. Same SVE/PAC host-only set as G4, plus the shared ssbs host/guest handling. Feature sets captured on m9g.metal-48xl across 5.10/6.1/6.18 hosts. Signed-off-by: Jay Chung --- tests/framework/utils_cpuid.py | 2 + .../functional/test_cpu_features_aarch64.py | 14 +++ .../test_cpu_features_host_vs_guest.py | 93 ++++++++++++------- 3 files changed, 73 insertions(+), 36 deletions(-) diff --git a/tests/framework/utils_cpuid.py b/tests/framework/utils_cpuid.py index 52976d5964a..6f339b115f9 100644 --- a/tests/framework/utils_cpuid.py +++ b/tests/framework/utils_cpuid.py @@ -29,6 +29,7 @@ class CpuModel(str, Enum): ARM_NEOVERSE_N1 = "ARM_NEOVERSE_N1" ARM_NEOVERSE_V1 = "ARM_NEOVERSE_V1" ARM_NEOVERSE_V2 = "ARM_NEOVERSE_V2" + ARM_NEOVERSE_V3 = "ARM_NEOVERSE_V3" INTEL_CASCADELAKE = "INTEL_CASCADELAKE" INTEL_ICELAKE = "INTEL_ICELAKE" INTEL_SAPPHIRE_RAPIDS = "INTEL_SAPPHIRE_RAPIDS" @@ -48,6 +49,7 @@ class CpuModel(str, Enum): "0xd0c": "ARM_NEOVERSE_N1", "0xd40": "ARM_NEOVERSE_V1", "0xd4f": "ARM_NEOVERSE_V2", + "0xd84": "ARM_NEOVERSE_V3", }, } diff --git a/tests/integration_tests/functional/test_cpu_features_aarch64.py b/tests/integration_tests/functional/test_cpu_features_aarch64.py index 2cafe5f6352..3e710c36fa8 100644 --- a/tests/integration_tests/functional/test_cpu_features_aarch64.py +++ b/tests/integration_tests/functional/test_cpu_features_aarch64.py @@ -31,6 +31,10 @@ "paca pacg sve sve2 sveaes svebitperm svepmull svesha3 svebf16 svei8mm".split() ) +G5_FEATS = G4_FEATS | set("afp ecv".split()) + +G5_SVE_AND_PAC = G4_SVE_AND_PAC + @pin_cpu_template(ALL_CPU_TEMPLATES) def test_guest_cpu_features(uvm_any): @@ -55,6 +59,16 @@ def test_guest_cpu_features(uvm_any): expected_cpu_features = G4_FEATS case CpuModel.ARM_NEOVERSE_V2, "AARCH64_WITH_SVE_AND_PAC": expected_cpu_features = G4_FEATS | G4_SVE_AND_PAC + case CpuModel.ARM_NEOVERSE_V3, "None": + expected_cpu_features = G5_FEATS + case CpuModel.ARM_NEOVERSE_V3, "AARCH64_WITH_SVE_AND_PAC": + expected_cpu_features = G5_FEATS | G5_SVE_AND_PAC + + if ( + global_props.cpu_model == CpuModel.ARM_NEOVERSE_V3 + and vm.guest_kernel_version >= (6, 1) + ): + expected_cpu_features = expected_cpu_features | {"wfxt"} guest_feats = set(vm.ssh.check_output(CPU_FEATURES_CMD).stdout.split()) assert guest_feats == expected_cpu_features diff --git a/tests/integration_tests/functional/test_cpu_features_host_vs_guest.py b/tests/integration_tests/functional/test_cpu_features_host_vs_guest.py index c80fb39e699..100a01ee8ec 100644 --- a/tests/integration_tests/functional/test_cpu_features_host_vs_guest.py +++ b/tests/integration_tests/functional/test_cpu_features_host_vs_guest.py @@ -258,6 +258,25 @@ } +def ssbs_host_guest_delta(vm): + """Return (host_only, guest_only) "ssbs" sets for a Neoverse core. + + Kernel v6.11+ hides "ssbs" from lscpu due to an errata. Amazon Linux + (v5.10, v6.1) backported the fix but our ubuntu host (v6.8) and guest + kernels (v5.10, v6.1) did not, so the host and guest can disagree. + https://github.com/torvalds/linux/commit/adeec61a4723fd3e39da68db4cc4d924e6d7f641 + """ + host_has_ssbs = global_props.host_os not in { + "amzn2", + "amzn2023", + } and global_props.host_linux_version_tpl < (6, 11) + guest_has_ssbs = vm.guest_kernel_version < (6, 11) + + host_only = {"ssbs"} if host_has_ssbs and not guest_has_ssbs else set() + guest_only = {"ssbs"} if guest_has_ssbs and not host_has_ssbs else set() + return host_only, guest_only + + def test_host_vs_guest_cpu_features(uvm): """Check CPU features host vs guest""" @@ -516,24 +535,9 @@ def test_host_vs_guest_cpu_features(uvm): expected_guest_minus_host = set() expected_host_minus_guest = set() - # Upstream kernel v6.11+ hides "ssbs" from "lscpu" on Neoverse-N1 and Neoverse-V1 since - # they have an errata whereby an MSR to the SSBS special-purpose register does not - # affect subsequent speculative instructions, permitting speculative store bypassing for - # a window of time. - # https://github.com/torvalds/linux/commit/adeec61a4723fd3e39da68db4cc4d924e6d7f641 - # - # While Amazon Linux kernels (v5.10 and v6.1) backported the above commit, our test - # ubuntu kernel (v6.8) and our guest kernels (v5.10 and v6.1) don't pick it. - host_has_ssbs = global_props.host_os not in { - "amzn2", - "amzn2023", - } and global_props.host_linux_version_tpl < (6, 11) - guest_has_ssbs = vm.guest_kernel_version < (6, 11) - - if host_has_ssbs and not guest_has_ssbs: - expected_host_minus_guest |= {"ssbs"} - if not host_has_ssbs and guest_has_ssbs: - expected_guest_minus_host |= {"ssbs"} + ssbs_host, ssbs_guest = ssbs_host_guest_delta(vm) + expected_host_minus_guest |= ssbs_host + expected_guest_minus_host |= ssbs_guest assert host_feats - guest_feats == expected_host_minus_guest assert guest_feats - host_feats == expected_guest_minus_host @@ -553,24 +557,41 @@ def test_host_vs_guest_cpu_features(uvm): "svepmull", } - # Upstream kernel v6.11+ hides "ssbs" from "lscpu" on Neoverse-N1 and Neoverse-V1 since - # they have an errata whereby an MSR to the SSBS special-purpose register does not - # affect subsequent speculative instructions, permitting speculative store bypassing for - # a window of time. - # https://github.com/torvalds/linux/commit/adeec61a4723fd3e39da68db4cc4d924e6d7f641 - # - # While Amazon Linux kernels (v5.10 and v6.1) backported the above commit, our test - # ubuntu kernel (v6.8) and our guest kernels (v5.10 and v6.1) don't pick it. - host_has_ssbs = global_props.host_os not in { - "amzn2", - "amzn2023", - } and global_props.host_linux_version_tpl < (6, 11) - guest_has_ssbs = vm.guest_kernel_version < (6, 11) - - if host_has_ssbs and not guest_has_ssbs: - expected_host_minus_guest |= {"ssbs"} - if not host_has_ssbs and guest_has_ssbs: - expected_guest_minus_host |= {"ssbs"} + ssbs_host, ssbs_guest = ssbs_host_guest_delta(vm) + expected_host_minus_guest |= ssbs_host + expected_guest_minus_host |= ssbs_guest + + assert host_feats - guest_feats == expected_host_minus_guest + assert guest_feats - host_feats == expected_guest_minus_host + + case CpuModel.ARM_NEOVERSE_V3: + expected_guest_minus_host = set() + expected_host_minus_guest = { + "paca", + "pacg", + "sve", + "sve2", + "sveaes", + "svebf16", + "svebitperm", + "svei8mm", + "svepmull", + "svesha3", + } + + # The "wfxt" (FEAT_WFxT) hwcap is exposed to userspace from kernel + # v6.1 (absent in v5.10, including Amazon Linux 5.10). + host_has_wfxt = global_props.host_linux_version_tpl >= (6, 1) + guest_has_wfxt = vm.guest_kernel_version >= (6, 1) + + if host_has_wfxt and not guest_has_wfxt: + expected_host_minus_guest |= {"wfxt"} + if not host_has_wfxt and guest_has_wfxt: + expected_guest_minus_host |= {"wfxt"} + + ssbs_host, ssbs_guest = ssbs_host_guest_delta(vm) + expected_host_minus_guest |= ssbs_host + expected_guest_minus_host |= ssbs_guest assert host_feats - guest_feats == expected_host_minus_guest assert guest_feats - host_feats == expected_guest_minus_host