diff options
author | Peter Maydell | 2018-02-02 17:26:41 +0100 |
---|---|---|
committer | Peter Maydell | 2018-02-02 17:26:41 +0100 |
commit | f74425e267f81f0f94adf47ecbd66224e0461936 (patch) | |
tree | b73f3aed99966e35fac6a38126bc79882c69b396 /tests/libqos/virtio.c | |
parent | Merge remote-tracking branch 'remotes/kraxel/tags/audio-20180202-pull-request... (diff) | |
parent | tests/virtio-9p: explicitly handle potential integer overflows (diff) | |
download | qemu-f74425e267f81f0f94adf47ecbd66224e0461936.tar.gz qemu-f74425e267f81f0f94adf47ecbd66224e0461936.tar.xz qemu-f74425e267f81f0f94adf47ecbd66224e0461936.zip |
Merge remote-tracking branch 'remotes/gkurz/tags/for-upstream' into staging
This series is mostly about 9p request cancellation. It fixes a
long standing bug (read "specification violation") where the server
would send an invalid response when the client has cancelled an
in-flight request. This was causing annoying spurious EINTR returns
in linux. The fix comes with some related testing in QTEST.
Other patches are code cleanup and improvements.
# gpg: Signature made Fri 02 Feb 2018 10:16:03 GMT
# gpg: using RSA key 71D4D5E5822F73D6
# gpg: Good signature from "Greg Kurz <groug@kaod.org>"
# gpg: aka "Gregory Kurz <gregory.kurz@free.fr>"
# gpg: aka "[jpeg image of size 3330]"
# Primary key fingerprint: B482 8BAF 9431 40CE F2A3 4910 71D4 D5E5 822F 73D6
* remotes/gkurz/tags/for-upstream:
tests/virtio-9p: explicitly handle potential integer overflows
tests: virtio-9p: add FLUSH operation test
libqos/virtio: return length written into used descriptor
tests: virtio-9p: add WRITE operation test
tests: virtio-9p: add LOPEN operation test
tests: virtio-9p: use the synth backend
tests: virtio-9p: wait for completion in the test code
tests: virtio-9p: move request tag to the test functions
9pfs: Correctly handle cancelled requests
9pfs: drop v9fs_register_transport()
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests/libqos/virtio.c')
-rw-r--r-- | tests/libqos/virtio.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c index 0879a621c8..0dad5c19ac 100644 --- a/tests/libqos/virtio.c +++ b/tests/libqos/virtio.c @@ -119,6 +119,8 @@ uint8_t qvirtio_wait_status_byte_no_isr(QVirtioDevice *d, /* * qvirtio_wait_used_elem: * @desc_idx: The next expected vq->desc[] index in the used ring + * @len: A pointer that is filled with the length written into the buffer, may + * be NULL * @timeout_us: How many microseconds to wait before failing * * This function waits for the next completed request on the used ring. @@ -126,6 +128,7 @@ uint8_t qvirtio_wait_status_byte_no_isr(QVirtioDevice *d, void qvirtio_wait_used_elem(QVirtioDevice *d, QVirtQueue *vq, uint32_t desc_idx, + uint32_t *len, gint64 timeout_us) { gint64 start_time = g_get_monotonic_time(); @@ -136,7 +139,7 @@ void qvirtio_wait_used_elem(QVirtioDevice *d, clock_step(100); if (d->bus->get_queue_isr_status(d, vq) && - qvirtqueue_get_buf(vq, &got_desc_idx)) { + qvirtqueue_get_buf(vq, &got_desc_idx, len)) { g_assert_cmpint(got_desc_idx, ==, desc_idx); return; } @@ -304,30 +307,36 @@ void qvirtqueue_kick(QVirtioDevice *d, QVirtQueue *vq, uint32_t free_head) /* * qvirtqueue_get_buf: * @desc_idx: A pointer that is filled with the vq->desc[] index, may be NULL + * @len: A pointer that is filled with the length written into the buffer, may + * be NULL * * This function gets the next used element if there is one ready. * * Returns: true if an element was ready, false otherwise */ -bool qvirtqueue_get_buf(QVirtQueue *vq, uint32_t *desc_idx) +bool qvirtqueue_get_buf(QVirtQueue *vq, uint32_t *desc_idx, uint32_t *len) { uint16_t idx; + uint64_t elem_addr; idx = readw(vq->used + offsetof(struct vring_used, idx)); if (idx == vq->last_used_idx) { return false; } - if (desc_idx) { - uint64_t elem_addr; + elem_addr = vq->used + + offsetof(struct vring_used, ring) + + (vq->last_used_idx % vq->size) * + sizeof(struct vring_used_elem); - elem_addr = vq->used + - offsetof(struct vring_used, ring) + - (vq->last_used_idx % vq->size) * - sizeof(struct vring_used_elem); + if (desc_idx) { *desc_idx = readl(elem_addr + offsetof(struct vring_used_elem, id)); } + if (len) { + *len = readw(elem_addr + offsetof(struct vring_used_elem, len)); + } + vq->last_used_idx++; return true; } |