1 /*- 2 * BSD LICENSE 3 * 4 * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <stdint.h> 35 #include <sys/types.h> 36 #include <unistd.h> 37 38 #include <rte_malloc.h> 39 #include <rte_kvargs.h> 40 41 #include "virtio_ethdev.h" 42 #include "virtio_logs.h" 43 #include "virtio_pci.h" 44 #include "virtqueue.h" 45 #include "virtio_rxtx.h" 46 #include "virtio_user/virtio_user_dev.h" 47 48 #define virtio_user_get_dev(hw) \ 49 ((struct virtio_user_dev *)(hw)->virtio_user_dev) 50 51 static void 52 virtio_user_read_dev_config(struct virtio_hw *hw, size_t offset, 53 void *dst, int length) 54 { 55 int i; 56 struct virtio_user_dev *dev = virtio_user_get_dev(hw); 57 58 if (offset == offsetof(struct virtio_net_config, mac) && 59 length == ETHER_ADDR_LEN) { 60 for (i = 0; i < ETHER_ADDR_LEN; ++i) 61 ((uint8_t *)dst)[i] = dev->mac_addr[i]; 62 return; 63 } 64 65 if (offset == offsetof(struct virtio_net_config, status)) 66 *(uint16_t *)dst = dev->status; 67 68 if (offset == offsetof(struct virtio_net_config, max_virtqueue_pairs)) 69 *(uint16_t *)dst = dev->max_queue_pairs; 70 } 71 72 static void 73 virtio_user_write_dev_config(struct virtio_hw *hw, size_t offset, 74 const void *src, int length) 75 { 76 int i; 77 struct virtio_user_dev *dev = virtio_user_get_dev(hw); 78 79 if ((offset == offsetof(struct virtio_net_config, mac)) && 80 (length == ETHER_ADDR_LEN)) 81 for (i = 0; i < ETHER_ADDR_LEN; ++i) 82 dev->mac_addr[i] = ((const uint8_t *)src)[i]; 83 else 84 PMD_DRV_LOG(ERR, "not supported offset=%zu, len=%d\n", 85 offset, length); 86 } 87 88 static void 89 virtio_user_set_status(struct virtio_hw *hw, uint8_t status) 90 { 91 struct virtio_user_dev *dev = virtio_user_get_dev(hw); 92 93 if (status & VIRTIO_CONFIG_STATUS_DRIVER_OK) 94 virtio_user_start_device(dev); 95 dev->status = status; 96 } 97 98 static void 99 virtio_user_reset(struct virtio_hw *hw) 100 { 101 struct virtio_user_dev *dev = virtio_user_get_dev(hw); 102 103 virtio_user_stop_device(dev); 104 } 105 106 static uint8_t 107 virtio_user_get_status(struct virtio_hw *hw) 108 { 109 struct virtio_user_dev *dev = virtio_user_get_dev(hw); 110 111 return dev->status; 112 } 113 114 static uint64_t 115 virtio_user_get_features(struct virtio_hw *hw) 116 { 117 struct virtio_user_dev *dev = virtio_user_get_dev(hw); 118 119 return dev->features; 120 } 121 122 static void 123 virtio_user_set_features(struct virtio_hw *hw, uint64_t features) 124 { 125 struct virtio_user_dev *dev = virtio_user_get_dev(hw); 126 127 dev->features = features; 128 } 129 130 static uint8_t 131 virtio_user_get_isr(struct virtio_hw *hw __rte_unused) 132 { 133 /* When config interrupt happens, driver calls this function to query 134 * what kinds of change happen. Interrupt mode not supported for now. 135 */ 136 return 0; 137 } 138 139 static uint16_t 140 virtio_user_set_config_irq(struct virtio_hw *hw __rte_unused, 141 uint16_t vec __rte_unused) 142 { 143 return VIRTIO_MSI_NO_VECTOR; 144 } 145 146 /* This function is to get the queue size, aka, number of descs, of a specified 147 * queue. Different with the VHOST_USER_GET_QUEUE_NUM, which is used to get the 148 * max supported queues. 149 */ 150 static uint16_t 151 virtio_user_get_queue_num(struct virtio_hw *hw, uint16_t queue_id __rte_unused) 152 { 153 struct virtio_user_dev *dev = virtio_user_get_dev(hw); 154 155 /* Currently, each queue has same queue size */ 156 return dev->queue_size; 157 } 158 159 static int 160 virtio_user_setup_queue(struct virtio_hw *hw, struct virtqueue *vq) 161 { 162 struct virtio_user_dev *dev = virtio_user_get_dev(hw); 163 uint16_t queue_idx = vq->vq_queue_index; 164 uint64_t desc_addr, avail_addr, used_addr; 165 166 desc_addr = (uintptr_t)vq->vq_ring_virt_mem; 167 avail_addr = desc_addr + vq->vq_nentries * sizeof(struct vring_desc); 168 used_addr = RTE_ALIGN_CEIL(avail_addr + offsetof(struct vring_avail, 169 ring[vq->vq_nentries]), 170 VIRTIO_PCI_VRING_ALIGN); 171 172 dev->vrings[queue_idx].num = vq->vq_nentries; 173 dev->vrings[queue_idx].desc = (void *)(uintptr_t)desc_addr; 174 dev->vrings[queue_idx].avail = (void *)(uintptr_t)avail_addr; 175 dev->vrings[queue_idx].used = (void *)(uintptr_t)used_addr; 176 177 return 0; 178 } 179 180 static void 181 virtio_user_del_queue(struct virtio_hw *hw, struct virtqueue *vq) 182 { 183 /* For legacy devices, write 0 to VIRTIO_PCI_QUEUE_PFN port, QEMU 184 * correspondingly stops the ioeventfds, and reset the status of 185 * the device. 186 * For modern devices, set queue desc, avail, used in PCI bar to 0, 187 * not see any more behavior in QEMU. 188 * 189 * Here we just care about what information to deliver to vhost-user 190 * or vhost-kernel. So we just close ioeventfd for now. 191 */ 192 struct virtio_user_dev *dev = virtio_user_get_dev(hw); 193 194 close(dev->callfds[vq->vq_queue_index]); 195 close(dev->kickfds[vq->vq_queue_index]); 196 } 197 198 static void 199 virtio_user_notify_queue(struct virtio_hw *hw, struct virtqueue *vq) 200 { 201 uint64_t buf = 1; 202 struct virtio_user_dev *dev = virtio_user_get_dev(hw); 203 204 if (hw->cvq && (hw->cvq->vq == vq)) { 205 virtio_user_handle_cq(dev, vq->vq_queue_index); 206 return; 207 } 208 209 if (write(dev->kickfds[vq->vq_queue_index], &buf, sizeof(buf)) < 0) 210 PMD_DRV_LOG(ERR, "failed to kick backend: %s\n", 211 strerror(errno)); 212 } 213 214 static const struct virtio_pci_ops virtio_user_ops = { 215 .read_dev_cfg = virtio_user_read_dev_config, 216 .write_dev_cfg = virtio_user_write_dev_config, 217 .reset = virtio_user_reset, 218 .get_status = virtio_user_get_status, 219 .set_status = virtio_user_set_status, 220 .get_features = virtio_user_get_features, 221 .set_features = virtio_user_set_features, 222 .get_isr = virtio_user_get_isr, 223 .set_config_irq = virtio_user_set_config_irq, 224 .get_queue_num = virtio_user_get_queue_num, 225 .setup_queue = virtio_user_setup_queue, 226 .del_queue = virtio_user_del_queue, 227 .notify_queue = virtio_user_notify_queue, 228 }; 229 230 static const char *valid_args[] = { 231 #define VIRTIO_USER_ARG_QUEUES_NUM "queues" 232 VIRTIO_USER_ARG_QUEUES_NUM, 233 #define VIRTIO_USER_ARG_CQ_NUM "cq" 234 VIRTIO_USER_ARG_CQ_NUM, 235 #define VIRTIO_USER_ARG_MAC "mac" 236 VIRTIO_USER_ARG_MAC, 237 #define VIRTIO_USER_ARG_PATH "path" 238 VIRTIO_USER_ARG_PATH, 239 #define VIRTIO_USER_ARG_QUEUE_SIZE "queue_size" 240 VIRTIO_USER_ARG_QUEUE_SIZE, 241 NULL 242 }; 243 244 #define VIRTIO_USER_DEF_CQ_EN 0 245 #define VIRTIO_USER_DEF_Q_NUM 1 246 #define VIRTIO_USER_DEF_Q_SZ 256 247 248 static int 249 get_string_arg(const char *key __rte_unused, 250 const char *value, void *extra_args) 251 { 252 if (!value || !extra_args) 253 return -EINVAL; 254 255 *(char **)extra_args = strdup(value); 256 257 return 0; 258 } 259 260 static int 261 get_integer_arg(const char *key __rte_unused, 262 const char *value, void *extra_args) 263 { 264 if (!value || !extra_args) 265 return -EINVAL; 266 267 *(uint64_t *)extra_args = strtoull(value, NULL, 0); 268 269 return 0; 270 } 271 272 static struct rte_eth_dev * 273 virtio_user_eth_dev_alloc(const char *name) 274 { 275 struct rte_eth_dev *eth_dev; 276 struct rte_eth_dev_data *data; 277 struct virtio_hw *hw; 278 struct virtio_user_dev *dev; 279 280 eth_dev = rte_eth_dev_allocate(name, RTE_ETH_DEV_VIRTUAL); 281 if (!eth_dev) { 282 PMD_INIT_LOG(ERR, "cannot alloc rte_eth_dev"); 283 return NULL; 284 } 285 286 data = eth_dev->data; 287 288 hw = rte_zmalloc(NULL, sizeof(*hw), 0); 289 if (!hw) { 290 PMD_INIT_LOG(ERR, "malloc virtio_hw failed"); 291 rte_eth_dev_release_port(eth_dev); 292 return NULL; 293 } 294 295 dev = rte_zmalloc(NULL, sizeof(*dev), 0); 296 if (!dev) { 297 PMD_INIT_LOG(ERR, "malloc virtio_user_dev failed"); 298 rte_eth_dev_release_port(eth_dev); 299 rte_free(hw); 300 return NULL; 301 } 302 303 hw->vtpci_ops = &virtio_user_ops; 304 hw->use_msix = 0; 305 hw->modern = 0; 306 hw->virtio_user_dev = dev; 307 data->dev_private = hw; 308 data->numa_node = SOCKET_ID_ANY; 309 data->kdrv = RTE_KDRV_NONE; 310 data->dev_flags = RTE_ETH_DEV_DETACHABLE; 311 eth_dev->pci_dev = NULL; 312 eth_dev->driver = NULL; 313 return eth_dev; 314 } 315 316 /* Dev initialization routine. Invoked once for each virtio vdev at 317 * EAL init time, see rte_eal_dev_init(). 318 * Returns 0 on success. 319 */ 320 static int 321 virtio_user_pmd_devinit(const char *name, const char *params) 322 { 323 struct rte_kvargs *kvlist; 324 struct rte_eth_dev *eth_dev; 325 struct virtio_hw *hw; 326 uint64_t queues = VIRTIO_USER_DEF_Q_NUM; 327 uint64_t cq = VIRTIO_USER_DEF_CQ_EN; 328 uint64_t queue_size = VIRTIO_USER_DEF_Q_SZ; 329 char *path = NULL; 330 char *mac_addr = NULL; 331 int ret = -1; 332 333 if (!params || params[0] == '\0') { 334 PMD_INIT_LOG(ERR, "arg %s is mandatory for virtio-user", 335 VIRTIO_USER_ARG_QUEUE_SIZE); 336 goto end; 337 } 338 339 kvlist = rte_kvargs_parse(params, valid_args); 340 if (!kvlist) { 341 PMD_INIT_LOG(ERR, "error when parsing param"); 342 goto end; 343 } 344 345 if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_PATH) == 1) 346 rte_kvargs_process(kvlist, VIRTIO_USER_ARG_PATH, 347 &get_string_arg, &path); 348 else { 349 PMD_INIT_LOG(ERR, "arg %s is mandatory for virtio-user\n", 350 VIRTIO_USER_ARG_QUEUE_SIZE); 351 goto end; 352 } 353 354 if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_MAC) == 1) 355 rte_kvargs_process(kvlist, VIRTIO_USER_ARG_MAC, 356 &get_string_arg, &mac_addr); 357 358 if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_QUEUE_SIZE) == 1) 359 rte_kvargs_process(kvlist, VIRTIO_USER_ARG_QUEUE_SIZE, 360 &get_integer_arg, &queue_size); 361 362 if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_QUEUES_NUM) == 1) 363 rte_kvargs_process(kvlist, VIRTIO_USER_ARG_QUEUES_NUM, 364 &get_integer_arg, &queues); 365 366 if (rte_kvargs_count(kvlist, VIRTIO_USER_ARG_CQ_NUM) == 1) 367 rte_kvargs_process(kvlist, VIRTIO_USER_ARG_CQ_NUM, 368 &get_integer_arg, &cq); 369 else if (queues > 1) 370 cq = 1; 371 372 if (queues > 1 && cq == 0) { 373 PMD_INIT_LOG(ERR, "multi-q requires ctrl-q"); 374 goto end; 375 } 376 377 eth_dev = virtio_user_eth_dev_alloc(name); 378 if (!eth_dev) { 379 PMD_INIT_LOG(ERR, "virtio-user fails to alloc device"); 380 goto end; 381 } 382 383 hw = eth_dev->data->dev_private; 384 if (virtio_user_dev_init(hw->virtio_user_dev, path, queues, cq, 385 queue_size, mac_addr) < 0) 386 goto end; 387 388 /* previously called by rte_eal_pci_probe() for physical dev */ 389 if (eth_virtio_dev_init(eth_dev) < 0) { 390 PMD_INIT_LOG(ERR, "eth_virtio_dev_init fails"); 391 goto end; 392 } 393 ret = 0; 394 395 end: 396 if (path) 397 free(path); 398 if (mac_addr) 399 free(mac_addr); 400 return ret; 401 } 402 403 /** Called by rte_eth_dev_detach() */ 404 static int 405 virtio_user_pmd_devuninit(const char *name) 406 { 407 struct rte_eth_dev *eth_dev; 408 struct virtio_hw *hw; 409 struct virtio_user_dev *dev; 410 411 if (!name) 412 return -EINVAL; 413 414 PMD_DRV_LOG(INFO, "Un-Initializing %s\n", name); 415 eth_dev = rte_eth_dev_allocated(name); 416 if (!eth_dev) 417 return -ENODEV; 418 419 /* make sure the device is stopped, queues freed */ 420 rte_eth_dev_close(eth_dev->data->port_id); 421 422 hw = eth_dev->data->dev_private; 423 dev = hw->virtio_user_dev; 424 virtio_user_dev_uninit(dev); 425 426 rte_free(eth_dev->data->dev_private); 427 rte_free(eth_dev->data); 428 rte_eth_dev_release_port(eth_dev); 429 430 return 0; 431 } 432 433 static struct rte_driver virtio_user_driver = { 434 .type = PMD_VDEV, 435 .init = virtio_user_pmd_devinit, 436 .uninit = virtio_user_pmd_devuninit, 437 }; 438 439 PMD_REGISTER_DRIVER(virtio_user_driver, virtio_user); 440 DRIVER_REGISTER_PARAM_STRING(virtio_user, 441 "path=<path> " 442 "mac=<mac addr> " 443 "cq=<int> " 444 "queue_size=<int> " 445 "queues=<int>"); 446