Revision 5802e066 target-i386/kvm.c
b/target-i386/kvm.c | ||
---|---|---|
18 | 18 |
#include <sys/utsname.h> |
19 | 19 |
|
20 | 20 |
#include <linux/kvm.h> |
21 |
#include <linux/kvm_para.h> |
|
21 | 22 |
|
22 | 23 |
#include "qemu-common.h" |
23 | 24 |
#include "sysemu.h" |
... | ... | |
29 | 30 |
#include "hw/apic.h" |
30 | 31 |
#include "ioport.h" |
31 | 32 |
|
32 |
#ifdef CONFIG_KVM_PARA |
|
33 |
#include <linux/kvm_para.h> |
|
34 |
#endif |
|
35 |
// |
|
36 | 33 |
//#define DEBUG_KVM |
37 | 34 |
|
38 | 35 |
#ifdef DEBUG_KVM |
... | ... | |
62 | 59 |
|
63 | 60 |
static bool has_msr_star; |
64 | 61 |
static bool has_msr_hsave_pa; |
65 |
#if defined(CONFIG_KVM_PARA) && defined(KVM_CAP_ASYNC_PF) |
|
66 | 62 |
static bool has_msr_async_pf_en; |
67 |
#endif |
|
68 | 63 |
static int lm_capable_kernel; |
69 | 64 |
|
70 | 65 |
static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max) |
... | ... | |
92 | 87 |
return cpuid; |
93 | 88 |
} |
94 | 89 |
|
95 |
#ifdef CONFIG_KVM_PARA |
|
96 | 90 |
struct kvm_para_features { |
97 | 91 |
int cap; |
98 | 92 |
int feature; |
... | ... | |
118 | 112 |
|
119 | 113 |
return features; |
120 | 114 |
} |
121 |
#endif |
|
122 | 115 |
|
123 | 116 |
|
124 | 117 |
uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, |
... | ... | |
128 | 121 |
int i, max; |
129 | 122 |
uint32_t ret = 0; |
130 | 123 |
uint32_t cpuid_1_edx; |
131 |
#ifdef CONFIG_KVM_PARA |
|
132 | 124 |
int has_kvm_features = 0; |
133 |
#endif |
|
134 | 125 |
|
135 | 126 |
max = 1; |
136 | 127 |
while ((cpuid = try_get_cpuid(env->kvm_state, max)) == NULL) { |
... | ... | |
140 | 131 |
for (i = 0; i < cpuid->nent; ++i) { |
141 | 132 |
if (cpuid->entries[i].function == function && |
142 | 133 |
cpuid->entries[i].index == index) { |
143 |
#ifdef CONFIG_KVM_PARA |
|
144 | 134 |
if (cpuid->entries[i].function == KVM_CPUID_FEATURES) { |
145 | 135 |
has_kvm_features = 1; |
146 | 136 |
} |
147 |
#endif |
|
148 | 137 |
switch (reg) { |
149 | 138 |
case R_EAX: |
150 | 139 |
ret = cpuid->entries[i].eax; |
... | ... | |
177 | 166 |
|
178 | 167 |
qemu_free(cpuid); |
179 | 168 |
|
180 |
#ifdef CONFIG_KVM_PARA |
|
181 | 169 |
/* fallback for older kernels */ |
182 | 170 |
if (!has_kvm_features && (function == KVM_CPUID_FEATURES)) { |
183 | 171 |
ret = get_para_features(env); |
184 | 172 |
} |
185 |
#endif |
|
186 | 173 |
|
187 | 174 |
return ret; |
188 | 175 |
} |
... | ... | |
377 | 364 |
uint32_t limit, i, j, cpuid_i; |
378 | 365 |
uint32_t unused; |
379 | 366 |
struct kvm_cpuid_entry2 *c; |
380 |
#ifdef CONFIG_KVM_PARA |
|
381 | 367 |
uint32_t signature[3]; |
382 |
#endif |
|
383 | 368 |
|
384 | 369 |
env->cpuid_features &= kvm_arch_get_supported_cpuid(env, 1, 0, R_EDX); |
385 | 370 |
|
... | ... | |
397 | 382 |
|
398 | 383 |
cpuid_i = 0; |
399 | 384 |
|
400 |
#ifdef CONFIG_KVM_PARA |
|
401 | 385 |
/* Paravirtualization CPUIDs */ |
402 | 386 |
memcpy(signature, "KVMKVMKVM\0\0\0", 12); |
403 | 387 |
c = &cpuid_data.entries[cpuid_i++]; |
... | ... | |
418 | 402 |
has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF); |
419 | 403 |
#endif |
420 | 404 |
|
421 |
#endif |
|
422 |
|
|
423 | 405 |
cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused); |
424 | 406 |
|
425 | 407 |
for (i = 0; i <= limit; i++) { |
... | ... | |
936 | 918 |
kvm_msr_entry_set(&msrs[n++], MSR_KVM_SYSTEM_TIME, |
937 | 919 |
env->system_time_msr); |
938 | 920 |
kvm_msr_entry_set(&msrs[n++], MSR_KVM_WALL_CLOCK, env->wall_clock_msr); |
939 |
#if defined(CONFIG_KVM_PARA) && defined(KVM_CAP_ASYNC_PF) |
|
940 | 921 |
if (has_msr_async_pf_en) { |
941 | 922 |
kvm_msr_entry_set(&msrs[n++], MSR_KVM_ASYNC_PF_EN, |
942 | 923 |
env->async_pf_en_msr); |
943 | 924 |
} |
944 |
#endif |
|
945 | 925 |
} |
946 | 926 |
#ifdef KVM_CAP_MCE |
947 | 927 |
if (env->mcg_cap) { |
... | ... | |
1182 | 1162 |
#endif |
1183 | 1163 |
msrs[n++].index = MSR_KVM_SYSTEM_TIME; |
1184 | 1164 |
msrs[n++].index = MSR_KVM_WALL_CLOCK; |
1185 |
#if defined(CONFIG_KVM_PARA) && defined(KVM_CAP_ASYNC_PF) |
|
1186 | 1165 |
if (has_msr_async_pf_en) { |
1187 | 1166 |
msrs[n++].index = MSR_KVM_ASYNC_PF_EN; |
1188 | 1167 |
} |
1189 |
#endif |
|
1190 | 1168 |
|
1191 | 1169 |
#ifdef KVM_CAP_MCE |
1192 | 1170 |
if (env->mcg_cap) { |
... | ... | |
1263 | 1241 |
} |
1264 | 1242 |
#endif |
1265 | 1243 |
break; |
1266 |
#if defined(CONFIG_KVM_PARA) && defined(KVM_CAP_ASYNC_PF) |
|
1267 | 1244 |
case MSR_KVM_ASYNC_PF_EN: |
1268 | 1245 |
env->async_pf_en_msr = msrs[i].data; |
1269 | 1246 |
break; |
1270 |
#endif |
|
1271 | 1247 |
} |
1272 | 1248 |
} |
1273 | 1249 |
|
Also available in: Unified diff