@@ -98,29 +98,50 @@ bool KvmVirtualProcessor::Initialize() noexcept {
9898 cpuid->nent = static_cast <__u32>(count);
9999
100100 // Build unordered map from custom CPUID entries
101- std::unordered_map<uint32_t , CPUIDResult> custom_cpuids;
101+ std::unordered_map<uint64_t , CPUIDResult> custom_cpuids;
102102 auto & cpuids = m_vm.GetSpecifications ().CPUIDResults ;
103+ uint64_t leaf_index = 0 ;
104+ uint32_t last_func = 0xFFFFFFFF ;
103105 for (auto it = cpuids.cbegin (); it != cpuids.cend (); it++) {
104- custom_cpuids[it->function ] = *it;
106+ if (it->function == last_func) {
107+ leaf_index++;
108+ }
109+ else {
110+ leaf_index = 0 ;
111+ last_func = it->function ;
112+ }
113+ custom_cpuids[(it->function ) | (leaf_index << 32ull )] = *it;
105114 }
106115
107116 // Build list of CPUID responses based on default and custom values
117+ leaf_index = 0 ;
118+ last_func = 0xFFFFFFFF ;
108119 for (size_t i = 0 ; i < count; i++) {
109120 const auto &entry = cpuid_defaults[i];
110- if (custom_cpuids.count (entry.function )) {
111- const auto & custom_entry = custom_cpuids[entry.function ];
112- cpuid->entries [i].function = entry.function ;
113- cpuid->entries [i].index = static_cast <__u32>(i);
114- cpuid->entries [i].flags = 0 ;
115- cpuid->entries [i].eax = entry.eax ;
116- cpuid->entries [i].ebx = entry.ebx ;
117- cpuid->entries [i].ecx = entry.ecx ;
118- cpuid->entries [i].edx = entry.edx ;
121+ if (entry.function == last_func) {
122+ leaf_index++;
123+ }
124+ else {
125+ leaf_index = 0 ;
126+ last_func = entry.function ;
127+ }
128+
129+ cpuid->entries [i].function = entry.function ;
130+ cpuid->entries [i].index = leaf_index;
131+ cpuid->entries [i].flags = 0 ;
132+ if (entry.function == 0x4 || entry.function == 0x7 || entry.function == 0xb || entry.function == 0xd ) {
133+ cpuid->entries [i].flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
134+ }
135+
136+ uint64_t custom_key = (entry.function ) | (leaf_index << 32ull );
137+ if (custom_cpuids.count (custom_key)) {
138+ const auto & custom_entry = custom_cpuids[custom_key];
139+ cpuid->entries [i].eax = custom_entry.eax ;
140+ cpuid->entries [i].ebx = custom_entry.ebx ;
141+ cpuid->entries [i].ecx = custom_entry.ecx ;
142+ cpuid->entries [i].edx = custom_entry.edx ;
119143 }
120144 else {
121- cpuid->entries [i].function = entry.function ;
122- cpuid->entries [i].index = static_cast <__u32>(i);
123- cpuid->entries [i].flags = 0 ;
124145 cpuid->entries [i].eax = entry.eax ;
125146 cpuid->entries [i].ebx = entry.ebx ;
126147 cpuid->entries [i].ecx = entry.ecx ;
0 commit comments