| 59 | } |
| 60 | |
| 61 | static __rte_always_inline int |
| 62 | enqueue_pkt(struct vhost_dev *dev, struct rte_vhost_vring *vr, |
| 63 | struct rte_mbuf *m, uint16_t desc_idx) |
| 64 | { |
| 65 | uint32_t desc_avail, desc_offset; |
| 66 | uint64_t desc_chunck_len; |
| 67 | uint32_t mbuf_avail, mbuf_offset; |
| 68 | uint32_t cpy_len; |
| 69 | struct vring_desc *desc; |
| 70 | uint64_t desc_addr, desc_gaddr; |
| 71 | struct virtio_net_hdr virtio_hdr = {0, 0, 0, 0, 0, 0}; |
| 72 | /* A counter to avoid desc dead loop chain */ |
| 73 | uint16_t nr_desc = 1; |
| 74 | |
| 75 | desc = &vr->desc[desc_idx]; |
| 76 | desc_chunck_len = desc->len; |
| 77 | desc_gaddr = desc->addr; |
| 78 | desc_addr = rte_vhost_va_from_guest_pa( |
| 79 | dev->mem, desc_gaddr, &desc_chunck_len); |
| 80 | /* |
| 81 | * Checking of 'desc_addr' placed outside of 'unlikely' macro to avoid |
| 82 | * performance issue with some versions of gcc (4.8.4 and 5.3.0) which |
| 83 | * otherwise stores offset on the stack instead of in a register. |
| 84 | */ |
| 85 | if (unlikely(desc->len < dev->hdr_len) || !desc_addr) |
| 86 | return -1; |
| 87 | |
| 88 | rte_prefetch0((void *)(uintptr_t)desc_addr); |
| 89 | |
| 90 | /* write virtio-net header */ |
| 91 | if (likely(desc_chunck_len >= dev->hdr_len)) { |
| 92 | *(struct virtio_net_hdr *)(uintptr_t)desc_addr = virtio_hdr; |
| 93 | desc_offset = dev->hdr_len; |
| 94 | } else { |
| 95 | uint64_t len; |
| 96 | uint64_t remain = dev->hdr_len; |
| 97 | uint64_t src = (uint64_t)(uintptr_t)&virtio_hdr, dst; |
| 98 | uint64_t guest_addr = desc_gaddr; |
| 99 | |
| 100 | while (remain) { |
| 101 | len = remain; |
| 102 | dst = rte_vhost_va_from_guest_pa(dev->mem, |
| 103 | guest_addr, &len); |
| 104 | if (unlikely(!dst || !len)) |
| 105 | return -1; |
| 106 | |
| 107 | rte_memcpy((void *)(uintptr_t)dst, |
| 108 | (void *)(uintptr_t)src, |
| 109 | len); |
| 110 | |
| 111 | remain -= len; |
| 112 | guest_addr += len; |
| 113 | src += len; |
| 114 | } |
| 115 | |
| 116 | desc_chunck_len = desc->len - dev->hdr_len; |
| 117 | desc_gaddr += dev->hdr_len; |
| 118 | desc_addr = rte_vhost_va_from_guest_pa( |
no test coverage detected