1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2018 Intel Corporation
3 */
4
5 #include <unistd.h>
6 #include <string.h>
7
8 #include <rte_errno.h>
9 #include <rte_log.h>
10 #include <rte_vfio.h>
11 #include <rte_eal.h>
12
13 #include "eal_vfio.h"
14
15 /**
16 * @file
17 * VFIO socket for communication between primary and secondary processes.
18 *
19 * This file is only compiled if RTE_EAL_VFIO is set.
20 */
21
22 #ifdef VFIO_PRESENT
23
24 static int
vfio_mp_primary(const struct rte_mp_msg * msg,const void * peer)25 vfio_mp_primary(const struct rte_mp_msg *msg, const void *peer)
26 {
27 int fd = -1;
28 int ret;
29 struct rte_mp_msg reply;
30 struct vfio_mp_param *r = (struct vfio_mp_param *)reply.param;
31 const struct vfio_mp_param *m =
32 (const struct vfio_mp_param *)msg->param;
33
34 if (msg->len_param != sizeof(*m)) {
35 RTE_LOG(ERR, EAL, "vfio received invalid message!\n");
36 return -1;
37 }
38
39 memset(&reply, 0, sizeof(reply));
40
41 switch (m->req) {
42 case SOCKET_REQ_GROUP:
43 r->req = SOCKET_REQ_GROUP;
44 r->group_num = m->group_num;
45 fd = rte_vfio_get_group_fd(m->group_num);
46 if (fd < 0 && fd != -ENOENT)
47 r->result = SOCKET_ERR;
48 else if (fd == -ENOENT)
49 /* if VFIO group exists but isn't bound to VFIO driver */
50 r->result = SOCKET_NO_FD;
51 else {
52 /* if group exists and is bound to VFIO driver */
53 r->result = SOCKET_OK;
54 reply.num_fds = 1;
55 reply.fds[0] = fd;
56 }
57 break;
58 case SOCKET_REQ_CONTAINER:
59 r->req = SOCKET_REQ_CONTAINER;
60 fd = rte_vfio_get_container_fd();
61 if (fd < 0)
62 r->result = SOCKET_ERR;
63 else {
64 r->result = SOCKET_OK;
65 reply.num_fds = 1;
66 reply.fds[0] = fd;
67 }
68 break;
69 case SOCKET_REQ_DEFAULT_CONTAINER:
70 r->req = SOCKET_REQ_DEFAULT_CONTAINER;
71 fd = vfio_get_default_container_fd();
72 if (fd < 0)
73 r->result = SOCKET_ERR;
74 else {
75 r->result = SOCKET_OK;
76 reply.num_fds = 1;
77 reply.fds[0] = fd;
78 }
79 break;
80 case SOCKET_REQ_IOMMU_TYPE:
81 {
82 int iommu_type_id;
83
84 r->req = SOCKET_REQ_IOMMU_TYPE;
85
86 iommu_type_id = vfio_get_iommu_type();
87
88 if (iommu_type_id < 0)
89 r->result = SOCKET_ERR;
90 else {
91 r->iommu_type_id = iommu_type_id;
92 r->result = SOCKET_OK;
93 }
94 break;
95 }
96 default:
97 RTE_LOG(ERR, EAL, "vfio received invalid message!\n");
98 return -1;
99 }
100
101 strcpy(reply.name, EAL_VFIO_MP);
102 reply.len_param = sizeof(*r);
103
104 ret = rte_mp_reply(&reply, peer);
105 if (m->req == SOCKET_REQ_CONTAINER && fd >= 0)
106 close(fd);
107 return ret;
108 }
109
110 int
vfio_mp_sync_setup(void)111 vfio_mp_sync_setup(void)
112 {
113 if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
114 int ret = rte_mp_action_register(EAL_VFIO_MP, vfio_mp_primary);
115 if (ret && rte_errno != ENOTSUP)
116 return -1;
117 }
118
119 return 0;
120 }
121
122 void
vfio_mp_sync_cleanup(void)123 vfio_mp_sync_cleanup(void)
124 {
125 if (rte_eal_process_type() != RTE_PROC_PRIMARY)
126 return;
127
128 rte_mp_action_unregister(EAL_VFIO_MP);
129 }
130 #endif
131