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;
int r;
r = kvm_dirty_pages_log_change(section->offset_within_address_space,
- section->size, true);
+ int128_get64(section->size), true);
if (r < 0) {
abort();
}
int r;
r = kvm_dirty_pages_log_change(section->offset_within_address_space,
- section->size, false);
+ int128_get64(section->size), false);
if (r < 0) {
abort();
}
unsigned int i, j;
unsigned long page_number, c;
hwaddr addr, addr1;
- unsigned int len = ((section->size / getpagesize()) + HOST_LONG_BITS - 1) / HOST_LONG_BITS;
+ unsigned int pages = int128_get64(section->size) / getpagesize();
+ unsigned int len = (pages + HOST_LONG_BITS - 1) / HOST_LONG_BITS;
unsigned long hpratio = getpagesize() / TARGET_PAGE_SIZE;
/*
KVMSlot *mem;
int ret = 0;
hwaddr start_addr = section->offset_within_address_space;
- hwaddr end_addr = start_addr + section->size;
+ hwaddr end_addr = start_addr + int128_get64(section->size);
d.dirty_bitmap = NULL;
while (start_addr < end_addr) {
bool writeable = !mr->readonly && !mr->rom_device;
bool readonly_flag = mr->readonly || memory_region_is_romd(mr);
hwaddr start_addr = section->offset_within_address_space;
- ram_addr_t size = section->size;
+ ram_addr_t size = int128_get64(section->size);
void *ram = NULL;
unsigned delta;
static void kvm_region_add(MemoryListener *listener,
MemoryRegionSection *section)
{
+ memory_region_ref(section->mr);
kvm_set_phys_mem(section, true);
}
MemoryRegionSection *section)
{
kvm_set_phys_mem(section, false);
+ memory_region_unref(section->mr);
}
static void kvm_log_sync(MemoryListener *listener,
int r;
r = kvm_set_ioeventfd_mmio(fd, section->offset_within_address_space,
- data, true, section->size, match_data);
+ data, true, int128_get64(section->size),
+ match_data);
if (r < 0) {
+ fprintf(stderr, "%s: error adding ioeventfd: %s\n",
+ __func__, strerror(-r));
abort();
}
}
int r;
r = kvm_set_ioeventfd_mmio(fd, section->offset_within_address_space,
- data, false, section->size, match_data);
+ data, false, int128_get64(section->size),
+ match_data);
if (r < 0) {
abort();
}
int r;
r = kvm_set_ioeventfd_pio(fd, section->offset_within_address_space,
- data, true, section->size, match_data);
+ data, true, int128_get64(section->size),
+ match_data);
if (r < 0) {
+ fprintf(stderr, "%s: error adding ioeventfd: %s\n",
+ __func__, strerror(-r));
abort();
}
}
int r;
r = kvm_set_ioeventfd_pio(fd, section->offset_within_address_space,
- data, false, section->size, match_data);
+ data, false, int128_get64(section->size),
+ match_data);
if (r < 0) {
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);
}
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;
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(¤t_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) {
}
}
- 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;
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;
}
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(¤t_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);
}
}
- 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;
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;
}
}
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);
}
}
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 */
-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;