diff --git a/src/anbox/cmds/check_features.cpp b/src/anbox/cmds/check_features.cpp index a1e1943047429f6f6e394ffe8fbf0329b905f1c0..4b6f448f7292f9b472da65623dc098e7cfe7c40a 100644 --- a/src/anbox/cmds/check_features.cpp +++ b/src/anbox/cmds/check_features.cpp @@ -52,7 +52,7 @@ anbox::cmds::CheckFeatures::CheckFeatures() cli::Name{"check-features"}, cli::Usage{"check-features"}, cli::Description{"Check that the host system supports all necessary features"}} { - action([](const cli::Command::Context&) { + action([this](const cli::Command::Context&) { #if defined(CPU_FEATURES_ARCH_X86) const auto info = cpu_features::GetX86Info(); std::vector missing_features; @@ -78,7 +78,7 @@ anbox::cmds::CheckFeatures::CheckFeatures() } } - if (missing_features.size() > 0 && !is_whitelisted) { + if (missing_features.size() > 0 && !is_whitelisted && !sanity_check_for_features()) { std::cerr << "The CPU of your computer (" << brand_string << ") does not support all" << std::endl << "features Anbox requires." << std::endl << "It is missing support for the following features: "; @@ -105,3 +105,32 @@ anbox::cmds::CheckFeatures::CheckFeatures() #endif }); } + +// In case that the CPU supports AVX we take the decision as from our analysis +// of the output from the cpu_features library. If it does not we have to check +// further via the compiler builtins if we the CPU supports all mandatory features +// or not. In case that any is missing we will fail the test. +// +// This uses the compiler builtin function __builtin_cpu_supports which allows us +// to detect certain CPU features. +// See https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html +bool anbox::cmds::CheckFeatures::sanity_check_for_features() { +#if defined(CPU_FEATURES_ARCH_X86) + if (__builtin_cpu_supports("avx")) + return true; + + std::vector missing_features; + +#define CHECK_FEATURE(name) \ + if (!__builtin_cpu_supports(name)) \ + missing_features.push_back(name); + + CHECK_FEATURE("sse4.1"); + CHECK_FEATURE("sse4.2"); + CHECK_FEATURE("ssse3"); + + return missing_features.empty(); +#else + return true; +#endif +} diff --git a/src/anbox/cmds/check_features.h b/src/anbox/cmds/check_features.h index e6c6ff78f7a2c1037e0e39a028d272ed41f78a81..8402ca6b5820968827f7d478125bc4894a939f3b 100644 --- a/src/anbox/cmds/check_features.h +++ b/src/anbox/cmds/check_features.h @@ -29,6 +29,9 @@ namespace cmds { class CheckFeatures : public cli::CommandWithFlagsAndAction { public: CheckFeatures(); + + private: + bool sanity_check_for_features(); }; } // namespace cmds } // namespace anbox