diff --git a/CheckTool/common.cpp b/CheckTool/common.cpp index 74dff6bf..8d486842 100644 --- a/CheckTool/common.cpp +++ b/CheckTool/common.cpp @@ -68,20 +68,17 @@ CheckResult ParseArguments(int &argc, char* argv[]) { } int Check() { - int ret = 0; + FeatureDetector fd; - haxm::check_util::FeatureDetector fd; - haxm::check_util::CheckResult detect_res = fd.Detect(); - - if (detect_res == haxm::check_util::kError) { - ret = -1; - } else if (detect_res == haxm::check_util::kFail) { - ret = 1; + if (fd.Detect() == kError) { + std::cout << "The handle is invalid or the system command is executed " + "exceptionally." << std::endl; + return -1; } fd.Print(); - return ret; + return fd.status(); } } // namespace check_util diff --git a/CheckTool/common.h b/CheckTool/common.h index e3baa420..e4c7a087 100644 --- a/CheckTool/common.h +++ b/CheckTool/common.h @@ -45,6 +45,7 @@ enum CheckResult { kFail, kNotApplicable, // e.g., CheckHypervDisabled() on macOS kError, + kMaxResult }; // Source: diff --git a/CheckTool/feature_detector.cpp b/CheckTool/feature_detector.cpp index daeabf72..a7a9570a 100644 --- a/CheckTool/feature_detector.cpp +++ b/CheckTool/feature_detector.cpp @@ -44,7 +44,49 @@ namespace haxm { namespace check_util { +enum Check { + // Hardware support bit + kCpuSupported = 0, + kVmxSupported = 1, + kNxSupported = 2, + kEm64tSupported = 3, + kEptSupported = 4, + // BIOS configuration bit + kVmxEnabled = 8, + kNxEnabled = 9, + kEm64tEnabled = 10, + // Host status bit + kOsVerSupported = 16, + kOsArchSupported = 17, + kHypervDisabled = 18, + kSandboxDisabled = 19, + // Guest status bit + kGuestUnoccupied = 24, + kMaxCheck = 32 +}; + +enum CheckFlag { + // Hardware support flag + kFlagCpuSupported = 1 << kCpuSupported, + kFlagVmxSupported = 1 << kVmxSupported, + kFlagNxSupported = 1 << kNxSupported, + kFlagEm64tSupported = 1 << kEm64tSupported, + kFlagEptSupported = 1 << kEptSupported, + // BIOS configuration flag + kFlagVmxEnabled = 1 << kVmxEnabled, + kFlagNxEnabled = 1 << kNxEnabled, + kFlagEm64tEnabled = 1 << kEm64tEnabled, + // Host status flag + kFlagOsverSupported = 1 << kOsVerSupported, + kFlagOsarchSupported = 1 << kOsArchSupported, + kFlagHypervDisabled = 1 << kHypervDisabled, + kFlagSandboxDisabled = 1 << kSandboxDisabled, + // Guest status flag + kFlagGuestUnoccupied = 1 << kGuestUnoccupied +}; + FeatureDetector::FeatureDetector() { + status_ = 0; os_ = new OsImpl(); } @@ -145,32 +187,37 @@ std::string FeatureDetector::ToString(OsType os_type) { } } -CheckResult FeatureDetector::Detect() const { - CheckResult res[11]; - - res[0] = CheckCpuVendor(); - res[1] = CheckLongModeSupported(); - res[2] = CheckNxSupported(); - res[3] = CheckNxEnabled(); - res[4] = CheckOsVersion(); - res[5] = CheckOsArchitecture(); - res[6] = CheckGuestOccupied(); - res[7] = CheckHyperVDisabled(); - res[8] = CheckVmxSupported(); - res[9] = CheckVmxEnabled(); - res[10] = CheckEptSupported(); - - int check_num = 11; +CheckResult FeatureDetector::Detect() { + CheckResult res[kMaxCheck] = {}; + int i; + + res[kCpuSupported] = CheckCpuVendor(); + res[kNxSupported] = CheckNxSupported(); + res[kEm64tSupported] = CheckLongModeSupported(); + res[kNxEnabled] = CheckNxEnabled(); + res[kOsVerSupported] = CheckOsVersion(); + res[kOsArchSupported] = CheckOsArchitecture(); + res[kHypervDisabled] = CheckHyperVDisabled(); + res[kGuestUnoccupied] = CheckGuestOccupied(); + // When Hyper-V is enabled, it will affect the checking results of VMX - // supported, VMX enabled and EPT supported, so only the first 8 items are + // supported, EPT supported and VMX enabled, so only the first 8 items are // checked. When Hyper-V is disabled, all items are checked. - if (res[7] == kFail) { - check_num = 8; + if (res[kHypervDisabled] != kFail) { + res[kVmxSupported] = CheckVmxSupported(); + res[kEptSupported] = CheckEptSupported(); + res[kVmxEnabled] = CheckVmxEnabled(); + } + + for (i = 0; i < kMaxCheck; ++i) { + if (res[i] == kFail) { + status_ |= 1 << i; + } } - int detector[5] = {}; + int detector[kMaxResult] = {}; - for (int i = 0; i < check_num; ++i) { + for (i = 0; i < kMaxCheck; ++i) { ++detector[static_cast(res[i])]; } @@ -178,14 +225,14 @@ CheckResult FeatureDetector::Detect() const { return kError; } - if (detector[static_cast(kUnknown)] > 0) { - return kUnknown; - } - if (detector[static_cast(kFail)] > 0) { return kFail; } + if (detector[static_cast(kUnknown)] > 0) { + return kUnknown; + } + return kPass; } @@ -265,5 +312,9 @@ void FeatureDetector::Print() const { << occupied_count << " guest(s)" << std::endl; } +int FeatureDetector::status() const { + return status_; +} + } // namespace check_util } // namespace haxm diff --git a/CheckTool/feature_detector.h b/CheckTool/feature_detector.h index 060f35f9..7b79b46a 100644 --- a/CheckTool/feature_detector.h +++ b/CheckTool/feature_detector.h @@ -44,8 +44,9 @@ class FeatureDetector { public: FeatureDetector(); ~FeatureDetector(); - CheckResult Detect() const; + CheckResult Detect(); void Print() const; + int status() const; private: CheckResult CheckCpuVendor(std::string* vendor = nullptr) const; @@ -62,6 +63,7 @@ class FeatureDetector { static std::string ToString(CheckResult res); static std::string ToString(OsType os_type); static std::string ToString(OsArchitecture os_arch); + int status_; Cpuid cpuid_; Os* os_; };