]> git.proxmox.com Git - qemu.git/commitdiff
Merge remote branch 'qemu-kvm/uq/master' into staging-tmp
authorAnthony Liguori <aliguori@us.ibm.com>
Mon, 8 Feb 2010 16:06:54 +0000 (10:06 -0600)
committerAnthony Liguori <aliguori@us.ibm.com>
Mon, 8 Feb 2010 16:06:54 +0000 (10:06 -0600)
cpu-all.h
cpu-defs.h
exec.c
hw/vmport.c
kvm-all.c
kvm.h
target-i386/kvm.c
vl.c

index 57b69f8865a15173f027dd9333325d91d1aa1d45..1ccc9a87b754ddd660c8257357301bb240eb794e 100644 (file)
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -915,6 +915,8 @@ void qemu_register_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
 
 void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size);
 
+void qemu_flush_coalesced_mmio_buffer(void);
+
 /*******************************************/
 /* host CPU ticks (if available) */
 
index 95068b530432ed38372d7eacfac50b7b015c52d8..7fdbe977877a0abd878ecf5263dfe83f2b17494e 100644 (file)
@@ -197,6 +197,7 @@ typedef struct CPUWatchpoint {
     const char *cpu_model_str;                                          \
     struct KVMState *kvm_state;                                         \
     struct kvm_run *kvm_run;                                            \
-    int kvm_fd;
+    int kvm_fd;                                                         \
+    int kvm_vcpu_dirty;
 
 #endif
diff --git a/exec.c b/exec.c
index b0caf7c24f81b0a598c8fd6fa31cf9febf0a0c37..0fb363b49d184e0a4cc91b6e85b27e3ca6e9b2f8 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -2415,6 +2415,12 @@ void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size)
         kvm_uncoalesce_mmio_region(addr, size);
 }
 
+void qemu_flush_coalesced_mmio_buffer(void)
+{
+    if (kvm_enabled())
+        kvm_flush_coalesced_mmio_buffer();
+}
+
 ram_addr_t qemu_ram_alloc(ram_addr_t size)
 {
     RAMBlock *new_block;
index 884af3fd9191978e3eac91d28d4624e31a29176d..6c9d7c9651a0a05ad3d38bc76536719fc3e17109 100644 (file)
@@ -25,6 +25,7 @@
 #include "isa.h"
 #include "pc.h"
 #include "sysemu.h"
+#include "kvm.h"
 
 //#define VMPORT_DEBUG
 
@@ -58,6 +59,8 @@ static uint32_t vmport_ioport_read(void *opaque, uint32_t addr)
     unsigned char command;
     uint32_t eax;
 
+    cpu_synchronize_state(env);
+
     eax = env->regs[R_EAX];
     if (eax != VMPORT_MAGIC)
         return eax;
index 15ec38e631f08301b1112c6a997a457fd6d8cba3..6c0fd373a2aebe504f62c02de6935c2d5c0d74fe 100644 (file)
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -57,8 +57,10 @@ struct KVMState
     KVMSlot slots[32];
     int fd;
     int vmfd;
-    int regs_modified;
     int coalesced_mmio;
+#ifdef KVM_CAP_COALESCED_MMIO
+    struct kvm_coalesced_mmio_ring *coalesced_mmio_ring;
+#endif
     int broken_set_mem_region;
     int migration_log;
     int vcpu_events;
@@ -200,6 +202,12 @@ int kvm_init_vcpu(CPUState *env)
         goto err;
     }
 
+#ifdef KVM_CAP_COALESCED_MMIO
+    if (s->coalesced_mmio && !s->coalesced_mmio_ring)
+        s->coalesced_mmio_ring = (void *) env->kvm_run +
+               s->coalesced_mmio * PAGE_SIZE;
+#endif
+
     ret = kvm_arch_init_vcpu(env);
     if (ret == 0) {
         qemu_register_reset(kvm_reset_vcpu, env);
@@ -466,10 +474,10 @@ int kvm_init(int smp_cpus)
         goto err;
     }
 
+    s->coalesced_mmio = 0;
 #ifdef KVM_CAP_COALESCED_MMIO
     s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO);
-#else
-    s->coalesced_mmio = 0;
+    s->coalesced_mmio_ring = NULL;
 #endif
 
     s->broken_set_mem_region = 1;
@@ -544,14 +552,12 @@ static int kvm_handle_io(uint16_t port, void *data, int direction, int size,
     return 1;
 }
 
-static void kvm_run_coalesced_mmio(CPUState *env, struct kvm_run *run)
+void kvm_flush_coalesced_mmio_buffer(void)
 {
 #ifdef KVM_CAP_COALESCED_MMIO
     KVMState *s = kvm_state;
-    if (s->coalesced_mmio) {
-        struct kvm_coalesced_mmio_ring *ring;
-
-        ring = (void *)run + (s->coalesced_mmio * TARGET_PAGE_SIZE);
+    if (s->coalesced_mmio_ring) {
+        struct kvm_coalesced_mmio_ring *ring = s->coalesced_mmio_ring;
         while (ring->first != ring->last) {
             struct kvm_coalesced_mmio *ent;
 
@@ -567,9 +573,9 @@ static void kvm_run_coalesced_mmio(CPUState *env, struct kvm_run *run)
 
 void kvm_cpu_synchronize_state(CPUState *env)
 {
-    if (!env->kvm_state->regs_modified) {
+    if (!env->kvm_vcpu_dirty) {
         kvm_arch_get_registers(env);
-        env->kvm_state->regs_modified = 1;
+        env->kvm_vcpu_dirty = 1;
     }
 }
 
@@ -587,9 +593,9 @@ int kvm_cpu_exec(CPUState *env)
             break;
         }
 
-        if (env->kvm_state->regs_modified) {
+        if (env->kvm_vcpu_dirty) {
             kvm_arch_put_registers(env);
-            env->kvm_state->regs_modified = 0;
+            env->kvm_vcpu_dirty = 0;
         }
 
         kvm_arch_pre_run(env, run);
@@ -609,7 +615,7 @@ int kvm_cpu_exec(CPUState *env)
             abort();
         }
 
-        kvm_run_coalesced_mmio(env, run);
+        kvm_flush_coalesced_mmio_buffer();
 
         ret = 0; /* exit loop */
         switch (run->exit_reason) {
@@ -939,9 +945,9 @@ static void kvm_invoke_set_guest_debug(void *data)
     struct kvm_set_guest_debug_data *dbg_data = data;
     CPUState *env = dbg_data->env;
 
-    if (env->kvm_state->regs_modified) {
+    if (env->kvm_vcpu_dirty) {
         kvm_arch_put_registers(env);
-        env->kvm_state->regs_modified = 0;
+        env->kvm_vcpu_dirty = 0;
     }
     dbg_data->err = kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, &dbg_data->dbg);
 }
diff --git a/kvm.h b/kvm.h
index 1c93ac57536de31ac558696da07b62182e784653..59cba18e962823ac4622b232363dddbbbb806d09 100644 (file)
--- a/kvm.h
+++ b/kvm.h
@@ -53,6 +53,7 @@ void kvm_setup_guest_memory(void *start, size_t size);
 
 int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
 int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
+void kvm_flush_coalesced_mmio_buffer(void);
 
 int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
                           target_ulong len, int type);
index 5b093ce3bf1c38075276966b483f7b634cae2176..0d08cd532ec309abadd99687243614976191dce9 100644 (file)
@@ -99,12 +99,18 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, int reg)
                 break;
             case R_EDX:
                 ret = cpuid->entries[i].edx;
-                if (function == 0x80000001) {
+                switch (function) {
+                case 1:
+                    /* KVM before 2.6.30 misreports the following features */
+                    ret |= CPUID_MTRR | CPUID_PAT | CPUID_MCE | CPUID_MCA;
+                    break;
+                case 0x80000001:
                     /* On Intel, kvm returns cpuid according to the Intel spec,
                      * so add missing bits according to the AMD spec:
                      */
                     cpuid_1_edx = kvm_arch_get_supported_cpuid(env, 1, R_EDX);
                     ret |= cpuid_1_edx & 0xdfeff7ff;
+                    break;
                 }
                 break;
             }
@@ -794,6 +800,9 @@ static int kvm_put_vcpu_events(CPUState *env)
 
     events.sipi_vector = env->sipi_vector;
 
+    events.flags =
+        KVM_VCPUEVENT_VALID_NMI_PENDING | KVM_VCPUEVENT_VALID_SIPI_VECTOR;
+
     return kvm_vcpu_ioctl(env, KVM_SET_VCPU_EVENTS, &events);
 #else
     return 0;
diff --git a/vl.c b/vl.c
index 5ddf1febdfe36af452230d391fdcc31aba5b5a0d..880bcd5943e9924938596c762a0d8190155de44f 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -2996,6 +2996,7 @@ static void gui_update(void *opaque)
     DisplayState *ds = opaque;
     DisplayChangeListener *dcl = ds->listeners;
 
+    qemu_flush_coalesced_mmio_buffer();
     dpy_refresh(ds);
 
     while (dcl != NULL) {
@@ -3011,6 +3012,7 @@ static void nographic_update(void *opaque)
 {
     uint64_t interval = GUI_REFRESH_INTERVAL;
 
+    qemu_flush_coalesced_mmio_buffer();
     qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock));
 }
 
@@ -3280,6 +3282,8 @@ static int cpu_can_run(CPUState *env)
         return 0;
     if (env->stopped)
         return 0;
+    if (!vm_running)
+        return 0;
     return 1;
 }