14b1addaeSSasha Levin #include <sys/epoll.h> 24b1addaeSSasha Levin #include <sys/un.h> 34b1addaeSSasha Levin #include <sys/types.h> 44b1addaeSSasha Levin #include <sys/socket.h> 5c733c80bSSasha Levin #include <sys/eventfd.h> 6e1063726SSasha Levin #include <dirent.h> 7e1063726SSasha Levin 8e1063726SSasha Levin #include "kvm/kvm-ipc.h" 9e1063726SSasha Levin #include "kvm/rwsem.h" 10e1063726SSasha Levin #include "kvm/read-write.h" 11e1063726SSasha Levin #include "kvm/util.h" 12e1063726SSasha Levin #include "kvm/kvm.h" 13e1063726SSasha Levin #include "kvm/builtin-debug.h" 14e1063726SSasha Levin #include "kvm/strbuf.h" 15e1063726SSasha Levin #include "kvm/kvm-cpu.h" 16e1063726SSasha Levin #include "kvm/8250-serial.h" 174b1addaeSSasha Levin 18a9aae6c5SLai Jiangshan struct kvm_ipc_head { 19a9aae6c5SLai Jiangshan u32 type; 20a9aae6c5SLai Jiangshan u32 len; 21a9aae6c5SLai Jiangshan }; 22a9aae6c5SLai Jiangshan 234b1addaeSSasha Levin #define KVM_IPC_MAX_MSGS 16 244b1addaeSSasha Levin 25e1063726SSasha Levin #define KVM_SOCK_SUFFIX ".sock" 26e1063726SSasha Levin #define KVM_SOCK_SUFFIX_LEN ((ssize_t)sizeof(KVM_SOCK_SUFFIX) - 1) 27e1063726SSasha Levin 28e1063726SSasha Levin extern __thread struct kvm_cpu *current_kvm_cpu; 29e1063726SSasha Levin static void (*msgs[KVM_IPC_MAX_MSGS])(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg); 304b1addaeSSasha Levin static DECLARE_RWSEM(msgs_rwlock); 31c733c80bSSasha Levin static int epoll_fd, server_fd, stop_fd; 32c733c80bSSasha Levin static pthread_t thread; 334b1addaeSSasha Levin 34e1063726SSasha Levin static int kvm__create_socket(struct kvm *kvm) 35e1063726SSasha Levin { 36e1063726SSasha Levin char full_name[PATH_MAX]; 37e1063726SSasha Levin unsigned int s; 38e1063726SSasha Levin struct sockaddr_un local; 39e1063726SSasha Levin int len, r; 40e1063726SSasha Levin 41e1063726SSasha Levin /* This usually 108 bytes long */ 42e1063726SSasha Levin BUILD_BUG_ON(sizeof(local.sun_path) < 32); 43e1063726SSasha Levin 44e1063726SSasha Levin snprintf(full_name, sizeof(full_name), "%s/%s%s", 45e1063726SSasha Levin kvm__get_dir(), kvm->cfg.guest_name, KVM_SOCK_SUFFIX); 46e1063726SSasha Levin if (access(full_name, F_OK) == 0) { 47e1063726SSasha Levin pr_err("Socket file %s already exist", full_name); 48e1063726SSasha Levin return -EEXIST; 49e1063726SSasha Levin } 50e1063726SSasha Levin 51e1063726SSasha Levin s = socket(AF_UNIX, SOCK_STREAM, 0); 52*211370d6SMichael Ellerman if (s < 0) { 53*211370d6SMichael Ellerman perror("socket"); 54e1063726SSasha Levin return s; 55*211370d6SMichael Ellerman } 56*211370d6SMichael Ellerman 57e1063726SSasha Levin local.sun_family = AF_UNIX; 58e1063726SSasha Levin strlcpy(local.sun_path, full_name, sizeof(local.sun_path)); 59e1063726SSasha Levin len = strlen(local.sun_path) + sizeof(local.sun_family); 60e1063726SSasha Levin r = bind(s, (struct sockaddr *)&local, len); 61*211370d6SMichael Ellerman if (r < 0) { 62*211370d6SMichael Ellerman perror("bind"); 63e1063726SSasha Levin goto fail; 64*211370d6SMichael Ellerman } 65e1063726SSasha Levin 66e1063726SSasha Levin r = listen(s, 5); 67*211370d6SMichael Ellerman if (r < 0) { 68*211370d6SMichael Ellerman perror("listen"); 69e1063726SSasha Levin goto fail; 70*211370d6SMichael Ellerman } 71e1063726SSasha Levin 72e1063726SSasha Levin return s; 73e1063726SSasha Levin 74e1063726SSasha Levin fail: 75e1063726SSasha Levin close(s); 76e1063726SSasha Levin return r; 77e1063726SSasha Levin } 78e1063726SSasha Levin 79e1063726SSasha Levin void kvm__remove_socket(const char *name) 80e1063726SSasha Levin { 81e1063726SSasha Levin char full_name[PATH_MAX]; 82e1063726SSasha Levin 83e1063726SSasha Levin snprintf(full_name, sizeof(full_name), "%s/%s%s", 84e1063726SSasha Levin kvm__get_dir(), name, KVM_SOCK_SUFFIX); 85e1063726SSasha Levin unlink(full_name); 86e1063726SSasha Levin } 87e1063726SSasha Levin 88e1063726SSasha Levin int kvm__get_sock_by_instance(const char *name) 89e1063726SSasha Levin { 90e1063726SSasha Levin int s, len, r; 91e1063726SSasha Levin char sock_file[PATH_MAX]; 92e1063726SSasha Levin struct sockaddr_un local; 93e1063726SSasha Levin 94e1063726SSasha Levin snprintf(sock_file, sizeof(sock_file), "%s/%s%s", 95e1063726SSasha Levin kvm__get_dir(), name, KVM_SOCK_SUFFIX); 96e1063726SSasha Levin s = socket(AF_UNIX, SOCK_STREAM, 0); 97e1063726SSasha Levin 98e1063726SSasha Levin local.sun_family = AF_UNIX; 99e1063726SSasha Levin strlcpy(local.sun_path, sock_file, sizeof(local.sun_path)); 100e1063726SSasha Levin len = strlen(local.sun_path) + sizeof(local.sun_family); 101e1063726SSasha Levin 102e1063726SSasha Levin r = connect(s, &local, len); 103e1063726SSasha Levin if (r < 0 && errno == ECONNREFUSED) { 104e1063726SSasha Levin /* Tell the user clean ghost socket file */ 105e1063726SSasha Levin pr_err("\"%s\" could be a ghost socket file, please remove it", 106e1063726SSasha Levin sock_file); 107e1063726SSasha Levin return r; 108e1063726SSasha Levin } else if (r < 0) { 109e1063726SSasha Levin return r; 110e1063726SSasha Levin } 111e1063726SSasha Levin 112e1063726SSasha Levin return s; 113e1063726SSasha Levin } 114e1063726SSasha Levin 115e1063726SSasha Levin int kvm__enumerate_instances(int (*callback)(const char *name, int fd)) 116e1063726SSasha Levin { 117e1063726SSasha Levin int sock; 118e1063726SSasha Levin DIR *dir; 119e1063726SSasha Levin struct dirent entry, *result; 120e1063726SSasha Levin int ret = 0; 121e1063726SSasha Levin 122e1063726SSasha Levin dir = opendir(kvm__get_dir()); 123e1063726SSasha Levin if (!dir) 124e1063726SSasha Levin return -errno; 125e1063726SSasha Levin 126e1063726SSasha Levin for (;;) { 127e1063726SSasha Levin readdir_r(dir, &entry, &result); 128e1063726SSasha Levin if (result == NULL) 129e1063726SSasha Levin break; 130e1063726SSasha Levin if (entry.d_type == DT_SOCK) { 131e1063726SSasha Levin ssize_t name_len = strlen(entry.d_name); 132e1063726SSasha Levin char *p; 133e1063726SSasha Levin 134e1063726SSasha Levin if (name_len <= KVM_SOCK_SUFFIX_LEN) 135e1063726SSasha Levin continue; 136e1063726SSasha Levin 137e1063726SSasha Levin p = &entry.d_name[name_len - KVM_SOCK_SUFFIX_LEN]; 138e1063726SSasha Levin if (memcmp(KVM_SOCK_SUFFIX, p, KVM_SOCK_SUFFIX_LEN)) 139e1063726SSasha Levin continue; 140e1063726SSasha Levin 141e1063726SSasha Levin *p = 0; 142e1063726SSasha Levin sock = kvm__get_sock_by_instance(entry.d_name); 143e1063726SSasha Levin if (sock < 0) 144e1063726SSasha Levin continue; 145e1063726SSasha Levin ret = callback(entry.d_name, sock); 146e1063726SSasha Levin close(sock); 147e1063726SSasha Levin if (ret < 0) 148e1063726SSasha Levin break; 149e1063726SSasha Levin } 150e1063726SSasha Levin } 151e1063726SSasha Levin 152e1063726SSasha Levin closedir(dir); 153e1063726SSasha Levin 154e1063726SSasha Levin return ret; 155e1063726SSasha Levin } 156e1063726SSasha Levin 157e1063726SSasha Levin int kvm_ipc__register_handler(u32 type, void (*cb)(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg)) 1584b1addaeSSasha Levin { 1594b1addaeSSasha Levin if (type >= KVM_IPC_MAX_MSGS) 1604b1addaeSSasha Levin return -ENOSPC; 1614b1addaeSSasha Levin 1624b1addaeSSasha Levin down_write(&msgs_rwlock); 1634b1addaeSSasha Levin msgs[type] = cb; 1644b1addaeSSasha Levin up_write(&msgs_rwlock); 1654b1addaeSSasha Levin 1664b1addaeSSasha Levin return 0; 1674b1addaeSSasha Levin } 1684b1addaeSSasha Levin 16950dc18aeSLai Jiangshan int kvm_ipc__send(int fd, u32 type) 17050dc18aeSLai Jiangshan { 17150dc18aeSLai Jiangshan struct kvm_ipc_head head = {.type = type, .len = 0,}; 17250dc18aeSLai Jiangshan 173ca088268SAsias He if (write_in_full(fd, &head, sizeof(head)) < 0) 17450dc18aeSLai Jiangshan return -1; 17550dc18aeSLai Jiangshan 17650dc18aeSLai Jiangshan return 0; 17750dc18aeSLai Jiangshan } 17850dc18aeSLai Jiangshan 17950dc18aeSLai Jiangshan int kvm_ipc__send_msg(int fd, u32 type, u32 len, u8 *msg) 18050dc18aeSLai Jiangshan { 18150dc18aeSLai Jiangshan struct kvm_ipc_head head = {.type = type, .len = len,}; 18250dc18aeSLai Jiangshan 183ca088268SAsias He if (write_in_full(fd, &head, sizeof(head)) < 0) 18450dc18aeSLai Jiangshan return -1; 18550dc18aeSLai Jiangshan 186fd5b45a1SAsias He if (write_in_full(fd, msg, len) < 0) 18750dc18aeSLai Jiangshan return -1; 18850dc18aeSLai Jiangshan 18950dc18aeSLai Jiangshan return 0; 19050dc18aeSLai Jiangshan } 19150dc18aeSLai Jiangshan 192e1063726SSasha Levin static int kvm_ipc__handle(struct kvm *kvm, int fd, u32 type, u32 len, u8 *data) 1934b1addaeSSasha Levin { 194e1063726SSasha Levin void (*cb)(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg); 1954b1addaeSSasha Levin 19644a56bfdSLai Jiangshan if (type >= KVM_IPC_MAX_MSGS) 1974b1addaeSSasha Levin return -ENOSPC; 1984b1addaeSSasha Levin 1994b1addaeSSasha Levin down_read(&msgs_rwlock); 20044a56bfdSLai Jiangshan cb = msgs[type]; 2014b1addaeSSasha Levin up_read(&msgs_rwlock); 2024b1addaeSSasha Levin 2034b1addaeSSasha Levin if (cb == NULL) { 20444a56bfdSLai Jiangshan pr_warning("No device handles type %u\n", type); 2054b1addaeSSasha Levin return -ENODEV; 2064b1addaeSSasha Levin } 2074b1addaeSSasha Levin 208e1063726SSasha Levin cb(kvm, fd, type, len, data); 2094b1addaeSSasha Levin 2104b1addaeSSasha Levin return 0; 2114b1addaeSSasha Levin } 2124b1addaeSSasha Levin 2134b1addaeSSasha Levin static int kvm_ipc__new_conn(int fd) 2144b1addaeSSasha Levin { 2154b1addaeSSasha Levin int client; 2164b1addaeSSasha Levin struct epoll_event ev; 2174b1addaeSSasha Levin 2184b1addaeSSasha Levin client = accept(fd, NULL, NULL); 2194b1addaeSSasha Levin if (client < 0) 2204b1addaeSSasha Levin return -1; 2214b1addaeSSasha Levin 2224b1addaeSSasha Levin ev.events = EPOLLIN | EPOLLRDHUP; 2234b1addaeSSasha Levin ev.data.fd = client; 2244b1addaeSSasha Levin if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client, &ev) < 0) { 2254b1addaeSSasha Levin close(client); 2264b1addaeSSasha Levin return -1; 2274b1addaeSSasha Levin } 2284b1addaeSSasha Levin 2294b1addaeSSasha Levin return client; 2304b1addaeSSasha Levin } 2314b1addaeSSasha Levin 2324b1addaeSSasha Levin static void kvm_ipc__close_conn(int fd) 2334b1addaeSSasha Levin { 2344b1addaeSSasha Levin epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); 2354b1addaeSSasha Levin close(fd); 2364b1addaeSSasha Levin } 2374b1addaeSSasha Levin 238e1063726SSasha Levin static int kvm_ipc__receive(struct kvm *kvm, int fd) 2394b1addaeSSasha Levin { 240a9aae6c5SLai Jiangshan struct kvm_ipc_head head; 241a9aae6c5SLai Jiangshan u8 *msg = NULL; 2424b1addaeSSasha Levin u32 n; 2434b1addaeSSasha Levin 244a9aae6c5SLai Jiangshan n = read(fd, &head, sizeof(head)); 245a9aae6c5SLai Jiangshan if (n != sizeof(head)) 246a9aae6c5SLai Jiangshan goto done; 247a9aae6c5SLai Jiangshan 248a9aae6c5SLai Jiangshan msg = malloc(head.len); 2494b1addaeSSasha Levin if (msg == NULL) 2504b1addaeSSasha Levin goto done; 2514b1addaeSSasha Levin 252a9aae6c5SLai Jiangshan n = read_in_full(fd, msg, head.len); 253a9aae6c5SLai Jiangshan if (n != head.len) 2544b1addaeSSasha Levin goto done; 2554b1addaeSSasha Levin 256e1063726SSasha Levin kvm_ipc__handle(kvm, fd, head.type, head.len, msg); 2574b1addaeSSasha Levin 2588e463c62SAsias He return 0; 2598e463c62SAsias He 2604b1addaeSSasha Levin done: 2614b1addaeSSasha Levin free(msg); 2628e463c62SAsias He return -1; 2634b1addaeSSasha Levin } 2644b1addaeSSasha Levin 2654b1addaeSSasha Levin static void *kvm_ipc__thread(void *param) 2664b1addaeSSasha Levin { 2674b1addaeSSasha Levin struct epoll_event event; 268e1063726SSasha Levin struct kvm *kvm = param; 2694b1addaeSSasha Levin 270a4d8c55eSSasha Levin kvm__set_thread_name("kvm-ipc"); 271a4d8c55eSSasha Levin 2724b1addaeSSasha Levin for (;;) { 2734b1addaeSSasha Levin int nfds; 2744b1addaeSSasha Levin 2754b1addaeSSasha Levin nfds = epoll_wait(epoll_fd, &event, 1, -1); 2764b1addaeSSasha Levin if (nfds > 0) { 2774b1addaeSSasha Levin int fd = event.data.fd; 2784b1addaeSSasha Levin 27947f72b90SSasha Levin if (fd == stop_fd && event.events & EPOLLIN) { 280c733c80bSSasha Levin break; 281c733c80bSSasha Levin } else if (fd == server_fd) { 2828e463c62SAsias He int client, r; 2834b1addaeSSasha Levin 2844b1addaeSSasha Levin client = kvm_ipc__new_conn(fd); 2858e463c62SAsias He /* 2868e463c62SAsias He * Handle multiple IPC cmd at a time 2878e463c62SAsias He */ 2888e463c62SAsias He do { 289e1063726SSasha Levin r = kvm_ipc__receive(kvm, client); 2908e463c62SAsias He } while (r == 0); 2918e463c62SAsias He 292066c5809SSasha Levin } else if (event.events & (EPOLLERR | EPOLLRDHUP | EPOLLHUP)) { 2934b1addaeSSasha Levin kvm_ipc__close_conn(fd); 2944b1addaeSSasha Levin } else { 295e1063726SSasha Levin kvm_ipc__receive(kvm, fd); 2964b1addaeSSasha Levin } 2974b1addaeSSasha Levin } 2984b1addaeSSasha Levin } 2994b1addaeSSasha Levin 3004b1addaeSSasha Levin return NULL; 3014b1addaeSSasha Levin } 3024b1addaeSSasha Levin 303e1063726SSasha Levin static void kvm__pid(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg) 304e1063726SSasha Levin { 305e1063726SSasha Levin pid_t pid = getpid(); 306e1063726SSasha Levin int r = 0; 307e1063726SSasha Levin 308e1063726SSasha Levin if (type == KVM_IPC_PID) 309e1063726SSasha Levin r = write(fd, &pid, sizeof(pid)); 310e1063726SSasha Levin 311e1063726SSasha Levin if (r < 0) 312e1063726SSasha Levin pr_warning("Failed sending PID"); 313e1063726SSasha Levin } 314e1063726SSasha Levin 315e1063726SSasha Levin static void handle_stop(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg) 316e1063726SSasha Levin { 317e1063726SSasha Levin if (WARN_ON(type != KVM_IPC_STOP || len)) 318e1063726SSasha Levin return; 319e1063726SSasha Levin 320e1063726SSasha Levin kvm_cpu__reboot(kvm); 321e1063726SSasha Levin } 322e1063726SSasha Levin 323e1063726SSasha Levin /* Pause/resume the guest using SIGUSR2 */ 324e1063726SSasha Levin static int is_paused; 325e1063726SSasha Levin 326e1063726SSasha Levin static void handle_pause(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg) 327e1063726SSasha Levin { 328e1063726SSasha Levin if (WARN_ON(len)) 329e1063726SSasha Levin return; 330e1063726SSasha Levin 331e1063726SSasha Levin if (type == KVM_IPC_RESUME && is_paused) { 332e1063726SSasha Levin kvm->vm_state = KVM_VMSTATE_RUNNING; 3334346fd8fSSasha Levin kvm__continue(kvm); 334e1063726SSasha Levin } else if (type == KVM_IPC_PAUSE && !is_paused) { 335e1063726SSasha Levin kvm->vm_state = KVM_VMSTATE_PAUSED; 336e1063726SSasha Levin ioctl(kvm->vm_fd, KVM_KVMCLOCK_CTRL); 3374346fd8fSSasha Levin kvm__pause(kvm); 338e1063726SSasha Levin } else { 339e1063726SSasha Levin return; 340e1063726SSasha Levin } 341e1063726SSasha Levin 342e1063726SSasha Levin is_paused = !is_paused; 343e1063726SSasha Levin } 344e1063726SSasha Levin 345e1063726SSasha Levin static void handle_vmstate(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg) 346e1063726SSasha Levin { 347e1063726SSasha Levin int r = 0; 348e1063726SSasha Levin 349e1063726SSasha Levin if (type == KVM_IPC_VMSTATE) 350e1063726SSasha Levin r = write(fd, &kvm->vm_state, sizeof(kvm->vm_state)); 351e1063726SSasha Levin 352e1063726SSasha Levin if (r < 0) 353e1063726SSasha Levin pr_warning("Failed sending VMSTATE"); 354e1063726SSasha Levin } 355e1063726SSasha Levin 356e1063726SSasha Levin /* 357e1063726SSasha Levin * Serialize debug printout so that the output of multiple vcpus does not 358e1063726SSasha Levin * get mixed up: 359e1063726SSasha Levin */ 360e1063726SSasha Levin static int printout_done; 361e1063726SSasha Levin 362e1063726SSasha Levin static void handle_sigusr1(int sig) 363e1063726SSasha Levin { 364e1063726SSasha Levin struct kvm_cpu *cpu = current_kvm_cpu; 365e1063726SSasha Levin int fd = kvm_cpu__get_debug_fd(); 366e1063726SSasha Levin 367e1063726SSasha Levin if (!cpu || cpu->needs_nmi) 368e1063726SSasha Levin return; 369e1063726SSasha Levin 370e1063726SSasha Levin dprintf(fd, "\n #\n # vCPU #%ld's dump:\n #\n", cpu->cpu_id); 371e1063726SSasha Levin kvm_cpu__show_registers(cpu); 372e1063726SSasha Levin kvm_cpu__show_code(cpu); 373e1063726SSasha Levin kvm_cpu__show_page_tables(cpu); 374e1063726SSasha Levin fflush(stdout); 375e1063726SSasha Levin printout_done = 1; 376e1063726SSasha Levin } 377e1063726SSasha Levin 378e1063726SSasha Levin static void handle_debug(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg) 379e1063726SSasha Levin { 380e1063726SSasha Levin int i; 381e1063726SSasha Levin struct debug_cmd_params *params; 382e1063726SSasha Levin u32 dbg_type; 383e1063726SSasha Levin u32 vcpu; 384e1063726SSasha Levin 385e1063726SSasha Levin if (WARN_ON(type != KVM_IPC_DEBUG || len != sizeof(*params))) 386e1063726SSasha Levin return; 387e1063726SSasha Levin 388e1063726SSasha Levin params = (void *)msg; 389e1063726SSasha Levin dbg_type = params->dbg_type; 390e1063726SSasha Levin vcpu = params->cpu; 391e1063726SSasha Levin 392e1063726SSasha Levin if (dbg_type & KVM_DEBUG_CMD_TYPE_SYSRQ) 393e1063726SSasha Levin serial8250__inject_sysrq(kvm, params->sysrq); 394e1063726SSasha Levin 395e1063726SSasha Levin if (dbg_type & KVM_DEBUG_CMD_TYPE_NMI) { 396e1063726SSasha Levin if ((int)vcpu >= kvm->nrcpus) 397e1063726SSasha Levin return; 398e1063726SSasha Levin 399e1063726SSasha Levin kvm->cpus[vcpu]->needs_nmi = 1; 400e1063726SSasha Levin pthread_kill(kvm->cpus[vcpu]->thread, SIGUSR1); 401e1063726SSasha Levin } 402e1063726SSasha Levin 403e1063726SSasha Levin if (!(dbg_type & KVM_DEBUG_CMD_TYPE_DUMP)) 404e1063726SSasha Levin return; 405e1063726SSasha Levin 406e1063726SSasha Levin for (i = 0; i < kvm->nrcpus; i++) { 407e1063726SSasha Levin struct kvm_cpu *cpu = kvm->cpus[i]; 408e1063726SSasha Levin 409e1063726SSasha Levin if (!cpu) 410e1063726SSasha Levin continue; 411e1063726SSasha Levin 412e1063726SSasha Levin printout_done = 0; 413e1063726SSasha Levin 414e1063726SSasha Levin kvm_cpu__set_debug_fd(fd); 415e1063726SSasha Levin pthread_kill(cpu->thread, SIGUSR1); 416e1063726SSasha Levin /* 417e1063726SSasha Levin * Wait for the vCPU to dump state before signalling 418e1063726SSasha Levin * the next thread. Since this is debug code it does 419e1063726SSasha Levin * not matter that we are burning CPU time a bit: 420e1063726SSasha Levin */ 421e1063726SSasha Levin while (!printout_done) 422e1063726SSasha Levin sleep(0); 423e1063726SSasha Levin } 424e1063726SSasha Levin 425e1063726SSasha Levin close(fd); 426e1063726SSasha Levin 427e1063726SSasha Levin serial8250__inject_sysrq(kvm, 'p'); 428e1063726SSasha Levin } 429e1063726SSasha Levin 430e1063726SSasha Levin int kvm_ipc__init(struct kvm *kvm) 4314b1addaeSSasha Levin { 432e21e8ff3SYang Bai int ret; 433e1063726SSasha Levin int sock = kvm__create_socket(kvm); 43421b3c2c0SSasha Levin struct epoll_event ev = {0}; 4354b1addaeSSasha Levin 4364b1addaeSSasha Levin server_fd = sock; 4374b1addaeSSasha Levin 4384b1addaeSSasha Levin epoll_fd = epoll_create(KVM_IPC_MAX_MSGS); 439e21e8ff3SYang Bai if (epoll_fd < 0) { 440*211370d6SMichael Ellerman perror("epoll_create"); 441e21e8ff3SYang Bai ret = epoll_fd; 442e21e8ff3SYang Bai goto err; 443e21e8ff3SYang Bai } 4444b1addaeSSasha Levin 44547f72b90SSasha Levin ev.events = EPOLLIN | EPOLLET; 4464b1addaeSSasha Levin ev.data.fd = sock; 447e21e8ff3SYang Bai if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sock, &ev) < 0) { 448*211370d6SMichael Ellerman pr_err("Failed adding socket to epoll"); 449e21e8ff3SYang Bai ret = -EFAULT; 450e21e8ff3SYang Bai goto err_epoll; 451e21e8ff3SYang Bai } 4524b1addaeSSasha Levin 453c733c80bSSasha Levin stop_fd = eventfd(0, 0); 454e21e8ff3SYang Bai if (stop_fd < 0) { 455*211370d6SMichael Ellerman perror("eventfd"); 456e21e8ff3SYang Bai ret = stop_fd; 457e21e8ff3SYang Bai goto err_epoll; 458e21e8ff3SYang Bai } 459e21e8ff3SYang Bai 46047f72b90SSasha Levin ev.events = EPOLLIN | EPOLLET; 461c733c80bSSasha Levin ev.data.fd = stop_fd; 462e21e8ff3SYang Bai if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, stop_fd, &ev) < 0) { 463e21e8ff3SYang Bai pr_err("Failed adding stop event to epoll"); 464e21e8ff3SYang Bai ret = -EFAULT; 465e21e8ff3SYang Bai goto err_stop; 466e21e8ff3SYang Bai } 467c733c80bSSasha Levin 468e1063726SSasha Levin if (pthread_create(&thread, NULL, kvm_ipc__thread, kvm) != 0) { 469e21e8ff3SYang Bai pr_err("Failed starting IPC thread"); 470e21e8ff3SYang Bai ret = -EFAULT; 471e21e8ff3SYang Bai goto err_stop; 472e21e8ff3SYang Bai } 4734b1addaeSSasha Levin 474e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_PID, kvm__pid); 475e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_DEBUG, handle_debug); 476e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_PAUSE, handle_pause); 477e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_RESUME, handle_pause); 478e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_STOP, handle_stop); 479e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_VMSTATE, handle_vmstate); 480e1063726SSasha Levin signal(SIGUSR1, handle_sigusr1); 481e1063726SSasha Levin 4824b1addaeSSasha Levin return 0; 483e21e8ff3SYang Bai 484e21e8ff3SYang Bai err_stop: 485e21e8ff3SYang Bai close(stop_fd); 486e21e8ff3SYang Bai err_epoll: 487e21e8ff3SYang Bai close(epoll_fd); 488e21e8ff3SYang Bai err: 489e21e8ff3SYang Bai return ret; 4904b1addaeSSasha Levin } 49149a8afd1SSasha Levin base_init(kvm_ipc__init); 492c733c80bSSasha Levin 493e1063726SSasha Levin int kvm_ipc__exit(struct kvm *kvm) 494c733c80bSSasha Levin { 495c733c80bSSasha Levin u64 val = 1; 496c733c80bSSasha Levin int ret; 497c733c80bSSasha Levin 498c733c80bSSasha Levin ret = write(stop_fd, &val, sizeof(val)); 499c733c80bSSasha Levin if (ret < 0) 500c733c80bSSasha Levin return ret; 501c733c80bSSasha Levin 502c733c80bSSasha Levin close(server_fd); 503c733c80bSSasha Levin close(epoll_fd); 504c733c80bSSasha Levin 505e1063726SSasha Levin kvm__remove_socket(kvm->cfg.guest_name); 506e1063726SSasha Levin 507c733c80bSSasha Levin return ret; 508c733c80bSSasha Levin } 50949a8afd1SSasha Levin base_exit(kvm_ipc__exit); 510