]> git.proxmox.com Git - mirror_qemu.git/blobdiff - kvm-all.c
cpu: Move singlestep_enabled field from CPU_COMMON to CPUState
[mirror_qemu.git] / kvm-all.c
index d3e5e5ebff8fad386314f23ebffad65627269d91..a2103893205462b3f3a7f2f910b6a8769cf25fe2 100644 (file)
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -107,6 +107,7 @@ struct KVMState
 KVMState *kvm_state;
 bool kvm_kernel_irqchip;
 bool kvm_async_interrupts_allowed;
+bool kvm_halt_in_kernel_allowed;
 bool kvm_irqfds_allowed;
 bool kvm_msi_via_irqfd_allowed;
 bool kvm_gsi_routing_allowed;
@@ -788,6 +789,7 @@ static void kvm_set_phys_mem(MemoryRegionSection *section, bool add)
 static void kvm_region_add(MemoryListener *listener,
                            MemoryRegionSection *section)
 {
+    memory_region_ref(section->mr);
     kvm_set_phys_mem(section, true);
 }
 
@@ -795,6 +797,7 @@ static void kvm_region_del(MemoryListener *listener,
                            MemoryRegionSection *section)
 {
     kvm_set_phys_mem(section, false);
+    memory_region_unref(section->mr);
 }
 
 static void kvm_log_sync(MemoryListener *listener,
@@ -836,6 +839,8 @@ static void kvm_mem_ioeventfd_add(MemoryListener *listener,
                                data, true, int128_get64(section->size),
                                match_data);
     if (r < 0) {
+        fprintf(stderr, "%s: error adding ioeventfd: %s\n",
+                __func__, strerror(-r));
         abort();
     }
 }
@@ -868,6 +873,8 @@ static void kvm_io_ioeventfd_add(MemoryListener *listener,
                               data, true, int128_get64(section->size),
                               match_data);
     if (r < 0) {
+        fprintf(stderr, "%s: error adding ioeventfd: %s\n",
+                __func__, strerror(-r));
         abort();
     }
 }
@@ -953,7 +960,7 @@ static void clear_gsi(KVMState *s, unsigned int gsi)
     s->used_gsi_bitmap[gsi / 32] &= ~(1U << (gsi % 32));
 }
 
-static void kvm_init_irq_routing(KVMState *s)
+void kvm_init_irq_routing(KVMState *s)
 {
     int gsi_count, i;
 
@@ -984,7 +991,7 @@ static void kvm_init_irq_routing(KVMState *s)
     kvm_arch_init_irq_routing(s);
 }
 
-static void kvm_irqchip_commit_routes(KVMState *s)
+void kvm_irqchip_commit_routes(KVMState *s)
 {
     int ret;
 
@@ -1011,15 +1018,10 @@ static void kvm_add_routing_entry(KVMState *s,
     }
     n = s->irq_routes->nr++;
     new = &s->irq_routes->entries[n];
-    memset(new, 0, sizeof(*new));
-    new->gsi = entry->gsi;
-    new->type = entry->type;
-    new->flags = entry->flags;
-    new->u = entry->u;
 
-    set_gsi(s, entry->gsi);
+    *new = *entry;
 
-    kvm_irqchip_commit_routes(s);
+    set_gsi(s, entry->gsi);
 }
 
 static int kvm_update_routing_entry(KVMState *s,
@@ -1034,9 +1036,11 @@ static int kvm_update_routing_entry(KVMState *s,
             continue;
         }
 
-        entry->type = new_entry->type;
-        entry->flags = new_entry->flags;
-        entry->u = new_entry->u;
+        if(!memcmp(entry, new_entry, sizeof *entry)) {
+            return 0;
+        }
+
+        *entry = *new_entry;
 
         kvm_irqchip_commit_routes(s);
 
@@ -1048,7 +1052,7 @@ static int kvm_update_routing_entry(KVMState *s,
 
 void kvm_irqchip_add_irq_route(KVMState *s, int irq, int irqchip, int pin)
 {
-    struct kvm_irq_routing_entry e;
+    struct kvm_irq_routing_entry e = {};
 
     assert(pin < s->gsi_count);
 
@@ -1130,7 +1134,7 @@ static KVMMSIRoute *kvm_lookup_msi_route(KVMState *s, MSIMessage msg)
     QTAILQ_FOREACH(route, &s->msi_hashtab[hash], entry) {
         if (route->kroute.u.msi.address_lo == (uint32_t)msg.address &&
             route->kroute.u.msi.address_hi == (msg.address >> 32) &&
-            route->kroute.u.msi.data == msg.data) {
+            route->kroute.u.msi.data == le32_to_cpu(msg.data)) {
             return route;
         }
     }
@@ -1145,7 +1149,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
     if (s->direct_msi) {
         msi.address_lo = (uint32_t)msg.address;
         msi.address_hi = msg.address >> 32;
-        msi.data = msg.data;
+        msi.data = le32_to_cpu(msg.data);
         msi.flags = 0;
         memset(msi.pad, 0, sizeof(msi.pad));
 
@@ -1161,15 +1165,16 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
             return virq;
         }
 
-        route = g_malloc(sizeof(KVMMSIRoute));
+        route = g_malloc0(sizeof(KVMMSIRoute));
         route->kroute.gsi = virq;
         route->kroute.type = KVM_IRQ_ROUTING_MSI;
         route->kroute.flags = 0;
         route->kroute.u.msi.address_lo = (uint32_t)msg.address;
         route->kroute.u.msi.address_hi = msg.address >> 32;
-        route->kroute.u.msi.data = msg.data;
+        route->kroute.u.msi.data = le32_to_cpu(msg.data);
 
         kvm_add_routing_entry(s, &route->kroute);
+        kvm_irqchip_commit_routes(s);
 
         QTAILQ_INSERT_TAIL(&s->msi_hashtab[kvm_hash_msi(msg.data)], route,
                            entry);
@@ -1182,7 +1187,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
 
 int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
 {
-    struct kvm_irq_routing_entry kroute;
+    struct kvm_irq_routing_entry kroute = {};
     int virq;
 
     if (!kvm_gsi_routing_enabled()) {
@@ -1199,16 +1204,17 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
     kroute.flags = 0;
     kroute.u.msi.address_lo = (uint32_t)msg.address;
     kroute.u.msi.address_hi = msg.address >> 32;
-    kroute.u.msi.data = msg.data;
+    kroute.u.msi.data = le32_to_cpu(msg.data);
 
     kvm_add_routing_entry(s, &kroute);
+    kvm_irqchip_commit_routes(s);
 
     return virq;
 }
 
 int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg)
 {
-    struct kvm_irq_routing_entry kroute;
+    struct kvm_irq_routing_entry kroute = {};
 
     if (!kvm_irqchip_in_kernel()) {
         return -ENOSYS;
@@ -1219,7 +1225,7 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg)
     kroute.flags = 0;
     kroute.u.msi.address_lo = (uint32_t)msg.address;
     kroute.u.msi.address_hi = msg.address >> 32;
-    kroute.u.msi.data = msg.data;
+    kroute.u.msi.data = le32_to_cpu(msg.data);
 
     return kvm_update_routing_entry(s, &kroute);
 }
@@ -1241,7 +1247,7 @@ static int kvm_irqchip_assign_irqfd(KVMState *s, int fd, int virq, bool assign)
 
 #else /* !KVM_CAP_IRQ_ROUTING */
 
-static void kvm_init_irq_routing(KVMState *s)
+void kvm_init_irq_routing(KVMState *s)
 {
 }
 
@@ -1282,12 +1288,9 @@ int kvm_irqchip_remove_irqfd_notifier(KVMState *s, EventNotifier *n, int virq)
 
 static int kvm_irqchip_create(KVMState *s)
 {
-    QemuOptsList *list = qemu_find_opts("machine");
     int ret;
 
-    if (QTAILQ_EMPTY(&list->head) ||
-        !qemu_opt_get_bool(QTAILQ_FIRST(&list->head),
-                           "kernel_irqchip", true) ||
+    if (!qemu_opt_get_bool(qemu_get_machine_opts(), "kernel_irqchip", true) ||
         !kvm_check_extension(s, KVM_CAP_IRQCHIP)) {
         return 0;
     }
@@ -1303,6 +1306,7 @@ static int kvm_irqchip_create(KVMState *s)
      * interrupt delivery (though the reverse is not necessarily true)
      */
     kvm_async_interrupts_allowed = true;
+    kvm_halt_in_kernel_allowed = true;
 
     kvm_init_irq_routing(s);
 
@@ -1607,9 +1611,8 @@ void kvm_cpu_synchronize_post_init(CPUState *cpu)
     cpu->kvm_vcpu_dirty = false;
 }
 
-int kvm_cpu_exec(CPUArchState *env)
+int kvm_cpu_exec(CPUState *cpu)
 {
-    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_run *run = cpu->kvm_run;
     int ret, run_ret;
 
@@ -1887,7 +1890,7 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
 
     data.dbg.control = reinject_trap;
 
-    if (env->singlestep_enabled) {
+    if (cpu->singlestep_enabled) {
         data.dbg.control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP;
     }
     kvm_arch_update_guest_debug(cpu, &data.dbg);
@@ -1897,16 +1900,15 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
     return data.err;
 }
 
-int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type)
 {
-    CPUState *current_cpu = ENV_GET_CPU(current_env);
+    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_sw_breakpoint *bp;
-    CPUArchState *env;
     int err;
 
     if (type == GDB_BREAKPOINT_SW) {
-        bp = kvm_find_sw_breakpoint(current_cpu, addr);
+        bp = kvm_find_sw_breakpoint(cpu, addr);
         if (bp) {
             bp->use_count++;
             return 0;
@@ -1919,14 +1921,13 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
 
         bp->pc = addr;
         bp->use_count = 1;
-        err = kvm_arch_insert_sw_breakpoint(current_cpu, bp);
+        err = kvm_arch_insert_sw_breakpoint(cpu, bp);
         if (err) {
             g_free(bp);
             return err;
         }
 
-        QTAILQ_INSERT_HEAD(&current_cpu->kvm_state->kvm_sw_breakpoints,
-                          bp, entry);
+        QTAILQ_INSERT_HEAD(&cpu->kvm_state->kvm_sw_breakpoints, bp, entry);
     } else {
         err = kvm_arch_insert_hw_breakpoint(addr, len, type);
         if (err) {
@@ -1934,7 +1935,9 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
         }
     }
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPUArchState *env = cpu->env_ptr;
+
         err = kvm_update_guest_debug(env, 0);
         if (err) {
             return err;
@@ -1943,16 +1946,15 @@ int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
     return 0;
 }
 
-int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type)
 {
-    CPUState *current_cpu = ENV_GET_CPU(current_env);
+    CPUState *cpu = ENV_GET_CPU(env);
     struct kvm_sw_breakpoint *bp;
-    CPUArchState *env;
     int err;
 
     if (type == GDB_BREAKPOINT_SW) {
-        bp = kvm_find_sw_breakpoint(current_cpu, addr);
+        bp = kvm_find_sw_breakpoint(cpu, addr);
         if (!bp) {
             return -ENOENT;
         }
@@ -1962,12 +1964,12 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
             return 0;
         }
 
-        err = kvm_arch_remove_sw_breakpoint(current_cpu, bp);
+        err = kvm_arch_remove_sw_breakpoint(cpu, bp);
         if (err) {
             return err;
         }
 
-        QTAILQ_REMOVE(&current_cpu->kvm_state->kvm_sw_breakpoints, bp, entry);
+        QTAILQ_REMOVE(&cpu->kvm_state->kvm_sw_breakpoints, bp, entry);
         g_free(bp);
     } else {
         err = kvm_arch_remove_hw_breakpoint(addr, len, type);
@@ -1976,7 +1978,9 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
         }
     }
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPUArchState *env = cpu->env_ptr;
+
         err = kvm_update_guest_debug(env, 0);
         if (err) {
             return err;
@@ -1985,19 +1989,15 @@ int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
     return 0;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *current_env)
+void kvm_remove_all_breakpoints(CPUState *cpu)
 {
-    CPUState *current_cpu = ENV_GET_CPU(current_env);
     struct kvm_sw_breakpoint *bp, *next;
-    KVMState *s = current_cpu->kvm_state;
-    CPUArchState *env;
-    CPUState *cpu;
+    KVMState *s = cpu->kvm_state;
 
     QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
-        if (kvm_arch_remove_sw_breakpoint(current_cpu, bp) != 0) {
+        if (kvm_arch_remove_sw_breakpoint(cpu, bp) != 0) {
             /* Try harder to find a CPU that currently sees the breakpoint. */
-            for (env = first_cpu; env != NULL; env = env->next_cpu) {
-                cpu = ENV_GET_CPU(env);
+            for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
                 if (kvm_arch_remove_sw_breakpoint(cpu, bp) == 0) {
                     break;
                 }
@@ -2008,7 +2008,9 @@ void kvm_remove_all_breakpoints(CPUArchState *current_env)
     }
     kvm_arch_remove_all_hw_breakpoints();
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPUArchState *env = cpu->env_ptr;
+
         kvm_update_guest_debug(env, 0);
     }
 }
@@ -2020,19 +2022,19 @@ int kvm_update_guest_debug(CPUArchState *env, unsigned long reinject_trap)
     return -EINVAL;
 }
 
-int kvm_insert_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_insert_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
 }
 
-int kvm_remove_breakpoint(CPUArchState *current_env, target_ulong addr,
+int kvm_remove_breakpoint(CPUArchState *env, target_ulong addr,
                           target_ulong len, int type)
 {
     return -EINVAL;
 }
 
-void kvm_remove_all_breakpoints(CPUArchState *current_env)
+void kvm_remove_all_breakpoints(CPUState *cpu)
 {
 }
 #endif /* !KVM_CAP_SET_GUEST_DEBUG */