New upstream version 18.11-rc1
[deb_dpdk.git] / lib / librte_eal / linuxapp / eal / 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_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 CONFIG_RTE_EAL_VFIO is set to "y".
20  */
21
22 #ifdef VFIO_PRESENT
23
24 static int
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)
47                         r->result = SOCKET_ERR;
48                 else if (fd == 0)
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         default:
81                 RTE_LOG(ERR, EAL, "vfio received invalid message!\n");
82                 return -1;
83         }
84
85         strcpy(reply.name, EAL_VFIO_MP);
86         reply.len_param = sizeof(*r);
87
88         ret = rte_mp_reply(&reply, peer);
89         if (m->req == SOCKET_REQ_CONTAINER && fd >= 0)
90                 close(fd);
91         return ret;
92 }
93
94 int
95 vfio_mp_sync_setup(void)
96 {
97         if (rte_eal_process_type() == RTE_PROC_PRIMARY)
98                 return rte_mp_action_register(EAL_VFIO_MP, vfio_mp_primary);
99
100         return 0;
101 }
102
103 #endif