+ if (!(xd = dpdk_vhost_user_device_from_hw_if_index (hw_if_indices[i])))
+ {
+ error = clib_error_return (0, "not dpdk vhost-user interface: '%s'",
+ hi->name);
+ goto done;
+ }
+ vui = xd->vu_intf;
+ vhost_dev = &xd->vu_vhost_dev;
+ mem = vhost_dev->mem;
+ u32 virtio_net_hdr_sz = (vui->num_vrings > 0 ?
+ vhost_dev->virtqueue[0]->vhost_hlen : 0);
+
+ vlib_cli_output (vm, "Interface: %v (ifindex %d)",
+ hi->name, hw_if_indices[i]);
+
+ vlib_cli_output (vm, "virtio_net_hdr_sz %d\n features (0x%llx): \n",
+ virtio_net_hdr_sz, xd->vu_vhost_dev.features);
+
+ feat_entry = (struct feat_struct *) &feat_array;
+ while (feat_entry->str)
+ {
+ if (xd->vu_vhost_dev.features & (1 << feat_entry->bit))
+ vlib_cli_output (vm, " %s (%d)", feat_entry->str,
+ feat_entry->bit);
+ feat_entry++;
+ }
+
+ vlib_cli_output (vm, "\n");
+
+ vlib_cli_output (vm, " socket filename %s type %s errno \"%s\"\n\n",
+ vui->sock_filename,
+ vui->sock_is_server ? "server" : "client",
+ strerror (vui->sock_errno));
+
+ vlib_cli_output (vm, " Memory regions (total %d)\n", mem->nregions);
+
+ if (mem->nregions)
+ {
+ vlib_cli_output (vm,
+ " region fd guest_phys_addr memory_size userspace_addr mmap_offset mmap_addr\n");
+ vlib_cli_output (vm,
+ " ====== ===== ================== ================== ================== ================== ==================\n");
+ }
+ for (j = 0; j < mem->nregions; j++)
+ {
+ vlib_cli_output (vm,
+ " %d %-5d 0x%016lx 0x%016lx 0x%016lx 0x%016lx 0x%016lx\n",
+ j, vui->region_fd[j],
+ mem->regions[j].guest_phys_address,
+ mem->regions[j].memory_size,
+ mem->regions[j].userspace_address,
+ mem->regions[j].address_offset,
+ vui->region_addr[j]);
+ }
+ for (q = 0; q < vui->num_vrings; q++)
+ {
+ struct vhost_virtqueue *vq = vhost_dev->virtqueue[q];
+ const char *qtype = (q & 1) ? "TX" : "RX";
+
+ vlib_cli_output (vm, "\n Virtqueue %d (%s)\n", q / 2, qtype);
+
+ vlib_cli_output (vm,
+ " qsz %d last_used_idx %d last_used_idx_res %d\n",
+ vq->size, vq->last_used_idx,
+ vq->last_used_idx_res);
+
+ if (vq->avail && vq->used)
+ vlib_cli_output (vm,
+ " avail.flags %x avail.idx %d used.flags %x used.idx %d\n",
+ vq->avail->flags, vq->avail->idx,
+ vq->used->flags, vq->used->idx);
+
+ vlib_cli_output (vm, " kickfd %d callfd %d errfd %d enabled %d\n",
+ vq->kickfd, vq->callfd, vui->vrings[q].errfd,
+ vq->enabled);
+
+ if (show_descr && vq->enabled)
+ {
+ vlib_cli_output (vm, "\n descriptor table:\n");
+ vlib_cli_output (vm,
+ " id addr len flags next user_addr\n");
+ vlib_cli_output (vm,
+ " ===== ================== ===== ====== ===== ==================\n");
+ for (j = 0; j < vq->size; j++)
+ {
+ vlib_cli_output (vm,
+ " %-5d 0x%016lx %-5d 0x%04x %-5d 0x%016lx\n",
+ j, vq->desc[j].addr, vq->desc[j].len,
+ vq->desc[j].flags, vq->desc[j].next,
+ pointer_to_uword (map_guest_mem
+ (xd, vq->desc[j].addr)));
+ }
+ }
+ }
+ vlib_cli_output (vm, "\n");