Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(test): Handle CPU feature diff between host and guest correctly #4900

Merged
merged 4 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 49 additions & 10 deletions tests/integration_tests/functional/test_cpu_features_aarch64.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import framework.utils_cpuid as cpuid_utils
from framework import utils
from framework.properties import global_props
from framework.utils_cpuid import CPU_FEATURES_CMD, CpuModel

PLATFORM = platform.machine()
Expand Down Expand Up @@ -81,25 +82,63 @@ def test_host_vs_guest_cpu_features_aarch64(uvm_nano):
cpu_model = cpuid_utils.get_cpu_model_name()
match cpu_model:
case CpuModel.ARM_NEOVERSE_N1:
assert host_feats - guest_feats == set()
# Kernel should hide this feature, but our guest kernel
# currently lacks the commit with this change.
# The commit that introduces the change:
# https://github.com/torvalds/linux/commit/7187bb7d0b5c7dfa18ca82e9e5c75e13861b1d88
assert guest_feats - host_feats == {"ssbs"}
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"}

assert host_feats - guest_feats == expected_host_minus_guest
assert guest_feats - host_feats == expected_guest_minus_host
case CpuModel.ARM_NEOVERSE_V1:
expected_guest_minus_host = set()
# KVM does not enable PAC or SVE features by default
# and Firecracker does not enable them either.
assert host_feats - guest_feats == {
expected_host_minus_guest = {
"paca",
"pacg",
"sve",
"svebf16",
"svei8mm",
}
# kernel should hide this feature, but our guest kernel
# is not recent enough for this.
assert guest_feats - host_feats == {"ssbs"}

# 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"}

assert host_feats - guest_feats == expected_host_minus_guest
assert guest_feats - host_feats == expected_guest_minus_host
case _:
if os.environ.get("BUILDKITE") is not None:
assert False, f"Cpu model {cpu_model} is not supported"
Expand Down
25 changes: 23 additions & 2 deletions tests/integration_tests/functional/test_cpu_features_x86_64.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ def test_host_vs_guest_cpu_features_x86_64(uvm_nano):
"umip",
}
case CpuModel.INTEL_CASCADELAKE:
assert host_feats - guest_feats == {
expected_host_minus_guest = {
"acpi",
"aperfmperf",
"arch_perfmon",
Expand Down Expand Up @@ -392,11 +392,32 @@ def test_host_vs_guest_cpu_features_x86_64(uvm_nano):
"vpid",
"xtpr",
}
assert guest_feats - host_feats == {
expected_guest_minus_host = {
"hypervisor",
"tsc_known_freq",
"umip",
}

# Linux kernel v6.4+ passes through the CPUID bit for "flush_l1d" to guests.
# https://github.com/torvalds/linux/commit/45cf86f26148e549c5ba4a8ab32a390e4bde216e
#
# Our test ubuntu host kernel is v6.8 and has the commit.
if global_props.host_linux_version_tpl >= (6, 4):
expected_host_minus_guest -= {"flush_l1d"}

# Linux kernel v6.6+ drops the "invpcid_single" synthetic feature bit.
# https://github.com/torvalds/linux/commit/54e3d9434ef61b97fd3263c141b928dc5635e50d
#
# Our test ubuntu host kernel is v6.8 and has the commit.
host_has_invpcid_single = global_props.host_linux_version_tpl < (6, 6)
guest_has_invpcid_single = vm.guest_kernel_version < (6, 6)
if host_has_invpcid_single and not guest_has_invpcid_single:
expected_host_minus_guest |= {"invpcid_single"}
if not host_has_invpcid_single and guest_has_invpcid_single:
expected_guest_minus_host |= {"invpcid_single"}

assert host_feats - guest_feats == expected_host_minus_guest
assert guest_feats - host_feats == expected_guest_minus_host
case CpuModel.INTEL_ICELAKE:
host_guest_diff_5_10 = {
"dtes64",
Expand Down
Loading