Revision 92067bf4 target-i386/kvm.c
b/target-i386/kvm.c | ||
---|---|---|
31 | 31 |
#include "hw/i386/pc.h" |
32 | 32 |
#include "hw/i386/apic.h" |
33 | 33 |
#include "exec/ioport.h" |
34 |
#include "hyperv.h"
|
|
34 |
#include <asm/hyperv.h>
|
|
35 | 35 |
#include "hw/pci/pci.h" |
36 | 36 |
|
37 | 37 |
//#define DEBUG_KVM |
... | ... | |
420 | 420 |
return cpu->env.cpuid_apic_id; |
421 | 421 |
} |
422 | 422 |
|
423 |
#ifndef KVM_CPUID_SIGNATURE_NEXT |
|
424 |
#define KVM_CPUID_SIGNATURE_NEXT 0x40000100 |
|
425 |
#endif |
|
426 |
|
|
427 |
static bool hyperv_hypercall_available(X86CPU *cpu) |
|
428 |
{ |
|
429 |
return cpu->hyperv_vapic || |
|
430 |
(cpu->hyperv_spinlock_attempts != HYPERV_SPINLOCK_NEVER_RETRY); |
|
431 |
} |
|
432 |
|
|
433 |
static bool hyperv_enabled(X86CPU *cpu) |
|
434 |
{ |
|
435 |
return hyperv_hypercall_available(cpu) || |
|
436 |
cpu->hyperv_relaxed_timing; |
|
437 |
} |
|
438 |
|
|
423 | 439 |
#define KVM_MAX_CPUID_ENTRIES 100 |
424 | 440 |
|
425 | 441 |
int kvm_arch_init_vcpu(CPUState *cs) |
... | ... | |
442 | 458 |
c = &cpuid_data.entries[cpuid_i++]; |
443 | 459 |
memset(c, 0, sizeof(*c)); |
444 | 460 |
c->function = KVM_CPUID_SIGNATURE; |
445 |
if (!hyperv_enabled()) { |
|
461 |
if (!hyperv_enabled(cpu)) {
|
|
446 | 462 |
memcpy(signature, "KVMKVMKVM\0\0\0", 12); |
447 | 463 |
c->eax = 0; |
448 | 464 |
} else { |
... | ... | |
458 | 474 |
c->function = KVM_CPUID_FEATURES; |
459 | 475 |
c->eax = env->features[FEAT_KVM]; |
460 | 476 |
|
461 |
if (hyperv_enabled()) { |
|
477 |
if (hyperv_enabled(cpu)) {
|
|
462 | 478 |
memcpy(signature, "Hv#1\0\0\0\0\0\0\0\0", 12); |
463 | 479 |
c->eax = signature[0]; |
464 | 480 |
|
... | ... | |
471 | 487 |
c = &cpuid_data.entries[cpuid_i++]; |
472 | 488 |
memset(c, 0, sizeof(*c)); |
473 | 489 |
c->function = HYPERV_CPUID_FEATURES; |
474 |
if (hyperv_relaxed_timing_enabled()) {
|
|
490 |
if (cpu->hyperv_relaxed_timing) {
|
|
475 | 491 |
c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE; |
476 | 492 |
} |
477 |
if (hyperv_vapic_recommended()) {
|
|
493 |
if (cpu->hyperv_vapic) {
|
|
478 | 494 |
c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE; |
479 | 495 |
c->eax |= HV_X64_MSR_APIC_ACCESS_AVAILABLE; |
480 | 496 |
} |
... | ... | |
482 | 498 |
c = &cpuid_data.entries[cpuid_i++]; |
483 | 499 |
memset(c, 0, sizeof(*c)); |
484 | 500 |
c->function = HYPERV_CPUID_ENLIGHTMENT_INFO; |
485 |
if (hyperv_relaxed_timing_enabled()) {
|
|
501 |
if (cpu->hyperv_relaxed_timing) {
|
|
486 | 502 |
c->eax |= HV_X64_RELAXED_TIMING_RECOMMENDED; |
487 | 503 |
} |
488 |
if (hyperv_vapic_recommended()) {
|
|
504 |
if (cpu->hyperv_vapic) {
|
|
489 | 505 |
c->eax |= HV_X64_APIC_ACCESS_RECOMMENDED; |
490 | 506 |
} |
491 |
c->ebx = hyperv_get_spinlock_retries();
|
|
507 |
c->ebx = cpu->hyperv_spinlock_attempts;
|
|
492 | 508 |
|
493 | 509 |
c = &cpuid_data.entries[cpuid_i++]; |
494 | 510 |
memset(c, 0, sizeof(*c)); |
... | ... | |
1114 | 1130 |
kvm_msr_entry_set(&msrs[n++], MSR_KVM_STEAL_TIME, |
1115 | 1131 |
env->steal_time_msr); |
1116 | 1132 |
} |
1117 |
if (hyperv_hypercall_available()) { |
|
1133 |
if (hyperv_hypercall_available(cpu)) {
|
|
1118 | 1134 |
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_GUEST_OS_ID, 0); |
1119 | 1135 |
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_HYPERCALL, 0); |
1120 | 1136 |
} |
1121 |
if (hyperv_vapic_recommended()) {
|
|
1137 |
if (cpu->hyperv_vapic) {
|
|
1122 | 1138 |
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_APIC_ASSIST_PAGE, 0); |
1123 | 1139 |
} |
1124 | 1140 |
} |
Also available in: Unified diff