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