Repository: firecracker-microvm/firecracker
File: tests/integration_tests/functional/test_cpu_features_aarch64.py (Python)

Code before:
            expected_cpu_features = DEFAULT_G3_FEATURES_V1N1
        case CpuModel.ARM_NEOVERSE_V1, _, "aarch64_with_sve_and_pac":
            expected_cpu_features = DEFAULT_G3_FEATURES_WITH_SVE_AND_PAC_5_10
        case CpuModel.ARM_NEOVERSE_V1, _, None:
            expected_cpu_features = DEFAULT_G3_FEATURES_5_10

    _, stdout, _ = test_microvm.ssh.check_output(CPU_FEATURES_CMD)
    flags = set(stdout.strip().split(" "))
    assert flags == expected_cpu_features


def get_cpu_template_dir(cpu_template):
    """
    Utility function to return a valid string which will be used as
    name of the directory where snapshot artifacts are stored during
    snapshot test and loaded from during restore test.

    """
    return cpu_template if cpu_template else "none"


@pytest.mark.skipif(
    PLATFORM != "aarch64",
    reason="This is aarch64 specific test.",
)
def test_host_vs_guest_cpu_features_aarch64(uvm_nano):
    """Check CPU features host vs guest"""

    vm = uvm_nano
    vm.add_net_iface()
    vm.start()
    host_feats = set(utils.check_output(CPU_FEATURES_CMD).stdout.strip().split(" "))
    guest_feats = set(vm.ssh.check_output(CPU_FEATURES_CMD).stdout.strip().split(" "))

    cpu_model = cpuid_utils.get_cpu_model_name()
    match cpu_model:
        case CpuModel.ARM_NEOVERSE_N1:
            assert host_feats - guest_feats == set()
            assert guest_feats - host_feats == {"ssbs"}
        case CpuModel.ARM_NEOVERSE_V1:
            assert host_feats - guest_feats == {
                "pacg",
                "sve",
                "paca",
                "svebf16",
                "svei8mm",
            }
            assert guest_feats - host_feats == {"ssbs"}
        case _:
            assert False, f"Cpu model {cpu_model} is not supported"


Review comment (suggestion):
We could make this test more generic and support x86_64. Maybe it belongs in a generic `test_cpu_features.py` (and move the current `test_cpu_features.py` to `test_cpu_features_x86.py`)

Code after:
        case CpuModel.ARM_NEOVERSE_V1, _, "v1n1":
            expected_cpu_features = DEFAULT_G3_FEATURES_V1N1
        case CpuModel.ARM_NEOVERSE_V1, _, "aarch64_with_sve_and_pac":
            expected_cpu_features = DEFAULT_G3_FEATURES_WITH_SVE_AND_PAC_5_10
        case CpuModel.ARM_NEOVERSE_V1, _, None:
            expected_cpu_features = DEFAULT_G3_FEATURES_5_10

    _, stdout, _ = test_microvm.ssh.check_output(CPU_FEATURES_CMD)
    flags = set(stdout.strip().split(" "))
    assert flags == expected_cpu_features


def get_cpu_template_dir(cpu_template):
    """
    Utility function to return a valid string which will be used as
    name of the directory where snapshot artifacts are stored during
    snapshot test and loaded from during restore test.

    """
    return cpu_template if cpu_template else "none"


@pytest.mark.skipif(
    PLATFORM != "aarch64",
    reason="This is aarch64 specific test.",
)
def test_host_vs_guest_cpu_features_aarch64(uvm_nano):
    """Check CPU features host vs guest"""

    vm = uvm_nano
    vm.add_net_iface()
    vm.start()
    host_feats = set(utils.check_output(CPU_FEATURES_CMD).stdout.strip().split(" "))
    guest_feats = set(vm.ssh.check_output(CPU_FEATURES_CMD).stdout.strip().split(" "))

    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"}
        case CpuModel.ARM_NEOVERSE_V1:
            # KVM does not enable PAC or SVE features by default
            # and Firecracker does not enable them either.
            assert host_feats - guest_feats == {
                "paca",
                "pacg",
                "sve",