summary refs log tree commit diff stats
path: root/target-i386/kvm.c
diff options
context:
space:
mode:
authorAnthony Liguori <anthony@codemonkey.ws>2013-08-20 09:51:53 -0500
committerAnthony Liguori <anthony@codemonkey.ws>2013-08-20 09:51:53 -0500
commit237e4f92a81696e5359766a7f19a77a9ff1d02e5 (patch)
treeae60a299d73e3f0742bf4238c3c379466510d7ad /target-i386/kvm.c
parentbc02fb304c6cc0f1dd0809545d226df2d6f5c093 (diff)
parent321bc0b2b27aa2dd64bf12e0e2a0f323a4903ecf (diff)
downloadfocaccia-qemu-237e4f92a81696e5359766a7f19a77a9ff1d02e5.tar.gz
focaccia-qemu-237e4f92a81696e5359766a7f19a77a9ff1d02e5.zip
Merge remote-tracking branch 'afaerber/tags/qom-cpu-for-anthony' into staging
QOM CPUState refactorings / X86CPU

* gdbstub coprocessor register count bugfix
* QOM instance_post_init infrastructure to override dynamic properties
* X86CPU HyperV preparations for CPU subclasses

# gpg: Signature made Fri 16 Aug 2013 11:49:02 AM CDT using RSA key ID 3E7E013F
# gpg: Can't check signature: public key not found

# By Eduardo Habkost (3) and others
# Via Andreas Färber
* afaerber/tags/qom-cpu-for-anthony:
  cpus: Use cpu_is_stopped() efficiently
  target-i386: Move hyperv_* static globals to X86CPU
  qdev: Set globals in instance_post_init function
  qom: Introduce instance_post_init hook
  tests: Unit tests for qdev global properties handling
  gdbstub: Fix gdb_register_coprocessor() register counting
Diffstat (limited to 'target-i386/kvm.c')
-rw-r--r--target-i386/kvm.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 376fc70ae3..0b6eb0155c 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -31,7 +31,7 @@
 #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
@@ -420,6 +420,22 @@ unsigned long kvm_arch_vcpu_id(CPUState *cs)
     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)
@@ -442,7 +458,7 @@ 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 {
@@ -458,7 +474,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
     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];
 
@@ -471,10 +487,10 @@ int kvm_arch_init_vcpu(CPUState *cs)
         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;
         }
@@ -482,13 +498,13 @@ int kvm_arch_init_vcpu(CPUState *cs)
         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));
@@ -1114,11 +1130,11 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
             kvm_msr_entry_set(&msrs[n++], MSR_KVM_STEAL_TIME,
                               env->steal_time_msr);
         }
-        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);
         }
     }