aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2023-10-05 09:01:01 -0400
committerStefan Hajnoczi <stefanha@redhat.com>2023-10-05 09:01:01 -0400
commit2f3913f4b2ad74baeb5a6f1d36efbd9ecdf1057d (patch)
tree2a77273973037c80a25b88dfa80bfc24baf7de52 /net
parent800af0aae1cfa456701c5fa1ef273ce47585179c (diff)
parentce0f3b032a960726c0dddfb4f81f223215179f26 (diff)
Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging
virtio,pci: features, cleanups vdpa: shadow vq vlan support net migration with cvq cxl: support emulating 4 HDM decoders serial number extended capability virtio: hared dma-buf Fixes, cleanups all over the place. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> * tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu: (53 commits) libvhost-user: handle shared_object msg vhost-user: add shared_object msg hw/display: introduce virtio-dmabuf util/uuid: add a hash function virtio: remove unused next argument from virtqueue_split_read_next_desc() virtio: remove unnecessary thread fence while reading next descriptor virtio: use shadow_avail_idx while checking number of heads libvhost-user.c: add assertion to vu_message_read_default pcie_sriov: unregister_vfs(): fix error path hw/i386/pc: improve physical address space bound check for 32-bit x86 systems amd_iommu: Fix APIC address check vdpa net: follow VirtIO initialization properly at cvq isolation probing vdpa net: stop probing if cannot set features vdpa net: fix error message setting virtio status hw/pci-bridge/cxl-upstream: Add serial number extended capability support hw/cxl: Support 4 HDM decoders at all levels of topology hw/cxl: Fix and use same calculation for HDM decoder block size everywhere hw/cxl: Add utility functions decoder interleave ways and target count. hw/cxl: Push cxl_decoder_count_enc() and cxl_decode_ig() into .c vdpa net: zero vhost_vdpa iova_tree pointer at cleanup ... Conflicts: hw/core/machine.c Context conflict with commit 314e0a84cd5d ("hw/core: remove needless includes") because it removed an adjacent #include.
Diffstat (limited to 'net')
-rw-r--r--net/vhost-vdpa.c145
1 files changed, 106 insertions, 39 deletions
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
index 4e94c50bc7..939c984d5b 100644
--- a/net/vhost-vdpa.c
+++ b/net/vhost-vdpa.c
@@ -114,6 +114,7 @@ static const uint64_t vdpa_svq_device_features =
BIT_ULL(VIRTIO_NET_F_STATUS) |
BIT_ULL(VIRTIO_NET_F_CTRL_VQ) |
BIT_ULL(VIRTIO_NET_F_CTRL_RX) |
+ BIT_ULL(VIRTIO_NET_F_CTRL_VLAN) |
BIT_ULL(VIRTIO_NET_F_CTRL_RX_EXTRA) |
BIT_ULL(VIRTIO_NET_F_MQ) |
BIT_ULL(VIRTIO_F_ANY_LAYOUT) |
@@ -374,6 +375,22 @@ static int vhost_vdpa_net_data_start(NetClientState *nc)
return 0;
}
+static int vhost_vdpa_net_data_load(NetClientState *nc)
+{
+ VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
+ struct vhost_vdpa *v = &s->vhost_vdpa;
+ bool has_cvq = v->dev->vq_index_end % 2;
+
+ if (has_cvq) {
+ return 0;
+ }
+
+ for (int i = 0; i < v->dev->nvqs; ++i) {
+ vhost_vdpa_set_vring_ready(v, i + v->dev->vq_index);
+ }
+ return 0;
+}
+
static void vhost_vdpa_net_client_stop(NetClientState *nc)
{
VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
@@ -388,6 +405,8 @@ static void vhost_vdpa_net_client_stop(NetClientState *nc)
dev = s->vhost_vdpa.dev;
if (dev->vq_index + dev->nvqs == dev->vq_index_end) {
g_clear_pointer(&s->vhost_vdpa.iova_tree, vhost_iova_tree_delete);
+ } else {
+ s->vhost_vdpa.iova_tree = NULL;
}
}
@@ -396,6 +415,7 @@ static NetClientInfo net_vhost_vdpa_info = {
.size = sizeof(VhostVDPAState),
.receive = vhost_vdpa_receive,
.start = vhost_vdpa_net_data_start,
+ .load = vhost_vdpa_net_data_load,
.stop = vhost_vdpa_net_client_stop,
.cleanup = vhost_vdpa_cleanup,
.has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
@@ -508,7 +528,7 @@ static int vhost_vdpa_net_cvq_start(NetClientState *nc)
s0 = vhost_vdpa_net_first_nc_vdpa(s);
v->shadow_data = s0->vhost_vdpa.shadow_vqs_enabled;
- v->shadow_vqs_enabled = s->always_svq;
+ v->shadow_vqs_enabled = s0->vhost_vdpa.shadow_vqs_enabled;
s->vhost_vdpa.address_space_id = VHOST_VDPA_GUEST_PA_ASID;
if (s->vhost_vdpa.shadow_data) {
@@ -627,7 +647,7 @@ static ssize_t vhost_vdpa_net_cvq_add(VhostVDPAState *s, size_t out_len,
* descriptor. Also, we need to take the answer before SVQ pulls by itself,
* when BQL is released
*/
- return vhost_svq_poll(svq);
+ return vhost_svq_poll(svq, 1);
}
static ssize_t vhost_vdpa_net_load_cmd(VhostVDPAState *s, uint8_t class,
@@ -968,7 +988,51 @@ static int vhost_vdpa_net_load_rx(VhostVDPAState *s,
return 0;
}
-static int vhost_vdpa_net_load(NetClientState *nc)
+static int vhost_vdpa_net_load_single_vlan(VhostVDPAState *s,
+ const VirtIONet *n,
+ uint16_t vid)
+{
+ const struct iovec data = {
+ .iov_base = &vid,
+ .iov_len = sizeof(vid),
+ };
+ ssize_t dev_written = vhost_vdpa_net_load_cmd(s, VIRTIO_NET_CTRL_VLAN,
+ VIRTIO_NET_CTRL_VLAN_ADD,
+ &data, 1);
+ if (unlikely(dev_written < 0)) {
+ return dev_written;
+ }
+ if (unlikely(*s->status != VIRTIO_NET_OK)) {
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int vhost_vdpa_net_load_vlan(VhostVDPAState *s,
+ const VirtIONet *n)
+{
+ int r;
+
+ if (!virtio_vdev_has_feature(&n->parent_obj, VIRTIO_NET_F_CTRL_VLAN)) {
+ return 0;
+ }
+
+ for (int i = 0; i < MAX_VLAN >> 5; i++) {
+ for (int j = 0; n->vlans[i] && j <= 0x1f; j++) {
+ if (n->vlans[i] & (1U << j)) {
+ r = vhost_vdpa_net_load_single_vlan(s, n, (i << 5) + j);
+ if (unlikely(r != 0)) {
+ return r;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int vhost_vdpa_net_cvq_load(NetClientState *nc)
{
VhostVDPAState *s = DO_UPCAST(VhostVDPAState, nc, nc);
struct vhost_vdpa *v = &s->vhost_vdpa;
@@ -977,26 +1041,34 @@ static int vhost_vdpa_net_load(NetClientState *nc)
assert(nc->info->type == NET_CLIENT_DRIVER_VHOST_VDPA);
- if (!v->shadow_vqs_enabled) {
- return 0;
- }
+ vhost_vdpa_set_vring_ready(v, v->dev->vq_index);
- n = VIRTIO_NET(v->dev->vdev);
- r = vhost_vdpa_net_load_mac(s, n);
- if (unlikely(r < 0)) {
- return r;
- }
- r = vhost_vdpa_net_load_mq(s, n);
- if (unlikely(r)) {
- return r;
- }
- r = vhost_vdpa_net_load_offloads(s, n);
- if (unlikely(r)) {
- return r;
+ if (v->shadow_vqs_enabled) {
+ n = VIRTIO_NET(v->dev->vdev);
+ r = vhost_vdpa_net_load_mac(s, n);
+ if (unlikely(r < 0)) {
+ return r;
+ }
+ r = vhost_vdpa_net_load_mq(s, n);
+ if (unlikely(r)) {
+ return r;
+ }
+ r = vhost_vdpa_net_load_offloads(s, n);
+ if (unlikely(r)) {
+ return r;
+ }
+ r = vhost_vdpa_net_load_rx(s, n);
+ if (unlikely(r)) {
+ return r;
+ }
+ r = vhost_vdpa_net_load_vlan(s, n);
+ if (unlikely(r)) {
+ return r;
+ }
}
- r = vhost_vdpa_net_load_rx(s, n);
- if (unlikely(r)) {
- return r;
+
+ for (int i = 0; i < v->dev->vq_index; ++i) {
+ vhost_vdpa_set_vring_ready(v, i);
}
return 0;
@@ -1007,7 +1079,7 @@ static NetClientInfo net_vhost_vdpa_cvq_info = {
.size = sizeof(VhostVDPAState),
.receive = vhost_vdpa_receive,
.start = vhost_vdpa_net_cvq_start,
- .load = vhost_vdpa_net_load,
+ .load = vhost_vdpa_net_cvq_load,
.stop = vhost_vdpa_net_cvq_stop,
.cleanup = vhost_vdpa_cleanup,
.has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
@@ -1273,8 +1345,7 @@ static int vhost_vdpa_probe_cvq_isolation(int device_fd, uint64_t features,
uint64_t backend_features;
int64_t cvq_group;
uint8_t status = VIRTIO_CONFIG_S_ACKNOWLEDGE |
- VIRTIO_CONFIG_S_DRIVER |
- VIRTIO_CONFIG_S_FEATURES_OK;
+ VIRTIO_CONFIG_S_DRIVER;
int r;
ERRP_GUARD();
@@ -1289,14 +1360,22 @@ static int vhost_vdpa_probe_cvq_isolation(int device_fd, uint64_t features,
return 0;
}
+ r = ioctl(device_fd, VHOST_VDPA_SET_STATUS, &status);
+ if (unlikely(r)) {
+ error_setg_errno(errp, -r, "Cannot set device status");
+ goto out;
+ }
+
r = ioctl(device_fd, VHOST_SET_FEATURES, &features);
if (unlikely(r)) {
- error_setg_errno(errp, errno, "Cannot set features");
+ error_setg_errno(errp, -r, "Cannot set features");
+ goto out;
}
+ status |= VIRTIO_CONFIG_S_FEATURES_OK;
r = ioctl(device_fd, VHOST_VDPA_SET_STATUS, &status);
if (unlikely(r)) {
- error_setg_errno(errp, -r, "Cannot set device features");
+ error_setg_errno(errp, -r, "Cannot set device status");
goto out;
}
@@ -1355,7 +1434,7 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
VhostVDPAState *s;
int ret = 0;
assert(name);
- int cvq_isolated;
+ int cvq_isolated = 0;
if (is_datapath) {
nc = qemu_new_net_client(&net_vhost_vdpa_info, peer, device,
@@ -1395,18 +1474,6 @@ static NetClientState *net_vhost_vdpa_init(NetClientState *peer,
s->vhost_vdpa.shadow_vq_ops = &vhost_vdpa_net_svq_ops;
s->vhost_vdpa.shadow_vq_ops_opaque = s;
s->cvq_isolated = cvq_isolated;
-
- /*
- * TODO: We cannot migrate devices with CVQ and no x-svq enabled as
- * there is no way to set the device state (MAC, MQ, etc) before
- * starting the datapath.
- *
- * Migration blocker ownership now belongs to s->vhost_vdpa.
- */
- if (!svq) {
- error_setg(&s->vhost_vdpa.migration_blocker,
- "net vdpa cannot migrate with CVQ feature");
- }
}
ret = vhost_vdpa_add(nc, (void *)&s->vhost_vdpa, queue_pair_index, nvqs);
if (ret) {