Path: blob/main/tests/integration_tests/functional/test_cpu_features.py
1958 views
# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.1# SPDX-License-Identifier: Apache-2.02"""Tests for the CPU topology emulation feature."""34import platform5import re6import pytest78import framework.utils_cpuid as utils9import host_tools.network as net_tools1011PLATFORM = platform.machine()121314def _check_cpuid_x86(test_microvm, expected_cpu_count, expected_htt):15expected_cpu_features = {16"cpu count": '{} ({})'.format(hex(expected_cpu_count),17expected_cpu_count),18"CLFLUSH line size": "0x8 (8)",19"hypervisor guest status": "true",20"hyper-threading / multi-core supported": expected_htt21}2223utils.check_guest_cpuid_output(test_microvm, "cpuid -1", None, '=',24expected_cpu_features)252627def _check_cpu_features_arm(test_microvm):28expected_cpu_features = {29"Flags": "fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp "30"asimdhp cpuid asimdrdm lrcpc dcpop asimddp ssbs",31}3233utils.check_guest_cpuid_output(test_microvm, "lscpu", None, ':',34expected_cpu_features)353637@pytest.mark.skipif(38PLATFORM != "x86_64",39reason="CPUID is only supported on x86_64."40)41@pytest.mark.parametrize(42"num_vcpus",43[1, 2, 16],44)45@pytest.mark.parametrize(46"htt",47[True, False],48)49def test_cpuid(test_microvm_with_ssh, network_config, num_vcpus, htt):50"""Check the CPUID for a microvm with the specified config."""51vm = test_microvm_with_ssh52vm.spawn()53vm.basic_config(vcpu_count=num_vcpus, ht_enabled=htt)54_tap, _, _ = vm.ssh_network_config(network_config, '1')55vm.start()56_check_cpuid_x86(vm, num_vcpus, "true" if num_vcpus > 1 else "false")575859@pytest.mark.skipif(60PLATFORM != "aarch64",61reason="The CPU features on x86 are tested as part of the CPU templates."62)63def test_cpu_features(test_microvm_with_ssh, network_config):64"""Check the CPU features for a microvm with the specified config."""65vm = test_microvm_with_ssh66vm.spawn()67vm.basic_config()68_tap, _, _ = vm.ssh_network_config(network_config, '1')69vm.start()70_check_cpu_features_arm(vm)717273@pytest.mark.skipif(74PLATFORM != "x86_64",75reason="The CPU brand string is masked only on x86_64."76)77def test_brand_string(test_microvm_with_ssh, network_config):78"""Ensure good formatting for the guest band string.7980* For Intel CPUs, the guest brand string should be:81Intel(R) Xeon(R) Processor @ {host frequency}82where {host frequency} is the frequency reported by the host CPUID83(e.g. 4.01GHz)84* For AMD CPUs, the guest brand string should be:85AMD EPYC86* For other CPUs, the guest brand string should be:87""88"""89cif = open('/proc/cpuinfo', 'r')90host_brand_string = None91while True:92line = cif.readline()93if line == '':94break95mo = re.search("^model name\\s+:\\s+(.+)$", line)96if mo:97host_brand_string = mo.group(1)98cif.close()99assert host_brand_string is not None100101test_microvm = test_microvm_with_ssh102test_microvm.spawn()103104test_microvm.basic_config(vcpu_count=1)105_tap, _, _ = test_microvm.ssh_network_config(network_config, '1')106test_microvm.start()107108ssh_connection = net_tools.SSHConnection(test_microvm.ssh_config)109110guest_cmd = "cat /proc/cpuinfo | grep 'model name' | head -1"111_, stdout, stderr = ssh_connection.execute_command(guest_cmd)112assert stderr.read() == ''113114line = stdout.readline().rstrip()115mo = re.search("^model name\\s+:\\s+(.+)$", line)116assert mo117guest_brand_string = mo.group(1)118assert guest_brand_string119120cpu_vendor = utils.get_cpu_vendor()121expected_guest_brand_string = ""122if cpu_vendor == utils.CpuVendor.AMD:123expected_guest_brand_string += "AMD EPYC"124elif cpu_vendor == utils.CpuVendor.INTEL:125expected_guest_brand_string = "Intel(R) Xeon(R) Processor"126mo = re.search("[.0-9]+[MG]Hz", host_brand_string)127if mo:128expected_guest_brand_string += " @ " + mo.group(0)129130assert guest_brand_string == expected_guest_brand_string131132133@pytest.mark.skipif(134PLATFORM != "x86_64",135reason="CPU features are masked only on x86_64."136)137@pytest.mark.parametrize("cpu_template", ["T2", "C3"])138def test_cpu_template(test_microvm_with_ssh, network_config, cpu_template):139"""Check that AVX2 & AVX512 instructions are disabled.140141This is a rather dummy test for checking that some features are not142exposed by mistake. It is a first step into checking the t2 & c3143templates. In a next iteration we should check **all** cpuid entries, not144just these features. We can achieve this with a template145containing all features on a t2/c3 instance and check that the cpuid in146the guest is an exact match of the template.147"""148common_masked_features_lscpu = ["dtes64", "monitor", "ds_cpl", "tm2",149"cnxt-id", "sdbg", "xtpr", "pdcm",150"osxsave",151"psn", "ds", "acpi", "tm", "ss", "pbe",152"fpdp", "rdt_m", "rdt_a", "mpx", "avx512f",153"intel_pt",154"avx512_vpopcntdq",155"3dnowprefetch", "pdpe1gb"]156157common_masked_features_cpuid = {"SGX": "false", "HLE": "false",158"RTM": "false", "RDSEED": "false",159"ADX": "false", "AVX512IFMA": "false",160"CLFLUSHOPT": "false", "CLWB": "false",161"AVX512PF": "false", "AVX512ER": "false",162"AVX512CD": "false", "SHA": "false",163"AVX512BW": "false", "AVX512VL": "false",164"AVX512VBMI": "false", "PKU": "false",165"OSPKE": "false", "RDPID": "false",166"SGX_LC": "false",167"AVX512_4VNNIW": "false",168"AVX512_4FMAPS": "false",169"XSAVEC": "false", "XGETBV": "false",170"XSAVES": "false"}171172# These are all discoverable by cpuid -1.173c3_masked_features = {"FMA": "false", "MOVBE": "false", "BMI": "false",174"AVX2": "false", "BMI2": "false", "INVPCID": "false"}175176test_microvm = test_microvm_with_ssh177test_microvm.spawn()178179test_microvm.basic_config(vcpu_count=1)180# Set template as specified in the `cpu_template` parameter.181response = test_microvm.machine_cfg.put(182vcpu_count=1,183mem_size_mib=256,184ht_enabled=False,185cpu_template=cpu_template,186)187assert test_microvm.api_session.is_status_no_content(response.status_code)188_tap, _, _ = test_microvm.ssh_network_config(network_config, '1')189190response = test_microvm.actions.put(action_type='InstanceStart')191if utils.get_cpu_vendor() != utils.CpuVendor.INTEL:192# We shouldn't be able to apply Intel templates on AMD hosts193assert test_microvm.api_session.is_status_bad_request(194response.status_code)195return196197assert test_microvm.api_session.is_status_no_content(198response.status_code)199200# Check that all common features discoverable with lscpu201# are properly masked.202ssh_connection = net_tools.SSHConnection(test_microvm.ssh_config)203guest_cmd = "cat /proc/cpuinfo | grep 'flags' | head -1"204_, stdout, stderr = ssh_connection.execute_command(guest_cmd)205assert stderr.read() == ''206207cpu_flags_output = stdout.readline().rstrip().split(' ')208209for feature in common_masked_features_lscpu:210assert feature not in cpu_flags_output, feature211212# Check that all common features discoverable with cpuid213# are properly masked.214utils.check_guest_cpuid_output(test_microvm, "cpuid -1", None, '=',215common_masked_features_cpuid)216217if cpu_template == "C3":218utils.check_guest_cpuid_output(test_microvm, "cpuid -1", None, '=',219c3_masked_features)220221# Check if XSAVE PKRU is masked for T3/C2.222expected_cpu_features = {223"XCR0 supported: PKRU state": "false"224}225226utils.check_guest_cpuid_output(test_microvm, "cpuid -1", None, '=',227expected_cpu_features)228229230