int sys_phys_cpu_add(id_t phys_cpu_id, id_t apic_id) { return phys_cpu_add(phys_cpu_id, apic_id); }
int main(int argc, char ** argv, char * envp[]) { struct pisces_cmd cmd; int pisces_fd = 0; memset(&cmd, 0, sizeof(struct pisces_cmd)); printf("Pisces Control Daemon\n"); CPU_ZERO(&enclave_cpus); /* Initialize CPU mask */ CPU_SET(0, &enclave_cpus); /* We always boot on CPU 0 */ pisces_fd = open(PISCES_CMD_PATH, O_RDWR); if (pisces_fd < 0) { printf("Error opening pisces cmd file (%s)\n", PISCES_CMD_PATH); return -1; } while (1) { int ret = 0; ret = read(pisces_fd, &cmd, sizeof(struct pisces_cmd)); if (ret != sizeof(struct pisces_cmd)) { printf("Error reading pisces CMD (ret=%d)\n", ret); break; } //printf("Command=%llu, data_len=%d\n", cmd.cmd, cmd.data_len); switch (cmd.cmd) { case ENCLAVE_CMD_ADD_MEM: { struct cmd_mem_add mem_cmd; struct pmem_region rgn; memset(&mem_cmd, 0, sizeof(struct cmd_mem_add)); memset(&rgn, 0, sizeof(struct pmem_region)); ret = read(pisces_fd, &mem_cmd, sizeof(struct cmd_mem_add)); if (ret != sizeof(struct cmd_mem_add)) { printf("Error reading pisces MEM_ADD CMD (ret=%d)\n", ret); send_resp(pisces_fd, -1); break; } rgn.start = mem_cmd.phys_addr; rgn.end = mem_cmd.phys_addr + mem_cmd.size; rgn.type_is_set = 1; rgn.type = PMEM_TYPE_UMEM; rgn.allocated_is_set = 1; rgn.allocated = 0; printf("Adding pmem (%p - %p)\n", (void *)rgn.start, (void *)rgn.end); ret = pmem_add(&rgn); printf("pmem_add returned %d\n", ret); ret = pmem_zero(&rgn); printf("pmem_zero returned %d\n", ret); send_resp(pisces_fd, 0); break; } case ENCLAVE_CMD_ADD_CPU: { struct cmd_cpu_add cpu_cmd; int logical_cpu = 0; ret = read(pisces_fd, &cpu_cmd, sizeof(struct cmd_cpu_add)); if (ret != sizeof(struct cmd_cpu_add)) { printf("Error reading pisces CPU_ADD CMD (ret=%d)\n", ret); send_resp(pisces_fd, -1); break; } printf("Adding CPU phys_id %llu, apic_id %llu\n", (unsigned long long) cpu_cmd.phys_cpu_id, (unsigned long long) cpu_cmd.apic_id); logical_cpu = phys_cpu_add(cpu_cmd.phys_cpu_id, cpu_cmd.apic_id); if (logical_cpu == -1) { printf("Error Adding CPU to Kitten\n"); send_resp(pisces_fd, -1); break; } /* Notify Palacios of New CPU */ if (issue_v3_cmd(V3_ADD_CPU, (uintptr_t)logical_cpu) == -1) { printf("Error: Could not add CPU to Palacios\n"); } CPU_SET(logical_cpu, &enclave_cpus); send_resp(pisces_fd, 0); break; } case ENCLAVE_CMD_REMOVE_CPU: { struct cmd_cpu_add cpu_cmd; int logical_cpu = 0; ret = read(pisces_fd, &cpu_cmd, sizeof(struct cmd_cpu_add)); if (ret != sizeof(struct cmd_cpu_add)) { printf("Error reading pisces CPU_ADD CMD (ret=%d)\n", ret); send_resp(pisces_fd, -1); break; } printf("Removing CPU phys_id %llu, apic_id %llu\n", (unsigned long long) cpu_cmd.phys_cpu_id, (unsigned long long) cpu_cmd.apic_id); logical_cpu = phys_cpu_remove(cpu_cmd.phys_cpu_id, cpu_cmd.apic_id); if (logical_cpu == -1) { printf("Error remove CPU to Kitten\n"); send_resp(pisces_fd, -1); break; } CPU_CLR(logical_cpu, &enclave_cpus); send_resp(pisces_fd, 0); break; } case ENCLAVE_CMD_LAUNCH_JOB: { struct cmd_launch_job * job_cmd = malloc(sizeof(struct cmd_launch_job)); int ret = 0; memset(job_cmd, 0, sizeof(struct cmd_launch_job)); ret = read(pisces_fd, job_cmd, sizeof(struct cmd_launch_job)); if (ret != sizeof(struct cmd_launch_job)) { printf("Error reading Job Launch CMD (ret = %d)\n", ret); free(job_cmd); send_resp(pisces_fd, -1); break; } ret = launch_job(pisces_fd, &(job_cmd->spec)); free(job_cmd); send_resp(pisces_fd, ret); break; } case ENCLAVE_CMD_LOAD_FILE: { struct cmd_load_file * load_cmd = malloc(sizeof(struct cmd_load_file)); int ret = 0; memset(load_cmd, 0, sizeof(struct cmd_load_file)); ret = read(pisces_fd, load_cmd, sizeof(struct cmd_load_file)); if (ret != sizeof(struct cmd_load_file)) { printf("Error reading LOAD FILE CMD (ret = %d)\n", ret); free(load_cmd); send_resp(pisces_fd, -1); break; } ret = load_file(pisces_fd, load_cmd->file_pair.lnx_file, load_cmd->file_pair.lwk_file); free(load_cmd); send_resp(pisces_fd, ret); break; } case ENCLAVE_CMD_STORE_FILE: { break; } case ENCLAVE_CMD_CREATE_VM: { struct pisces_user_file_info * file_info = NULL; struct cmd_create_vm vm_cmd; struct pmem_region rgn; struct v3_guest_img guest_img; id_t my_aspace_id; vaddr_t file_addr; size_t file_size = 0; int path_len = 0; int vm_id = -1; int status = 0; memset(&vm_cmd, 0, sizeof(struct cmd_create_vm)); memset(&rgn, 0, sizeof(struct pmem_region)); memset(&guest_img, 0, sizeof(struct v3_guest_img)); ret = read(pisces_fd, &vm_cmd, sizeof(struct cmd_create_vm)); if (ret != sizeof(struct cmd_create_vm)) { send_resp(pisces_fd, -1); printf("Error: CREATE_VM command could not be read\n"); break; } path_len = strlen((char *)vm_cmd.path.file_name) + 1; file_info = malloc(sizeof(struct pisces_user_file_info) + path_len); memset(file_info, 0, sizeof(struct pisces_user_file_info) + path_len); file_info->path_len = path_len; strncpy(file_info->path, (char *)vm_cmd.path.file_name, path_len - 1); file_size = ioctl(pisces_fd, PISCES_STAT_FILE, file_info); status = aspace_get_myid(&my_aspace_id); if (status != 0) return status; if (pmem_alloc_umem(file_size, PAGE_SIZE, &rgn)) { printf("Error: Could not allocate umem for guest image (size=%lu)\n", file_size); break; } pmem_zero(&rgn); status = aspace_map_region_anywhere( my_aspace_id, &file_addr, round_up(file_size, PAGE_SIZE), (VM_USER|VM_READ|VM_WRITE), PAGE_SIZE, "VM Image", rgn.start ); file_info->user_addr = file_addr; ioctl(pisces_fd, PISCES_LOAD_FILE, file_info); guest_img.size = file_size; guest_img.guest_data = (void *)file_info->user_addr; strncpy(guest_img.name, (char *)vm_cmd.path.vm_name, 127); /* Issue VM Create command to Palacios */ vm_id = issue_v3_cmd(V3_CREATE_GUEST, (uintptr_t)&guest_img); aspace_unmap_region(my_aspace_id, file_addr, round_up(file_size, PAGE_SIZE)); pmem_free_umem(&rgn); if (vm_id < 0) { printf("Error: Could not create VM (%s) at (%s) (err=%d)\n", vm_cmd.path.vm_name, vm_cmd.path.file_name, vm_id); send_resp(pisces_fd, vm_id); break; } printf("Created VM (%d)\n", vm_id); send_resp(pisces_fd, vm_id); break; } case ENCLAVE_CMD_FREE_VM: { struct cmd_vm_ctrl vm_cmd; ret = read(pisces_fd, &vm_cmd, sizeof(struct cmd_vm_ctrl)); if (ret != sizeof(struct cmd_vm_ctrl)) { send_resp(pisces_fd, -1); break; } /* Signal Palacios to Launch VM */ if (issue_v3_cmd(V3_FREE_GUEST, (uintptr_t)vm_cmd.vm_id) == -1) { send_resp(pisces_fd, -1); break; } send_resp(pisces_fd, 0); break; } case ENCLAVE_CMD_ADD_V3_PCI: { struct cmd_add_pci_dev cmd; struct v3_hw_pci_dev v3_pci_spec; int ret = 0; memset(&cmd, 0, sizeof(struct cmd_add_pci_dev)); printf("Adding V3 PCI Device\n"); ret = read(pisces_fd, &cmd, sizeof(struct cmd_add_pci_dev)); if (ret != sizeof(struct cmd_add_pci_dev)) { send_resp(pisces_fd, -1); break; } memcpy(v3_pci_spec.name, cmd.spec.name, 128); v3_pci_spec.bus = cmd.spec.bus; v3_pci_spec.dev = cmd.spec.dev; v3_pci_spec.func = cmd.spec.func; /* Issue Device Add operation to Palacios */ if (issue_v3_cmd(V3_ADD_PCI, (uintptr_t)&(v3_pci_spec)) == -1) { printf("Error: Could not add PCI device to Palacios\n"); send_resp(pisces_fd, -1); break; } send_resp(pisces_fd, 0); break; } case ENCLAVE_CMD_FREE_V3_PCI: { struct cmd_add_pci_dev cmd; struct v3_hw_pci_dev v3_pci_spec; int ret = 0; memset(&cmd, 0, sizeof(struct cmd_add_pci_dev)); printf("Removing V3 PCI Device\n"); ret = read(pisces_fd, &cmd, sizeof(struct cmd_add_pci_dev)); if (ret != sizeof(struct cmd_add_pci_dev)) { send_resp(pisces_fd, -1); break; } memcpy(v3_pci_spec.name, cmd.spec.name, 128); v3_pci_spec.bus = cmd.spec.bus; v3_pci_spec.dev = cmd.spec.dev; v3_pci_spec.func = cmd.spec.func; /* Issue Device Add operation to Palacios */ if (issue_v3_cmd(V3_REMOVE_PCI, (uintptr_t)&(v3_pci_spec)) == -1) { printf("Error: Could not remove PCI device from Palacios\n"); send_resp(pisces_fd, -1); break; } send_resp(pisces_fd, 0); break; } case ENCLAVE_CMD_LAUNCH_VM: { struct cmd_vm_ctrl vm_cmd; ret = read(pisces_fd, &vm_cmd, sizeof(struct cmd_vm_ctrl)); if (ret != sizeof(struct cmd_vm_ctrl)) { send_resp(pisces_fd, -1); break; } /* Signal Palacios to Launch VM */ if (issue_vm_cmd(vm_cmd.vm_id, V3_VM_LAUNCH, (uintptr_t)NULL) == -1) { send_resp(pisces_fd, -1); break; } /* if (xpmem_pisces_add_dom(palacios_fd, vm_cmd.vm_id)) { printf("ERROR: Could not add connect to Palacios VM %d XPMEM channel\n", vm_cmd.vm_id); } */ send_resp(pisces_fd, 0); break; } case ENCLAVE_CMD_STOP_VM: { struct cmd_vm_ctrl vm_cmd; ret = read(pisces_fd, &vm_cmd, sizeof(struct cmd_vm_ctrl)); if (ret != sizeof(struct cmd_vm_ctrl)) { send_resp(pisces_fd, -1); break; } /* Signal Palacios to Launch VM */ if (issue_vm_cmd(vm_cmd.vm_id, V3_VM_STOP, (uintptr_t)NULL) == -1) { send_resp(pisces_fd, -1); break; } send_resp(pisces_fd, 0); break; } case ENCLAVE_CMD_PAUSE_VM: { struct cmd_vm_ctrl vm_cmd; ret = read(pisces_fd, &vm_cmd, sizeof(struct cmd_vm_ctrl)); if (ret != sizeof(struct cmd_vm_ctrl)) { send_resp(pisces_fd, -1); break; } /* Signal Palacios to Launch VM */ if (issue_vm_cmd(vm_cmd.vm_id, V3_VM_PAUSE, (uintptr_t)NULL) == -1) { send_resp(pisces_fd, -1); break; } send_resp(pisces_fd, 0); break; } case ENCLAVE_CMD_CONTINUE_VM: { struct cmd_vm_ctrl vm_cmd; ret = read(pisces_fd, &vm_cmd, sizeof(struct cmd_vm_ctrl)); if (ret != sizeof(struct cmd_vm_ctrl)) { send_resp(pisces_fd, -1); break; } /* Signal Palacios to Launch VM */ if (issue_vm_cmd(vm_cmd.vm_id, V3_VM_CONTINUE, (uintptr_t)NULL) == -1) { send_resp(pisces_fd, -1); break; } send_resp(pisces_fd, 0); break; } case ENCLAVE_CMD_VM_CONS_CONNECT: { struct cmd_vm_ctrl vm_cmd; u64 cons_ring_buf = 0; ret = read(pisces_fd, &vm_cmd, sizeof(struct cmd_vm_ctrl)); if (ret != sizeof(struct cmd_vm_ctrl)) { printf("Error reading console command\n"); send_resp(pisces_fd, -1); break; } /* Signal Palacios to connect the console */ if (issue_vm_cmd(vm_cmd.vm_id, V3_VM_CONSOLE_CONNECT, (uintptr_t)&cons_ring_buf) == -1) { cons_ring_buf = 0; } printf("Cons Ring Buf=%p\n", (void *)cons_ring_buf); send_resp(pisces_fd, cons_ring_buf); break; } case ENCLAVE_CMD_VM_CONS_DISCONNECT: { struct cmd_vm_ctrl vm_cmd; ret = read(pisces_fd, &vm_cmd, sizeof(struct cmd_vm_ctrl)); if (ret != sizeof(struct cmd_vm_ctrl)) { send_resp(pisces_fd, -1); break; } /* Send Disconnect Request to Palacios */ if (issue_vm_cmd(vm_cmd.vm_id, V3_VM_CONSOLE_DISCONNECT, (uintptr_t)NULL) == -1) { send_resp(pisces_fd, -1); break; } send_resp(pisces_fd, 0); break; } case ENCLAVE_CMD_VM_CONS_KEYCODE: { struct cmd_vm_cons_keycode vm_cmd; ret = read(pisces_fd, &vm_cmd, sizeof(struct cmd_vm_cons_keycode)); if (ret != sizeof(struct cmd_vm_cons_keycode)) { send_resp(pisces_fd, -1); break; } /* Send Keycode to Palacios */ if (issue_vm_cmd(vm_cmd.vm_id, V3_VM_KEYBOARD_EVENT, vm_cmd.scan_code) == -1) { send_resp(pisces_fd, -1); break; } send_resp(pisces_fd, 0); break; } case ENCLAVE_CMD_VM_DBG: { struct cmd_vm_debug pisces_cmd; struct v3_debug_cmd v3_cmd; ret = read(pisces_fd, &pisces_cmd, sizeof(struct cmd_vm_debug)); if (ret != sizeof(struct cmd_vm_debug)) { send_resp(pisces_fd, -1); break; } v3_cmd.core = pisces_cmd.spec.core; v3_cmd.cmd = pisces_cmd.spec.cmd; if (issue_vm_cmd(pisces_cmd.spec.vm_id, V3_VM_DEBUG, (uintptr_t)&v3_cmd) == -1) { send_resp(pisces_fd, -1); break; } send_resp(pisces_fd, 0); break; } case ENCLAVE_CMD_SHUTDOWN: { if (issue_v3_cmd(V3_SHUTDOWN, 0) == -1) { printf("Error: Could not shutdown Palacios VMM\n"); send_resp(pisces_fd, -1); break; } /* Perform additional Cleanup is necessary */ send_resp(pisces_fd, 0); close(pisces_fd); exit(0); } default: { printf("Unknown Pisces Command (%llu)\n", cmd.cmd); send_resp(pisces_fd, -1); break; } } } close(pisces_fd); return 0; }
static int __add_cpu(hcq_handle_t hcq, uint64_t cmd) { char * err_str = "ERROR: Adding Kitten CPUs through Hobbes not (yet) supported. Use the Pisces ctrl channel"; ERROR("%s\n", err_str); hcq_cmd_return(hcq, cmd, -1, smart_strlen(err_str) + 1, err_str); return 0; #if 0 uint32_t data_size = 0; char * xml_str = NULL; pet_xml_t xml = NULL; char * err_str = NULL; uint32_t cpu_id = -1; uint32_t apic_id = -1; int logical_id = 0; int ret = -1; xml_str = hcq_get_cmd_data(hcq, cmd, &data_size); if (xml_str == NULL) { err_str = "Could not read memory spec"; goto out; } xml = pet_xml_parse_str(xml_str); if (xml == PET_INVALID_XML) { err_str = "Invalid XML syntax"; goto out; } cpu_id = smart_atou32(-1, pet_xml_get_val(xml, "phys_cpu_id" )); apic_id = smart_atou32(-1, pet_xml_get_val(xml, "apic_id" )); //if ((base_addr == -1) || (num_pgs == -1)) { if (cpu_id == (uint32_t)-1) { err_str = "Invalid command syntax: invalid cpu_id"; goto out; } if (apic_id == (uint32_t)-1) { err_str = "Invalid command syntax: invalid apic_id"; goto out; } /* Add it */ logical_id = phys_cpu_add(cpu_id, apic_id); if (logical_id == -1) { err_str = "Error adding cpu to Kitten via phys_cpu_add"; goto out; } if (palacios_enabled) { /* Notify Palacios of new cpu */ ret = v3_add_cpu(logical_id); if (ret == -1) { err_str = "Error adding cpu to Palacios"; phys_cpu_remove(cpu_id, apic_id); goto out; } ret = 0; } out: if (err_str) ERROR("%s\n", err_str); hcq_cmd_return(hcq, cmd, ret, smart_strlen(err_str) + 1, err_str); return 0; #endif }