@@ -4947,7 +4947,13 @@ struct VM {
49474947 for (unsigned i = 0 ; i < CPUID_ITER; ++i) {
49484948 // read rdtsc and accumulate delta
49494949 const u64 now = rdtsc ();
4950- acc += (now >= last) ? (now - last) : (u64 )((u64 )0 - last + now);
4950+
4951+ // If now < last, the hypervisor rewound the TSC or it's a very rare 64-bit overflow
4952+ // we do not increment acc to ensure ratio t2_delta / t1_delta drops below 0.95
4953+ if (now >= last) {
4954+ acc += (now - last);
4955+ }
4956+
49514957 last = now;
49524958
49534959 // store latency if buffer has space
@@ -4964,7 +4970,11 @@ struct VM {
49644970
49654971 // final rdtsc after detecting finish
49664972 const u64 final_now = rdtsc ();
4967- acc += (final_now >= last) ? (final_now - last) : (u64 )((u64 )0 - last + final_now);
4973+
4974+ if (final_now >= last) {
4975+ acc += (final_now - last);
4976+ }
4977+
49684978 last = final_now;
49694979
49704980 // publish results
@@ -5011,7 +5021,7 @@ struct VM {
50115021
50125022 if (cpuid_latency >= cycle_threshold) {
50135023 debug (" TIMER: Detected a vmexit on CPUID" );
5014- return true ;
5024+ return core::add (brands::NULL_BRAND, 100 ); // to prevent FPs due to kernel noise
50155025 }
50165026 else if (cpuid_latency <= 25 ) {
50175027 debug (" TIMER: Detected a hypervisor downscaling CPUID latency" );
@@ -6573,16 +6583,6 @@ struct VM {
65736583 debug (" FIRMWARE: C2 and C3 latencies indicate VM" );
65746584 return true ;
65756585 }
6576-
6577- if (buffer_len >= 276 ) {
6578- u64 hypervisor_vid = 0 ;
6579- memcpy (&hypervisor_vid, buffer + 268 , 8 );
6580-
6581- if (hypervisor_vid != 0 ) {
6582- debug (" FIRMWARE: FACP 'Hypervisor Vendor Identity' field is occupied" );
6583- return true ;
6584- }
6585- }
65866586 }
65876587
65886588 return false ;
@@ -7513,6 +7513,10 @@ struct VM {
75137513 }
75147514 #endif
75157515
7516+ // ARM CPUs trigger this check
7517+ if (util::is_running_under_translator ())
7518+ return false ;
7519+
75167520 const HMODULE kernel32 = GetModuleHandleA (" kernel32.dll" );
75177521 const HMODULE ntdll = util::get_ntdll ();
75187522 if (!kernel32 || !ntdll) {
@@ -11211,22 +11215,26 @@ struct VM {
1121111215 if (util::get_manufacturer_model (&manufacturer, &model)) {
1121211216 auto ci_contains = [](const char * hay, const char * needle) noexcept -> bool {
1121311217 if (!hay || !needle || !*hay || !*needle) return false ;
11214- const unsigned char * h = reinterpret_cast <const unsigned char *>(hay);
11215- const unsigned char * n = reinterpret_cast <const unsigned char *>(needle);
11216- const size_t nlen = strlen (reinterpret_cast <const char *>(n));
11218+
11219+ const unsigned char * h =
11220+ reinterpret_cast <const unsigned char *>(hay);
11221+ const unsigned char * n =
11222+ reinterpret_cast <const unsigned char *>(needle);
11223+
1121711224 for (; *h; ++h) {
1121811225 size_t i = 0 ;
1121911226 for (;; ++i) {
1122011227 unsigned char hc = h[i];
1122111228 unsigned char nc = n[i];
11222- if (!nc) return false ; // matched whole needle
11223- if (!hc) break ; // hay ended
11224- // ascii lowercase
11229+
11230+ if (!nc) return true ;
11231+ if (!hc) break ;
11232+
1122511233 if (hc >= ' A' && hc <= ' Z' ) hc += 32 ;
1122611234 if (nc >= ' A' && nc <= ' Z' ) nc += 32 ;
11235+
1122711236 if (hc != nc) break ;
1122811237 }
11229- if (i == nlen) return false ;
1123011238 }
1123111239 return false ;
1123211240 };
@@ -11355,8 +11363,6 @@ struct VM {
1135511363 { 0x4B564D00u , 0x4B564DFFu }
1135611364 };
1135711365
11358- static thread_local bool g_msr_faulted = false ;
11359-
1136011366 auto try_read = [](u32 msr_index) -> bool {
1136111367 #if (MSVC)
1136211368 unsigned __int64 value = 0 ;
@@ -11369,7 +11375,7 @@ struct VM {
1136911375 return false ;
1137011376 }
1137111377 #elif (GCC || CLANG)
11372- g_msr_faulted = false ;
11378+ static thread_local bool g_msr_faulted = false ;
1137311379
1137411380 auto veh_handler = [](PEXCEPTION_POINTERS info) -> LONG {
1137511381 if (info->ExceptionRecord ->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION) {
0 commit comments