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