aboutsummaryrefslogtreecommitdiff
path: root/tests/libqos
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2019-10-23 11:04:17 +0100
committerMichael S. Tsirkin <mst@redhat.com>2019-10-25 07:46:22 -0400
commitc0f79698ed562814158d9652a29e77c97cc074f6 (patch)
treed2c83aa9cf12d40e1b79687b7770cf54aa135d21 /tests/libqos
parent56140fbb8f2bb717eb2670aa1056aeaefe8b0246 (diff)
downloadqemu-c0f79698ed562814158d9652a29e77c97cc074f6.zip
qemu-c0f79698ed562814158d9652a29e77c97cc074f6.tar.gz
qemu-c0f79698ed562814158d9652a29e77c97cc074f6.tar.bz2
libqos: implement VIRTIO 1.0 FEATURES_OK step
Device initialization has an extra step in VIRTIO 1.0. The FEATURES_OK status bit is set to indicate that feature negotiation has completed. The driver then reads the status register again to check that the device agrees with the final features. Implement this step as part of qvirtio_set_features() instead of introducing a separate function. This way all existing code works without modifications. The check in qvirtio_set_driver_ok() needs to be updated because FEATURES_OK will be set for VIRTIO 1.0 devices. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Message-Id: <20191023100425.12168-9-stefanha@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Thomas Huth" <thuth@redhat.com>
Diffstat (limited to 'tests/libqos')
-rw-r--r--tests/libqos/virtio.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c
index 6049ff3..fa597c2 100644
--- a/tests/libqos/virtio.c
+++ b/tests/libqos/virtio.c
@@ -46,6 +46,20 @@ void qvirtio_set_features(QVirtioDevice *d, uint64_t features)
{
d->features = features;
d->bus->set_features(d, features);
+
+ /*
+ * This could be a separate function for drivers that want to access
+ * configuration space before setting FEATURES_OK, but no existing users
+ * need that and it's less code for callers if this is done implicitly.
+ */
+ if (features & (1ull << VIRTIO_F_VERSION_1)) {
+ uint8_t status = d->bus->get_status(d) |
+ VIRTIO_CONFIG_S_FEATURES_OK;
+
+ d->bus->set_status(d, status);
+ g_assert_cmphex(d->bus->get_status(d), ==, status);
+ }
+
d->features_negotiated = true;
}
@@ -86,7 +100,9 @@ void qvirtio_set_driver_ok(QVirtioDevice *d)
{
d->bus->set_status(d, d->bus->get_status(d) | VIRTIO_CONFIG_S_DRIVER_OK);
g_assert_cmphex(d->bus->get_status(d), ==, VIRTIO_CONFIG_S_DRIVER_OK |
- VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_ACKNOWLEDGE);
+ VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_ACKNOWLEDGE |
+ (d->features & (1ull << VIRTIO_F_VERSION_1) ?
+ VIRTIO_CONFIG_S_FEATURES_OK : 0));
}
void qvirtio_wait_queue_isr(QTestState *qts, QVirtioDevice *d,