Branch data Line data Source code
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 27 : 21 : vfio_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 [ - + ]: 21 : if (msg->len_param != sizeof(*m)) { 37 : 0 : EAL_LOG(ERR, "vfio received invalid message!"); 38 : 0 : return -1; 39 : : } 40 : : 41 : : memset(&reply, 0, sizeof(reply)); 42 : : 43 [ - - + - : 21 : switch (m->req) { - ] 44 : 0 : case SOCKET_REQ_GROUP: 45 : 0 : r->req = SOCKET_REQ_GROUP; 46 : 0 : r->group_num = m->group_num; 47 : 0 : fd = rte_vfio_get_group_fd(m->group_num); 48 [ # # ]: 0 : if (fd < 0 && fd != -ENOENT) 49 : 0 : r->result = SOCKET_ERR; 50 [ # # ]: 0 : else if (fd == -ENOENT) 51 : : /* if VFIO group exists but isn't bound to VFIO driver */ 52 : 0 : r->result = SOCKET_NO_FD; 53 : : else { 54 : : /* if group exists and is bound to VFIO driver */ 55 : 0 : r->result = SOCKET_OK; 56 : 0 : reply.num_fds = 1; 57 : 0 : reply.fds[0] = fd; 58 : : } 59 : : break; 60 : 0 : case SOCKET_REQ_CONTAINER: 61 : 0 : r->req = SOCKET_REQ_CONTAINER; 62 : 0 : fd = rte_vfio_get_container_fd(); 63 [ # # ]: 0 : if (fd < 0) 64 : 0 : r->result = SOCKET_ERR; 65 : : else { 66 : 0 : r->result = SOCKET_OK; 67 : 0 : reply.num_fds = 1; 68 : 0 : reply.fds[0] = fd; 69 : : } 70 : : break; 71 : 21 : case SOCKET_REQ_DEFAULT_CONTAINER: 72 : 21 : r->req = SOCKET_REQ_DEFAULT_CONTAINER; 73 : 21 : fd = vfio_get_default_container_fd(); 74 [ - + ]: 21 : if (fd < 0) 75 : 0 : r->result = SOCKET_ERR; 76 : : else { 77 : 21 : r->result = SOCKET_OK; 78 : 21 : reply.num_fds = 1; 79 : 21 : reply.fds[0] = fd; 80 : : } 81 : : break; 82 : 0 : case SOCKET_REQ_IOMMU_TYPE: 83 : : { 84 : : int iommu_type_id; 85 : : 86 : 0 : r->req = SOCKET_REQ_IOMMU_TYPE; 87 : : 88 : 0 : iommu_type_id = vfio_get_iommu_type(); 89 : : 90 [ # # ]: 0 : if (iommu_type_id < 0) 91 : 0 : r->result = SOCKET_ERR; 92 : : else { 93 : 0 : r->iommu_type_id = iommu_type_id; 94 : 0 : r->result = SOCKET_OK; 95 : : } 96 : : break; 97 : : } 98 : 0 : default: 99 : 0 : EAL_LOG(ERR, "vfio received invalid message!"); 100 : 0 : return -1; 101 : : } 102 : : 103 : : strcpy(reply.name, EAL_VFIO_MP); 104 : 21 : reply.len_param = sizeof(*r); 105 : : 106 : 21 : ret = rte_mp_reply(&reply, peer); 107 [ - + - - ]: 21 : if (m->req == SOCKET_REQ_CONTAINER && fd >= 0) 108 : 0 : close(fd); 109 : : return ret; 110 : : } 111 : : 112 : : int 113 : 164 : vfio_mp_sync_setup(void) 114 : : { 115 [ + + ]: 164 : if (rte_eal_process_type() == RTE_PROC_PRIMARY) { 116 : 144 : int ret = rte_mp_action_register(EAL_VFIO_MP, vfio_mp_primary); 117 [ + + - + ]: 144 : if (ret && rte_errno != ENOTSUP) 118 : 0 : return -1; 119 : : } 120 : : 121 : : return 0; 122 : : } 123 : : 124 : : void 125 : 235 : vfio_mp_sync_cleanup(void) 126 : : { 127 [ + + ]: 235 : if (rte_eal_process_type() != RTE_PROC_PRIMARY) 128 : : return; 129 : : 130 : 212 : rte_mp_action_unregister(EAL_VFIO_MP); 131 : : } 132 : : #endif