KVMSlot slots[32];
int fd;
int vmfd;
+ int regs_modified;
int coalesced_mmio;
int broken_set_mem_region;
int migration_log;
#ifdef KVM_CAP_SET_GUEST_DEBUG
struct kvm_sw_breakpoint_head kvm_sw_breakpoints;
#endif
+ int irqchip_in_kernel;
+ int pit_in_kernel;
};
static KVMState *kvm_state;
}
}
-static void on_vcpu(CPUState *env, void (*func)(void *data), void *data)
+int kvm_irqchip_in_kernel(void)
{
- if (env == cpu_single_env) {
- func(data);
- return;
- }
- abort();
+ return kvm_state->irqchip_in_kernel;
+}
+
+int kvm_pit_in_kernel(void)
+{
+ return kvm_state->pit_in_kernel;
}
+
int kvm_init_vcpu(CPUState *env)
{
KVMState *s = kvm_state;
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().
KVMDirtyLog d;
KVMSlot *mem;
int ret = 0;
- int r;
d.dirty_bitmap = NULL;
while (start_addr < end_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);
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;
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) {
- unsigned long *bitmap = (unsigned long *)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);
}
}
#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;
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);
}
#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)
{