Skip to content

Commit bb802f2

Browse files
author
Ivan Roberto de Oliveira
committed
KVM fixes
1 parent 30aaec9 commit bb802f2

File tree

2 files changed

+40
-17
lines changed

2 files changed

+40
-17
lines changed

modules/kvm/src/kvm_helpers.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,12 @@ void LoadSegment(RegValue& value, const struct kvm_segment *segment) noexcept {
3535
value.segment.selector = segment->selector;
3636
value.segment.base = segment->base;
3737
value.segment.limit = segment->limit;
38+
value.segment.attributes.u16 = 0;
3839
value.segment.attributes.type = segment->type;
3940
value.segment.attributes.present = segment->present;
4041
value.segment.attributes.privilegeLevel = segment->dpl;
41-
value.segment.attributes.system = segment->db;
42-
value.segment.attributes.defaultSize = segment->s;
42+
value.segment.attributes.system = segment->s;
43+
value.segment.attributes.defaultSize = segment->db;
4344
value.segment.attributes.longMode = segment->l;
4445
value.segment.attributes.granularity = segment->g;
4546
value.segment.attributes.available = segment->avl;
@@ -52,8 +53,8 @@ void StoreSegment(const RegValue& value, struct kvm_segment *segment) noexcept {
5253
segment->type = value.segment.attributes.type;
5354
segment->present = value.segment.attributes.present;
5455
segment->dpl = value.segment.attributes.privilegeLevel;
55-
segment->db = value.segment.attributes.system;
56-
segment->s = value.segment.attributes.defaultSize;
56+
segment->db = value.segment.attributes.defaultSize;
57+
segment->s = value.segment.attributes.system;
5758
segment->l = value.segment.attributes.longMode;
5859
segment->g = value.segment.attributes.granularity;
5960
segment->avl = value.segment.attributes.available;

modules/kvm/src/kvm_vp.cpp

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)