int kvm_init_vcpu(CPUArchState *env) { KVMState *s = kvm_state; long mmap_size; int ret; DPRINTF("kvm_init_vcpu\n"); #ifdef CONFIG_SOLARIS ret = kvm_vm_clone(kvm_state); if (ret < 0) { fprintf(stderr, "kvm_init_vcpu could not clone fd: %m\n"); goto err; } env->kvm_fd = ret; ret = ioctl(env->kvm_fd, KVM_CREATE_VCPU, env->cpu_index); #else ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, env->cpu_index); #endif if (ret < 0) { DPRINTF("kvm_create_vcpu failed\n"); goto err; } #ifndef CONFIG_SOLARIS env->kvm_fd = ret; #endif env->kvm_state = s; env->kvm_vcpu_dirty = 1; mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0); if (mmap_size < 0) { ret = mmap_size; DPRINTF("KVM_GET_VCPU_MMAP_SIZE failed\n"); goto err; } env->kvm_run = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, env->kvm_fd, 0); if (env->kvm_run == MAP_FAILED) { ret = -errno; DPRINTF("mmap'ing vcpu state failed\n"); goto err; } if (s->coalesced_mmio && !s->coalesced_mmio_ring) { s->coalesced_mmio_ring = (void *)env->kvm_run + s->coalesced_mmio * PAGE_SIZE; } ret = kvm_arch_init_vcpu(env); if (ret == 0) { qemu_register_reset(kvm_reset_vcpu, env); kvm_arch_reset_vcpu(env); } err: return ret; }
static void kvm_create_vcpu(CPUState *env, int id) { long mmap_size; int r; KVMState *s = kvm_state; r = kvm_vm_ioctl(kvm_state, KVM_CREATE_VCPU, id); if (r < 0) { fprintf(stderr, "kvm_create_vcpu: %m\n"); fprintf(stderr, "Failed to create vCPU. Check the -smp parameter.\n"); goto err; } env->kvm_fd = r; env->kvm_state = kvm_state; mmap_size = kvm_ioctl(kvm_state, KVM_GET_VCPU_MMAP_SIZE, 0); if (mmap_size < 0) { fprintf(stderr, "get vcpu mmap size: %m\n"); goto err_fd; } env->kvm_run = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED, env->kvm_fd, 0); if (env->kvm_run == MAP_FAILED) { fprintf(stderr, "mmap vcpu area: %m\n"); goto err_fd; } #ifdef KVM_CAP_COALESCED_MMIO if (s->coalesced_mmio && !s->coalesced_mmio_ring) s->coalesced_mmio_ring = (void *) env->kvm_run + s->coalesced_mmio * PAGE_SIZE; #endif r = kvm_arch_init_vcpu(env); if (r == 0) { qemu_register_reset(kvm_reset_vcpu, env); } return; err_fd: close(env->kvm_fd); err: /* We're no good with semi-broken states. */ abort(); }