xref: /dpdk/lib/eal/linux/eal_vfio_mp_sync.c (revision ae67895b507bb6af22263c79ba0d5c374b396485)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2010-2018 Intel Corporation
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
572b452c5SDmitry Kozlyuk #include <errno.h>
699a2dd95SBruce Richardson #include <unistd.h>
799a2dd95SBruce Richardson #include <string.h>
899a2dd95SBruce Richardson 
999a2dd95SBruce Richardson #include <rte_errno.h>
1099a2dd95SBruce Richardson #include <rte_log.h>
1199a2dd95SBruce Richardson #include <rte_vfio.h>
1299a2dd95SBruce Richardson #include <rte_eal.h>
1399a2dd95SBruce Richardson 
14*ae67895bSDavid Marchand #include "eal_private.h"
1599a2dd95SBruce Richardson #include "eal_vfio.h"
1699a2dd95SBruce Richardson 
1799a2dd95SBruce Richardson /**
1899a2dd95SBruce Richardson  * @file
1999a2dd95SBruce Richardson  * VFIO socket for communication between primary and secondary processes.
2099a2dd95SBruce Richardson  *
2199a2dd95SBruce Richardson  * This file is only compiled if RTE_EAL_VFIO is set.
2299a2dd95SBruce Richardson  */
2399a2dd95SBruce Richardson 
2499a2dd95SBruce Richardson #ifdef VFIO_PRESENT
2599a2dd95SBruce Richardson 
2699a2dd95SBruce Richardson static int
vfio_mp_primary(const struct rte_mp_msg * msg,const void * peer)2799a2dd95SBruce Richardson vfio_mp_primary(const struct rte_mp_msg *msg, const void *peer)
2899a2dd95SBruce Richardson {
2999a2dd95SBruce Richardson 	int fd = -1;
3099a2dd95SBruce Richardson 	int ret;
3199a2dd95SBruce Richardson 	struct rte_mp_msg reply;
3299a2dd95SBruce Richardson 	struct vfio_mp_param *r = (struct vfio_mp_param *)reply.param;
3399a2dd95SBruce Richardson 	const struct vfio_mp_param *m =
3499a2dd95SBruce Richardson 		(const struct vfio_mp_param *)msg->param;
3599a2dd95SBruce Richardson 
3699a2dd95SBruce Richardson 	if (msg->len_param != sizeof(*m)) {
37*ae67895bSDavid Marchand 		EAL_LOG(ERR, "vfio received invalid message!");
3899a2dd95SBruce Richardson 		return -1;
3999a2dd95SBruce Richardson 	}
4099a2dd95SBruce Richardson 
4199a2dd95SBruce Richardson 	memset(&reply, 0, sizeof(reply));
4299a2dd95SBruce Richardson 
4399a2dd95SBruce Richardson 	switch (m->req) {
4499a2dd95SBruce Richardson 	case SOCKET_REQ_GROUP:
4599a2dd95SBruce Richardson 		r->req = SOCKET_REQ_GROUP;
4699a2dd95SBruce Richardson 		r->group_num = m->group_num;
4799a2dd95SBruce Richardson 		fd = rte_vfio_get_group_fd(m->group_num);
4899a2dd95SBruce Richardson 		if (fd < 0 && fd != -ENOENT)
4999a2dd95SBruce Richardson 			r->result = SOCKET_ERR;
5099a2dd95SBruce Richardson 		else if (fd == -ENOENT)
5199a2dd95SBruce Richardson 			/* if VFIO group exists but isn't bound to VFIO driver */
5299a2dd95SBruce Richardson 			r->result = SOCKET_NO_FD;
5399a2dd95SBruce Richardson 		else {
5499a2dd95SBruce Richardson 			/* if group exists and is bound to VFIO driver */
5599a2dd95SBruce Richardson 			r->result = SOCKET_OK;
5699a2dd95SBruce Richardson 			reply.num_fds = 1;
5799a2dd95SBruce Richardson 			reply.fds[0] = fd;
5899a2dd95SBruce Richardson 		}
5999a2dd95SBruce Richardson 		break;
6099a2dd95SBruce Richardson 	case SOCKET_REQ_CONTAINER:
6199a2dd95SBruce Richardson 		r->req = SOCKET_REQ_CONTAINER;
6299a2dd95SBruce Richardson 		fd = rte_vfio_get_container_fd();
6399a2dd95SBruce Richardson 		if (fd < 0)
6499a2dd95SBruce Richardson 			r->result = SOCKET_ERR;
6599a2dd95SBruce Richardson 		else {
6699a2dd95SBruce Richardson 			r->result = SOCKET_OK;
6799a2dd95SBruce Richardson 			reply.num_fds = 1;
6899a2dd95SBruce Richardson 			reply.fds[0] = fd;
6999a2dd95SBruce Richardson 		}
7099a2dd95SBruce Richardson 		break;
7199a2dd95SBruce Richardson 	case SOCKET_REQ_DEFAULT_CONTAINER:
7299a2dd95SBruce Richardson 		r->req = SOCKET_REQ_DEFAULT_CONTAINER;
7399a2dd95SBruce Richardson 		fd = vfio_get_default_container_fd();
7499a2dd95SBruce Richardson 		if (fd < 0)
7599a2dd95SBruce Richardson 			r->result = SOCKET_ERR;
7699a2dd95SBruce Richardson 		else {
7799a2dd95SBruce Richardson 			r->result = SOCKET_OK;
7899a2dd95SBruce Richardson 			reply.num_fds = 1;
7999a2dd95SBruce Richardson 			reply.fds[0] = fd;
8099a2dd95SBruce Richardson 		}
8199a2dd95SBruce Richardson 		break;
8299a2dd95SBruce Richardson 	case SOCKET_REQ_IOMMU_TYPE:
8399a2dd95SBruce Richardson 	{
8499a2dd95SBruce Richardson 		int iommu_type_id;
8599a2dd95SBruce Richardson 
8699a2dd95SBruce Richardson 		r->req = SOCKET_REQ_IOMMU_TYPE;
8799a2dd95SBruce Richardson 
8899a2dd95SBruce Richardson 		iommu_type_id = vfio_get_iommu_type();
8999a2dd95SBruce Richardson 
9099a2dd95SBruce Richardson 		if (iommu_type_id < 0)
9199a2dd95SBruce Richardson 			r->result = SOCKET_ERR;
9299a2dd95SBruce Richardson 		else {
9399a2dd95SBruce Richardson 			r->iommu_type_id = iommu_type_id;
9499a2dd95SBruce Richardson 			r->result = SOCKET_OK;
9599a2dd95SBruce Richardson 		}
9699a2dd95SBruce Richardson 		break;
9799a2dd95SBruce Richardson 	}
9899a2dd95SBruce Richardson 	default:
99*ae67895bSDavid Marchand 		EAL_LOG(ERR, "vfio received invalid message!");
10099a2dd95SBruce Richardson 		return -1;
10199a2dd95SBruce Richardson 	}
10299a2dd95SBruce Richardson 
10399a2dd95SBruce Richardson 	strcpy(reply.name, EAL_VFIO_MP);
10499a2dd95SBruce Richardson 	reply.len_param = sizeof(*r);
10599a2dd95SBruce Richardson 
10699a2dd95SBruce Richardson 	ret = rte_mp_reply(&reply, peer);
10799a2dd95SBruce Richardson 	if (m->req == SOCKET_REQ_CONTAINER && fd >= 0)
10899a2dd95SBruce Richardson 		close(fd);
10999a2dd95SBruce Richardson 	return ret;
11099a2dd95SBruce Richardson }
11199a2dd95SBruce Richardson 
11299a2dd95SBruce Richardson int
vfio_mp_sync_setup(void)11399a2dd95SBruce Richardson vfio_mp_sync_setup(void)
11499a2dd95SBruce Richardson {
11599a2dd95SBruce Richardson 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
11699a2dd95SBruce Richardson 		int ret = rte_mp_action_register(EAL_VFIO_MP, vfio_mp_primary);
11799a2dd95SBruce Richardson 		if (ret && rte_errno != ENOTSUP)
11899a2dd95SBruce Richardson 			return -1;
11999a2dd95SBruce Richardson 	}
12099a2dd95SBruce Richardson 
12199a2dd95SBruce Richardson 	return 0;
12299a2dd95SBruce Richardson }
12399a2dd95SBruce Richardson 
1246412941aSStephen Hemminger void
vfio_mp_sync_cleanup(void)1256412941aSStephen Hemminger vfio_mp_sync_cleanup(void)
1266412941aSStephen Hemminger {
1276412941aSStephen Hemminger 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
1286412941aSStephen Hemminger 		return;
1296412941aSStephen Hemminger 
1306412941aSStephen Hemminger 	rte_mp_action_unregister(EAL_VFIO_MP);
1316412941aSStephen Hemminger }
13299a2dd95SBruce Richardson #endif
133