xref: /kvmtool/kvm-ipc.c (revision d30d94872e7fe998bd527e5cc6c38db58d46ee03)
14b1addaeSSasha Levin #include <sys/epoll.h>
24b1addaeSSasha Levin #include <sys/un.h>
34b1addaeSSasha Levin #include <sys/types.h>
44b1addaeSSasha Levin #include <sys/socket.h>
5e1063726SSasha Levin #include <dirent.h>
6e1063726SSasha Levin 
7*d30d9487SJean-Philippe Brucker #include "kvm/epoll.h"
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);
31*d30d9487SJean-Philippe Brucker static int server_fd;
32*d30d9487SJean-Philippe Brucker static struct kvm__epoll epoll;
334b1addaeSSasha Levin 
kvm__create_socket(struct kvm * kvm)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);
57ef5b941fSAndre Przywara 	/* Check for an existing socket file */
58ef5b941fSAndre Przywara 	if (r < 0 && errno == EADDRINUSE) {
59ef5b941fSAndre Przywara 		r = connect(s, (struct sockaddr *)&local, len);
60ef5b941fSAndre Przywara 		if (r == 0) {
61ef5b941fSAndre Przywara 			/*
62ef5b941fSAndre Przywara 			 * If we could connect, there is already a guest
63ef5b941fSAndre Przywara 			 * using this same name. This should not happen
64ef5b941fSAndre Przywara 			 * for PID derived names, but could happen for user
65ef5b941fSAndre Przywara 			 * provided guest names.
66ef5b941fSAndre Przywara 			 */
67ef5b941fSAndre Przywara 			pr_err("Guest socket file %s already exists.",
68ef5b941fSAndre Przywara 			       full_name);
69ef5b941fSAndre Przywara 			r = -EEXIST;
70ef5b941fSAndre Przywara 			goto fail;
71ef5b941fSAndre Przywara 		}
72ef5b941fSAndre Przywara 		if (errno == ECONNREFUSED) {
73ef5b941fSAndre Przywara 			/*
74ef5b941fSAndre Przywara 			 * This is a ghost socket file, with no-one listening
75ef5b941fSAndre Przywara 			 * on the other end. Since kvmtool will only bind
76ef5b941fSAndre Przywara 			 * above when creating a new guest, there is no
77ef5b941fSAndre Przywara 			 * danger in just removing the file and re-trying.
78ef5b941fSAndre Przywara 			 */
79ef5b941fSAndre Przywara 			unlink(full_name);
80ef5b941fSAndre Przywara 			pr_info("Removed ghost socket file \"%s\".", full_name);
81ef5b941fSAndre Przywara 			r = bind(s, (struct sockaddr *)&local, len);
82ef5b941fSAndre Przywara 		}
83ef5b941fSAndre 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 
kvm__remove_socket(const char * name)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 
kvm__get_sock_by_instance(const char * name)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 
is_socket(const char * base_path,const struct dirent * dent)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 
kvm__enumerate_instances(int (* callback)(const char * name,int fd))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 
kvm_ipc__register_handler(u32 type,void (* cb)(struct kvm * kvm,int fd,u32 type,u32 len,u8 * msg))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 
kvm_ipc__send(int fd,u32 type)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 
kvm_ipc__send_msg(int fd,u32 type,u32 len,u8 * msg)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 
kvm_ipc__handle(struct kvm * kvm,int fd,u32 type,u32 len,u8 * data)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 
kvm_ipc__new_conn(int fd)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;
271*d30d9487SJean-Philippe Brucker 	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 
kvm_ipc__close_conn(int fd)2794b1addaeSSasha Levin static void kvm_ipc__close_conn(int fd)
2804b1addaeSSasha Levin {
281*d30d9487SJean-Philippe Brucker 	epoll_ctl(epoll.fd, EPOLL_CTL_DEL, fd, NULL);
2824b1addaeSSasha Levin 	close(fd);
2834b1addaeSSasha Levin }
2844b1addaeSSasha Levin 
kvm_ipc__receive(struct kvm * kvm,int fd)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 
kvm_ipc__handle_event(struct kvm * kvm,struct epoll_event * ev)312*d30d9487SJean-Philippe Brucker static void kvm_ipc__handle_event(struct kvm *kvm, struct epoll_event *ev)
3134b1addaeSSasha Levin {
314*d30d9487SJean-Philippe Brucker 	int fd = ev->data.fd;
3154b1addaeSSasha Levin 
316*d30d9487SJean-Philippe Brucker 	if (fd == server_fd) {
3178e463c62SAsias He 		int client, r;
3184b1addaeSSasha Levin 
3194b1addaeSSasha Levin 		client = kvm_ipc__new_conn(fd);
3208e463c62SAsias He 		/*
3218e463c62SAsias He 		 * Handle multiple IPC cmd at a time
3228e463c62SAsias He 		 */
3238e463c62SAsias He 		do {
324e1063726SSasha Levin 			r = kvm_ipc__receive(kvm, client);
3258e463c62SAsias He 		} while	(r == 0);
3268e463c62SAsias He 
327*d30d9487SJean-Philippe Brucker 	} else if (ev->events & (EPOLLERR | EPOLLRDHUP | EPOLLHUP)) {
3284b1addaeSSasha Levin 		kvm_ipc__close_conn(fd);
3294b1addaeSSasha Levin 	} else {
330e1063726SSasha Levin 		kvm_ipc__receive(kvm, fd);
3314b1addaeSSasha Levin 	}
3324b1addaeSSasha Levin }
3334b1addaeSSasha Levin 
kvm__pid(struct kvm * kvm,int fd,u32 type,u32 len,u8 * msg)334e1063726SSasha Levin static void kvm__pid(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg)
335e1063726SSasha Levin {
336e1063726SSasha Levin 	pid_t pid = getpid();
337e1063726SSasha Levin 	int r = 0;
338e1063726SSasha Levin 
339e1063726SSasha Levin 	if (type == KVM_IPC_PID)
340e1063726SSasha Levin 		r = write(fd, &pid, sizeof(pid));
341e1063726SSasha Levin 
342e1063726SSasha Levin 	if (r < 0)
343e1063726SSasha Levin 		pr_warning("Failed sending PID");
344e1063726SSasha Levin }
345e1063726SSasha Levin 
handle_stop(struct kvm * kvm,int fd,u32 type,u32 len,u8 * msg)346e1063726SSasha Levin static void handle_stop(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg)
347e1063726SSasha Levin {
348e1063726SSasha Levin 	if (WARN_ON(type != KVM_IPC_STOP || len))
349e1063726SSasha Levin 		return;
350e1063726SSasha Levin 
3512aa76b26SWill Deacon 	kvm__reboot(kvm);
352e1063726SSasha Levin }
353e1063726SSasha Levin 
354e1063726SSasha Levin /* Pause/resume the guest using SIGUSR2 */
355e1063726SSasha Levin static int is_paused;
356e1063726SSasha Levin 
handle_pause(struct kvm * kvm,int fd,u32 type,u32 len,u8 * msg)357e1063726SSasha Levin static void handle_pause(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg)
358e1063726SSasha Levin {
359e1063726SSasha Levin 	if (WARN_ON(len))
360e1063726SSasha Levin 		return;
361e1063726SSasha Levin 
362e1063726SSasha Levin 	if (type == KVM_IPC_RESUME && is_paused) {
363e1063726SSasha Levin 		kvm->vm_state = KVM_VMSTATE_RUNNING;
3644346fd8fSSasha Levin 		kvm__continue(kvm);
365e1063726SSasha Levin 	} else if (type == KVM_IPC_PAUSE && !is_paused) {
366e1063726SSasha Levin 		kvm->vm_state = KVM_VMSTATE_PAUSED;
367e1063726SSasha Levin 		ioctl(kvm->vm_fd, KVM_KVMCLOCK_CTRL);
3684346fd8fSSasha Levin 		kvm__pause(kvm);
369e1063726SSasha Levin 	} else {
370e1063726SSasha Levin 		return;
371e1063726SSasha Levin 	}
372e1063726SSasha Levin 
373e1063726SSasha Levin 	is_paused = !is_paused;
374e1063726SSasha Levin }
375e1063726SSasha Levin 
handle_vmstate(struct kvm * kvm,int fd,u32 type,u32 len,u8 * msg)376e1063726SSasha Levin static void handle_vmstate(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg)
377e1063726SSasha Levin {
378e1063726SSasha Levin 	int r = 0;
379e1063726SSasha Levin 
380e1063726SSasha Levin 	if (type == KVM_IPC_VMSTATE)
381e1063726SSasha Levin 		r = write(fd, &kvm->vm_state, sizeof(kvm->vm_state));
382e1063726SSasha Levin 
383e1063726SSasha Levin 	if (r < 0)
384e1063726SSasha Levin 		pr_warning("Failed sending VMSTATE");
385e1063726SSasha Levin }
386e1063726SSasha Levin 
387e1063726SSasha Levin /*
388e1063726SSasha Levin  * Serialize debug printout so that the output of multiple vcpus does not
389e1063726SSasha Levin  * get mixed up:
390e1063726SSasha Levin  */
391e1063726SSasha Levin static int printout_done;
392e1063726SSasha Levin 
handle_sigusr1(int sig)393e1063726SSasha Levin static void handle_sigusr1(int sig)
394e1063726SSasha Levin {
395e1063726SSasha Levin 	struct kvm_cpu *cpu = current_kvm_cpu;
396e1063726SSasha Levin 	int fd = kvm_cpu__get_debug_fd();
397e1063726SSasha Levin 
398e1063726SSasha Levin 	if (!cpu || cpu->needs_nmi)
399e1063726SSasha Levin 		return;
400e1063726SSasha Levin 
401e1063726SSasha Levin 	dprintf(fd, "\n #\n # vCPU #%ld's dump:\n #\n", cpu->cpu_id);
402e1063726SSasha Levin 	kvm_cpu__show_registers(cpu);
403e1063726SSasha Levin 	kvm_cpu__show_code(cpu);
404e1063726SSasha Levin 	kvm_cpu__show_page_tables(cpu);
405e1063726SSasha Levin 	fflush(stdout);
406e1063726SSasha Levin 	printout_done = 1;
407e1063726SSasha Levin }
408e1063726SSasha Levin 
handle_debug(struct kvm * kvm,int fd,u32 type,u32 len,u8 * msg)409e1063726SSasha Levin static void handle_debug(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg)
410e1063726SSasha Levin {
411e1063726SSasha Levin 	int i;
412e1063726SSasha Levin 	struct debug_cmd_params *params;
413e1063726SSasha Levin 	u32 dbg_type;
414e1063726SSasha Levin 	u32 vcpu;
415e1063726SSasha Levin 
416e1063726SSasha Levin 	if (WARN_ON(type != KVM_IPC_DEBUG || len != sizeof(*params)))
417e1063726SSasha Levin 		return;
418e1063726SSasha Levin 
419e1063726SSasha Levin 	params = (void *)msg;
420e1063726SSasha Levin 	dbg_type = params->dbg_type;
421e1063726SSasha Levin 	vcpu = params->cpu;
422e1063726SSasha Levin 
423e1063726SSasha Levin 	if (dbg_type & KVM_DEBUG_CMD_TYPE_SYSRQ)
424e1063726SSasha Levin 		serial8250__inject_sysrq(kvm, params->sysrq);
425e1063726SSasha Levin 
426e1063726SSasha Levin 	if (dbg_type & KVM_DEBUG_CMD_TYPE_NMI) {
427e1063726SSasha Levin 		if ((int)vcpu >= kvm->nrcpus)
428e1063726SSasha Levin 			return;
429e1063726SSasha Levin 
430e1063726SSasha Levin 		kvm->cpus[vcpu]->needs_nmi = 1;
431e1063726SSasha Levin 		pthread_kill(kvm->cpus[vcpu]->thread, SIGUSR1);
432e1063726SSasha Levin 	}
433e1063726SSasha Levin 
434e1063726SSasha Levin 	if (!(dbg_type & KVM_DEBUG_CMD_TYPE_DUMP))
435e1063726SSasha Levin 		return;
436e1063726SSasha Levin 
437e1063726SSasha Levin 	for (i = 0; i < kvm->nrcpus; i++) {
438e1063726SSasha Levin 		struct kvm_cpu *cpu = kvm->cpus[i];
439e1063726SSasha Levin 
440e1063726SSasha Levin 		if (!cpu)
441e1063726SSasha Levin 			continue;
442e1063726SSasha Levin 
443e1063726SSasha Levin 		printout_done = 0;
444e1063726SSasha Levin 
445e1063726SSasha Levin 		kvm_cpu__set_debug_fd(fd);
446e1063726SSasha Levin 		pthread_kill(cpu->thread, SIGUSR1);
447e1063726SSasha Levin 		/*
448e1063726SSasha Levin 		 * Wait for the vCPU to dump state before signalling
449e1063726SSasha Levin 		 * the next thread. Since this is debug code it does
450e1063726SSasha Levin 		 * not matter that we are burning CPU time a bit:
451e1063726SSasha Levin 		 */
452e1063726SSasha Levin 		while (!printout_done)
453e1063726SSasha Levin 			sleep(0);
454e1063726SSasha Levin 	}
455e1063726SSasha Levin 
456e1063726SSasha Levin 	close(fd);
457e1063726SSasha Levin 
458e1063726SSasha Levin 	serial8250__inject_sysrq(kvm, 'p');
459e1063726SSasha Levin }
460e1063726SSasha Levin 
kvm_ipc__init(struct kvm * kvm)461e1063726SSasha Levin int kvm_ipc__init(struct kvm *kvm)
4624b1addaeSSasha Levin {
463e21e8ff3SYang Bai 	int ret;
464e1063726SSasha Levin 	int sock = kvm__create_socket(kvm);
46521b3c2c0SSasha Levin 	struct epoll_event ev = {0};
4664b1addaeSSasha Levin 
4674b1addaeSSasha Levin 	server_fd = sock;
4684b1addaeSSasha Levin 
469*d30d9487SJean-Philippe Brucker 	ret = epoll__init(kvm, &epoll, "kvm-ipc",
470*d30d9487SJean-Philippe Brucker 			  kvm_ipc__handle_event);
471*d30d9487SJean-Philippe Brucker 	if (ret) {
472*d30d9487SJean-Philippe Brucker 		pr_err("Failed starting IPC thread");
473e21e8ff3SYang Bai 		goto err;
474e21e8ff3SYang Bai 	}
4754b1addaeSSasha Levin 
47647f72b90SSasha Levin 	ev.events = EPOLLIN | EPOLLET;
4774b1addaeSSasha Levin 	ev.data.fd = sock;
478*d30d9487SJean-Philippe Brucker 	if (epoll_ctl(epoll.fd, EPOLL_CTL_ADD, sock, &ev) < 0) {
479211370d6SMichael Ellerman 		pr_err("Failed adding socket to epoll");
480e21e8ff3SYang Bai 		ret = -EFAULT;
481e21e8ff3SYang Bai 		goto err_epoll;
482e21e8ff3SYang Bai 	}
4834b1addaeSSasha Levin 
484e1063726SSasha Levin 	kvm_ipc__register_handler(KVM_IPC_PID, kvm__pid);
485e1063726SSasha Levin 	kvm_ipc__register_handler(KVM_IPC_DEBUG, handle_debug);
486e1063726SSasha Levin 	kvm_ipc__register_handler(KVM_IPC_PAUSE, handle_pause);
487e1063726SSasha Levin 	kvm_ipc__register_handler(KVM_IPC_RESUME, handle_pause);
488e1063726SSasha Levin 	kvm_ipc__register_handler(KVM_IPC_STOP, handle_stop);
489e1063726SSasha Levin 	kvm_ipc__register_handler(KVM_IPC_VMSTATE, handle_vmstate);
490e1063726SSasha Levin 	signal(SIGUSR1, handle_sigusr1);
491e1063726SSasha Levin 
4924b1addaeSSasha Levin 	return 0;
493e21e8ff3SYang Bai 
494e21e8ff3SYang Bai err_epoll:
495*d30d9487SJean-Philippe Brucker 	epoll__exit(&epoll);
496*d30d9487SJean-Philippe Brucker 	close(server_fd);
497e21e8ff3SYang Bai err:
498e21e8ff3SYang Bai 	return ret;
4994b1addaeSSasha Levin }
50049a8afd1SSasha Levin base_init(kvm_ipc__init);
501c733c80bSSasha Levin 
kvm_ipc__exit(struct kvm * kvm)502e1063726SSasha Levin int kvm_ipc__exit(struct kvm *kvm)
503c733c80bSSasha Levin {
504*d30d9487SJean-Philippe Brucker 	epoll__exit(&epoll);
505c733c80bSSasha Levin 	close(server_fd);
506c733c80bSSasha Levin 
507e1063726SSasha Levin 	kvm__remove_socket(kvm->cfg.guest_name);
508e1063726SSasha Levin 
509*d30d9487SJean-Philippe Brucker 	return 0;
510c733c80bSSasha Levin }
51149a8afd1SSasha Levin base_exit(kvm_ipc__exit);
512