int hax_vcpu_create(int id) { struct hax_vcpu_state *vcpu = NULL; int ret; if (!hax_global.vm) { fprintf(stderr, "vcpu %x created failed, vm is null\n", id); return -1; } if (hax_global.vm->vcpus[id]) { fprintf(stderr, "vcpu %x allocated already\n", id); return 0; } vcpu = g_new0(struct hax_vcpu_state, 1); ret = hax_host_create_vcpu(hax_global.vm->fd, id); if (ret) { fprintf(stderr, "Failed to create vcpu %x\n", id); goto error; } vcpu->vcpu_id = id; vcpu->fd = hax_host_open_vcpu(hax_global.vm->id, id); if (hax_invalid_fd(vcpu->fd)) { fprintf(stderr, "Failed to open the vcpu\n"); ret = -ENODEV; goto error; } hax_global.vm->vcpus[id] = vcpu; ret = hax_host_setup_vcpu_channel(vcpu); if (ret) { fprintf(stderr, "Invalid hax tunnel size\n"); ret = -EINVAL; goto error; } return 0; error: /* vcpu and tunnel will be closed automatically */ if (vcpu && !hax_invalid_fd(vcpu->fd)) { hax_close_fd(vcpu->fd); } hax_global.vm->vcpus[id] = NULL; g_free(vcpu); return -1; }
hax_vcpu_state *VCpu_Create(hax_state *Hax) { if (!Hax->vm) { printf("vCPU created failed, vm is null\n"); return nullptr; } // Find the next free vCPU index int cpuId = -1; for (int i = 0; i < ARRAYSIZE(Hax->vm->vcpus); i++) { if (Hax->vm->vcpus[i]) continue; cpuId = i; break; } if (cpuId == -1) { printf("Maximum number of vCPUs have been allocated for this VM!\n"); return nullptr; } // Allocate the virtual CPU instance structure and // zero memory auto vCPU = (hax_vcpu_state *)malloc(sizeof(hax_vcpu_state)); if (!vCPU) { printf("Failed to alloc vCPU state\n"); return nullptr; } memset(vCPU, 0, sizeof(hax_vcpu_state)); // Tell the driver to create the vCPU instance vCPU->vcpu_id = cpuId; if (hax_host_create_vcpu(Hax->vm->fd, cpuId) < 0) { printf("Failed to create vCPU %x\n", cpuId); goto error; } // Grab a handle to the driver's instance vCPU->fd = hax_host_open_vcpu(Hax->vm->id, cpuId); if (hax_invalid_fd(vCPU->fd)) { printf("Failed to open the vCPU handle\n"); goto error; } // Mark the CPU index as used with a pointer Hax->vm->vcpus[cpuId] = vCPU; // Create the tunnel to kernel data if (hax_host_setup_vcpu_channel(vCPU) < 0) { printf("Invalid HAX tunnel size \n"); goto error; } return vCPU; error: // vCPU and tunnel will be closed automatically if (vCPU && !hax_invalid_fd(vCPU->fd)) hax_close_fd(vCPU->fd); Hax->vm->vcpus[cpuId] = nullptr; free(vCPU); return nullptr; }