From 0a0bc21c88ed5bb7469624e6e657f1f5db7a09d5 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Mon, 28 Feb 2022 19:50:55 -0800 Subject: [PATCH] CPUID: Implements leaf 4000_0000 This region is reserved for hypervisor uses. Let's follow other examples and return a hypervisor vendor id signature as another way for software to find if it is running under FEX-Emu. --- .../FEXCore/Source/Interface/Core/CPUID.cpp | 25 +++++++++++++++++++ .../FEXCore/Source/Interface/Core/CPUID.h | 1 + 2 files changed, 26 insertions(+) diff --git a/External/FEXCore/Source/Interface/Core/CPUID.cpp b/External/FEXCore/Source/Interface/Core/CPUID.cpp index d67b2956ec..00d31858ad 100644 --- a/External/FEXCore/Source/Interface/Core/CPUID.cpp +++ b/External/FEXCore/Source/Interface/Core/CPUID.cpp @@ -812,6 +812,28 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_1Ah(uint32_t Leaf) { return Res; } +// Hypervisor CPUID information leaf +FEXCore::CPUID::FunctionResults CPUIDEmu::Function_4000_0000h(uint32_t Leaf) { + FEXCore::CPUID::FunctionResults Res{}; + // Maximum supported hypervisor leafs + // We only expose the information leaf + // + // Common courtesy to follow VMWare's "Hypervisor CPUID Interface proposal" + // 4000_0000h - Information leaf. Advertising to the software which hypervisor this is + // 4000_0001h - 4000_000Fh - Hypervisor specific leafs. FEX can use these for anything + // 4000_0010h - 4000_00FFh - "Generic Leafs" - Try not to overwrite, other hypervisors might expect information in these + // + // CPUID documentation information: + // 4000_0000h - 4FFF_FFFFh - No existing or future CPU will return information in this range + // Reserved entirely for VMs to do whatever they want. + Res.eax = 0x40000000; + + // EBX, EDX, ECX become the hypervisor ID signature + constexpr static char HypervisorID[12] = "FEXIFEXIEMU"; + memcpy(&Res.ebx, HypervisorID, sizeof(HypervisorID)); + return Res; +} + // Highest extended function implemented FEXCore::CPUID::FunctionResults CPUIDEmu::Function_8000_0000h(uint32_t Leaf) { FEXCore::CPUID::FunctionResults Res{}; @@ -1204,6 +1226,9 @@ void CPUIDEmu::Init(FEXCore::Context::Context *ctx) { #ifndef CPUID_AMD RegisterFunction(0x1A, &CPUIDEmu::Function_1Ah); #endif + // Hypervisor CPUID information leaf + RegisterFunction(0x4000'0000, &CPUIDEmu::Function_4000_0000h); + // Largest extended function number RegisterFunction(0x8000'0000, &CPUIDEmu::Function_8000_0000h); // Processor vendor diff --git a/External/FEXCore/Source/Interface/Core/CPUID.h b/External/FEXCore/Source/Interface/Core/CPUID.h index 4b380edc00..fe9248cc56 100644 --- a/External/FEXCore/Source/Interface/Core/CPUID.h +++ b/External/FEXCore/Source/Interface/Core/CPUID.h @@ -79,6 +79,7 @@ class CPUIDEmu final { FEXCore::CPUID::FunctionResults Function_0Dh(uint32_t Leaf); FEXCore::CPUID::FunctionResults Function_15h(uint32_t Leaf); FEXCore::CPUID::FunctionResults Function_1Ah(uint32_t Leaf); + FEXCore::CPUID::FunctionResults Function_4000_0000h(uint32_t Leaf); FEXCore::CPUID::FunctionResults Function_8000_0000h(uint32_t Leaf); FEXCore::CPUID::FunctionResults Function_8000_0001h(uint32_t Leaf); FEXCore::CPUID::FunctionResults Function_8000_0002h(uint32_t Leaf);