#include "hw/i386/pc.h"
#include "hw/i386/apic.h"
#include "exec/ioport.h"
-#include "hyperv.h"
+#include <asm/hyperv.h>
#include "hw/pci/pci.h"
//#define DEBUG_KVM
return cpu->env.cpuid_apic_id;
}
+#ifndef KVM_CPUID_SIGNATURE_NEXT
+#define KVM_CPUID_SIGNATURE_NEXT 0x40000100
+#endif
+
+static bool hyperv_hypercall_available(X86CPU *cpu)
+{
+ return cpu->hyperv_vapic ||
+ (cpu->hyperv_spinlock_attempts != HYPERV_SPINLOCK_NEVER_RETRY);
+}
+
+static bool hyperv_enabled(X86CPU *cpu)
+{
+ return hyperv_hypercall_available(cpu) ||
+ cpu->hyperv_relaxed_timing;
+}
+
#define KVM_MAX_CPUID_ENTRIES 100
int kvm_arch_init_vcpu(CPUState *cs)
c = &cpuid_data.entries[cpuid_i++];
memset(c, 0, sizeof(*c));
c->function = KVM_CPUID_SIGNATURE;
- if (!hyperv_enabled()) {
+ if (!hyperv_enabled(cpu)) {
memcpy(signature, "KVMKVMKVM\0\0\0", 12);
c->eax = 0;
} else {
c->function = KVM_CPUID_FEATURES;
c->eax = env->features[FEAT_KVM];
- if (hyperv_enabled()) {
+ if (hyperv_enabled(cpu)) {
memcpy(signature, "Hv#1\0\0\0\0\0\0\0\0", 12);
c->eax = signature[0];
c = &cpuid_data.entries[cpuid_i++];
memset(c, 0, sizeof(*c));
c->function = HYPERV_CPUID_FEATURES;
- if (hyperv_relaxed_timing_enabled()) {
+ if (cpu->hyperv_relaxed_timing) {
c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE;
}
- if (hyperv_vapic_recommended()) {
+ if (cpu->hyperv_vapic) {
c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE;
c->eax |= HV_X64_MSR_APIC_ACCESS_AVAILABLE;
}
c = &cpuid_data.entries[cpuid_i++];
memset(c, 0, sizeof(*c));
c->function = HYPERV_CPUID_ENLIGHTMENT_INFO;
- if (hyperv_relaxed_timing_enabled()) {
+ if (cpu->hyperv_relaxed_timing) {
c->eax |= HV_X64_RELAXED_TIMING_RECOMMENDED;
}
- if (hyperv_vapic_recommended()) {
+ if (cpu->hyperv_vapic) {
c->eax |= HV_X64_APIC_ACCESS_RECOMMENDED;
}
- c->ebx = hyperv_get_spinlock_retries();
+ c->ebx = cpu->hyperv_spinlock_attempts;
c = &cpuid_data.entries[cpuid_i++];
memset(c, 0, sizeof(*c));
kvm_msr_entry_set(&msrs[n++], MSR_CORE_PERF_GLOBAL_CTRL,
env->msr_global_ctrl);
}
- if (hyperv_hypercall_available()) {
+ if (hyperv_hypercall_available(cpu)) {
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_GUEST_OS_ID, 0);
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_HYPERCALL, 0);
}
- if (hyperv_vapic_recommended()) {
+ if (cpu->hyperv_vapic) {
kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_APIC_ASSIST_PAGE, 0);
}
if (has_msr_feature_control) {
*/
if (reinject_trap ||
(!kvm_has_robust_singlestep() && cs->singlestep_enabled)) {
- ret = kvm_update_guest_debug(env, reinject_trap);
+ ret = kvm_update_guest_debug(cs, reinject_trap);
}
return ret;
}