From 6dd7902d6f148a4ac78e5478edb3a2ca8624f74c Mon Sep 17 00:00:00 2001
From: gcontini <1121667+gcontini@users.noreply.github.com>
Date: 周日, 15 3月 2020 16:07:14 +0800
Subject: [PATCH] cpu brand

---
 src/library/os/linux/cpu_info.cpp |   50 +++++++++++++++++++++++++++++++-------------------
 1 files changed, 31 insertions(+), 19 deletions(-)

diff --git a/src/library/os/linux/cpu_info.cpp b/src/library/os/linux/cpu_info.cpp
index 4db4ba0..37620cb 100644
--- a/src/library/os/linux/cpu_info.cpp
+++ b/src/library/os/linux/cpu_info.cpp
@@ -8,14 +8,13 @@
 #include <cpuid.h>
 #include <string>
 #include <unordered_set>
+#include <memory.h>
 #include "../cpu_info.hpp"
 
 namespace license {
+namespace os {
 using namespace std;
 
-const unordered_set<string> virtual_cpu_names = {"bhyve bhyve ", "KVMKVMKVM",	"Microsoft Hv",
-												 " lrpepyh vr",  "prl hyperv  ", "VMwareVMware",
-												 "XenVMMXenVMM", "ACRNACRNACRN", "VBoxVBoxVBox"};
 struct CPUVendorID {
 	unsigned int ebx;
 	unsigned int edx;
@@ -24,27 +23,47 @@
 	string toString() const { return string(reinterpret_cast<const char *>(this), 12); }
 };
 
-CpuInfo::CpuInfo() {}
+static string get_cpu_vendor() {
+	unsigned int level = 0, eax = 0, ebx = 0, ecx = 0, edx = 0;
+	// hypervisor flag false, try to get the vendor name, see if it's a virtual cpu
+	__get_cpuid(level, &eax, &ebx, &ecx, &edx);
+	CPUVendorID vendorID{.ebx = ebx, .edx = edx, .ecx = ecx};
+	return vendorID.toString();
+}
+
+// https://en.wikipedia.org/wiki/CPUID
+static string get_cpu_brand() {
+	string result;
+	uint32_t brand[0x10];
+
+	if (!__get_cpuid_max(0x80000004, NULL)) {
+		result = "NA";
+	} else {
+		memset(brand, 0, sizeof(brand));
+		__get_cpuid(0x80000002, brand + 0x0, brand + 0x1, brand + 0x2, brand + 0x3);
+		__get_cpuid(0x80000003, brand + 0x4, brand + 0x5, brand + 0x6, brand + 0x7);
+		__get_cpuid(0x80000004, brand + 0x8, brand + 0x9, brand + 0xa, brand + 0xb);
+		result = string(reinterpret_cast<char *>(brand));
+	}
+	return result;
+}
+
+CpuInfo::CpuInfo() : m_vendor(get_cpu_vendor()), m_brand(get_cpu_brand()) {}
 
 CpuInfo::~CpuInfo() {}
 /**
  * Detect Virtual machine using hypervisor bit.
  * @return true if the cpu hypervisor bit is set to 1
  */
-bool CpuInfo::cpu_virtual() const {
+bool CpuInfo::is_hypervisor_set() const {
 	unsigned int level = 1, eax = 0, ebx = 0, ecx = 0, edx = 0;
 	__get_cpuid(level, &eax, &ebx, &ecx, &edx);
 
 	bool is_virtual = (((ecx >> 31) & 1) == 1);  // hypervisor flag
-	if (!is_virtual) {
-		string cpu_vendor = vendor();
-		auto it = virtual_cpu_names.find(cpu_vendor);
-		is_virtual = (it != virtual_cpu_names.end());
-	}
 	return is_virtual;
 }
 
-uint32_t CpuInfo::model() {
+uint32_t CpuInfo::model() const {
 	unsigned int level = 1, eax = 0, ebx = 0, ecx = 0, edx = 0;
 	__get_cpuid(level, &eax, &ebx, &ecx, &edx);
 	// ax bits 0-3 stepping,4-7 model,8-11 family id,12-13 processor type
@@ -53,12 +72,5 @@
 	return (eax & 0x3FFF) | (eax & 0x3FF8000) >> 2 | (ebx & 0xff) << 24;
 }
 
-string CpuInfo::vendor() const {
-	unsigned int level = 0, eax = 0, ebx = 0, ecx = 0, edx = 0;
-	// hypervisor flag false, try to get the vendor name, see if it's a virtual cpu
-	__get_cpuid(level, &eax, &ebx, &ecx, &edx);
-	CPUVendorID vendorID{.ebx = ebx, .edx = edx, .ecx = ecx};
-	return vendorID.toString();
-}
-
+}  // namespace os
 } /* namespace license */

--
Gitblit v1.9.1