struct kvm_cpu *kvm_cpu__init(struct kvm *kvm, unsigned long cpu_id) { struct kvm_cpu *vcpu; int mmap_size; int coalesced_offset; vcpu = kvm_cpu__new(kvm); if (!vcpu) return NULL; vcpu->cpu_id = cpu_id; vcpu->vcpu_fd = ioctl(vcpu->kvm->vm_fd, KVM_CREATE_VCPU, cpu_id); if (vcpu->vcpu_fd < 0) die_perror("KVM_CREATE_VCPU ioctl"); mmap_size = ioctl(vcpu->kvm->sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0); if (mmap_size < 0) die_perror("KVM_GET_VCPU_MMAP_SIZE ioctl"); vcpu->kvm_run = mmap(NULL, mmap_size, PROT_RW, MAP_SHARED, vcpu->vcpu_fd, 0); if (vcpu->kvm_run == MAP_FAILED) die("unable to mmap vcpu fd"); coalesced_offset = ioctl(kvm->sys_fd, KVM_CHECK_EXTENSION, KVM_CAP_COALESCED_MMIO); if (coalesced_offset) vcpu->ring = (void *)vcpu->kvm_run + (coalesced_offset * PAGE_SIZE); vcpu->is_running = true; return vcpu; }
struct kvm_cpu *kvm_cpu__init(struct kvm *kvm, unsigned long cpu_id) { struct kvm_cpu *vcpu; int mmap_size; struct kvm_enable_cap papr_cap = { .cap = KVM_CAP_PPC_PAPR }; vcpu = kvm_cpu__new(kvm); if (!vcpu) return NULL; vcpu->cpu_id = cpu_id; vcpu->vcpu_fd = ioctl(vcpu->kvm->vm_fd, KVM_CREATE_VCPU, cpu_id); if (vcpu->vcpu_fd < 0) die_perror("KVM_CREATE_VCPU ioctl"); mmap_size = ioctl(vcpu->kvm->sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0); if (mmap_size < 0) die_perror("KVM_GET_VCPU_MMAP_SIZE ioctl"); vcpu->kvm_run = mmap(NULL, mmap_size, PROT_RW, MAP_SHARED, vcpu->vcpu_fd, 0); if (vcpu->kvm_run == MAP_FAILED) die("unable to mmap vcpu fd"); if (ioctl(vcpu->vcpu_fd, KVM_ENABLE_CAP, &papr_cap) < 0) die("unable to enable PAPR capability"); /* * We start all CPUs, directing non-primary threads into the kernel's * secondary start point. When we come to support SLOF, we will start * only one and SLOF will RTAS call us to ask for others to be * started. (FIXME: make more generic & interface with whichever * firmware a platform may be using.) */ vcpu->is_running = true; /* Register with IRQ controller (FIXME, assumes XICS) */ xics_cpu_register(vcpu); return vcpu; }