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;
data, true, int128_get64(section->size),
match_data);
if (r < 0) {
+ fprintf(stderr, "%s: error adding ioeventfd: %s\n",
+ __func__, strerror(-r));
abort();
}
}
data, true, int128_get64(section->size),
match_data);
if (r < 0) {
+ fprintf(stderr, "%s: error adding ioeventfd: %s\n",
+ __func__, strerror(-r));
abort();
}
}
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;
kvm_arch_init_irq_routing(s);
}
-static void kvm_irqchip_commit_routes(KVMState *s)
+void kvm_irqchip_commit_routes(KVMState *s)
{
int ret;
}
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,
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);
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);
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;
}
}
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));
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);
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()) {
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;
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);
}
#else /* !KVM_CAP_IRQ_ROUTING */
-static void kvm_init_irq_routing(KVMState *s)
+void kvm_init_irq_routing(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);
}
}
-static int kvm_handle_internal_error(CPUArchState *env, struct kvm_run *run)
+static int kvm_handle_internal_error(CPUState *cpu, struct kvm_run *run)
{
- CPUState *cpu = ENV_GET_CPU(env);
-
fprintf(stderr, "KVM internal error.");
if (kvm_check_extension(kvm_state, KVM_CAP_INTERNAL_ERROR_DATA)) {
int i;
if (run->internal.suberror == KVM_INTERNAL_ERROR_EMULATION) {
fprintf(stderr, "emulation failure\n");
if (!kvm_arch_stop_on_emulation_error(cpu)) {
- cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
+ cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_CODE);
return EXCP_INTERRUPT;
}
}
}
}
-void kvm_cpu_synchronize_state(CPUArchState *env)
+void kvm_cpu_synchronize_state(CPUState *cpu)
{
- CPUState *cpu = ENV_GET_CPU(env);
-
if (!cpu->kvm_vcpu_dirty) {
run_on_cpu(cpu, do_kvm_cpu_synchronize_state, 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;
ret = -1;
break;
case KVM_EXIT_INTERNAL_ERROR:
- ret = kvm_handle_internal_error(env, run);
+ ret = kvm_handle_internal_error(cpu, run);
break;
default:
DPRINTF("kvm_arch_handle_exit\n");
} while (ret == 0);
if (ret < 0) {
- cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE);
+ cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_CODE);
vm_stop(RUN_STATE_INTERNAL_ERROR);
}
}
#endif /* !KVM_CAP_SET_GUEST_DEBUG */
-int kvm_set_signal_mask(CPUArchState *env, const sigset_t *sigset)
+int kvm_set_signal_mask(CPUState *cpu, const sigset_t *sigset)
{
- CPUState *cpu = ENV_GET_CPU(env);
struct kvm_signal_mask *sigmask;
int r;