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 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 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 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