[RFC PATCH kvmtool 6/7] Introduce kvm_create_thread()

Alexandru Elisei alexandru.elisei at arm.com
Thu Sep 17 08:49:31 PDT 2026


Switch over all pthread_create() invocations to kvm_create_thread(). Also
add error checking where it was missing.

Signed-off-by: Alexandru Elisei <alexandru.elisei at arm.com>
---
 disk/aio.c               |  3 +--
 disk/blk.c               | 12 +++++++++--
 disk/core.c              | 29 +++++++++++++-------------
 disk/qcow.c              | 44 ++++++++++++++++++++++++++++------------
 disk/raw.c               | 21 +++++++++++++++----
 epoll.c                  |  2 +-
 include/kvm/disk-image.h | 28 +++++++++++++++++--------
 include/kvm/qcow.h       |  3 ++-
 include/kvm/uip.h        |  2 ++
 include/kvm/util.h       |  2 ++
 net/uip/tcp.c            |  7 +++----
 net/uip/udp.c            |  5 +++--
 term.c                   |  4 ++--
 ui/gtk3.c                |  2 +-
 ui/sdl.c                 |  2 +-
 ui/vnc.c                 |  2 +-
 util/threadpool.c        |  9 ++++----
 util/util.c              | 12 +++++++++++
 virtio/blk.c             |  2 +-
 virtio/net.c             | 26 ++++++++++++++++--------
 20 files changed, 146 insertions(+), 71 deletions(-)

diff --git a/disk/aio.c b/disk/aio.c
index a7418c8c261d..365f075272dd 100644
--- a/disk/aio.c
+++ b/disk/aio.c
@@ -127,9 +127,8 @@ int disk_aio_setup(struct disk_image *disk)
 		return -errno;
 
 	io_setup(AIO_MAX, &disk->ctx);
-	r = pthread_create(&disk->thread, NULL, disk_aio_thread, disk);
+	r = kvm_create_thread(disk->kvm, &disk->thread, disk_aio_thread, disk);
 	if (r) {
-		r = -errno;
 		close(disk->evt);
 		return r;
 	}
diff --git a/disk/blk.c b/disk/blk.c
index b4c9fba3bcec..82e1937a1906 100644
--- a/disk/blk.c
+++ b/disk/blk.c
@@ -35,8 +35,14 @@ static bool is_mounted(struct stat *st)
 	return false;
 }
 
-struct disk_image *blkdev__probe(const char *filename, int flags, struct stat *st)
+struct disk_image *blkdev__probe(const char *filename, int flags, struct stat *st,
+				 struct kvm *kvm)
 {
+	struct new_disk_image ndi = {
+		.ops	= &blk_dev_ops,
+		.kvm	= kvm,
+		.flags	= DISK_IMAGE_REGULAR,
+	};
 	int fd, r;
 	u64 size;
 
@@ -56,17 +62,19 @@ struct disk_image *blkdev__probe(const char *filename, int flags, struct stat *s
 	fd = open(filename, flags);
 	if (fd < 0)
 		return ERR_PTR(fd);
+	ndi.fd = fd;
 
 	if (ioctl(fd, BLKGETSIZE64, &size) < 0) {
 		r = -errno;
 		close(fd);
 		return ERR_PTR(r);
 	}
+	ndi.size = size;
 
 	/*
 	 * FIXME: This will not work on 32-bit host because we can not
 	 * mmap large disk. There is not enough virtual address space
 	 * in 32-bit host. However, this works on 64-bit host.
 	 */
-	return disk_image__new(fd, size, &blk_dev_ops, DISK_IMAGE_REGULAR);
+	return disk_image__new(&ndi);
 }
diff --git a/disk/core.c b/disk/core.c
index b232eece9e73..5a1692fc7951 100644
--- a/disk/core.c
+++ b/disk/core.c
@@ -59,9 +59,7 @@ int disk_img_name_parser(const struct option *opt, const char *arg, int unset)
 	return 0;
 }
 
-struct disk_image *disk_image__new(int fd, u64 size,
-				   struct disk_image_operations *ops,
-				   int use_mmap)
+struct disk_image *disk_image__new(struct new_disk_image *ndi)
 {
 	struct disk_image *disk;
 	int r;
@@ -71,16 +69,18 @@ struct disk_image *disk_image__new(int fd, u64 size,
 		return ERR_PTR(-ENOMEM);
 
 	*disk = (struct disk_image) {
-		.fd	= fd,
-		.size	= size,
-		.ops	= ops,
+		.fd	= ndi->fd,
+		.size	= ndi->size,
+		.ops	= ndi->ops,
+		.kvm	= ndi->kvm,
 	};
 
-	if (use_mmap == DISK_IMAGE_MMAP) {
+	if (ndi->flags == DISK_IMAGE_MMAP) {
 		/*
 		 * The write to disk image will be discarded
 		 */
-		disk->priv = mmap(NULL, size, PROT_RW, MAP_PRIVATE | MAP_NORESERVE, fd, 0);
+		disk->priv = mmap(NULL, ndi->size, PROT_RW,
+				  MAP_PRIVATE | MAP_NORESERVE, ndi->fd, 0);
 		if (disk->priv == MAP_FAILED) {
 			r = -errno;
 			goto err_free_disk;
@@ -95,13 +95,14 @@ struct disk_image *disk_image__new(int fd, u64 size,
 
 err_unmap_disk:
 	if (disk->priv)
-		munmap(disk->priv, size);
+		munmap(disk->priv, ndi->size);
 err_free_disk:
 	free(disk);
 	return ERR_PTR(r);
 }
 
-static struct disk_image *disk_image__open(const char *filename, bool readonly, bool direct)
+static struct disk_image *disk_image__open(const char *filename, bool readonly, bool direct,
+					   struct kvm *kvm)
 {
 	struct disk_image *disk;
 	struct stat st;
@@ -118,7 +119,7 @@ static struct disk_image *disk_image__open(const char *filename, bool readonly,
 		return ERR_PTR(-errno);
 
 	/* blk device ?*/
-	disk = blkdev__probe(filename, flags, &st);
+	disk = blkdev__probe(filename, flags, &st, kvm);
 	if (!IS_ERR_OR_NULL(disk)) {
 		disk->readonly = readonly;
 		return disk;
@@ -129,7 +130,7 @@ static struct disk_image *disk_image__open(const char *filename, bool readonly,
 		return ERR_PTR(fd);
 
 	/* qcow image ?*/
-	disk = qcow_probe(fd, true);
+	disk = qcow_probe(fd, true, kvm);
 	if (!IS_ERR_OR_NULL(disk)) {
 		pr_warning("Forcing read-only support for QCOW");
 		disk->readonly = true;
@@ -137,7 +138,7 @@ static struct disk_image *disk_image__open(const char *filename, bool readonly,
 	}
 
 	/* raw image ?*/
-	disk = raw_image__probe(fd, &st, readonly);
+	disk = raw_image__probe(fd, &st, readonly, kvm);
 	if (!IS_ERR_OR_NULL(disk)) {
 		disk->readonly = readonly;
 		return disk;
@@ -188,7 +189,7 @@ static struct disk_image **disk_image__open_all(struct kvm *kvm)
 		if (!filename)
 			continue;
 
-		disks[i] = disk_image__open(filename, readonly, direct);
+		disks[i] = disk_image__open(filename, readonly, direct, kvm);
 		if (IS_ERR_OR_NULL(disks[i])) {
 			pr_err("Loading disk image '%s' failed", filename);
 			err = disks[i];
diff --git a/disk/qcow.c b/disk/qcow.c
index dd6be62ee183..eed18bb169bb 100644
--- a/disk/qcow.c
+++ b/disk/qcow.c
@@ -1273,8 +1273,13 @@ static void *qcow2_read_header(int fd)
 	return header;
 }
 
-static struct disk_image *qcow2_probe(int fd, bool readonly)
+static struct disk_image *qcow2_probe(int fd, bool readonly, struct kvm *kvm)
 {
+	struct new_disk_image ndi = {
+		.kvm	= kvm,
+		.fd	= fd,
+		.flags	= DISK_IMAGE_REGULAR,
+	};
 	struct disk_image *disk_image;
 	struct qcow_l1_table *l1t;
 	struct qcow_header *h;
@@ -1295,6 +1300,7 @@ static struct disk_image *qcow2_probe(int fd, bool readonly)
 	h = q->header = qcow2_read_header(fd);
 	if (!h)
 		goto free_qcow;
+	ndi.size = h->size;
 
 	q->version = QCOW2_VERSION;
 	q->csize_shift = (62 - (q->header->cluster_bits - 8));
@@ -1329,10 +1335,13 @@ static struct disk_image *qcow2_probe(int fd, bool readonly)
 	/*
 	 * Do not use mmap use read/write instead
 	 */
-	if (readonly)
-		disk_image = disk_image__new(fd, h->size, &qcow_disk_readonly_ops, DISK_IMAGE_REGULAR);
-	else
-		disk_image = disk_image__new(fd, h->size, &qcow_disk_ops, DISK_IMAGE_REGULAR);
+	if (readonly) {
+		ndi.ops = &qcow_disk_readonly_ops;
+		disk_image = disk_image__new(&ndi);
+	} else {
+		ndi.ops = &qcow_disk_ops;
+		disk_image = disk_image__new(&ndi);
+	}
 
 	if (IS_ERR_OR_NULL(disk_image))
 		goto free_refcount_table;
@@ -1418,8 +1427,13 @@ static void *qcow1_read_header(int fd)
 	return header;
 }
 
-static struct disk_image *qcow1_probe(int fd, bool readonly)
+static struct disk_image *qcow1_probe(int fd, bool readonly, struct kvm *kvm)
 {
+	struct new_disk_image ndi = {
+		.kvm	= kvm,
+		.fd	= fd,
+		.flags	= DISK_IMAGE_REGULAR,
+	};
 	struct disk_image *disk_image;
 	struct qcow_l1_table *l1t;
 	struct qcow_header *h;
@@ -1441,6 +1455,7 @@ static struct disk_image *qcow1_probe(int fd, bool readonly)
 	h = q->header = qcow1_read_header(fd);
 	if (!h)
 		goto free_qcow;
+	ndi.size = h->size;
 
 	q->version = QCOW1_VERSION;
 	q->cluster_size = 1 << q->header->cluster_bits;
@@ -1465,10 +1480,13 @@ static struct disk_image *qcow1_probe(int fd, bool readonly)
 	/*
 	 * Do not use mmap use read/write instead
 	 */
-	if (readonly)
-		disk_image = disk_image__new(fd, h->size, &qcow_disk_readonly_ops, DISK_IMAGE_REGULAR);
-	else
-		disk_image = disk_image__new(fd, h->size, &qcow_disk_ops, DISK_IMAGE_REGULAR);
+	if (readonly) {
+		ndi.ops = &qcow_disk_readonly_ops;
+		disk_image = disk_image__new(&ndi);
+	} else {
+		ndi.ops = &qcow_disk_ops;
+		disk_image = disk_image__new(&ndi);
+	}
 
 	if (!disk_image)
 		goto free_l1_table;
@@ -1514,13 +1532,13 @@ static bool qcow1_check_image(int fd)
 	return true;
 }
 
-struct disk_image *qcow_probe(int fd, bool readonly)
+struct disk_image *qcow_probe(int fd, bool readonly, struct kvm *kvm)
 {
 	if (qcow1_check_image(fd))
-		return qcow1_probe(fd, readonly);
+		return qcow1_probe(fd, readonly, kvm);
 
 	if (qcow2_check_image(fd))
-		return qcow2_probe(fd, readonly);
+		return qcow2_probe(fd, readonly, kvm);
 
 	return NULL;
 }
diff --git a/disk/raw.c b/disk/raw.c
index 54b4e7408661..9ad09d20db12 100644
--- a/disk/raw.c
+++ b/disk/raw.c
@@ -83,8 +83,14 @@ struct disk_image_operations ro_ops_nowrite = {
 	.async	= true,
 };
 
-struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly)
+struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly,
+				    struct kvm *kvm)
 {
+	struct new_disk_image new = {
+		.kvm	= kvm,
+		.size	= st->st_size,
+		.fd	= fd,
+	};
 	if (readonly) {
 		/*
 		 * Use mmap's MAP_PRIVATE to implement non-persistent write
@@ -92,16 +98,23 @@ struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly)
 		 */
 		struct disk_image *disk;
 
-		disk = disk_image__new(fd, st->st_size, &ro_ops, DISK_IMAGE_MMAP);
+		new.ops = &ro_ops;
+		new.flags = DISK_IMAGE_MMAP;
+		disk = disk_image__new(&new);
+
 		if (IS_ERR_OR_NULL(disk)) {
-			disk = disk_image__new(fd, st->st_size, &ro_ops_nowrite, DISK_IMAGE_REGULAR);
+			new.ops = &ro_ops_nowrite;
+			new.flags = DISK_IMAGE_REGULAR;
+			disk = disk_image__new(&new);
 		}
 
 		return disk;
 	} else {
+		new.ops = &raw_image_regular_ops;
+		new.flags = DISK_IMAGE_REGULAR;
 		/*
 		 * Use read/write instead of mmap
 		 */
-		return disk_image__new(fd, st->st_size, &raw_image_regular_ops, DISK_IMAGE_REGULAR);
+		return disk_image__new(&new);
 	}
 }
diff --git a/epoll.c b/epoll.c
index 8cb0cee5822e..0ddd235d89a8 100644
--- a/epoll.c
+++ b/epoll.c
@@ -58,7 +58,7 @@ int epoll__init(struct kvm *kvm, struct kvm__epoll *epoll,
 	if (r < 0)
 		goto err_close_all;
 
-	r = pthread_create(&epoll->thread, NULL, epoll__thread, epoll);
+	r = kvm_create_thread(kvm, &epoll->thread, epoll__thread, epoll);
 	if (r < 0)
 		goto err_close_all;
 
diff --git a/include/kvm/disk-image.h b/include/kvm/disk-image.h
index cbe91b07af0b..f1c61f0403e3 100644
--- a/include/kvm/disk-image.h
+++ b/include/kvm/disk-image.h
@@ -26,11 +26,6 @@
 #define SECTOR_SHIFT		9
 #define SECTOR_SIZE		(1UL << SECTOR_SHIFT)
 
-enum {
-	DISK_IMAGE_REGULAR,
-	DISK_IMAGE_MMAP,
-};
-
 #define MAX_DISK_IMAGES         4
 
 struct disk_image;
@@ -54,6 +49,20 @@ struct disk_image_params {
 	bool direct;
 };
 
+enum new_disk_image_flags {
+	DISK_IMAGE_REGULAR,
+	DISK_IMAGE_MMAP,
+};
+
+struct kvm;
+struct new_disk_image {
+	struct disk_image_operations	*ops;
+	struct kvm			*kvm;
+	u64				size;
+	int				fd;
+	enum new_disk_image_flags	flags;
+};
+
 struct disk_image {
 	int				fd;
 	u64				size;
@@ -61,6 +70,7 @@ struct disk_image {
 	void				*priv;
 	void				*disk_req_cb_param;
 	void				(*disk_req_cb)(void *param, long len);
+	struct kvm			*kvm;
 	bool				readonly;
 	bool				async;
 #ifdef CONFIG_HAS_AIO
@@ -76,7 +86,7 @@ struct disk_image {
 int disk_img_name_parser(const struct option *opt, const char *arg, int unset);
 int disk_image__init(struct kvm *kvm);
 int disk_image__exit(struct kvm *kvm);
-struct disk_image *disk_image__new(int fd, u64 size, struct disk_image_operations *ops, int mmap);
+struct disk_image *disk_image__new(struct new_disk_image *ndi);
 int disk_image__flush(struct disk_image *disk);
 int disk_image__wait(struct disk_image *disk);
 ssize_t disk_image__read(struct disk_image *disk, u64 sector, const struct iovec *iov,
@@ -86,8 +96,10 @@ ssize_t disk_image__write(struct disk_image *disk, u64 sector, const struct iove
 ssize_t disk_image__get_serial(struct disk_image *disk, struct iovec *iov,
 			       int iovcount, ssize_t len);
 
-struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly);
-struct disk_image *blkdev__probe(const char *filename, int flags, struct stat *st);
+struct disk_image *raw_image__probe(int fd, struct stat *st, bool readonly,
+				    struct kvm *kvm);
+struct disk_image *blkdev__probe(const char *filename, int flags, struct stat *st,
+				 struct kvm *kvm);
 
 ssize_t raw_image__read_sync(struct disk_image *disk, u64 sector,
 			     const struct iovec *iov, int iovcount, void *param);
diff --git a/include/kvm/qcow.h b/include/kvm/qcow.h
index f8492462ddaa..c0293ef8bf75 100644
--- a/include/kvm/qcow.h
+++ b/include/kvm/qcow.h
@@ -128,6 +128,7 @@ struct qcow2_header_disk {
 	u64				snapshots_offset;
 };
 
-struct disk_image *qcow_probe(int fd, bool readonly);
+struct kvm;
+struct disk_image *qcow_probe(int fd, bool readonly, struct kvm *kvm);
 
 #endif /* KVM__QCOW_H */
diff --git a/include/kvm/uip.h b/include/kvm/uip.h
index efa508a50f51..39db4b656fd5 100644
--- a/include/kvm/uip.h
+++ b/include/kvm/uip.h
@@ -184,6 +184,7 @@ struct uip_dhcp {
 	u8 option[UIP_DHCP_OPTION_LEN];
 } __attribute__((packed));
 
+struct kvm;
 struct uip_info {
 	struct list_head udp_socket_head;
 	struct list_head tcp_socket_head;
@@ -196,6 +197,7 @@ struct uip_info {
 	struct list_head buf_head;
 	struct mutex buf_lock;
 	pthread_t udp_thread;
+	struct kvm *kvm;
 	u8 *udp_buf;
 	int udp_epollfd;
 	int buf_free_nr;
diff --git a/include/kvm/util.h b/include/kvm/util.h
index 0f5a4bba5714..86edb77edfce 100644
--- a/include/kvm/util.h
+++ b/include/kvm/util.h
@@ -151,6 +151,8 @@ void *mmap_hugetlbfs(struct kvm *kvm, const char *htlbfs_path, u64 size);
 void *mmap_anon_or_hugetlbfs(struct kvm *kvm, const char *hugetlbfs_path, u64 size);
 void *mmap_guest_memfd(struct kvm *kvm, u64 size);
 
+int kvm_create_thread(struct kvm *kvm, pthread_t *thread,
+		      void *(*start_routine)(void *), void *arg);
 int kvm_create_vcpu_thread(struct kvm *kvm, pthread_t *thread,
 			   void *(*start_routine)(void *), void *arg);
 
diff --git a/net/uip/tcp.c b/net/uip/tcp.c
index 42e6e992cd6a..54252016ac02 100644
--- a/net/uip/tcp.c
+++ b/net/uip/tcp.c
@@ -253,7 +253,7 @@ out:
 	return NULL;
 }
 
-static int uip_tcp_socket_receive(struct uip_tcp_socket *sk)
+static int uip_tcp_socket_receive(struct uip_tcp_socket *sk, struct kvm *kvm)
 {
 	int ret;
 
@@ -261,8 +261,7 @@ static int uip_tcp_socket_receive(struct uip_tcp_socket *sk)
 		sk->buf = malloc(UIP_MAX_TCP_PAYLOAD);
 		if (!sk->buf)
 			return -ENOMEM;
-		ret = pthread_create(&sk->thread, NULL, uip_tcp_socket_thread,
-				     (void *)sk);
+		ret = kvm_create_thread(kvm, &sk->thread, uip_tcp_socket_thread, sk);
 		if (ret)
 			free(sk->buf);
 		return ret;
@@ -324,7 +323,7 @@ int uip_tx_do_ipv4_tcp(struct uip_tx_arg *arg)
 		/*
 		 * Start receive thread for data from remote to guest
 		 */
-		uip_tcp_socket_receive(sk);
+		uip_tcp_socket_receive(sk, arg->info->kvm);
 
 		goto out;
 	}
diff --git a/net/uip/udp.c b/net/uip/udp.c
index d2580d06e851..e63c8ad97c63 100644
--- a/net/uip/udp.c
+++ b/net/uip/udp.c
@@ -238,10 +238,11 @@ int uip_tx_do_ipv4_udp(struct uip_tx_arg *arg)
 		if (!info->udp_buf)
 			return -1;
 
-		pthread_create(&info->udp_thread, NULL, uip_udp_socket_thread, (void *)info);
+		ret = kvm_create_thread(info->kvm, &info->udp_thread,
+					uip_udp_socket_thread, info);
 	}
 
-	return 0;
+	return ret;
 }
 
 void uip_udp_exit(struct uip_info *info)
diff --git a/term.c b/term.c
index b8a70fe2ab7b..e1b31737e0f7 100644
--- a/term.c
+++ b/term.c
@@ -196,8 +196,8 @@ static int term_init(struct kvm *kvm)
 
 
 	/* Use our own blocking thread to read stdin, don't require a tick */
-	if(pthread_create(&term_poll_thread, NULL, term_poll_thread_loop,kvm))
-		die("Unable to create console input poll thread\n");
+	if (kvm_create_thread(kvm, &term_poll_thread, term_poll_thread_loop, kvm))
+		die_perror("Unable to create console input poll thread");
 
 	signal(SIGTERM, term_sig_cleanup);
 	atexit(term_cleanup);
diff --git a/ui/gtk3.c b/ui/gtk3.c
index 1e08a8f6b76a..b6f3a3000b01 100644
--- a/ui/gtk3.c
+++ b/ui/gtk3.c
@@ -277,7 +277,7 @@ static int kvm_gtk_start(struct framebuffer *fb)
 {
 	pthread_t thread;
 
-	if (pthread_create(&thread, NULL, kvm_gtk_thread, fb) != 0)
+	if (kvm_create_thread(fb->kvm, &thread, kvm_gtk_thread, fb) != 0)
 		return -1;
 
 	return 0;
diff --git a/ui/sdl.c b/ui/sdl.c
index 5035405bb488..2014ec5bcfe9 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -277,7 +277,7 @@ static int sdl__start(struct framebuffer *fb)
 
 	running = true;
 
-	if (pthread_create(&thread, NULL, sdl__thread, fb) != 0)
+	if (kvm_create_thread(fb->kvm, &thread, sdl__thread, fb) != 0)
 		return -1;
 
 	return 0;
diff --git a/ui/vnc.c b/ui/vnc.c
index 12e4bd53fe0d..8371b3cc9f8c 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -205,7 +205,7 @@ static int vnc__start(struct framebuffer *fb)
 {
 	pthread_t thread;
 
-	if (pthread_create(&thread, NULL, vnc__thread, fb) != 0)
+	if (kvm_create_thread(fb->kvm, &thread, vnc__thread, fb) != 0)
 		return -1;
 
 	return 0;
diff --git a/util/threadpool.c b/util/threadpool.c
index 1dc3bf7e7ef2..05722b5c09a4 100644
--- a/util/threadpool.c
+++ b/util/threadpool.c
@@ -97,7 +97,7 @@ static void *thread_pool__threadfunc(void *param)
 	return NULL;
 }
 
-static int thread_pool__addthread(void)
+static int thread_pool__addthread(struct kvm *kvm)
 {
 	int res;
 	void *newthreads;
@@ -111,9 +111,8 @@ static int thread_pool__addthread(void)
 
 	threads = newthreads;
 
-	res = pthread_create(threads + threadcount, NULL,
-			     thread_pool__threadfunc, NULL);
-
+	res = kvm_create_thread(kvm, threads + threadcount,
+				thread_pool__threadfunc, NULL);
 	if (res == 0)
 		threadcount++;
 	mutex_unlock(&thread_mutex);
@@ -129,7 +128,7 @@ int thread_pool__init(struct kvm *kvm)
 	running = true;
 
 	for (i = 0; i < thread_count; i++)
-		if (thread_pool__addthread() < 0)
+		if (thread_pool__addthread(kvm) < 0)
 			return i;
 
 	return i;
diff --git a/util/util.c b/util/util.c
index ff888bf9e061..7238fe57bace 100644
--- a/util/util.c
+++ b/util/util.c
@@ -207,6 +207,18 @@ void *mmap_guest_memfd(struct kvm *kvm, u64 size)
 	return addr;
 }
 
+int kvm_create_thread(struct kvm *kvm, pthread_t *thread,
+		      void *(*start_routine)(void *), void *arg)
+{
+	int ret;
+
+	ret = pthread_create(thread, NULL, start_routine, arg);
+	if (ret)
+		errno = ret;
+
+	return -ret;
+}
+
 int kvm_create_vcpu_thread(struct kvm *kvm, pthread_t *thread,
 			   void *(*start_routine)(void *), void *arg)
 {
diff --git a/virtio/blk.c b/virtio/blk.c
index b2d6180d118a..0ffafff1663b 100644
--- a/virtio/blk.c
+++ b/virtio/blk.c
@@ -237,7 +237,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq)
 	if (bdev->io_efd < 0)
 		return -errno;
 
-	if (pthread_create(&bdev->io_thread, NULL, virtio_blk_thread, bdev))
+	if (kvm_create_thread(kvm, &bdev->io_thread, virtio_blk_thread, bdev))
 		return -errno;
 
 	return 0;
diff --git a/virtio/net.c b/virtio/net.c
index 492c57675b1f..097bc32fc12b 100644
--- a/virtio/net.c
+++ b/virtio/net.c
@@ -610,17 +610,23 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq)
 	mutex_init(&net_queue->lock);
 	pthread_cond_init(&net_queue->cond, NULL);
 	if (is_ctrl_vq(ndev, vq)) {
-		pthread_create(&net_queue->thread, NULL, virtio_net_ctrl_thread,
-			       net_queue);
-
+		r = kvm_create_thread(kvm, &net_queue->thread,
+				      virtio_net_ctrl_thread, net_queue);
+		if (r)
+			die_perror("virtio_net_ctrl_thread");
 		return 0;
 	} else if (ndev->vhost_fd == 0 ) {
-		if (vq & 1)
-			pthread_create(&net_queue->thread, NULL,
-				       virtio_net_tx_thread, net_queue);
-		else
-			pthread_create(&net_queue->thread, NULL,
-				       virtio_net_rx_thread, net_queue);
+		if (vq & 1) {
+			r = kvm_create_thread(kvm, &net_queue->thread,
+					      virtio_net_tx_thread, net_queue);
+			if (r)
+				die_perror("virtio_net_tx_thread");
+		} else {
+			r = kvm_create_thread(kvm, &net_queue->thread,
+					      virtio_net_rx_thread, net_queue);
+			if (r)
+				die_perror("virtio_net_rx_thread");
+		}
 
 		return 0;
 	}
@@ -870,6 +876,8 @@ static int virtio_net__init_one(struct virtio_net_params *params)
 	mutex_init(&ndev->mutex);
 	ndev->queue_pairs = max(1, min(VIRTIO_NET_NUM_QUEUES, params->mq));
 
+	ndev->info.kvm = params->kvm;
+
 	for (i = 0 ; i < 6 ; i++) {
 		ndev->config.mac[i]		= params->guest_mac[i];
 		ndev->info.guest_mac.addr[i]	= params->guest_mac[i];
-- 
2.55.0




More information about the linux-arm-kernel mailing list