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 RTE_EAL_VFIO is set. 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 && fd != -ENOENT) 48 r->result = SOCKET_ERR; 49 else if (fd == -ENOENT) 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 124