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]; 37a2583dbfSAndre Przywara 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 47e1063726SSasha Levin s = socket(AF_UNIX, SOCK_STREAM, 0); 48211370d6SMichael Ellerman if (s < 0) { 49211370d6SMichael Ellerman perror("socket"); 50e1063726SSasha Levin return s; 51211370d6SMichael Ellerman } 52211370d6SMichael Ellerman 53e1063726SSasha Levin local.sun_family = AF_UNIX; 54e1063726SSasha Levin strlcpy(local.sun_path, full_name, sizeof(local.sun_path)); 55e1063726SSasha Levin len = strlen(local.sun_path) + sizeof(local.sun_family); 56e1063726SSasha Levin r = bind(s, (struct sockaddr *)&local, len); 57*ef5b941fSAndre Przywara /* Check for an existing socket file */ 58*ef5b941fSAndre Przywara if (r < 0 && errno == EADDRINUSE) { 59*ef5b941fSAndre Przywara r = connect(s, (struct sockaddr *)&local, len); 60*ef5b941fSAndre Przywara if (r == 0) { 61*ef5b941fSAndre Przywara /* 62*ef5b941fSAndre Przywara * If we could connect, there is already a guest 63*ef5b941fSAndre Przywara * using this same name. This should not happen 64*ef5b941fSAndre Przywara * for PID derived names, but could happen for user 65*ef5b941fSAndre Przywara * provided guest names. 66*ef5b941fSAndre Przywara */ 67*ef5b941fSAndre Przywara pr_err("Guest socket file %s already exists.", 68*ef5b941fSAndre Przywara full_name); 69*ef5b941fSAndre Przywara r = -EEXIST; 70*ef5b941fSAndre Przywara goto fail; 71*ef5b941fSAndre Przywara } 72*ef5b941fSAndre Przywara if (errno == ECONNREFUSED) { 73*ef5b941fSAndre Przywara /* 74*ef5b941fSAndre Przywara * This is a ghost socket file, with no-one listening 75*ef5b941fSAndre Przywara * on the other end. Since kvmtool will only bind 76*ef5b941fSAndre Przywara * above when creating a new guest, there is no 77*ef5b941fSAndre Przywara * danger in just removing the file and re-trying. 78*ef5b941fSAndre Przywara */ 79*ef5b941fSAndre Przywara unlink(full_name); 80*ef5b941fSAndre Przywara pr_info("Removed ghost socket file \"%s\".", full_name); 81*ef5b941fSAndre Przywara r = bind(s, (struct sockaddr *)&local, len); 82*ef5b941fSAndre Przywara } 83*ef5b941fSAndre Przywara } 84211370d6SMichael Ellerman if (r < 0) { 85211370d6SMichael Ellerman perror("bind"); 86e1063726SSasha Levin goto fail; 87211370d6SMichael Ellerman } 88e1063726SSasha Levin 89e1063726SSasha Levin r = listen(s, 5); 90211370d6SMichael Ellerman if (r < 0) { 91211370d6SMichael Ellerman perror("listen"); 92e1063726SSasha Levin goto fail; 93211370d6SMichael Ellerman } 94e1063726SSasha Levin 95e1063726SSasha Levin return s; 96e1063726SSasha Levin 97e1063726SSasha Levin fail: 98e1063726SSasha Levin close(s); 99e1063726SSasha Levin return r; 100e1063726SSasha Levin } 101e1063726SSasha Levin 102e1063726SSasha Levin void kvm__remove_socket(const char *name) 103e1063726SSasha Levin { 104e1063726SSasha Levin char full_name[PATH_MAX]; 105e1063726SSasha Levin 106e1063726SSasha Levin snprintf(full_name, sizeof(full_name), "%s/%s%s", 107e1063726SSasha Levin kvm__get_dir(), name, KVM_SOCK_SUFFIX); 108e1063726SSasha Levin unlink(full_name); 109e1063726SSasha Levin } 110e1063726SSasha Levin 111e1063726SSasha Levin int kvm__get_sock_by_instance(const char *name) 112e1063726SSasha Levin { 113e1063726SSasha Levin int s, len, r; 114e1063726SSasha Levin char sock_file[PATH_MAX]; 115e1063726SSasha Levin struct sockaddr_un local; 116e1063726SSasha Levin 117e1063726SSasha Levin snprintf(sock_file, sizeof(sock_file), "%s/%s%s", 118e1063726SSasha Levin kvm__get_dir(), name, KVM_SOCK_SUFFIX); 119e1063726SSasha Levin s = socket(AF_UNIX, SOCK_STREAM, 0); 120e1063726SSasha Levin 121e1063726SSasha Levin local.sun_family = AF_UNIX; 122e1063726SSasha Levin strlcpy(local.sun_path, sock_file, sizeof(local.sun_path)); 123e1063726SSasha Levin len = strlen(local.sun_path) + sizeof(local.sun_family); 124e1063726SSasha Levin 125d77bd4f4SAndre Przywara r = connect(s, (struct sockaddr *)&local, len); 126e1063726SSasha Levin if (r < 0 && errno == ECONNREFUSED) { 12767f9f7b7SAndre Przywara /* Clean up the ghost socket file */ 12867f9f7b7SAndre Przywara unlink(local.sun_path); 12967f9f7b7SAndre Przywara pr_info("Removed ghost socket file \"%s\".", sock_file); 130e1063726SSasha Levin return r; 131e1063726SSasha Levin } else if (r < 0) { 132e1063726SSasha Levin return r; 133e1063726SSasha Levin } 134e1063726SSasha Levin 135e1063726SSasha Levin return s; 136e1063726SSasha Levin } 137e1063726SSasha Levin 13822fb13f6SMilan Kocian static bool is_socket(const char *base_path, const struct dirent *dent) 13922fb13f6SMilan Kocian { 14022fb13f6SMilan Kocian switch (dent->d_type) { 14122fb13f6SMilan Kocian case DT_SOCK: 14222fb13f6SMilan Kocian return true; 14322fb13f6SMilan Kocian 14422fb13f6SMilan Kocian case DT_UNKNOWN: { 14522fb13f6SMilan Kocian char path[PATH_MAX]; 14622fb13f6SMilan Kocian struct stat st; 14722fb13f6SMilan Kocian 14822fb13f6SMilan Kocian sprintf(path, "%s/%s", base_path, dent->d_name); 14922fb13f6SMilan Kocian if (stat(path, &st)) 15022fb13f6SMilan Kocian return false; 15122fb13f6SMilan Kocian 15222fb13f6SMilan Kocian return S_ISSOCK(st.st_mode); 15322fb13f6SMilan Kocian } 15422fb13f6SMilan Kocian default: 15522fb13f6SMilan Kocian return false; 15622fb13f6SMilan Kocian } 15722fb13f6SMilan Kocian } 15822fb13f6SMilan Kocian 159e1063726SSasha Levin int kvm__enumerate_instances(int (*callback)(const char *name, int fd)) 160e1063726SSasha Levin { 161e1063726SSasha Levin int sock; 162e1063726SSasha Levin DIR *dir; 163d62653e1SMichal Rostecki struct dirent *entry; 164e1063726SSasha Levin int ret = 0; 16522fb13f6SMilan Kocian const char *path; 166e1063726SSasha Levin 16722fb13f6SMilan Kocian path = kvm__get_dir(); 16822fb13f6SMilan Kocian 16922fb13f6SMilan Kocian dir = opendir(path); 170e1063726SSasha Levin if (!dir) 171e1063726SSasha Levin return -errno; 172e1063726SSasha Levin 173e1063726SSasha Levin for (;;) { 174d62653e1SMichal Rostecki entry = readdir(dir); 175d62653e1SMichal Rostecki if (!entry) 176e1063726SSasha Levin break; 177d62653e1SMichal Rostecki if (is_socket(path, entry)) { 178d62653e1SMichal Rostecki ssize_t name_len = strlen(entry->d_name); 179e1063726SSasha Levin char *p; 180e1063726SSasha Levin 181e1063726SSasha Levin if (name_len <= KVM_SOCK_SUFFIX_LEN) 182e1063726SSasha Levin continue; 183e1063726SSasha Levin 184d62653e1SMichal Rostecki p = &entry->d_name[name_len - KVM_SOCK_SUFFIX_LEN]; 185e1063726SSasha Levin if (memcmp(KVM_SOCK_SUFFIX, p, KVM_SOCK_SUFFIX_LEN)) 186e1063726SSasha Levin continue; 187e1063726SSasha Levin 188e1063726SSasha Levin *p = 0; 189d62653e1SMichal Rostecki sock = kvm__get_sock_by_instance(entry->d_name); 190e1063726SSasha Levin if (sock < 0) 191e1063726SSasha Levin continue; 192d62653e1SMichal Rostecki ret = callback(entry->d_name, sock); 193e1063726SSasha Levin close(sock); 194e1063726SSasha Levin if (ret < 0) 195e1063726SSasha Levin break; 196e1063726SSasha Levin } 197e1063726SSasha Levin } 198e1063726SSasha Levin 199e1063726SSasha Levin closedir(dir); 200e1063726SSasha Levin 201e1063726SSasha Levin return ret; 202e1063726SSasha Levin } 203e1063726SSasha Levin 204e1063726SSasha Levin int kvm_ipc__register_handler(u32 type, void (*cb)(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg)) 2054b1addaeSSasha Levin { 2064b1addaeSSasha Levin if (type >= KVM_IPC_MAX_MSGS) 2074b1addaeSSasha Levin return -ENOSPC; 2084b1addaeSSasha Levin 2094b1addaeSSasha Levin down_write(&msgs_rwlock); 2104b1addaeSSasha Levin msgs[type] = cb; 2114b1addaeSSasha Levin up_write(&msgs_rwlock); 2124b1addaeSSasha Levin 2134b1addaeSSasha Levin return 0; 2144b1addaeSSasha Levin } 2154b1addaeSSasha Levin 21650dc18aeSLai Jiangshan int kvm_ipc__send(int fd, u32 type) 21750dc18aeSLai Jiangshan { 21850dc18aeSLai Jiangshan struct kvm_ipc_head head = {.type = type, .len = 0,}; 21950dc18aeSLai Jiangshan 220ca088268SAsias He if (write_in_full(fd, &head, sizeof(head)) < 0) 22150dc18aeSLai Jiangshan return -1; 22250dc18aeSLai Jiangshan 22350dc18aeSLai Jiangshan return 0; 22450dc18aeSLai Jiangshan } 22550dc18aeSLai Jiangshan 22650dc18aeSLai Jiangshan int kvm_ipc__send_msg(int fd, u32 type, u32 len, u8 *msg) 22750dc18aeSLai Jiangshan { 22850dc18aeSLai Jiangshan struct kvm_ipc_head head = {.type = type, .len = len,}; 22950dc18aeSLai Jiangshan 230ca088268SAsias He if (write_in_full(fd, &head, sizeof(head)) < 0) 23150dc18aeSLai Jiangshan return -1; 23250dc18aeSLai Jiangshan 233fd5b45a1SAsias He if (write_in_full(fd, msg, len) < 0) 23450dc18aeSLai Jiangshan return -1; 23550dc18aeSLai Jiangshan 23650dc18aeSLai Jiangshan return 0; 23750dc18aeSLai Jiangshan } 23850dc18aeSLai Jiangshan 239e1063726SSasha Levin static int kvm_ipc__handle(struct kvm *kvm, int fd, u32 type, u32 len, u8 *data) 2404b1addaeSSasha Levin { 241e1063726SSasha Levin void (*cb)(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg); 2424b1addaeSSasha Levin 24344a56bfdSLai Jiangshan if (type >= KVM_IPC_MAX_MSGS) 2444b1addaeSSasha Levin return -ENOSPC; 2454b1addaeSSasha Levin 2464b1addaeSSasha Levin down_read(&msgs_rwlock); 24744a56bfdSLai Jiangshan cb = msgs[type]; 2484b1addaeSSasha Levin up_read(&msgs_rwlock); 2494b1addaeSSasha Levin 2504b1addaeSSasha Levin if (cb == NULL) { 25144a56bfdSLai Jiangshan pr_warning("No device handles type %u\n", type); 2524b1addaeSSasha Levin return -ENODEV; 2534b1addaeSSasha Levin } 2544b1addaeSSasha Levin 255e1063726SSasha Levin cb(kvm, fd, type, len, data); 2564b1addaeSSasha Levin 2574b1addaeSSasha Levin return 0; 2584b1addaeSSasha Levin } 2594b1addaeSSasha Levin 2604b1addaeSSasha Levin static int kvm_ipc__new_conn(int fd) 2614b1addaeSSasha Levin { 2624b1addaeSSasha Levin int client; 2634b1addaeSSasha Levin struct epoll_event ev; 2644b1addaeSSasha Levin 2654b1addaeSSasha Levin client = accept(fd, NULL, NULL); 2664b1addaeSSasha Levin if (client < 0) 2674b1addaeSSasha Levin return -1; 2684b1addaeSSasha Levin 2694b1addaeSSasha Levin ev.events = EPOLLIN | EPOLLRDHUP; 2704b1addaeSSasha Levin ev.data.fd = client; 2714b1addaeSSasha Levin if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client, &ev) < 0) { 2724b1addaeSSasha Levin close(client); 2734b1addaeSSasha Levin return -1; 2744b1addaeSSasha Levin } 2754b1addaeSSasha Levin 2764b1addaeSSasha Levin return client; 2774b1addaeSSasha Levin } 2784b1addaeSSasha Levin 2794b1addaeSSasha Levin static void kvm_ipc__close_conn(int fd) 2804b1addaeSSasha Levin { 2814b1addaeSSasha Levin epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fd, NULL); 2824b1addaeSSasha Levin close(fd); 2834b1addaeSSasha Levin } 2844b1addaeSSasha Levin 285e1063726SSasha Levin static int kvm_ipc__receive(struct kvm *kvm, int fd) 2864b1addaeSSasha Levin { 287a9aae6c5SLai Jiangshan struct kvm_ipc_head head; 288a9aae6c5SLai Jiangshan u8 *msg = NULL; 2894b1addaeSSasha Levin u32 n; 2904b1addaeSSasha Levin 291a9aae6c5SLai Jiangshan n = read(fd, &head, sizeof(head)); 292a9aae6c5SLai Jiangshan if (n != sizeof(head)) 293a9aae6c5SLai Jiangshan goto done; 294a9aae6c5SLai Jiangshan 295a9aae6c5SLai Jiangshan msg = malloc(head.len); 2964b1addaeSSasha Levin if (msg == NULL) 2974b1addaeSSasha Levin goto done; 2984b1addaeSSasha Levin 299a9aae6c5SLai Jiangshan n = read_in_full(fd, msg, head.len); 300a9aae6c5SLai Jiangshan if (n != head.len) 3014b1addaeSSasha Levin goto done; 3024b1addaeSSasha Levin 303e1063726SSasha Levin kvm_ipc__handle(kvm, fd, head.type, head.len, msg); 3044b1addaeSSasha Levin 3058e463c62SAsias He return 0; 3068e463c62SAsias He 3074b1addaeSSasha Levin done: 3084b1addaeSSasha Levin free(msg); 3098e463c62SAsias He return -1; 3104b1addaeSSasha Levin } 3114b1addaeSSasha Levin 3124b1addaeSSasha Levin static void *kvm_ipc__thread(void *param) 3134b1addaeSSasha Levin { 3144b1addaeSSasha Levin struct epoll_event event; 315e1063726SSasha Levin struct kvm *kvm = param; 3164b1addaeSSasha Levin 317a4d8c55eSSasha Levin kvm__set_thread_name("kvm-ipc"); 318a4d8c55eSSasha Levin 3194b1addaeSSasha Levin for (;;) { 3204b1addaeSSasha Levin int nfds; 3214b1addaeSSasha Levin 3224b1addaeSSasha Levin nfds = epoll_wait(epoll_fd, &event, 1, -1); 3234b1addaeSSasha Levin if (nfds > 0) { 3244b1addaeSSasha Levin int fd = event.data.fd; 3254b1addaeSSasha Levin 32647f72b90SSasha Levin if (fd == stop_fd && event.events & EPOLLIN) { 327c733c80bSSasha Levin break; 328c733c80bSSasha Levin } else if (fd == server_fd) { 3298e463c62SAsias He int client, r; 3304b1addaeSSasha Levin 3314b1addaeSSasha Levin client = kvm_ipc__new_conn(fd); 3328e463c62SAsias He /* 3338e463c62SAsias He * Handle multiple IPC cmd at a time 3348e463c62SAsias He */ 3358e463c62SAsias He do { 336e1063726SSasha Levin r = kvm_ipc__receive(kvm, client); 3378e463c62SAsias He } while (r == 0); 3388e463c62SAsias He 339066c5809SSasha Levin } else if (event.events & (EPOLLERR | EPOLLRDHUP | EPOLLHUP)) { 3404b1addaeSSasha Levin kvm_ipc__close_conn(fd); 3414b1addaeSSasha Levin } else { 342e1063726SSasha Levin kvm_ipc__receive(kvm, fd); 3434b1addaeSSasha Levin } 3444b1addaeSSasha Levin } 3454b1addaeSSasha Levin } 3464b1addaeSSasha Levin 3474b1addaeSSasha Levin return NULL; 3484b1addaeSSasha Levin } 3494b1addaeSSasha Levin 350e1063726SSasha Levin static void kvm__pid(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg) 351e1063726SSasha Levin { 352e1063726SSasha Levin pid_t pid = getpid(); 353e1063726SSasha Levin int r = 0; 354e1063726SSasha Levin 355e1063726SSasha Levin if (type == KVM_IPC_PID) 356e1063726SSasha Levin r = write(fd, &pid, sizeof(pid)); 357e1063726SSasha Levin 358e1063726SSasha Levin if (r < 0) 359e1063726SSasha Levin pr_warning("Failed sending PID"); 360e1063726SSasha Levin } 361e1063726SSasha Levin 362e1063726SSasha Levin static void handle_stop(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg) 363e1063726SSasha Levin { 364e1063726SSasha Levin if (WARN_ON(type != KVM_IPC_STOP || len)) 365e1063726SSasha Levin return; 366e1063726SSasha Levin 3672aa76b26SWill Deacon kvm__reboot(kvm); 368e1063726SSasha Levin } 369e1063726SSasha Levin 370e1063726SSasha Levin /* Pause/resume the guest using SIGUSR2 */ 371e1063726SSasha Levin static int is_paused; 372e1063726SSasha Levin 373e1063726SSasha Levin static void handle_pause(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg) 374e1063726SSasha Levin { 375e1063726SSasha Levin if (WARN_ON(len)) 376e1063726SSasha Levin return; 377e1063726SSasha Levin 378e1063726SSasha Levin if (type == KVM_IPC_RESUME && is_paused) { 379e1063726SSasha Levin kvm->vm_state = KVM_VMSTATE_RUNNING; 3804346fd8fSSasha Levin kvm__continue(kvm); 381e1063726SSasha Levin } else if (type == KVM_IPC_PAUSE && !is_paused) { 382e1063726SSasha Levin kvm->vm_state = KVM_VMSTATE_PAUSED; 383e1063726SSasha Levin ioctl(kvm->vm_fd, KVM_KVMCLOCK_CTRL); 3844346fd8fSSasha Levin kvm__pause(kvm); 385e1063726SSasha Levin } else { 386e1063726SSasha Levin return; 387e1063726SSasha Levin } 388e1063726SSasha Levin 389e1063726SSasha Levin is_paused = !is_paused; 390e1063726SSasha Levin } 391e1063726SSasha Levin 392e1063726SSasha Levin static void handle_vmstate(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg) 393e1063726SSasha Levin { 394e1063726SSasha Levin int r = 0; 395e1063726SSasha Levin 396e1063726SSasha Levin if (type == KVM_IPC_VMSTATE) 397e1063726SSasha Levin r = write(fd, &kvm->vm_state, sizeof(kvm->vm_state)); 398e1063726SSasha Levin 399e1063726SSasha Levin if (r < 0) 400e1063726SSasha Levin pr_warning("Failed sending VMSTATE"); 401e1063726SSasha Levin } 402e1063726SSasha Levin 403e1063726SSasha Levin /* 404e1063726SSasha Levin * Serialize debug printout so that the output of multiple vcpus does not 405e1063726SSasha Levin * get mixed up: 406e1063726SSasha Levin */ 407e1063726SSasha Levin static int printout_done; 408e1063726SSasha Levin 409e1063726SSasha Levin static void handle_sigusr1(int sig) 410e1063726SSasha Levin { 411e1063726SSasha Levin struct kvm_cpu *cpu = current_kvm_cpu; 412e1063726SSasha Levin int fd = kvm_cpu__get_debug_fd(); 413e1063726SSasha Levin 414e1063726SSasha Levin if (!cpu || cpu->needs_nmi) 415e1063726SSasha Levin return; 416e1063726SSasha Levin 417e1063726SSasha Levin dprintf(fd, "\n #\n # vCPU #%ld's dump:\n #\n", cpu->cpu_id); 418e1063726SSasha Levin kvm_cpu__show_registers(cpu); 419e1063726SSasha Levin kvm_cpu__show_code(cpu); 420e1063726SSasha Levin kvm_cpu__show_page_tables(cpu); 421e1063726SSasha Levin fflush(stdout); 422e1063726SSasha Levin printout_done = 1; 423e1063726SSasha Levin } 424e1063726SSasha Levin 425e1063726SSasha Levin static void handle_debug(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg) 426e1063726SSasha Levin { 427e1063726SSasha Levin int i; 428e1063726SSasha Levin struct debug_cmd_params *params; 429e1063726SSasha Levin u32 dbg_type; 430e1063726SSasha Levin u32 vcpu; 431e1063726SSasha Levin 432e1063726SSasha Levin if (WARN_ON(type != KVM_IPC_DEBUG || len != sizeof(*params))) 433e1063726SSasha Levin return; 434e1063726SSasha Levin 435e1063726SSasha Levin params = (void *)msg; 436e1063726SSasha Levin dbg_type = params->dbg_type; 437e1063726SSasha Levin vcpu = params->cpu; 438e1063726SSasha Levin 439e1063726SSasha Levin if (dbg_type & KVM_DEBUG_CMD_TYPE_SYSRQ) 440e1063726SSasha Levin serial8250__inject_sysrq(kvm, params->sysrq); 441e1063726SSasha Levin 442e1063726SSasha Levin if (dbg_type & KVM_DEBUG_CMD_TYPE_NMI) { 443e1063726SSasha Levin if ((int)vcpu >= kvm->nrcpus) 444e1063726SSasha Levin return; 445e1063726SSasha Levin 446e1063726SSasha Levin kvm->cpus[vcpu]->needs_nmi = 1; 447e1063726SSasha Levin pthread_kill(kvm->cpus[vcpu]->thread, SIGUSR1); 448e1063726SSasha Levin } 449e1063726SSasha Levin 450e1063726SSasha Levin if (!(dbg_type & KVM_DEBUG_CMD_TYPE_DUMP)) 451e1063726SSasha Levin return; 452e1063726SSasha Levin 453e1063726SSasha Levin for (i = 0; i < kvm->nrcpus; i++) { 454e1063726SSasha Levin struct kvm_cpu *cpu = kvm->cpus[i]; 455e1063726SSasha Levin 456e1063726SSasha Levin if (!cpu) 457e1063726SSasha Levin continue; 458e1063726SSasha Levin 459e1063726SSasha Levin printout_done = 0; 460e1063726SSasha Levin 461e1063726SSasha Levin kvm_cpu__set_debug_fd(fd); 462e1063726SSasha Levin pthread_kill(cpu->thread, SIGUSR1); 463e1063726SSasha Levin /* 464e1063726SSasha Levin * Wait for the vCPU to dump state before signalling 465e1063726SSasha Levin * the next thread. Since this is debug code it does 466e1063726SSasha Levin * not matter that we are burning CPU time a bit: 467e1063726SSasha Levin */ 468e1063726SSasha Levin while (!printout_done) 469e1063726SSasha Levin sleep(0); 470e1063726SSasha Levin } 471e1063726SSasha Levin 472e1063726SSasha Levin close(fd); 473e1063726SSasha Levin 474e1063726SSasha Levin serial8250__inject_sysrq(kvm, 'p'); 475e1063726SSasha Levin } 476e1063726SSasha Levin 477e1063726SSasha Levin int kvm_ipc__init(struct kvm *kvm) 4784b1addaeSSasha Levin { 479e21e8ff3SYang Bai int ret; 480e1063726SSasha Levin int sock = kvm__create_socket(kvm); 48121b3c2c0SSasha Levin struct epoll_event ev = {0}; 4824b1addaeSSasha Levin 4834b1addaeSSasha Levin server_fd = sock; 4844b1addaeSSasha Levin 4854b1addaeSSasha Levin epoll_fd = epoll_create(KVM_IPC_MAX_MSGS); 486e21e8ff3SYang Bai if (epoll_fd < 0) { 487211370d6SMichael Ellerman perror("epoll_create"); 488e21e8ff3SYang Bai ret = epoll_fd; 489e21e8ff3SYang Bai goto err; 490e21e8ff3SYang Bai } 4914b1addaeSSasha Levin 49247f72b90SSasha Levin ev.events = EPOLLIN | EPOLLET; 4934b1addaeSSasha Levin ev.data.fd = sock; 494e21e8ff3SYang Bai if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, sock, &ev) < 0) { 495211370d6SMichael Ellerman pr_err("Failed adding socket to epoll"); 496e21e8ff3SYang Bai ret = -EFAULT; 497e21e8ff3SYang Bai goto err_epoll; 498e21e8ff3SYang Bai } 4994b1addaeSSasha Levin 500c733c80bSSasha Levin stop_fd = eventfd(0, 0); 501e21e8ff3SYang Bai if (stop_fd < 0) { 502211370d6SMichael Ellerman perror("eventfd"); 503e21e8ff3SYang Bai ret = stop_fd; 504e21e8ff3SYang Bai goto err_epoll; 505e21e8ff3SYang Bai } 506e21e8ff3SYang Bai 50747f72b90SSasha Levin ev.events = EPOLLIN | EPOLLET; 508c733c80bSSasha Levin ev.data.fd = stop_fd; 509e21e8ff3SYang Bai if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, stop_fd, &ev) < 0) { 510e21e8ff3SYang Bai pr_err("Failed adding stop event to epoll"); 511e21e8ff3SYang Bai ret = -EFAULT; 512e21e8ff3SYang Bai goto err_stop; 513e21e8ff3SYang Bai } 514c733c80bSSasha Levin 515e1063726SSasha Levin if (pthread_create(&thread, NULL, kvm_ipc__thread, kvm) != 0) { 516e21e8ff3SYang Bai pr_err("Failed starting IPC thread"); 517e21e8ff3SYang Bai ret = -EFAULT; 518e21e8ff3SYang Bai goto err_stop; 519e21e8ff3SYang Bai } 5204b1addaeSSasha Levin 521e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_PID, kvm__pid); 522e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_DEBUG, handle_debug); 523e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_PAUSE, handle_pause); 524e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_RESUME, handle_pause); 525e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_STOP, handle_stop); 526e1063726SSasha Levin kvm_ipc__register_handler(KVM_IPC_VMSTATE, handle_vmstate); 527e1063726SSasha Levin signal(SIGUSR1, handle_sigusr1); 528e1063726SSasha Levin 5294b1addaeSSasha Levin return 0; 530e21e8ff3SYang Bai 531e21e8ff3SYang Bai err_stop: 532e21e8ff3SYang Bai close(stop_fd); 533e21e8ff3SYang Bai err_epoll: 534e21e8ff3SYang Bai close(epoll_fd); 535e21e8ff3SYang Bai err: 536e21e8ff3SYang Bai return ret; 5374b1addaeSSasha Levin } 53849a8afd1SSasha Levin base_init(kvm_ipc__init); 539c733c80bSSasha Levin 540e1063726SSasha Levin int kvm_ipc__exit(struct kvm *kvm) 541c733c80bSSasha Levin { 542c733c80bSSasha Levin u64 val = 1; 543c733c80bSSasha Levin int ret; 544c733c80bSSasha Levin 545c733c80bSSasha Levin ret = write(stop_fd, &val, sizeof(val)); 546c733c80bSSasha Levin if (ret < 0) 547c733c80bSSasha Levin return ret; 548c733c80bSSasha Levin 549c733c80bSSasha Levin close(server_fd); 550c733c80bSSasha Levin close(epoll_fd); 551c733c80bSSasha Levin 552e1063726SSasha Levin kvm__remove_socket(kvm->cfg.guest_name); 553e1063726SSasha Levin 554c733c80bSSasha Levin return ret; 555c733c80bSSasha Levin } 55649a8afd1SSasha Levin base_exit(kvm_ipc__exit); 557