Revision f0b9b111
b/target-i386/cpu.c | ||
---|---|---|
1201 | 1201 |
* |
1202 | 1202 |
* This function may be called only if KVM is enabled. |
1203 | 1203 |
*/ |
1204 |
static int kvm_check_features_against_host(X86CPU *cpu) |
|
1204 |
static int kvm_check_features_against_host(KVMState *s, X86CPU *cpu)
|
|
1205 | 1205 |
{ |
1206 | 1206 |
CPUX86State *env = &cpu->env; |
1207 |
x86_def_t host_def; |
|
1208 |
uint32_t mask; |
|
1209 |
int rv, i; |
|
1210 |
struct model_features_t ft[] = { |
|
1211 |
{&env->features[FEAT_1_EDX], |
|
1212 |
&host_def.features[FEAT_1_EDX], |
|
1213 |
FEAT_1_EDX }, |
|
1214 |
{&env->features[FEAT_1_ECX], |
|
1215 |
&host_def.features[FEAT_1_ECX], |
|
1216 |
FEAT_1_ECX }, |
|
1217 |
{&env->features[FEAT_8000_0001_EDX], |
|
1218 |
&host_def.features[FEAT_8000_0001_EDX], |
|
1219 |
FEAT_8000_0001_EDX }, |
|
1220 |
{&env->features[FEAT_8000_0001_ECX], |
|
1221 |
&host_def.features[FEAT_8000_0001_ECX], |
|
1222 |
FEAT_8000_0001_ECX }, |
|
1223 |
{&env->features[FEAT_C000_0001_EDX], |
|
1224 |
&host_def.features[FEAT_C000_0001_EDX], |
|
1225 |
FEAT_C000_0001_EDX }, |
|
1226 |
{&env->features[FEAT_7_0_EBX], |
|
1227 |
&host_def.features[FEAT_7_0_EBX], |
|
1228 |
FEAT_7_0_EBX }, |
|
1229 |
{&env->features[FEAT_SVM], |
|
1230 |
&host_def.features[FEAT_SVM], |
|
1231 |
FEAT_SVM }, |
|
1232 |
{&env->features[FEAT_KVM], |
|
1233 |
&host_def.features[FEAT_KVM], |
|
1234 |
FEAT_KVM }, |
|
1235 |
}; |
|
1207 |
int rv = 0; |
|
1208 |
FeatureWord w; |
|
1236 | 1209 |
|
1237 | 1210 |
assert(kvm_enabled()); |
1238 | 1211 |
|
1239 |
kvm_cpu_fill_host(&host_def); |
|
1240 |
for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i) { |
|
1241 |
FeatureWord w = ft[i].feat_word; |
|
1212 |
for (w = 0; w < FEATURE_WORDS; w++) { |
|
1242 | 1213 |
FeatureWordInfo *wi = &feature_word_info[w]; |
1214 |
uint32_t guest_feat = env->features[w]; |
|
1215 |
uint32_t host_feat = kvm_arch_get_supported_cpuid(s, wi->cpuid_eax, |
|
1216 |
wi->cpuid_ecx, |
|
1217 |
wi->cpuid_reg); |
|
1218 |
uint32_t mask; |
|
1243 | 1219 |
for (mask = 1; mask; mask <<= 1) { |
1244 |
if (*ft[i].guest_feat & mask && |
|
1245 |
!(*ft[i].host_feat & mask)) { |
|
1220 |
if (guest_feat & mask && !(host_feat & mask)) { |
|
1246 | 1221 |
unavailable_host_feature(wi, mask); |
1247 | 1222 |
rv = 1; |
1248 | 1223 |
} |
... | ... | |
2563 | 2538 |
env->features[FEAT_8000_0001_ECX] &= TCG_EXT3_FEATURES; |
2564 | 2539 |
env->features[FEAT_SVM] &= TCG_SVM_FEATURES; |
2565 | 2540 |
} else { |
2541 |
KVMState *s = kvm_state; |
|
2566 | 2542 |
if ((cpu->check_cpuid || cpu->enforce_cpuid) |
2567 |
&& kvm_check_features_against_host(cpu) && cpu->enforce_cpuid) { |
|
2543 |
&& kvm_check_features_against_host(s, cpu) && cpu->enforce_cpuid) {
|
|
2568 | 2544 |
error_setg(&local_err, |
2569 | 2545 |
"Host's CPU doesn't support requested features"); |
2570 | 2546 |
goto out; |
Also available in: Unified diff