split away drive init from ide_init2()
[qemu] / kvm-all.c
index 9d02ce3..ac57984 100644 (file)
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -57,6 +57,7 @@ struct KVMState
     KVMSlot slots[32];
     int fd;
     int vmfd;
+    int regs_modified;
     int coalesced_mmio;
     int broken_set_mem_region;
     int migration_log;
@@ -155,15 +156,6 @@ static void kvm_reset_vcpu(void *opaque)
     }
 }
 
-static void on_vcpu(CPUState *env, void (*func)(void *data), void *data)
-{
-    if (env == cpu_single_env) {
-        func(data);
-        return;
-    }
-    abort();
-}
-
 int kvm_irqchip_in_kernel(void)
 {
     return kvm_state->irqchip_in_kernel;
@@ -304,6 +296,11 @@ int kvm_set_migration_log(int enable)
     return 0;
 }
 
+static int test_le_bit(unsigned long nr, unsigned char *addr)
+{
+    return (addr[nr >> 3] >> (nr & 7)) & 1;
+}
+
 /**
  * kvm_physical_sync_dirty_bitmap - Grab dirty bitmap from kernel space
  * This function updates qemu's dirty bitmap using cpu_physical_memory_set_dirty().
@@ -322,7 +319,6 @@ int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
     KVMDirtyLog d;
     KVMSlot *mem;
     int ret = 0;
-    int r;
 
     d.dirty_bitmap = NULL;
     while (start_addr < end_addr) {
@@ -331,11 +327,6 @@ int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
             break;
         }
 
-        /* We didn't activate dirty logging? Don't care then. */
-        if(!(mem->flags & KVM_MEM_LOG_DIRTY_PAGES)) {
-            continue;
-        }
-
         size = ((mem->memory_size >> TARGET_PAGE_BITS) + 7) / 8;
         if (!d.dirty_bitmap) {
             d.dirty_bitmap = qemu_malloc(size);
@@ -347,8 +338,7 @@ int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
 
         d.slot = mem->slot;
 
-        r = kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d);
-        if (r == -EINVAL) {
+        if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) == -1) {
             dprintf("ioctl failed %d\n", errno);
             ret = -1;
             break;
@@ -357,16 +347,10 @@ int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
         for (phys_addr = mem->start_addr, addr = mem->phys_offset;
              phys_addr < mem->start_addr + mem->memory_size;
              phys_addr += TARGET_PAGE_SIZE, addr += TARGET_PAGE_SIZE) {
-            uint64_t *bitmap = (uint64_t *)d.dirty_bitmap;
+            unsigned char *bitmap = (unsigned char *)d.dirty_bitmap;
             unsigned nr = (phys_addr - mem->start_addr) >> TARGET_PAGE_BITS;
-            unsigned word = nr / (sizeof(*bitmap) * 8);
-            unsigned bit = nr % (sizeof(*bitmap) * 8);
 
-            if ((bitmap[word] >> bit) & 1) {
-                cpu_physical_memory_set_dirty(addr);
-            } else if (r < 0) {
-                /* When our KVM implementation doesn't know about dirty logging
-                 * we can just assume it's always dirty and be fine. */
+            if (test_le_bit(nr, bitmap)) {
                 cpu_physical_memory_set_dirty(addr);
             }
         }
@@ -444,7 +428,7 @@ int kvm_init(int smp_cpus)
     s = qemu_mallocz(sizeof(KVMState));
 
 #ifdef KVM_CAP_SET_GUEST_DEBUG
-    TAILQ_INIT(&s->kvm_sw_breakpoints);
+    QTAILQ_INIT(&s->kvm_sw_breakpoints);
 #endif
     for (i = 0; i < ARRAY_SIZE(s->slots); i++)
         s->slots[i].slot = i;
@@ -593,6 +577,14 @@ static void kvm_run_coalesced_mmio(CPUState *env, struct kvm_run *run)
 #endif
 }
 
+void kvm_cpu_synchronize_state(CPUState *env)
+{
+    if (!env->kvm_state->regs_modified) {
+        kvm_arch_get_registers(env);
+        env->kvm_state->regs_modified = 1;
+    }
+}
+
 int kvm_cpu_exec(CPUState *env)
 {
     struct kvm_run *run = env->kvm_run;
@@ -607,6 +599,11 @@ int kvm_cpu_exec(CPUState *env)
             break;
         }
 
+        if (env->kvm_state->regs_modified) {
+            kvm_arch_put_registers(env);
+            env->kvm_state->regs_modified = 0;
+        }
+
         kvm_arch_pre_run(env, run);
         ret = kvm_vcpu_ioctl(env, KVM_RUN, 0);
         kvm_arch_post_run(env, run);
@@ -906,12 +903,21 @@ void kvm_setup_guest_memory(void *start, size_t size)
 }
 
 #ifdef KVM_CAP_SET_GUEST_DEBUG
+static void on_vcpu(CPUState *env, void (*func)(void *data), void *data)
+{
+    if (env == cpu_single_env) {
+        func(data);
+        return;
+    }
+    abort();
+}
+
 struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env,
                                                  target_ulong pc)
 {
     struct kvm_sw_breakpoint *bp;
 
-    TAILQ_FOREACH(bp, &env->kvm_state->kvm_sw_breakpoints, entry) {
+    QTAILQ_FOREACH(bp, &env->kvm_state->kvm_sw_breakpoints, entry) {
         if (bp->pc == pc)
             return bp;
     }
@@ -920,7 +926,7 @@ struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env,
 
 int kvm_sw_breakpoints_active(CPUState *env)
 {
-    return !TAILQ_EMPTY(&env->kvm_state->kvm_sw_breakpoints);
+    return !QTAILQ_EMPTY(&env->kvm_state->kvm_sw_breakpoints);
 }
 
 struct kvm_set_guest_debug_data {
@@ -977,7 +983,7 @@ int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
             return err;
         }
 
-        TAILQ_INSERT_HEAD(&current_env->kvm_state->kvm_sw_breakpoints,
+        QTAILQ_INSERT_HEAD(&current_env->kvm_state->kvm_sw_breakpoints,
                           bp, entry);
     } else {
         err = kvm_arch_insert_hw_breakpoint(addr, len, type);
@@ -1014,7 +1020,7 @@ int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,
         if (err)
             return err;
 
-        TAILQ_REMOVE(&current_env->kvm_state->kvm_sw_breakpoints, bp, entry);
+        QTAILQ_REMOVE(&current_env->kvm_state->kvm_sw_breakpoints, bp, entry);
         qemu_free(bp);
     } else {
         err = kvm_arch_remove_hw_breakpoint(addr, len, type);
@@ -1036,7 +1042,7 @@ void kvm_remove_all_breakpoints(CPUState *current_env)
     KVMState *s = current_env->kvm_state;
     CPUState *env;
 
-    TAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
+    QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
         if (kvm_arch_remove_sw_breakpoint(current_env, bp) != 0) {
             /* Try harder to find a CPU that currently sees the breakpoint. */
             for (env = first_cpu; env != NULL; env = env->next_cpu) {