@@ -34,6 +34,7 @@ SOFTWARE.
3434#include < linux/kvm.h>
3535#include < assert.h>
3636#include < memory>
37+ #include < unordered_map>
3738
3839#include " virt86/util/bytemanip.hpp"
3940
@@ -90,13 +91,24 @@ bool KvmVirtualProcessor::Initialize() noexcept {
9091
9192 // Configure the custom CPUIDs if supported
9293 if (m_vm.GetPlatform ().GetFeatures ().customCPUIDs ) {
94+ // Allocate memory for CPUID responses
95+ auto & cpuid_defaults = m_vm.GetPlatform ().GetFeatures ().supportedCustomCPUIDs ;
96+ size_t count = cpuid_defaults.size ();
97+ auto cpuid = allocVarEntry<kvm_cpuid2, kvm_cpuid_entry2>(count);
98+ cpuid->nent = static_cast <__u32>(count);
99+
100+ // Build unordered map from custom CPUID entries
101+ std::unordered_map<uint32_t , CPUIDResult> custom_cpuids;
93102 auto & cpuids = m_vm.GetSpecifications ().CPUIDResults ;
94- if (!cpuids.empty ()) {
95- size_t count = cpuids.size ();
96- auto cpuid = allocVarEntry<kvm_cpuid2, kvm_cpuid_entry2>(count);
97- cpuid->nent = static_cast <__u32>(count);
98- for (size_t i = 0 ; i < count; i++) {
99- auto &entry = cpuids[i];
103+ for (auto it = cpuids.cbegin (); it != cpuids.cend (); it++) {
104+ custom_cpuids[it->function ] = *it;
105+ }
106+
107+ // Build list of CPUID responses based on default and custom values
108+ for (size_t i = 0 ; i < count; i++) {
109+ const auto &entry = cpuid_defaults[i];
110+ if (custom_cpuids.count (entry.function )) {
111+ const auto & custom_entry = custom_cpuids[entry.function ];
100112 cpuid->entries [i].function = entry.function ;
101113 cpuid->entries [i].index = static_cast <__u32>(i);
102114 cpuid->entries [i].flags = 0 ;
@@ -105,16 +117,26 @@ bool KvmVirtualProcessor::Initialize() noexcept {
105117 cpuid->entries [i].ecx = entry.ecx ;
106118 cpuid->entries [i].edx = entry.edx ;
107119 }
108-
109- int result = ioctl (m_fd, KVM_SET_CPUID2, cpuid);
110- if (result < 0 ) {
111- close (m_fd);
112- m_fd = -1 ;
113- free (cpuid);
114- return false ;
120+ else {
121+ cpuid->entries [i].function = entry.function ;
122+ cpuid->entries [i].index = static_cast <__u32>(i);
123+ cpuid->entries [i].flags = 0 ;
124+ cpuid->entries [i].eax = entry.eax ;
125+ cpuid->entries [i].ebx = entry.ebx ;
126+ cpuid->entries [i].ecx = entry.ecx ;
127+ cpuid->entries [i].edx = entry.edx ;
115128 }
129+ }
130+
131+ // Apply changes
132+ int result = ioctl (m_fd, KVM_SET_CPUID2, cpuid);
133+ if (result < 0 ) {
134+ close (m_fd);
135+ m_fd = -1 ;
116136 free (cpuid);
137+ return false ;
117138 }
139+ free (cpuid);
118140 }
119141
120142 return true ;
0 commit comments