aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS5
-rw-r--r--docs/system/device-emulation.rst1
-rw-r--r--docs/system/devices/vdpa-net.rst121
-rw-r--r--hw/audio/virtio-snd.c129
-rw-r--r--hw/block/vhost-user-blk.c11
-rw-r--r--hw/net/virtio-net.c16
-rw-r--r--hw/virtio/vdpa-dev.c7
-rw-r--r--hw/virtio/virtio-pci.c189
-rw-r--r--hw/virtio/virtio.c51
-rw-r--r--include/hw/audio/virtio-snd.h16
-rw-r--r--include/hw/virtio/virtio-pci.h5
-rw-r--r--include/hw/virtio/virtio.h19
-rw-r--r--include/standard-headers/linux/virtio_pci.h7
-rw-r--r--system/qdev-monitor.c2
14 files changed, 97 insertions, 482 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index d3fc2a06e3..f1f6922025 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2371,11 +2371,6 @@ F: hw/virtio/vhost-user-scmi*
F: include/hw/virtio/vhost-user-scmi.h
F: tests/qtest/libqos/virtio-scmi.*
-vdpa-net
-M: Hao Chen <chenh@yusur.tech>
-S: Maintained
-F: docs/system/devices/vdpa-net.rst
-
virtio-crypto
M: Gonglei <arei.gonglei@huawei.com>
S: Supported
diff --git a/docs/system/device-emulation.rst b/docs/system/device-emulation.rst
index e4a27f53c8..f19777411c 100644
--- a/docs/system/device-emulation.rst
+++ b/docs/system/device-emulation.rst
@@ -99,4 +99,3 @@ Emulated Devices
devices/canokey.rst
devices/usb-u2f.rst
devices/igb.rst
- devices/vdpa-net.rst
diff --git a/docs/system/devices/vdpa-net.rst b/docs/system/devices/vdpa-net.rst
deleted file mode 100644
index 323d8c926a..0000000000
--- a/docs/system/devices/vdpa-net.rst
+++ /dev/null
@@ -1,121 +0,0 @@
-vdpa net
-============
-
-This document explains the setup and usage of the vdpa network device.
-The vdpa network device is a paravirtualized vdpa emulate device.
-
-Description
------------
-
-VDPA net devices support dirty page bitmap mark and vring state saving and recovery.
-
-Users can use this VDPA device for live migration simulation testing in a nested virtualization environment.
-
-Registers layout
-----------------
-
-The vdpa device add live migrate registers layout as follow::
-
- Offset Register Name Bitwidth Associated vq
- 0x0 LM_LOGGING_CTRL 4bits
- 0x10 LM_BASE_ADDR_LOW 32bits
- 0x14 LM_BASE_ADDR_HIGH 32bits
- 0x18 LM_END_ADDR_LOW 32bits
- 0x1c LM_END_ADDR_HIGH 32bits
- 0x20 LM_RING_STATE_OFFSET 32bits vq0
- 0x24 LM_RING_STATE_OFFSET 32bits vq1
- 0x28 LM_RING_STATE_OFFSET 32bits vq2
- ......
- 0x20+1023*4 LM_RING_STATE_OFFSET 32bits vq1023
-
-These registers are extended at the end of the notify bar space.
-
-Architecture diagram
---------------------
-::
-
- |------------------------------------------------------------------------|
- | guest-L1-user-space |
- | |
- | |----------------------------------------|
- | | [virtio-net driver] |
- | | ^ guest-L2-src(iommu=on) |
- | |--------------|-------------------------|
- | | | qemu-L2-src(viommu) |
- | [dpdk-vdpa]<->[vhost socket]<-+->[vhost-user backend(iommu=on)] |
- --------------------------------------------------------------------------
- --------------------------------------------------------------------------
- | ^ guest-L1-kernel-space |
- | | |
- | [VFIO] |
- | ^ |
- | | guest-L1-src(iommu=on) |
- --------|-----------------------------------------------------------------
- --------|-----------------------------------------------------------------
- | [vdpa net device(iommu=on)] [manager nic device] |
- | | | |
- | | | |
- | [tap device] qemu-L1-src(viommu) | |
- ------------------------------------------------+-------------------------
- |
- |
- --------------------- |
- | kernel net bridge |<-----
- | virbr0 |<----------------------------------
- --------------------- |
- |
- |
- -------------------------------------------------------------------------- |
- | guest-L1-user-space | |
- | | |
- | |----------------------------------------| |
- | | [virtio-net driver] | |
- | | ^ guest-L2-dst(iommu=on) | |
- | |--------------|-------------------------| |
- | | | qemu-L2-dst(viommu) | |
- | [dpdk-vdpa]<->[vhost socket]<-+->[vhost-user backend(iommu=on)] | |
- -------------------------------------------------------------------------- |
- -------------------------------------------------------------------------- |
- | ^ guest-L1-kernel-space | |
- | | | |
- | [VFIO] | |
- | ^ | |
- | | guest-L1-dst(iommu=on) | |
- --------|----------------------------------------------------------------- |
- --------|----------------------------------------------------------------- |
- | [vdpa net device(iommu=on)] [manager nic device]----------------+----
- | | |
- | | |
- | [tap device] qemu-L1-dst(viommu) |
- --------------------------------------------------------------------------
-
-
-Device properties
------------------
-
-The Virtio vdpa device can be configured with the following properties:
-
- * ``vdpa=on`` open vdpa device emulated.
-
-Usages
---------
-This patch add virtio sriov support and vdpa live migrate support.
-You can open vdpa by set xml file as follow::
-
- <qemu:commandline xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
- <qemu:arg value='-device'/>
- <qemu:arg value='intel-iommu,intremap=on,device-iotlb=on,aw-bits=48'/>
- <qemu:arg value='-netdev'/>
- <qemu:arg value='tap,id=hostnet1,script=no,downscript=no,vhost=off'/>
- <qemu:arg value='-device'/>
- <qemu:arg value='virtio-net-pci,netdev=hostnet1,id=net1,mac=56:4a:b7:4f:4d:a9,bus=pci.6,addr=0x0,iommu_platform=on,ats=on,vdpa=on'/>
- </qemu:commandline>
-
-Limitations
------------
-1. Dependent on tap device with param ``vhost=off``.
-2. Nested virtualization environment only supports ``q35`` machines.
-3. Current only support split vring live migrate.
-
-
-
diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c
index e604d8f30c..90d9a2796e 100644
--- a/hw/audio/virtio-snd.c
+++ b/hw/audio/virtio-snd.c
@@ -456,7 +456,6 @@ static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id)
stream->s = s;
qemu_mutex_init(&stream->queue_mutex);
QSIMPLEQ_INIT(&stream->queue);
- QSIMPLEQ_INIT(&stream->invalid);
/*
* stream_id >= s->snd_conf.streams was checked before so this is
@@ -611,9 +610,6 @@ static size_t virtio_snd_pcm_get_io_msgs_count(VirtIOSoundPCMStream *stream)
QSIMPLEQ_FOREACH_SAFE(buffer, &stream->queue, entry, next) {
count += 1;
}
- QSIMPLEQ_FOREACH_SAFE(buffer, &stream->invalid, entry, next) {
- count += 1;
- }
}
return count;
}
@@ -831,47 +827,36 @@ static void virtio_snd_handle_event(VirtIODevice *vdev, VirtQueue *vq)
trace_virtio_snd_handle_event();
}
+/*
+ * Must only be called if vsnd->invalid is not empty.
+ */
static inline void empty_invalid_queue(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOSoundPCMBuffer *buffer = NULL;
- VirtIOSoundPCMStream *stream = NULL;
virtio_snd_pcm_status resp = { 0 };
VirtIOSound *vsnd = VIRTIO_SND(vdev);
- bool any = false;
- for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) {
- stream = vsnd->pcm->streams[i];
- if (stream) {
- any = false;
- WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
- while (!QSIMPLEQ_EMPTY(&stream->invalid)) {
- buffer = QSIMPLEQ_FIRST(&stream->invalid);
- if (buffer->vq != vq) {
- break;
- }
- any = true;
- resp.status = cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
- iov_from_buf(buffer->elem->in_sg,
- buffer->elem->in_num,
- 0,
- &resp,
- sizeof(virtio_snd_pcm_status));
- virtqueue_push(vq,
- buffer->elem,
- sizeof(virtio_snd_pcm_status));
- QSIMPLEQ_REMOVE_HEAD(&stream->invalid, entry);
- virtio_snd_pcm_buffer_free(buffer);
- }
- if (any) {
- /*
- * Notify vq about virtio_snd_pcm_status responses.
- * Buffer responses must be notified separately later.
- */
- virtio_notify(vdev, vq);
- }
- }
- }
+ g_assert(!QSIMPLEQ_EMPTY(&vsnd->invalid));
+
+ while (!QSIMPLEQ_EMPTY(&vsnd->invalid)) {
+ buffer = QSIMPLEQ_FIRST(&vsnd->invalid);
+ /* If buffer->vq != vq, our logic is fundamentally wrong, so bail out */
+ g_assert(buffer->vq == vq);
+
+ resp.status = cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
+ iov_from_buf(buffer->elem->in_sg,
+ buffer->elem->in_num,
+ 0,
+ &resp,
+ sizeof(virtio_snd_pcm_status));
+ virtqueue_push(vq,
+ buffer->elem,
+ sizeof(virtio_snd_pcm_status));
+ QSIMPLEQ_REMOVE_HEAD(&vsnd->invalid, entry);
+ virtio_snd_pcm_buffer_free(buffer);
}
+ /* Notify vq about virtio_snd_pcm_status responses. */
+ virtio_notify(vdev, vq);
}
/*
@@ -883,15 +868,14 @@ static inline void empty_invalid_queue(VirtIODevice *vdev, VirtQueue *vq)
*/
static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
{
- VirtIOSound *s = VIRTIO_SND(vdev);
- VirtIOSoundPCMStream *stream = NULL;
+ VirtIOSound *vsnd = VIRTIO_SND(vdev);
VirtIOSoundPCMBuffer *buffer;
VirtQueueElement *elem;
size_t msg_sz, size;
virtio_snd_pcm_xfer hdr;
uint32_t stream_id;
/*
- * If any of the I/O messages are invalid, put them in stream->invalid and
+ * If any of the I/O messages are invalid, put them in vsnd->invalid and
* return them after the for loop.
*/
bool must_empty_invalid_queue = false;
@@ -901,7 +885,7 @@ static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
}
trace_virtio_snd_handle_tx_xfer();
- for (;;) {
+ for (VirtIOSoundPCMStream *stream = NULL;; stream = NULL) {
elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
if (!elem) {
break;
@@ -917,12 +901,12 @@ static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
}
stream_id = le32_to_cpu(hdr.stream_id);
- if (stream_id >= s->snd_conf.streams
- || s->pcm->streams[stream_id] == NULL) {
+ if (stream_id >= vsnd->snd_conf.streams
+ || vsnd->pcm->streams[stream_id] == NULL) {
goto tx_err;
}
- stream = s->pcm->streams[stream_id];
+ stream = vsnd->pcm->streams[stream_id];
if (stream->info.direction != VIRTIO_SND_D_OUTPUT) {
goto tx_err;
}
@@ -942,13 +926,11 @@ static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
continue;
tx_err:
- WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
- must_empty_invalid_queue = true;
- buffer = g_malloc0(sizeof(VirtIOSoundPCMBuffer));
- buffer->elem = elem;
- buffer->vq = vq;
- QSIMPLEQ_INSERT_TAIL(&stream->invalid, buffer, entry);
- }
+ must_empty_invalid_queue = true;
+ buffer = g_malloc0(sizeof(VirtIOSoundPCMBuffer));
+ buffer->elem = elem;
+ buffer->vq = vq;
+ QSIMPLEQ_INSERT_TAIL(&vsnd->invalid, buffer, entry);
}
if (must_empty_invalid_queue) {
@@ -965,15 +947,14 @@ tx_err:
*/
static void virtio_snd_handle_rx_xfer(VirtIODevice *vdev, VirtQueue *vq)
{
- VirtIOSound *s = VIRTIO_SND(vdev);
- VirtIOSoundPCMStream *stream = NULL;
+ VirtIOSound *vsnd = VIRTIO_SND(vdev);
VirtIOSoundPCMBuffer *buffer;
VirtQueueElement *elem;
size_t msg_sz, size;
virtio_snd_pcm_xfer hdr;
uint32_t stream_id;
/*
- * if any of the I/O messages are invalid, put them in stream->invalid and
+ * if any of the I/O messages are invalid, put them in vsnd->invalid and
* return them after the for loop.
*/
bool must_empty_invalid_queue = false;
@@ -983,7 +964,7 @@ static void virtio_snd_handle_rx_xfer(VirtIODevice *vdev, VirtQueue *vq)
}
trace_virtio_snd_handle_rx_xfer();
- for (;;) {
+ for (VirtIOSoundPCMStream *stream = NULL;; stream = NULL) {
elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
if (!elem) {
break;
@@ -999,12 +980,12 @@ static void virtio_snd_handle_rx_xfer(VirtIODevice *vdev, VirtQueue *vq)
}
stream_id = le32_to_cpu(hdr.stream_id);
- if (stream_id >= s->snd_conf.streams
- || !s->pcm->streams[stream_id]) {
+ if (stream_id >= vsnd->snd_conf.streams
+ || !vsnd->pcm->streams[stream_id]) {
goto rx_err;
}
- stream = s->pcm->streams[stream_id];
+ stream = vsnd->pcm->streams[stream_id];
if (stream == NULL || stream->info.direction != VIRTIO_SND_D_INPUT) {
goto rx_err;
}
@@ -1021,13 +1002,11 @@ static void virtio_snd_handle_rx_xfer(VirtIODevice *vdev, VirtQueue *vq)
continue;
rx_err:
- WITH_QEMU_LOCK_GUARD(&stream->queue_mutex) {
- must_empty_invalid_queue = true;
- buffer = g_malloc0(sizeof(VirtIOSoundPCMBuffer));
- buffer->elem = elem;
- buffer->vq = vq;
- QSIMPLEQ_INSERT_TAIL(&stream->invalid, buffer, entry);
- }
+ must_empty_invalid_queue = true;
+ buffer = g_malloc0(sizeof(VirtIOSoundPCMBuffer));
+ buffer->elem = elem;
+ buffer->vq = vq;
+ QSIMPLEQ_INSERT_TAIL(&vsnd->invalid, buffer, entry);
}
if (must_empty_invalid_queue) {
@@ -1127,6 +1106,7 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp)
virtio_add_queue(vdev, 64, virtio_snd_handle_rx_xfer);
qemu_mutex_init(&vsnd->cmdq_mutex);
QTAILQ_INIT(&vsnd->cmdq);
+ QSIMPLEQ_INIT(&vsnd->invalid);
for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) {
status = virtio_snd_set_pcm_params(vsnd, i, &default_params);
@@ -1376,13 +1356,20 @@ static void virtio_snd_unrealize(DeviceState *dev)
static void virtio_snd_reset(VirtIODevice *vdev)
{
- VirtIOSound *s = VIRTIO_SND(vdev);
+ VirtIOSound *vsnd = VIRTIO_SND(vdev);
virtio_snd_ctrl_command *cmd;
- WITH_QEMU_LOCK_GUARD(&s->cmdq_mutex) {
- while (!QTAILQ_EMPTY(&s->cmdq)) {
- cmd = QTAILQ_FIRST(&s->cmdq);
- QTAILQ_REMOVE(&s->cmdq, cmd, next);
+ /*
+ * Sanity check that the invalid buffer message queue is emptied at the end
+ * of every virtio_snd_handle_tx_xfer/virtio_snd_handle_rx_xfer call, and
+ * must be empty otherwise.
+ */
+ g_assert(QSIMPLEQ_EMPTY(&vsnd->invalid));
+
+ WITH_QEMU_LOCK_GUARD(&vsnd->cmdq_mutex) {
+ while (!QTAILQ_EMPTY(&vsnd->cmdq)) {
+ cmd = QTAILQ_FIRST(&vsnd->cmdq);
+ QTAILQ_REMOVE(&vsnd->cmdq, cmd, next);
virtio_snd_ctrl_cmd_free(cmd);
}
}
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index 6a856ad51a..9e6bbc6950 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -91,7 +91,6 @@ static void vhost_user_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
static int vhost_user_blk_handle_config_change(struct vhost_dev *dev)
{
int ret;
- struct virtio_blk_config blkcfg;
VirtIODevice *vdev = dev->vdev;
VHostUserBlk *s = VHOST_USER_BLK(dev->vdev);
Error *local_err = NULL;
@@ -100,19 +99,15 @@ static int vhost_user_blk_handle_config_change(struct vhost_dev *dev)
return 0;
}
- ret = vhost_dev_get_config(dev, (uint8_t *)&blkcfg,
+ ret = vhost_dev_get_config(dev, (uint8_t *)&s->blkcfg,
vdev->config_len, &local_err);
if (ret < 0) {
error_report_err(local_err);
return ret;
}
- /* valid for resize only */
- if (blkcfg.capacity != s->blkcfg.capacity) {
- s->blkcfg.capacity = blkcfg.capacity;
- memcpy(dev->vdev->config, &s->blkcfg, vdev->config_len);
- virtio_notify_config(dev->vdev);
- }
+ memcpy(dev->vdev->config, &s->blkcfg, vdev->config_len);
+ virtio_notify_config(dev->vdev);
return 0;
}
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 58014a92ad..24e5e7d347 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -2039,22 +2039,6 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf,
goto err;
}
- /* Mark dirty page's bitmap of guest memory */
- if (vdev->lm_logging_ctrl == LM_ENABLE) {
- uint64_t chunk = elem->in_addr[i] / VHOST_LOG_CHUNK;
- /* Get chunk index */
- BitmapMemoryRegionCaches *caches = qatomic_rcu_read(&vdev->caches);
- uint64_t index = chunk / 8;
- uint64_t shift = chunk % 8;
- uint8_t val = 0;
- address_space_read_cached(&caches->bitmap, index, &val,
- sizeof(val));
- val |= 1 << shift;
- address_space_write_cached(&caches->bitmap, index, &val,
- sizeof(val));
- address_space_cache_invalidate(&caches->bitmap, index, sizeof(val));
- }
-
elems[i] = elem;
lens[i] = total;
i++;
diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c
index 13e87f06f6..64b96b226c 100644
--- a/hw/virtio/vdpa-dev.c
+++ b/hw/virtio/vdpa-dev.c
@@ -195,7 +195,14 @@ static void
vhost_vdpa_device_get_config(VirtIODevice *vdev, uint8_t *config)
{
VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev);
+ int ret;
+ ret = vhost_dev_get_config(&s->dev, s->config, s->config_size,
+ NULL);
+ if (ret < 0) {
+ error_report("get device config space failed");
+ return;
+ }
memcpy(config, s->config, s->config_size);
}
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index eaaf86402c..cb6940fc0e 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -1442,155 +1442,6 @@ int virtio_pci_add_shm_cap(VirtIOPCIProxy *proxy,
return virtio_pci_add_mem_cap(proxy, &cap.cap);
}
-/* Called within call_rcu(). */
-static void bitmap_free_region_cache(BitmapMemoryRegionCaches *caches)
-{
- assert(caches != NULL);
- address_space_cache_destroy(&caches->bitmap);
- g_free(caches);
-}
-
-static void lm_disable(VirtIODevice *vdev)
-{
- BitmapMemoryRegionCaches *caches;
- caches = qatomic_read(&vdev->caches);
- qatomic_rcu_set(&vdev->caches, NULL);
- if (caches) {
- call_rcu(caches, bitmap_free_region_cache, rcu);
- }
-}
-
-static void lm_enable(VirtIODevice *vdev)
-{
- BitmapMemoryRegionCaches *old = vdev->caches;
- BitmapMemoryRegionCaches *new = NULL;
- hwaddr addr, end, size;
- int64_t len;
-
- addr = vdev->lm_base_addr_low | ((hwaddr)(vdev->lm_base_addr_high) << 32);
- end = vdev->lm_end_addr_low | ((hwaddr)(vdev->lm_end_addr_high) << 32);
- size = end - addr;
- if (size <= 0) {
- error_report("Invalid lm size.");
- return;
- }
-
- new = g_new0(BitmapMemoryRegionCaches, 1);
- len = address_space_cache_init(&new->bitmap, vdev->dma_as, addr, size,
- true);
- if (len < size) {
- virtio_error(vdev, "Cannot map bitmap");
- goto err_bitmap;
- }
- qatomic_rcu_set(&vdev->caches, new);
-
- if (old) {
- call_rcu(old, bitmap_free_region_cache, rcu);
- }
-
- return;
-
-err_bitmap:
- address_space_cache_destroy(&new->bitmap);
- g_free(new);
-}
-
-static uint64_t virtio_pci_lm_read(void *opaque, hwaddr addr,
- unsigned size)
-{
- VirtIOPCIProxy *proxy = opaque;
- VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
- hwaddr offset_end = LM_VRING_STATE_OFFSET +
- virtio_pci_queue_mem_mult(proxy) * VIRTIO_QUEUE_MAX;
- uint32_t val;
- int qid;
-
- if (vdev == NULL) {
- return UINT64_MAX;
- }
- switch (addr) {
- case LM_LOGGING_CTRL:
- val = vdev->lm_logging_ctrl;
- break;
- case LM_BASE_ADDR_LOW:
- val = vdev->lm_base_addr_low;
- break;
- case LM_BASE_ADDR_HIGH:
- val = vdev->lm_base_addr_high;
- break;
- case LM_END_ADDR_LOW:
- val = vdev->lm_end_addr_low;
- break;
- case LM_END_ADDR_HIGH:
- val = vdev->lm_end_addr_high;
- break;
- default:
- if (addr >= LM_VRING_STATE_OFFSET && addr <= offset_end) {
- qid = (addr - LM_VRING_STATE_OFFSET) /
- virtio_pci_queue_mem_mult(proxy);
- val = virtio_queue_get_vring_states(vdev, qid);
- } else
- val = 0;
-
- break;
- }
-
- return val;
-}
-
-static void virtio_pci_lm_write(void *opaque, hwaddr addr,
- uint64_t val, unsigned size)
-{
- VirtIOPCIProxy *proxy = opaque;
- VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
- hwaddr offset_end = LM_VRING_STATE_OFFSET +
- virtio_pci_queue_mem_mult(proxy) * VIRTIO_QUEUE_MAX;
- int qid;
-
- if (vdev == NULL) {
- return;
- }
-
- switch (addr) {
- case LM_LOGGING_CTRL:
- vdev->lm_logging_ctrl = val;
- switch (val) {
- case LM_DISABLE:
- lm_disable(vdev);
- break;
- case LM_ENABLE:
- lm_enable(vdev);
- break;
- default:
- virtio_error(vdev, "Unsupport LM_LOGGING_CTRL value: %"PRIx64,
- val);
- break;
- };
-
- break;
- case LM_BASE_ADDR_LOW:
- vdev->lm_base_addr_low = val;
- break;
- case LM_BASE_ADDR_HIGH:
- vdev->lm_base_addr_high = val;
- break;
- case LM_END_ADDR_LOW:
- vdev->lm_end_addr_low = val;
- break;
- case LM_END_ADDR_HIGH:
- vdev->lm_end_addr_high = val;
- break;
- default:
- if (addr >= LM_VRING_STATE_OFFSET && addr <= offset_end) {
- qid = (addr - LM_VRING_STATE_OFFSET) /
- virtio_pci_queue_mem_mult(proxy);
- virtio_queue_set_vring_states(vdev, qid, val);
- } else
- virtio_error(vdev, "Unsupport addr: %"PRIx64, addr);
- break;
- }
-}
-
static uint64_t virtio_pci_common_read(void *opaque, hwaddr addr,
unsigned size)
{
@@ -1972,15 +1823,6 @@ static void virtio_pci_modern_regions_init(VirtIOPCIProxy *proxy,
},
.endianness = DEVICE_LITTLE_ENDIAN,
};
- static const MemoryRegionOps lm_ops = {
- .read = virtio_pci_lm_read,
- .write = virtio_pci_lm_write,
- .impl = {
- .min_access_size = 1,
- .max_access_size = 4,
- },
- .endianness = DEVICE_LITTLE_ENDIAN,
- };
g_autoptr(GString) name = g_string_new(NULL);
g_string_printf(name, "virtio-pci-common-%s", vdev_name);
@@ -2017,14 +1859,6 @@ static void virtio_pci_modern_regions_init(VirtIOPCIProxy *proxy,
proxy,
name->str,
proxy->notify_pio.size);
- if (proxy->flags & VIRTIO_PCI_FLAG_VDPA) {
- g_string_printf(name, "virtio-pci-lm-%s", vdev_name);
- memory_region_init_io(&proxy->lm.mr, OBJECT(proxy),
- &lm_ops,
- proxy,
- name->str,
- proxy->lm.size);
- }
}
static void virtio_pci_modern_region_map(VirtIOPCIProxy *proxy,
@@ -2187,10 +2021,6 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp)
virtio_pci_modern_mem_region_map(proxy, &proxy->isr, &cap);
virtio_pci_modern_mem_region_map(proxy, &proxy->device, &cap);
virtio_pci_modern_mem_region_map(proxy, &proxy->notify, &notify.cap);
- if (proxy->flags & VIRTIO_PCI_FLAG_VDPA) {
- memory_region_add_subregion(&proxy->modern_bar,
- proxy->lm.offset, &proxy->lm.mr);
- }
if (modern_pio) {
memory_region_init(&proxy->io_bar, OBJECT(proxy),
@@ -2260,9 +2090,6 @@ static void virtio_pci_device_unplugged(DeviceState *d)
virtio_pci_modern_mem_region_unmap(proxy, &proxy->isr);
virtio_pci_modern_mem_region_unmap(proxy, &proxy->device);
virtio_pci_modern_mem_region_unmap(proxy, &proxy->notify);
- if (proxy->flags & VIRTIO_PCI_FLAG_VDPA) {
- memory_region_del_subregion(&proxy->modern_bar, &proxy->lm.mr);
- }
if (modern_pio) {
virtio_pci_modern_io_region_unmap(proxy, &proxy->notify_pio);
}
@@ -2317,17 +2144,9 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp)
proxy->notify_pio.type = VIRTIO_PCI_CAP_NOTIFY_CFG;
/* subclasses can enforce modern, so do this unconditionally */
- if (!(proxy->flags & VIRTIO_PCI_FLAG_VDPA)) {
- memory_region_init(&proxy->modern_bar, OBJECT(proxy), "virtio-pci",
- /* PCI BAR regions must be powers of 2 */
- pow2ceil(proxy->notify.offset + proxy->notify.size));
- } else {
- proxy->lm.offset = proxy->notify.offset + proxy->notify.size;
- proxy->lm.size = 0x20 + VIRTIO_QUEUE_MAX * 4;
- memory_region_init(&proxy->modern_bar, OBJECT(proxy), "virtio-pci",
- /* PCI BAR regions must be powers of 2 */
- pow2ceil(proxy->lm.offset + proxy->lm.size));
- }
+ memory_region_init(&proxy->modern_bar, OBJECT(proxy), "virtio-pci",
+ /* PCI BAR regions must be powers of 2 */
+ pow2ceil(proxy->notify.offset + proxy->notify.size));
if (proxy->disable_legacy == ON_OFF_AUTO_AUTO) {
proxy->disable_legacy = pcie_port ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
@@ -2482,8 +2301,6 @@ static Property virtio_pci_properties[] = {
VIRTIO_PCI_FLAG_INIT_FLR_BIT, true),
DEFINE_PROP_BIT("aer", VirtIOPCIProxy, flags,
VIRTIO_PCI_FLAG_AER_BIT, false),
- DEFINE_PROP_BIT("vdpa", VirtIOPCIProxy, flags,
- VIRTIO_PCI_FLAG_VDPA_BIT, false),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index fb6b4ccd83..c5bedca848 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -957,12 +957,20 @@ static void virtqueue_packed_flush(VirtQueue *vq, unsigned int count)
return;
}
+ /*
+ * For indirect element's 'ndescs' is 1.
+ * For all other elemment's 'ndescs' is the
+ * number of descriptors chained by NEXT (as set in virtqueue_packed_pop).
+ * So When the 'elem' be filled into the descriptor ring,
+ * The 'idx' of this 'elem' shall be
+ * the value of 'vq->used_idx' plus the 'ndescs'.
+ */
+ ndescs += vq->used_elems[0].ndescs;
for (i = 1; i < count; i++) {
- virtqueue_packed_fill_desc(vq, &vq->used_elems[i], i, false);
+ virtqueue_packed_fill_desc(vq, &vq->used_elems[i], ndescs, false);
ndescs += vq->used_elems[i].ndescs;
}
virtqueue_packed_fill_desc(vq, &vq->used_elems[0], 0, true);
- ndescs += vq->used_elems[0].ndescs;
vq->inuse -= ndescs;
vq->used_idx += ndescs;
@@ -3368,18 +3376,6 @@ static uint16_t virtio_queue_split_get_last_avail_idx(VirtIODevice *vdev,
return vdev->vq[n].last_avail_idx;
}
-static uint32_t virtio_queue_split_get_vring_states(VirtIODevice *vdev,
- int n)
-{
- struct VirtQueue *vq = &vdev->vq[n];
- uint16_t avail, used;
-
- avail = vq->last_avail_idx;
- used = vq->used_idx;
-
- return avail | (uint32_t)used << 16;
-}
-
unsigned int virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n)
{
if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) {
@@ -3389,33 +3385,6 @@ unsigned int virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n)
}
}
-unsigned int virtio_queue_get_vring_states(VirtIODevice *vdev, int n)
-{
- if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) {
- return -1;
- } else {
- return virtio_queue_split_get_vring_states(vdev, n);
- }
-}
-
-static void virtio_queue_split_set_vring_states(VirtIODevice *vdev,
- int n, uint32_t idx)
-{
- struct VirtQueue *vq = &vdev->vq[n];
- vq->last_avail_idx = (uint16_t)(idx & 0xffff);
- vq->shadow_avail_idx = (uint16_t)(idx & 0xffff);
- vq->used_idx = (uint16_t)(idx >> 16);
-}
-
-void virtio_queue_set_vring_states(VirtIODevice *vdev, int n, uint32_t idx)
-{
- if (virtio_vdev_has_feature(vdev, VIRTIO_F_RING_PACKED)) {
- return;
- } else {
- virtio_queue_split_set_vring_states(vdev, n, idx);
- }
-}
-
static void virtio_queue_packed_set_last_avail_idx(VirtIODevice *vdev,
int n, unsigned int idx)
{
diff --git a/include/hw/audio/virtio-snd.h b/include/hw/audio/virtio-snd.h
index 3d79181364..8dafedb276 100644
--- a/include/hw/audio/virtio-snd.h
+++ b/include/hw/audio/virtio-snd.h
@@ -151,7 +151,6 @@ struct VirtIOSoundPCMStream {
QemuMutex queue_mutex;
bool active;
QSIMPLEQ_HEAD(, VirtIOSoundPCMBuffer) queue;
- QSIMPLEQ_HEAD(, VirtIOSoundPCMBuffer) invalid;
};
/*
@@ -223,6 +222,21 @@ struct VirtIOSound {
QemuMutex cmdq_mutex;
QTAILQ_HEAD(, virtio_snd_ctrl_command) cmdq;
bool processing_cmdq;
+ /*
+ * Convenience queue to keep track of invalid tx/rx queue messages inside
+ * the tx/rx callbacks.
+ *
+ * In the callbacks as a first step we are emptying the virtqueue to handle
+ * each message and we cannot add an invalid message back to the queue: we
+ * would re-process it in subsequent loop iterations.
+ *
+ * Instead, we add them to this queue and after finishing examining every
+ * virtqueue element, we inform the guest for each invalid message.
+ *
+ * This queue must be empty at all times except for inside the tx/rx
+ * callbacks.
+ */
+ QSIMPLEQ_HEAD(, VirtIOSoundPCMBuffer) invalid;
};
struct virtio_snd_ctrl_command {
diff --git a/include/hw/virtio/virtio-pci.h b/include/hw/virtio/virtio-pci.h
index 4d57a9c751..59d88018c1 100644
--- a/include/hw/virtio/virtio-pci.h
+++ b/include/hw/virtio/virtio-pci.h
@@ -43,7 +43,6 @@ enum {
VIRTIO_PCI_FLAG_INIT_FLR_BIT,
VIRTIO_PCI_FLAG_AER_BIT,
VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED_BIT,
- VIRTIO_PCI_FLAG_VDPA_BIT,
};
/* Need to activate work-arounds for buggy guests at vmstate load. */
@@ -90,9 +89,6 @@ enum {
#define VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED \
(1 << VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED_BIT)
-/* VDPA supported flags */
-#define VIRTIO_PCI_FLAG_VDPA (1 << VIRTIO_PCI_FLAG_VDPA_BIT)
-
typedef struct {
MSIMessage msg;
int virq;
@@ -144,7 +140,6 @@ struct VirtIOPCIProxy {
};
VirtIOPCIRegion regs[5];
};
- VirtIOPCIRegion lm;
MemoryRegion modern_bar;
MemoryRegion io_bar;
uint32_t legacy_io_bar_idx;
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index b3c74a1bca..c8f72850bc 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -35,9 +35,6 @@
(0x1ULL << VIRTIO_F_NOTIFY_ON_EMPTY) | \
(0x1ULL << VIRTIO_F_ANY_LAYOUT))
-#define LM_DISABLE 0x00
-#define LM_ENABLE 0x01
-
struct VirtQueue;
static inline hwaddr vring_align(hwaddr addr,
@@ -98,11 +95,6 @@ enum virtio_device_endian {
VIRTIO_DEVICE_ENDIAN_BIG,
};
-typedef struct BitmapMemoryRegionCaches {
- struct rcu_head rcu;
- MemoryRegionCache bitmap;
-} BitmapMemoryRegionCaches;
-
/**
* struct VirtIODevice - common VirtIO structure
* @name: name of the device
@@ -136,14 +128,6 @@ struct VirtIODevice
uint32_t generation;
int nvectors;
VirtQueue *vq;
- uint8_t lm_logging_ctrl;
- uint32_t lm_base_addr_low;
- uint32_t lm_base_addr_high;
- uint32_t lm_end_addr_low;
- uint32_t lm_end_addr_high;
-
- BitmapMemoryRegionCaches *caches;
-
MemoryListener listener;
uint16_t device_id;
/* @vm_running: current VM running state via virtio_vmstate_change() */
@@ -395,11 +379,8 @@ hwaddr virtio_queue_get_desc_size(VirtIODevice *vdev, int n);
hwaddr virtio_queue_get_avail_size(VirtIODevice *vdev, int n);
hwaddr virtio_queue_get_used_size(VirtIODevice *vdev, int n);
unsigned int virtio_queue_get_last_avail_idx(VirtIODevice *vdev, int n);
-unsigned int virtio_queue_get_vring_states(VirtIODevice *vdev, int n);
void virtio_queue_set_last_avail_idx(VirtIODevice *vdev, int n,
unsigned int idx);
-void virtio_queue_set_vring_states(VirtIODevice *vdev, int n,
- unsigned int idx);
void virtio_queue_restore_last_avail_idx(VirtIODevice *vdev, int n);
void virtio_queue_invalidate_signalled_used(VirtIODevice *vdev, int n);
void virtio_queue_update_used_idx(VirtIODevice *vdev, int n);
diff --git a/include/standard-headers/linux/virtio_pci.h b/include/standard-headers/linux/virtio_pci.h
index 86733278ba..3e2bc2c97e 100644
--- a/include/standard-headers/linux/virtio_pci.h
+++ b/include/standard-headers/linux/virtio_pci.h
@@ -221,13 +221,6 @@ struct virtio_pci_cfg_cap {
#define VIRTIO_PCI_COMMON_ADM_Q_IDX 60
#define VIRTIO_PCI_COMMON_ADM_Q_NUM 62
-#define LM_LOGGING_CTRL 0
-#define LM_BASE_ADDR_LOW 4
-#define LM_BASE_ADDR_HIGH 8
-#define LM_END_ADDR_LOW 12
-#define LM_END_ADDR_HIGH 16
-#define LM_VRING_STATE_OFFSET 0x20
-
#endif /* VIRTIO_PCI_NO_MODERN */
/* Admin command status. */
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index c1243891c3..840177d19f 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -891,7 +891,7 @@ static DeviceState *find_device_state(const char *id, Error **errp)
dev = (DeviceState *)object_dynamic_cast(obj, TYPE_DEVICE);
if (!dev) {
- error_setg(errp, "%s is not a hotpluggable device", id);
+ error_setg(errp, "%s is not a device", id);
return NULL;
}