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

test: add a test to check for nested virtualization #4404

Merged
merged 5 commits into from
Jan 25, 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
10 changes: 0 additions & 10 deletions .buildkite/pipeline_cpu_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,6 @@ class BkStep(str, Enum):
},
"instances": ["m5d.metal", "m6i.metal", "m6a.metal"],
},
"aarch64_cpu_templates": {
BkStep.COMMAND: [
"tools/devtool -y test -- -s -ra -m nonci --log-cli-level=INFO integration_tests/functional/test_cpu_features_aarch64.py"
],
BkStep.LABEL: "📖 cpu templates",
"instances": ["m6g.metal", "c7g.metal"],
"platforms": [("al2023", "linux_6.1")],
},
"fingerprint": {
BkStep.COMMAND: [
"tools/devtool -y test -- -m no_block_pr integration_tests/functional/test_cpu_template_helper.py -k test_guest_cpu_config_change",
Expand Down Expand Up @@ -171,8 +163,6 @@ def main():
test_group = group_single(cpu_template_test[test_args.test])
elif test_args.test == "cpuid_wrmsr":
test_group = group_snapshot_restore(cpu_template_test[test_args.test])
elif test_args.test == "aarch64_cpu_templates":
test_group = group_single(cpu_template_test[test_args.test])
elif test_args.test == "fingerprint":
test_group = group_single(cpu_template_test[test_args.test])

Expand Down
12 changes: 12 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,18 @@ def custom_cpu_template(request, record_property):
return request.param


@pytest.fixture(
params=list(static_cpu_templates_params()) + list(custom_cpu_templates_params())
)
def cpu_template_any(request, record_property):
"""This fixture combines static and custom CPU templates"""
if "name" in request.param:
record_property("custom_cpu_template", request.param["name"])
else:
record_property("static_cpu_template", request.param)
return request.param


@pytest.fixture(params=["Sync", "Async"])
def io_engine(request):
"""All supported io_engines"""
Expand Down
5 changes: 5 additions & 0 deletions tests/framework/properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ def __init__(self):
self.instance = "NA"
self.ami = "NA"

@property
def host_linux_version_tpl(self):
"""Host Linux version major.minor, as a tuple for easy comparison"""
return tuple(int(x) for x in self.host_linux_version.split("."))

@property
def is_ec2(self):
"""Are we running on an EC2 instance?"""
Expand Down
16 changes: 6 additions & 10 deletions tests/framework/utils_cpu_templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,18 @@ def get_supported_cpu_templates():
"""
Return the list of CPU templates supported by the platform.
"""
# pylint:disable=too-many-return-statements
match cpuid_utils.get_cpu_vendor():
JonathanWoollett-Light marked this conversation as resolved.
Show resolved Hide resolved
case cpuid_utils.CpuVendor.INTEL:
# T2CL template is only supported on Cascade Lake and newer CPUs.

if global_props.cpu_codename == cpuid_utils.CpuModel.INTEL_SKYLAKE:
return sorted(set(INTEL_TEMPLATES) - set(["T2CL"]))
return INTEL_TEMPLATES
case cpuid_utils.CpuVendor.AMD:
return AMD_TEMPLATES
case cpuid_utils.CpuVendor.ARM:
if global_props.host_linux_version_tpl < (6, 1):
return []
match global_props.cpu_model:
case cpuid_utils.CpuModel.ARM_NEOVERSE_N1:
return []
Expand All @@ -59,13 +61,14 @@ def get_supported_custom_cpu_templates():
match cpuid_utils.get_cpu_vendor():
case cpuid_utils.CpuVendor.INTEL:
# T2CL template is only supported on Cascade Lake and newer CPUs.
skylake_model = "Intel(R) Xeon(R) Platinum 8175M CPU @ 2.50GHz"
if global_props.cpu_model == skylake_model:
if global_props.cpu_codename == cpuid_utils.CpuModel.INTEL_SKYLAKE:
return set(INTEL_TEMPLATES) - {"T2CL"}
return INTEL_TEMPLATES
case cpuid_utils.CpuVendor.AMD:
return AMD_TEMPLATES
case cpuid_utils.CpuVendor.ARM:
if global_props.host_linux_version_tpl < (6, 1):
return []
match global_props.cpu_model:
case cpuid_utils.CpuModel.ARM_NEOVERSE_N1:
return AARCH64_CUSTOM_CPU_TEMPLATES_G2
Expand All @@ -87,10 +90,3 @@ def static_cpu_templates_params():
"""Return Static CPU templates as pytest parameters"""
for name in sorted(get_supported_cpu_templates()):
yield pytest.param(name, id="static_" + name)


def nonci_on_arm(func):
"""Temporary decorator used to mark specific cpu template related tests as nonci on ARM platforms"""
if cpuid_utils.get_cpu_vendor() == cpuid_utils.CpuVendor.ARM:
return pytest.mark.nonci(func)
return func
2 changes: 0 additions & 2 deletions tests/integration_tests/functional/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import host_tools.network as net_tools
from framework import utils_cpuid
from framework.utils import get_firecracker_version_from_toml, is_io_uring_supported
from framework.utils_cpu_templates import nonci_on_arm

MEM_LIMIT = 1000000000

Expand Down Expand Up @@ -462,7 +461,6 @@ def test_negative_machine_config_api(test_microvm_with_api):
)


@nonci_on_arm
def test_api_cpu_config(test_microvm_with_api, custom_cpu_template):
"""
Test /cpu-config PUT scenarios.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import pytest

import framework.utils_cpuid as cpuid_utils
from framework.utils_cpu_templates import nonci_on_arm
from framework.utils_cpuid import CpuModel

PLATFORM = platform.machine()
Expand Down Expand Up @@ -94,7 +93,6 @@ def test_default_cpu_features(microvm_factory, guest_kernel, rootfs_ubuntu_22):
PLATFORM != "aarch64",
reason="This is aarch64 specific test.",
)
@nonci_on_arm
def test_cpu_features_with_static_template(
microvm_factory, guest_kernel, rootfs_ubuntu_22, cpu_template
):
Expand All @@ -115,7 +113,6 @@ def test_cpu_features_with_static_template(
PLATFORM != "aarch64",
reason="This is aarch64 specific test.",
)
@nonci_on_arm
def test_cpu_features_with_custom_template(
microvm_factory, guest_kernel, rootfs_ubuntu_22, custom_cpu_template
):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from framework import utils
from framework.defs import SUPPORTED_HOST_KERNELS
from framework.properties import global_props
from framework.utils_cpu_templates import nonci_on_arm
from framework.utils_cpuid import get_guest_cpuid
from host_tools import cargo_build

Expand Down Expand Up @@ -405,13 +404,14 @@ def test_guest_cpu_config_change(
)


@nonci_on_arm
def test_json_static_templates(
test_microvm_with_api, cpu_template_helper, tmp_path, custom_cpu_template
):
"""
Verify that JSON static CPU templates are applied as intended.
"""
if custom_cpu_template["name"] == "aarch64_with_sve_and_pac":
pytest.skip("does not work yet")
# Generate VM config with JSON static CPU template
microvm = test_microvm_with_api
microvm.spawn()
Expand Down
48 changes: 48 additions & 0 deletions tests/integration_tests/security/test_nv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

"""Tests ensuring nested virtualization is not present when using CPU templates.
We have tests that ensure CPU templates provide a consistent set of features in
the guest:
- file:../functional/test_cpu_features.py
- file:../functional/test_feat_parity.py
- Commit: 681e781f999e3390b6d46422a3c7b1a7e36e1b24
These already include the absence of VMX/SVM in the guest.
This test is a safety-net to make the test explicit and catch cases where we
start providing the feature by mistake.
"""

import pytest


@pytest.fixture
def uvm_with_cpu_template(
microvm_factory, guest_kernel, rootfs_ubuntu_22, cpu_template_any
):
"""A microvm fixture parametrized with all possible templates"""
vm = microvm_factory.build(guest_kernel, rootfs_ubuntu_22)
vm.spawn()
cpu_template = None
if isinstance(cpu_template_any, str):
cpu_template = cpu_template_any
vm.basic_config(cpu_template=cpu_template)
if cpu_template is None:
vm.api.cpu_config.put(**cpu_template_any["template"])
vm.add_net_iface()
vm.start()
yield vm


def test_no_nv_when_using_cpu_templates(uvm_with_cpu_template):
"""
Double-check that guests using CPU templates don't have Nested Virtualization
enabled.
"""

vm = uvm_with_cpu_template
rc, _, _ = vm.ssh.run("[ ! -e /dev/kvm ]")
assert rc == 0, "/dev/kvm exists"
2 changes: 1 addition & 1 deletion tests/integration_tests/security/test_sec_audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ def set_of_vulnerabilities(output: CommandReturn):
)

git_ab_test_host_command_if_pr(
"cargo audit --deny warnings -q --json",
"cargo audit --deny warnings -q --json |grep -Po '{.*}'",
comparator=set_did_not_grow_comparator(set_of_vulnerabilities),
)
20 changes: 9 additions & 11 deletions tests/integration_tests/security/test_vulnerabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
)
from framework.properties import global_props
from framework.utils import CommandReturn
from framework.utils_cpu_templates import nonci_on_arm

CHECKER_URL = "https://meltdown.ovh"
CHECKER_FILENAME = "spectre-meltdown-checker.sh"
Expand Down Expand Up @@ -299,7 +298,6 @@ def test_spectre_meltdown_checker_on_restored_guest(
global_props.instance == "c7g.metal" and global_props.host_linux_version == "4.14",
reason="c7g host 4.14 requires modifications to the 5.10 guest kernel to boot successfully.",
)
@nonci_on_arm
def test_spectre_meltdown_checker_on_guest_with_template(
spectre_meltdown_checker, build_microvm_with_template
):
Expand All @@ -320,7 +318,6 @@ def test_spectre_meltdown_checker_on_guest_with_template(
global_props.instance == "c7g.metal" and global_props.host_linux_version == "4.14",
reason="c7g host 4.14 requires modifications to the 5.10 guest kernel to boot successfully.",
)
@nonci_on_arm
def test_spectre_meltdown_checker_on_guest_with_custom_template(
spectre_meltdown_checker, build_microvm_with_custom_template
):
Expand All @@ -340,7 +337,6 @@ def test_spectre_meltdown_checker_on_guest_with_custom_template(
global_props.instance == "c7g.metal" and global_props.host_linux_version == "4.14",
reason="c7g host 4.14 requires modifications to the 5.10 guest kernel to boot successfully.",
)
@nonci_on_arm
def test_spectre_meltdown_checker_on_restored_guest_with_template(
spectre_meltdown_checker, build_microvm_with_template, microvm_factory
):
Expand All @@ -363,13 +359,17 @@ def test_spectre_meltdown_checker_on_restored_guest_with_template(
global_props.instance == "c7g.metal" and global_props.host_linux_version == "4.14",
reason="c7g host 4.14 requires modifications to the 5.10 guest kernel to boot successfully.",
)
@nonci_on_arm
def test_spectre_meltdown_checker_on_restored_guest_with_custom_template(
spectre_meltdown_checker, build_microvm_with_custom_template, microvm_factory
spectre_meltdown_checker,
build_microvm_with_custom_template,
microvm_factory,
custom_cpu_template,
):
"""
Test with the spectre / meltdown checker on a restored guest with a custom CPU template.
"""
if custom_cpu_template["name"] == "aarch64_with_sve_and_pac":
pytest.skip("does not work yet")
git_ab_test_guest_command_if_pr(
with_checker(
with_restore(build_microvm_with_custom_template, microvm_factory),
Expand Down Expand Up @@ -501,15 +501,13 @@ def test_vulnerabilities_files_on_restored_guest(build_microvm, microvm_factory)
check_vulnerabilities_files_ab(with_restore(build_microvm, microvm_factory))


@nonci_on_arm
def test_vulnerabilities_files_on_guest_with_template(build_microvm_with_template):
"""
Test vulnerabilities files on guest with CPU template.
"""
check_vulnerabilities_files_ab(build_microvm_with_template)


@nonci_on_arm
def test_vulnerabilities_files_on_guest_with_custom_template(
build_microvm_with_custom_template,
):
Expand All @@ -519,7 +517,6 @@ def test_vulnerabilities_files_on_guest_with_custom_template(
check_vulnerabilities_files_ab(build_microvm_with_custom_template)


@nonci_on_arm
def test_vulnerabilities_files_on_restored_guest_with_template(
build_microvm_with_template, microvm_factory
):
Expand All @@ -531,13 +528,14 @@ def test_vulnerabilities_files_on_restored_guest_with_template(
)


@nonci_on_arm
def test_vulnerabilities_files_on_restored_guest_with_custom_template(
build_microvm_with_custom_template, microvm_factory
build_microvm_with_custom_template, microvm_factory, custom_cpu_template
):
"""
Test vulnerabilities files on a restored guest with a custom CPU template.
"""
if custom_cpu_template["name"] == "aarch64_with_sve_and_pac":
pytest.skip("does not work yet")
check_vulnerabilities_files_ab(
with_restore(build_microvm_with_custom_template, microvm_factory)
)
Loading