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> 6*e1063726SSasha Levin #include <dirent.h> 7*e1063726SSasha Levin 8*e1063726SSasha Levin #include "kvm/kvm-ipc.h" 9*e1063726SSasha Levin #include "kvm/rwsem.h" 10*e1063726SSasha Levin #include "kvm/read-write.h" 11*e1063726SSasha Levin #include "kvm/util.h" 12*e1063726SSasha Levin #include "kvm/kvm.h" 13*e1063726SSasha Levin #include "kvm/builtin-debug.h" 14*e1063726SSasha Levin #include "kvm/strbuf.h" 15*e1063726SSasha Levin #include "kvm/kvm-cpu.h" 16*e1063726SSasha 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 25*e1063726SSasha Levin #define KVM_SOCK_SUFFIX ".sock" 26*e1063726SSasha Levin #define KVM_SOCK_SUFFIX_LEN ((ssize_t)sizeof(KVM_SOCK_SUFFIX) - 1) 27*e1063726SSasha Levin 28*e1063726SSasha Levin extern __thread struct kvm_cpu *current_kvm_cpu; 29*e1063726SSasha 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 34*e1063726SSasha Levin static int kvm__create_socket(struct kvm *kvm) 35*e1063726SSasha Levin { 36*e1063726SSasha Levin char full_name[PATH_MAX]; 37*e1063726SSasha Levin unsigned int s; 38*e1063726SSasha Levin struct sockaddr_un local; 39*e1063726SSasha Levin int len, r; 40*e1063726SSasha Levin 41*e1063726SSasha Levin /* This usually 108 bytes long */ 42*e1063726SSasha Levin BUILD_BUG_ON(sizeof(local.sun_path) < 32); 43*e1063726SSasha Levin 44*e1063726SSasha Levin snprintf(full_name, sizeof(full_name), "%s/%s%s", 45*e1063726SSasha Levin kvm__get_dir(), kvm->cfg.guest_name, KVM_SOCK_SUFFIX); 46*e1063726SSasha Levin if (access(full_name, F_OK) == 0) { 47*e1063726SSasha Levin pr_err("Socket file %s already exist", full_name); 48*e1063726SSasha Levin return -EEXIST; 49*e1063726SSasha Levin } 50*e1063726SSasha Levin 51*e1063726SSasha Levin s = socket(AF_UNIX, SOCK_STREAM, 0); 52*e1063726SSasha Levin if (s < 0) 53*e1063726SSasha Levin return s; 54*e1063726SSasha Levin local.sun_family = AF_UNIX; 55*e1063726SSasha Levin strlcpy(local.sun_path, full_name, sizeof(local.sun_path)); 56*e1063726SSasha Levin len = strlen(local.sun_path) + sizeof(local.sun_family); 57*e1063726SSasha Levin r = bind(s, (struct sockaddr *)&local, len); 58*e1063726SSasha Levin if (r < 0) 59*e1063726SSasha Levin goto fail; 60*e1063726SSasha Levin 61*e1063726SSasha Levin r = listen(s, 5); 62*e1063726SSasha Levin if (r < 0) 63*e1063726SSasha Levin goto fail; 64*e1063726SSasha Levin 65*e1063726SSasha Levin return s; 66*e1063726SSasha Levin 67*e1063726SSasha Levin fail: 68*e1063726SSasha Levin close(s); 69*e1063726SSasha Levin return r; 70*e1063726SSasha Levin } 71*e1063726SSasha Levin 72*e1063726SSasha Levin void kvm__remove_socket(const char *name) 73*e1063726SSasha Levin { 74*e1063726SSasha Levin char full_name[PATH_MAX]; 75*e1063726SSasha Levin 76*e1063726SSasha Levin snprintf(full_name, sizeof(full_name), "%s/%s%s", 77*e1063726SSasha Levin kvm__get_dir(), name, KVM_SOCK_SUFFIX); 78*e1063726SSasha Levin unlink(full_name); 79*e1063726SSasha Levin } 80*e1063726SSasha Levin 81*e1063726SSasha Levin int kvm__get_sock_by_instance(const char *name) 82*e1063726SSasha Levin { 83*e1063726SSasha Levin int s, len, r; 84*e1063726SSasha Levin char sock_file[PATH_MAX]; 85*e1063726SSasha Levin struct sockaddr_un local; 86*e1063726SSasha Levin 87*e1063726SSasha Levin snprintf(sock_file, sizeof(sock_file), "%s/%s%s", 88*e1063726SSasha Levin kvm__get_dir(), name, KVM_SOCK_SUFFIX); 89*e1063726SSasha Levin s = socket(AF_UNIX, SOCK_STREAM, 0); 90*e1063726SSasha Levin 91*e1063726SSasha Levin local.sun_family = AF_UNIX; 92*e1063726SSasha Levin strlcpy(local.sun_path, sock_file, sizeof(local.sun_path)); 93*e1063726SSasha Levin len = strlen(local.sun_path) + sizeof(local.sun_family); 94*e1063726SSasha Levin 95*e1063726SSasha Levin r = connect(s, &local, len); 96*e1063726SSasha Levin if (r < 0 && errno == ECONNREFUSED) { 97*e1063726SSasha Levin /* Tell the user clean ghost socket file */ 98*e1063726SSasha Levin pr_err("\"%s\" could be a ghost socket file, please remove it", 99*e1063726SSasha Levin sock_file); 100*e1063726SSasha Levin return r; 101*e1063726SSasha Levin } else if (r < 0) { 102*e1063726SSasha Levin return r; 103*e1063726SSasha Levin } 104*e1063726SSasha Levin 105*e1063726SSasha Levin return s; 106*e1063726SSasha Levin } 107*e1063726SSasha Levin 108*e1063726SSasha Levin int kvm__enumerate_instances(int (*callback)(const char *name, int fd)) 109*e1063726SSasha Levin { 110*e1063726SSasha Levin int sock; 111*e1063726SSasha Levin DIR *dir; 112*e1063726SSasha Levin struct dirent entry, *result; 113*e1063726SSasha Levin int ret = 0; 114*e1063726SSasha Levin 115*e1063726SSasha Levin dir = opendir(kvm__get_dir()); 116*e1063726SSasha Levin if (!dir) 117*e1063726SSasha Levin return -errno; 118*e1063726SSasha Levin 119*e1063726SSasha Levin for (;;) { 120*e1063726SSasha Levin readdir_r(dir, &entry, &result); 121*e1063726SSasha Levin if (result == NULL) 122*e1063726SSasha Levin break; 123*e1063726SSasha Levin if (entry.d_type == DT_SOCK) { 124*e1063726SSasha Levin ssize_t name_len = strlen(entry.d_name); 125*e1063726SSasha Levin char *p; 126*e1063726SSasha Levin 127*e1063726SSasha Levin if (name_len <= KVM_SOCK_SUFFIX_LEN) 128*e1063726SSasha Levin continue; 129*e1063726SSasha Levin 130*e1063726SSasha Levin p = &entry.d_name[name_len - KVM_SOCK_SUFFIX_LEN]; 131*e1063726SSasha Levin if (memcmp(KVM_SOCK_SUFFIX, p, KVM_SOCK_SUFFIX_LEN)) 132*e1063726SSasha Levin continue; 133*e1063726SSasha Levin 134*e1063726SSasha Levin *p = 0; 135*e1063726SSasha Levin sock = kvm__get_sock_by_instance(entry.d_name); 136*e1063726SSasha Levin if (sock < 0) 137*e1063726SSasha Levin continue; 138*e1063726SSasha Levin ret = callback(entry.d_name, sock); 139*e1063726SSasha Levin close(sock); 140*e1063726SSasha Levin if (ret < 0) 141*e1063726SSasha Levin break; 142*e1063726SSasha Levin } 143*e1063726SSasha Levin } 144*e1063726SSasha Levin 145*e1063726SSasha Levin closedir(dir); 146*e1063726SSasha Levin 147*e1063726SSasha Levin return ret; 148*e1063726SSasha Levin } 149*e1063726SSasha Levin 150*e1063726SSasha Levin int kvm_ipc__register_handler(u32 type, void (*cb)(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg)) 1514b1addaeSSasha Levin { 1524b1addaeSSasha Levin if (type >= KVM_IPC_MAX_MSGS) 1534b1addaeSSasha Levin return -ENOSPC; 1544b1addaeSSasha Levin 1554b1addaeSSasha Levin down_write(&msgs_rwlock); 1564b1addaeSSasha Levin msgs[type] = cb; 1574b1addaeSSasha Levin up_write(&msgs_rwlock); 1584b1addaeSSasha Levin 1594b1addaeSSasha Levin return 0; 1604b1addaeSSasha Levin } 1614b1addaeSSasha Levin 16250dc18aeSLai Jiangshan int kvm_ipc__send(int fd, u32 type) 16350dc18aeSLai Jiangshan { 16450dc18aeSLai Jiangshan struct kvm_ipc_head head = {.type = type, .len = 0,}; 16550dc18aeSLai Jiangshan 166ca088268SAsias He if (write_in_full(fd, &head, sizeof(head)) < 0) 16750dc18aeSLai Jiangshan return -1; 16850dc18aeSLai Jiangshan 16950dc18aeSLai Jiangshan return 0; 17050dc18aeSLai Jiangshan } 17150dc18aeSLai Jiangshan 17250dc18aeSLai Jiangshan int kvm_ipc__send_msg(int fd, u32 type, u32 len, u8 *msg) 17350dc18aeSLai Jiangshan { 17450dc18aeSLai Jiangshan struct kvm_ipc_head head = {.type = type, .len = len,}; 17550dc18aeSLai Jiangshan 176ca088268SAsias He if (write_in_full(fd, &head, sizeof(head)) < 0) 17750dc18aeSLai Jiangshan return -1; 17850dc18aeSLai Jiangshan 179fd5b45a1SAsias He if (write_in_full(fd, msg, len) < 0) 18050dc18aeSLai Jiangshan return -1; 18150dc18aeSLai Jiangshan 18250dc18aeSLai Jiangshan return 0; 18350dc18aeSLai Jiangshan } 18450dc18aeSLai Jiangshan 185*e1063726SSasha Levin static int kvm_ipc__handle(struct kvm *kvm, int fd, u32 type, u32 len, u8 *data) 1864b1addaeSSasha Levin { 187*e1063726SSasha Levin void (*cb)(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg); 1884b1addaeSSasha Levin 18944a56bfdSLai Jiangshan if (type >= KVM_IPC_MAX_MSGS) 1904b1addaeSSasha Levin return -ENOSPC; 1914b1addaeSSasha Levin 1924b1addaeSSasha Levin down_read(&msgs_rwlock); 19344a56bfdSLai Jiangshan cb = msgs[type]; 1944b1addaeSSasha Levin up_read(&msgs_rwlock); 1954b1addaeSSasha Levin 1964b1addaeSSasha Levin if (cb == NULL) { 19744a56bfdSLai Jiangshan pr_warning("No device handles type %u\n", type); 1984b1addaeSSasha Levin return -ENODEV; 1994b1addaeSSasha Levin } 2004b1addaeSSasha Levin 201*e1063726SSasha Levin cb(kvm, fd, type, len, data); 2024b1addaeSSasha Levin 2034b1addaeSSasha Levin return 0; 2044b1addaeSSasha Levin } 2054b1addaeSSasha Levin 2064b1addaeSSasha Levin static int kvm_ipc__new_conn(int fd) 2074b1addaeSSasha Levin { 2084b1addaeSSasha Levin int client; 2094b1addaeSSasha Levin struct epoll_event ev; 2104b1addaeSSasha Levin 2114b1addaeSSasha Levin client = accept(fd, NULL, NULL); 2124b1addaeSSasha Levin if (client < 0) 2134b1addaeSSasha Levin return -1; 2144b1addaeSSasha Levin 2154b1addaeSSasha Levin ev.events = EPOLLIN | EPOLLRDHUP; 2164b1addaeSSasha Levin ev.data.fd = client; 2174b1addaeSSasha Levin if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client, &ev) < 0) { 2184b1addaeSSasha Levin close(client); 2194b1addaeSSasha Levin return -1; 2204b1addaeSSasha Levin } 2214b1addaeSSasha Levin 2224b1addaeSSasha Levin return client; 2234b1addaeSSasha Levin } 2244b1addaeSSasha Levin 2254b1addaeSSasha Levin static void kvm_ipc__close_conn(int fd) 2264b1addaeSSasha Levin { 2274b1addaeSSasha Levin epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); 2284b1addaeSSasha Levin close(fd); 2294b1addaeSSasha Levin } 2304b1addaeSSasha Levin 231*e1063726SSasha Levin static int kvm_ipc__receive(struct kvm *kvm, int fd) 2324b1addaeSSasha Levin { 233a9aae6c5SLai Jiangshan struct kvm_ipc_head head; 234a9aae6c5SLai Jiangshan u8 *msg = NULL; 2354b1addaeSSasha Levin u32 n; 2364b1addaeSSasha Levin 237a9aae6c5SLai Jiangshan n = read(fd, &head, sizeof(head)); 238a9aae6c5SLai Jiangshan if (n != sizeof(head)) 239a9aae6c5SLai Jiangshan goto done; 240a9aae6c5SLai Jiangshan 241a9aae6c5SLai Jiangshan msg = malloc(head.len); 2424b1addaeSSasha Levin if (msg == NULL) 2434b1addaeSSasha Levin goto done; 2444b1addaeSSasha Levin 245a9aae6c5SLai Jiangshan n = read_in_full(fd, msg, head.len); 246a9aae6c5SLai Jiangshan if (n != head.len) 2474b1addaeSSasha Levin goto done; 2484b1addaeSSasha Levin 249*e1063726SSasha Levin kvm_ipc__handle(kvm, fd, head.type, head.len, msg); 2504b1addaeSSasha Levin 2518e463c62SAsias He return 0; 2528e463c62SAsias He 2534b1addaeSSasha Levin done: 2544b1addaeSSasha Levin free(msg); 2558e463c62SAsias He return -1; 2564b1addaeSSasha Levin } 2574b1addaeSSasha Levin 2584b1addaeSSasha Levin static void *kvm_ipc__thread(void *param) 2594b1addaeSSasha Levin { 2604b1addaeSSasha Levin struct epoll_event event; 261*e1063726SSasha Levin struct kvm *kvm = param; 2624b1addaeSSasha Levin 2634b1addaeSSasha Levin for (;;) { 2644b1addaeSSasha Levin int nfds; 2654b1addaeSSasha Levin 2664b1addaeSSasha Levin nfds = epoll_wait(epoll_fd, &event, 1, -1); 2674b1addaeSSasha Levin if (nfds > 0) { 2684b1addaeSSasha Levin int fd = event.data.fd; 2694b1addaeSSasha Levin 27047f72b90SSasha Levin if (fd == stop_fd && event.events & EPOLLIN) { 271c733c80bSSasha Levin break; 272c733c80bSSasha Levin } else if (fd == server_fd) { 2738e463c62SAsias He int client, r; 2744b1addaeSSasha Levin 2754b1addaeSSasha Levin client = kvm_ipc__new_conn(fd); 2768e463c62SAsias He /* 2778e463c62SAsias He * Handle multiple IPC cmd at a time 2788e463c62SAsias He */ 2798e463c62SAsias He do { 280*e1063726SSasha Levin r = kvm_ipc__receive(kvm, client); 2818e463c62SAsias He } while (r == 0); 2828e463c62SAsias He 283066c5809SSasha Levin } else if (event.events & (EPOLLERR | EPOLLRDHUP | EPOLLHUP)) { 2844b1addaeSSasha Levin kvm_ipc__close_conn(fd); 2854b1addaeSSasha Levin } else { 286*e1063726SSasha Levin kvm_ipc__receive(kvm, fd); 2874b1addaeSSasha Levin } 2884b1addaeSSasha Levin } 2894b1addaeSSasha Levin } 2904b1addaeSSasha Levin 2914b1addaeSSasha Levin return NULL; 2924b1addaeSSasha Levin } 2934b1addaeSSasha Levin 294*e1063726SSasha Levin static void kvm__pid(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg) 295*e1063726SSasha Levin { 296*e1063726SSasha Levin pid_t pid = getpid(); 297*e1063726SSasha Levin int r = 0; 298*e1063726SSasha Levin 299*e1063726SSasha Levin if (type == KVM_IPC_PID) 300*e1063726SSasha Levin r = write(fd, &pid, sizeof(pid)); 301*e1063726SSasha Levin 302*e1063726SSasha Levin if (r < 0) 303*e1063726SSasha Levin pr_warning("Failed sending PID"); 304*e1063726SSasha Levin } 305*e1063726SSasha Levin 306*e1063726SSasha Levin static void handle_stop(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg) 307*e1063726SSasha Levin { 308*e1063726SSasha Levin if (WARN_ON(type != KVM_IPC_STOP || len)) 309*e1063726SSasha Levin return; 310*e1063726SSasha Levin 311*e1063726SSasha Levin kvm_cpu__reboot(kvm); 312*e1063726SSasha Levin } 313*e1063726SSasha Levin 314*e1063726SSasha Levin /* Pause/resume the guest using SIGUSR2 */ 315*e1063726SSasha Levin static int is_paused; 316*e1063726SSasha Levin 317*e1063726SSasha Levin static void handle_pause(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg) 318*e1063726SSasha Levin { 319*e1063726SSasha Levin if (WARN_ON(len)) 320*e1063726SSasha Levin return; 321*e1063726SSasha Levin 322*e1063726SSasha Levin if (type == KVM_IPC_RESUME && is_paused) { 323*e1063726SSasha Levin kvm->vm_state = KVM_VMSTATE_RUNNING; 324*e1063726SSasha Levin kvm__continue(); 325*e1063726SSasha Levin } else if (type == KVM_IPC_PAUSE && !is_paused) { 326*e1063726SSasha Levin kvm->vm_state = KVM_VMSTATE_PAUSED; 327*e1063726SSasha Levin ioctl(kvm->vm_fd, KVM_KVMCLOCK_CTRL); 328*e1063726SSasha Levin kvm__pause(); 329*e1063726SSasha Levin } else { 330*e1063726SSasha Levin return; 331*e1063726SSasha Levin } 332*e1063726SSasha Levin 333*e1063726SSasha Levin is_paused = !is_paused; 334*e1063726SSasha Levin } 335*e1063726SSasha Levin 336*e1063726SSasha Levin static void handle_vmstate(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg) 337*e1063726SSasha Levin { 338*e1063726SSasha Levin int r = 0; 339*e1063726SSasha Levin 340*e1063726SSasha Levin if (type == KVM_IPC_VMSTATE) 341*e1063726SSasha Levin r = write(fd, &kvm->vm_state, sizeof(kvm->vm_state)); 342*e1063726SSasha Levin 343*e1063726SSasha Levin if (r < 0) 344*e1063726SSasha Levin pr_warning("Failed sending VMSTATE"); 345*e1063726SSasha Levin } 346*e1063726SSasha Levin 347*e1063726SSasha Levin /* 348*e1063726SSasha Levin * Serialize debug printout so that the output of multiple vcpus does not 349*e1063726SSasha Levin * get mixed up: 350*e1063726SSasha Levin */ 351*e1063726SSasha Levin static int printout_done; 352*e1063726SSasha Levin 353*e1063726SSasha Levin static void handle_sigusr1(int sig) 354*e1063726SSasha Levin { 355*e1063726SSasha Levin struct kvm_cpu *cpu = current_kvm_cpu; 356*e1063726SSasha Levin int fd = kvm_cpu__get_debug_fd(); 357*e1063726SSasha Levin 358*e1063726SSasha Levin if (!cpu || cpu->needs_nmi) 359*e1063726SSasha Levin return; 360*e1063726SSasha Levin 361*e1063726SSasha Levin dprintf(fd, "\n #\n # vCPU #%ld's dump:\n #\n", cpu->cpu_id); 362*e1063726SSasha Levin kvm_cpu__show_registers(cpu); 363*e1063726SSasha Levin kvm_cpu__show_code(cpu); 364*e1063726SSasha Levin kvm_cpu__show_page_tables(cpu); 365*e1063726SSasha Levin fflush(stdout); 366*e1063726SSasha Levin printout_done = 1; 367*e1063726SSasha Levin } 368*e1063726SSasha Levin 369*e1063726SSasha Levin static void handle_debug(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg) 370*e1063726SSasha Levin { 371*e1063726SSasha Levin int i; 372*e1063726SSasha Levin struct debug_cmd_params *params; 373*e1063726SSasha Levin u32 dbg_type; 374*e1063726SSasha Levin u32 vcpu; 375*e1063726SSasha Levin 376*e1063726SSasha Levin if (WARN_ON(type != KVM_IPC_DEBUG || len != sizeof(*params))) 377*e1063726SSasha Levin return; 378*e1063726SSasha Levin 379*e1063726SSasha Levin params = (void *)msg; 380*e1063726SSasha Levin dbg_type = params->dbg_type; 381*e1063726SSasha Levin vcpu = params->cpu; 382*e1063726SSasha Levin 383*e1063726SSasha Levin if (dbg_type & KVM_DEBUG_CMD_TYPE_SYSRQ) 384*e1063726SSasha Levin serial8250__inject_sysrq(kvm, params->sysrq); 385*e1063726SSasha Levin 386*e1063726SSasha Levin if (dbg_type & KVM_DEBUG_CMD_TYPE_NMI) { 387*e1063726SSasha Levin if ((int)vcpu >= kvm->nrcpus) 388*e1063726SSasha Levin return; 389*e1063726SSasha Levin 390*e1063726SSasha Levin kvm->cpus[vcpu]->needs_nmi = 1; 391*e1063726SSasha Levin pthread_kill(kvm->cpus[vcpu]->thread, SIGUSR1); 392*e1063726SSasha Levin } 393*e1063726SSasha Levin 394*e1063726SSasha Levin if (!(dbg_type & KVM_DEBUG_CMD_TYPE_DUMP)) 395*e1063726SSasha Levin return; 396*e1063726SSasha Levin 397*e1063726SSasha Levin for (i = 0; i < kvm->nrcpus; i++) { 398*e1063726SSasha Levin struct kvm_cpu *cpu = kvm->cpus[i]; 399*e1063726SSasha Levin 400*e1063726SSasha Levin if (!cpu) 401*e1063726SSasha Levin continue; 402*e1063726SSasha Levin 403*e1063726SSasha Levin printout_done = 0; 404*e1063726SSasha Levin 405*e1063726SSasha Levin kvm_cpu__set_debug_fd(fd); 406*e1063726SSasha Levin pthread_kill(cpu->thread, SIGUSR1); 407*e1063726SSasha Levin /* 408*e1063726SSasha Levin * Wait for the vCPU to dump state before signalling 409*e1063726SSasha Levin * the next thread. Since this is debug code it does 410*e1063726SSasha Levin * not matter that we are burning CPU time a bit: 411*e1063726SSasha Levin */ 412*e1063726SSasha Levin while (!printout_done) 413*e1063726SSasha Levin sleep(0); 414*e1063726SSasha Levin } 415*e1063726SSasha Levin 416*e1063726SSasha Levin close(fd); 417*e1063726SSasha Levin 418*e1063726SSasha Levin serial8250__inject_sysrq(kvm, 'p'); 419*e1063726SSasha Levin } 420*e1063726SSasha Levin 421*e1063726SSasha Levin int kvm_ipc__init(struct kvm *kvm) 4224b1addaeSSasha Levin { 423e21e8ff3SYang Bai int ret; 424*e1063726SSasha Levin int sock = kvm__create_socket(kvm); 42521b3c2c0SSasha Levin struct epoll_event ev = {0}; 4264b1addaeSSasha Levin 4274b1addaeSSasha Levin server_fd = sock; 4284b1addaeSSasha Levin 4294b1addaeSSasha Levin epoll_fd = epoll_create(KVM_IPC_MAX_MSGS); 430e21e8ff3SYang Bai if (epoll_fd < 0) { 431e21e8ff3SYang Bai ret = epoll_fd; 432e21e8ff3SYang Bai goto err; 433e21e8ff3SYang Bai } 4344b1addaeSSasha Levin 43547f72b90SSasha Levin ev.events = EPOLLIN | EPOLLET; 4364b1addaeSSasha Levin ev.data.fd = sock; 437e21e8ff3SYang Bai if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sock, &ev) < 0) { 438e21e8ff3SYang Bai pr_err("Failed starting IPC thread"); 439e21e8ff3SYang Bai ret = -EFAULT; 440e21e8ff3SYang Bai goto err_epoll; 441e21e8ff3SYang Bai } 4424b1addaeSSasha Levin 443c733c80bSSasha Levin stop_fd = eventfd(0, 0); 444e21e8ff3SYang Bai if (stop_fd < 0) { 445e21e8ff3SYang Bai ret = stop_fd; 446e21e8ff3SYang Bai goto err_epoll; 447e21e8ff3SYang Bai } 448e21e8ff3SYang Bai 44947f72b90SSasha Levin ev.events = EPOLLIN | EPOLLET; 450c733c80bSSasha Levin ev.data.fd = stop_fd; 451e21e8ff3SYang Bai if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, stop_fd, &ev) < 0) { 452e21e8ff3SYang Bai pr_err("Failed adding stop event to epoll"); 453e21e8ff3SYang Bai ret = -EFAULT; 454e21e8ff3SYang Bai goto err_stop; 455e21e8ff3SYang Bai } 456c733c80bSSasha Levin 457*e1063726SSasha Levin if (pthread_create(&thread, NULL, kvm_ipc__thread, kvm) != 0) { 458e21e8ff3SYang Bai pr_err("Failed starting IPC thread"); 459e21e8ff3SYang Bai ret = -EFAULT; 460e21e8ff3SYang Bai goto err_stop; 461e21e8ff3SYang Bai } 4624b1addaeSSasha Levin 463*e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_PID, kvm__pid); 464*e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_DEBUG, handle_debug); 465*e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_PAUSE, handle_pause); 466*e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_RESUME, handle_pause); 467*e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_STOP, handle_stop); 468*e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_VMSTATE, handle_vmstate); 469*e1063726SSasha Levin signal(SIGUSR1, handle_sigusr1); 470*e1063726SSasha Levin 4714b1addaeSSasha Levin return 0; 472e21e8ff3SYang Bai 473e21e8ff3SYang Bai err_stop: 474e21e8ff3SYang Bai close(stop_fd); 475e21e8ff3SYang Bai err_epoll: 476e21e8ff3SYang Bai close(epoll_fd); 477e21e8ff3SYang Bai err: 478e21e8ff3SYang Bai return ret; 4794b1addaeSSasha Levin } 480c733c80bSSasha Levin 481*e1063726SSasha Levin int kvm_ipc__exit(struct kvm *kvm) 482c733c80bSSasha Levin { 483c733c80bSSasha Levin u64 val = 1; 484c733c80bSSasha Levin int ret; 485c733c80bSSasha Levin 486c733c80bSSasha Levin ret = write(stop_fd, &val, sizeof(val)); 487c733c80bSSasha Levin if (ret < 0) 488c733c80bSSasha Levin return ret; 489c733c80bSSasha Levin 490c733c80bSSasha Levin close(server_fd); 491c733c80bSSasha Levin close(epoll_fd); 492c733c80bSSasha Levin 493*e1063726SSasha Levin kvm__remove_socket(kvm->cfg.guest_name); 494*e1063726SSasha Levin 495c733c80bSSasha Levin return ret; 496c733c80bSSasha Levin } 497