Skip to content

Commit

Permalink
Fix build
Browse files Browse the repository at this point in the history
  • Loading branch information
am11 committed Jun 28, 2024
1 parent 1daa030 commit e4030bf
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.InteropServices;
using System.Threading;

internal static partial class Interop
{
Expand All @@ -11,7 +12,22 @@ internal static partial class Sys
[return: MarshalAs(UnmanagedType.Bool)]
private static partial bool IsQemuDetectedImpl();

private static bool? _isQemuDetected;
internal static bool IsQemuDetected() => _isQemuDetected ??= IsQemuDetectedImpl();
private static int s_isQemuDetected;

internal static bool IsQemuDetected()
{
int isQemuDetected = Interlocked.CompareExchange(ref s_isQemuDetected, 0, 0);
if (isQemuDetected == 0)
{
isQemuDetected = IsQemuDetectedImpl() ? 1 : 2;
int oldValue = Interlocked.CompareExchange(ref s_isQemuDetected, isQemuDetected, 0);
if (oldValue != 0) // a different thread has managed to update the value
{
isQemuDetected = oldValue;
}
}

return isQemuDetected == 1;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static partial class PlatformDetection
public static bool IsNotMonoLinuxArm64 => !IsMonoLinuxArm64;

public static bool IsQemuDetected =>
#if TARGET_WINDOWS
#if TARGET_WINDOWS || TARGET_BROWSER || TARGET_WASI
false;
#else
Interop.Sys.IsQemuDetected();
Expand Down
2 changes: 1 addition & 1 deletion src/native/libs/System.Native/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ set(NATIVE_SOURCES
pal_time.c
pal_datetime.c
pal_sysctl.c
"${CLR_SRC_NATIVE_DIR}/minipal/cpufeatures.c"
)

list(APPEND NATIVE_SOURCES
Expand All @@ -48,6 +47,7 @@ if (NOT CLR_CMAKE_TARGET_WASI)
pal_signal.c
pal_threading.c
pal_uid.c
"${CLR_SRC_NATIVE_DIR}/minipal/cpufeatures.c"
)
else()
list (APPEND NATIVE_SOURCES
Expand Down
94 changes: 48 additions & 46 deletions src/native/minipal/cpufeatures.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
#include <sys/auxv.h>
#include <asm/hwcap.h>

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-macros"
#endif

// Light-up for hardware capabilities that are not present in older headers used by the portable build.
#ifndef HWCAP_ASIMDRDM
#define HWCAP_ASIMDRDM (1 << 12)
Expand All @@ -45,6 +50,14 @@
#define HWCAP_SVE (1 << 22)
#endif

#ifndef XSTATE_MASK_AVX512
#define XSTATE_MASK_AVX512 (0xE0) /* 0b1110_0000 */
#endif // XSTATE_MASK_AVX512

#ifdef __clang__
#pragma clang diagnostic pop
#endif

#endif

#if HAVE_SYSCTLBYNAME
Expand All @@ -56,7 +69,7 @@
#if defined(HOST_UNIX)
#if defined(HOST_X86) || defined(HOST_AMD64)

static uint32_t xmmYmmStateSupport()
static uint32_t xmmYmmStateSupport(void)
{
uint32_t eax;
__asm(" xgetbv\n" \
Expand All @@ -68,11 +81,7 @@ static uint32_t xmmYmmStateSupport()
return ((eax & 0x06) == 0x06) ? 1 : 0;
}

#ifndef XSTATE_MASK_AVX512
#define XSTATE_MASK_AVX512 (0xE0) /* 0b1110_0000 */
#endif // XSTATE_MASK_AVX512

static uint32_t avx512StateSupport()
static uint32_t avx512StateSupport(void)
{
#if defined(HOST_APPLE)
// MacOS has specialized behavior where it reports AVX512 support but doesnt
Expand All @@ -99,12 +108,12 @@ static uint32_t avx512StateSupport()
#endif
}

static bool IsAvxEnabled()
static bool IsAvxEnabled(void)
{
return true;
}

static bool IsAvx512Enabled()
static bool IsAvx512Enabled(void)
{
return true;
}
Expand Down Expand Up @@ -222,11 +231,11 @@ int minipal_getcpufeatures(void)

if (IsAvx512Enabled() && (avx512StateSupport() == 1)) // XGETBV XRC0[7:5] == 111
{
if (((cpuidInfo[CPUID_EBX] & (1 << 16)) != 0) && // AVX512F
((cpuidInfo[CPUID_EBX] & (1 << 30)) != 0) && // AVX512BW
((cpuidInfo[CPUID_EBX] & (1 << 28)) != 0) && // AVX512CD
((cpuidInfo[CPUID_EBX] & (1 << 17)) != 0) && // AVX512DQ
((cpuidInfo[CPUID_EBX] & (1 << 31)) != 0)) // AVX512VL
if ((((uint32_t)cpuidInfo[CPUID_EBX] & ((uint32_t)1 << 16)) != 0) && // AVX512F
(((uint32_t)cpuidInfo[CPUID_EBX] & ((uint32_t)1 << 30)) != 0) && // AVX512BW
(((uint32_t)cpuidInfo[CPUID_EBX] & ((uint32_t)1 << 28)) != 0) && // AVX512CD
(((uint32_t)cpuidInfo[CPUID_EBX] & ((uint32_t)1 << 17)) != 0) && // AVX512DQ
(((uint32_t)cpuidInfo[CPUID_EBX] & ((uint32_t)1 << 31)) != 0)) // AVX512VL
{
// While the AVX-512 ISAs can be individually lit-up, they really
// need F, BW, CD, DQ, and VL to be fully functional without adding
Expand Down Expand Up @@ -301,12 +310,12 @@ int minipal_getcpufeatures(void)
}
}

__cpuid(cpuidInfo, 0x80000000);
__cpuid(cpuidInfo, (int)0x80000000);
uint32_t maxCpuIdEx = (uint32_t)cpuidInfo[CPUID_EAX];

if (maxCpuIdEx >= 0x80000001)
{
__cpuid(cpuidInfo, 0x80000001);
__cpuid(cpuidInfo, (int)0x80000001);

if ((cpuidInfo[CPUID_ECX] & (1 << 5)) != 0) // LZCNT
{
Expand Down Expand Up @@ -441,67 +450,58 @@ int minipal_getcpufeatures(void)
return result;
}

// Detect if the current process is running under the Apple Rosetta x64 emulator
bool minipal_detect_rosetta(void)
static bool GetCpuBrand(char* brand, size_t bufferSize)
{
#if defined(HOST_AMD64) || defined(HOST_X86)
// Check for CPU brand indicating emulation
int regs[4];
char brand[49];

// Get the maximum value for extended function CPUID info
__cpuid(regs, (int)0x80000000);
if ((unsigned int)regs[0] < 0x80000004)
{
return false; // Extended CPUID not supported
brand[0] = '\0'; // Extended CPUID not supported, return empty string or handle error
return false;
}

// Retrieve the CPU brand string
// Retrieve the CPU brand string directly into the caller-provided buffer
for (unsigned int i = 0x80000002; i <= 0x80000004; ++i)
{
__cpuid(regs, (int)i);
memcpy(brand + (i - 0x80000002) * sizeof(regs), regs, sizeof(regs));
}
brand[sizeof(brand) - 1] = '\0';

// Check if CPU brand indicates emulation
if (strstr(brand, "VirtualApple") != NULL)
{
return true;
}
#endif // HOST_AMD64 || HOST_X86
brand[bufferSize - 1] = '\0';

return true;
#else
(void)brand;
(void)bufferSize;
return false;
#endif // HOST_AMD64 || HOST_X86
}

bool minipal_detect_qemu(void)
// Detect if the current process is running under the Apple Rosetta x64 emulator
bool minipal_detect_rosetta(void)
{
#if defined(HOST_AMD64) || defined(HOST_X86)
// Check for CPU brand indicating emulation
unsigned int regs[4];
char brand[49];

// Get the maximum value for extended function CPUID info
__cpuid(0x80000000, regs[0], regs[1], regs[2], regs[3]);
if (regs[0] < 0x80000004)
{
return false; // Extended CPUID not supported
}
// Check if CPU brand indicates emulation
return GetCpuBrand(brand, sizeof(brand)) && (strstr(brand, "VirtualApple") != NULL);
}

// Retrieve the CPU brand string
for (unsigned int i = 0x80000002; i <= 0x80000004; ++i)
{
__cpuid(i, regs[0], regs[1], regs[2], regs[3]);
memcpy(brand + (i - 0x80000002) * sizeof(regs), regs, sizeof(regs));
}
brand[sizeof(brand) - 1] = '\0';
#if !defined(HOST_WINDOWS)

// Detect if the current process is running under QEMU
bool minipal_detect_qemu(void)
{
char brand[49];

// Check if CPU brand indicates emulation
if (strstr(brand, "QEMU") != NULL)
if (GetCpuBrand(brand, sizeof(brand)) && strstr(brand, "QEMU") != NULL)
{
return true;
}
#endif

// Check for process name of PID 1 indicating emulation
char cmdline[256];
Expand Down Expand Up @@ -535,3 +535,5 @@ bool minipal_detect_qemu(void)

return false;
}

#endif // !HOST_WINDOWS

0 comments on commit e4030bf

Please sign in to comment.