diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-04-09 16:25:38 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-04-09 16:25:39 +0100 |
commit | a84e937649f09d372e677b3978a933f1207513a2 (patch) | |
tree | 7a5b5dfc0e152d736ae3d443b4013330d5cc6f03 | |
parent | 9005774b27b6aa5e1c99d80bd59d5d048c2f7077 (diff) | |
parent | d434e5ac5d70e9da7d20e50246af9251a125bdad (diff) | |
download | qemu-a84e937649f09d372e677b3978a933f1207513a2.zip qemu-a84e937649f09d372e677b3978a933f1207513a2.tar.gz qemu-a84e937649f09d372e677b3978a933f1207513a2.tar.bz2 |
Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
virtio,vhost: fixes
Add a feature flag for new protocol messages.
Misc fixes.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
# gpg: Signature made Mon 09 Apr 2018 15:37:29 BST
# gpg: using RSA key 281F0DB8D28D5469
# gpg: Good signature from "Michael S. Tsirkin <mst@kernel.org>"
# gpg: aka "Michael S. Tsirkin <mst@redhat.com>"
# Primary key fingerprint: 0270 606B 6F3C DF3D 0B17 0970 C350 3912 AFBE 8E67
# Subkey fingerprint: 5D09 FD08 71C8 F85B 94CA 8A0D 281F 0DB8 D28D 5469
* remotes/mst/tags/for_upstream:
virtio-serial: fix heap-over-flow
vhost: Allow adjoining regions
contrib/libvhost-user: add the protocol feature used for SET/GET message
vhost-user: back SET/GET_CONFIG requests with a protocol feature
vhost-user-blk: set config ops before vhost-user init
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | contrib/libvhost-user/libvhost-user.h | 1 | ||||
-rw-r--r-- | docs/interop/vhost-user.txt | 21 | ||||
-rw-r--r-- | hw/block/vhost-user-blk.c | 4 | ||||
-rw-r--r-- | hw/char/virtio-serial-bus.c | 7 | ||||
-rw-r--r-- | hw/virtio/vhost-user.c | 22 | ||||
-rw-r--r-- | hw/virtio/vhost.c | 14 |
6 files changed, 51 insertions, 18 deletions
diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h index 79f7a53..b27075e 100644 --- a/contrib/libvhost-user/libvhost-user.h +++ b/contrib/libvhost-user/libvhost-user.h @@ -50,6 +50,7 @@ enum VhostUserProtocolFeature { VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6, VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7, VHOST_USER_PROTOCOL_F_PAGEFAULT = 8, + VHOST_USER_PROTOCOL_F_CONFIG = 9, VHOST_USER_PROTOCOL_F_MAX }; diff --git a/docs/interop/vhost-user.txt b/docs/interop/vhost-user.txt index c058c40..534caab 100644 --- a/docs/interop/vhost-user.txt +++ b/docs/interop/vhost-user.txt @@ -379,6 +379,7 @@ Protocol features #define VHOST_USER_PROTOCOL_F_CROSS_ENDIAN 6 #define VHOST_USER_PROTOCOL_F_CRYPTO_SESSION 7 #define VHOST_USER_PROTOCOL_F_PAGEFAULT 8 +#define VHOST_USER_PROTOCOL_F_CONFIG 9 Master message types -------------------- @@ -664,7 +665,8 @@ Master message types Master payload: virtio device config space Slave payload: virtio device config space - Submitted by the vhost-user master to fetch the contents of the virtio + When VHOST_USER_PROTOCOL_F_CONFIG is negotiated, this message is + submitted by the vhost-user master to fetch the contents of the virtio device configuration space, vhost-user slave's payload size MUST match master's request, vhost-user slave uses zero length of payload to indicate an error to vhost-user master. The vhost-user master may @@ -677,7 +679,8 @@ Master message types Master payload: virtio device config space Slave payload: N/A - Submitted by the vhost-user master when the Guest changes the virtio + When VHOST_USER_PROTOCOL_F_CONFIG is negotiated, this message is + submitted by the vhost-user master when the Guest changes the virtio device configuration space and also can be used for live migration on the destination host. The vhost-user slave must check the flags field, and slaves MUST NOT accept SET_CONFIG for read-only @@ -766,13 +769,13 @@ Slave message types Slave payload: N/A Master payload: N/A - Vhost-user slave sends such messages to notify that the virtio device's - configuration space has changed, for those host devices which can support - such feature, host driver can send VHOST_USER_GET_CONFIG message to slave - to get the latest content. If VHOST_USER_PROTOCOL_F_REPLY_ACK is - negotiated, and slave set the VHOST_USER_NEED_REPLY flag, master must - respond with zero when operation is successfully completed, or non-zero - otherwise. + When VHOST_USER_PROTOCOL_F_CONFIG is negotiated, vhost-user slave sends + such messages to notify that the virtio device's configuration space has + changed, for those host devices which can support such feature, host + driver can send VHOST_USER_GET_CONFIG message to slave to get the latest + content. If VHOST_USER_PROTOCOL_F_REPLY_ACK is negotiated, and slave set + the VHOST_USER_NEED_REPLY flag, master must respond with zero when + operation is successfully completed, or non-zero otherwise. VHOST_USER_PROTOCOL_F_REPLY_ACK: ------------------------------- diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index f840f07..262baca 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -259,6 +259,8 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp) s->dev.vq_index = 0; s->dev.backend_features = 0; + vhost_dev_set_config_notifier(&s->dev, &blk_ops); + ret = vhost_dev_init(&s->dev, &s->chardev, VHOST_BACKEND_TYPE_USER, 0); if (ret < 0) { error_setg(errp, "vhost-user-blk: vhost initialization failed: %s", @@ -277,8 +279,6 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp) s->blkcfg.num_queues = s->num_queues; } - vhost_dev_set_config_notifier(&s->dev, &blk_ops); - return; vhost_err: diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index 9470bd7..d2dd8ab 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -580,13 +580,16 @@ static void set_config(VirtIODevice *vdev, const uint8_t *config_data) VirtIOSerial *vser = VIRTIO_SERIAL(vdev); struct virtio_console_config *config = (struct virtio_console_config *)config_data; - uint8_t emerg_wr_lo = le32_to_cpu(config->emerg_wr); VirtIOSerialPort *port = find_first_connected_console(vser); VirtIOSerialPortClass *vsc; + uint8_t emerg_wr_lo; - if (!config->emerg_wr) { + if (!virtio_has_feature(vser->host_features, + VIRTIO_CONSOLE_F_EMERG_WRITE) || !config->emerg_wr) { return; } + + emerg_wr_lo = le32_to_cpu(config->emerg_wr); /* Make sure we don't misdetect an emergency write when the guest * does a short config write after an emergency write. */ config->emerg_wr = 0; diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index 44aea5c..38da869 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -46,6 +46,7 @@ enum VhostUserProtocolFeature { VHOST_USER_PROTOCOL_F_CROSS_ENDIAN = 6, VHOST_USER_PROTOCOL_F_CRYPTO_SESSION = 7, VHOST_USER_PROTOCOL_F_PAGEFAULT = 8, + VHOST_USER_PROTOCOL_F_CONFIG = 9, VHOST_USER_PROTOCOL_F_MAX }; @@ -1211,6 +1212,17 @@ static int vhost_user_init(struct vhost_dev *dev, void *opaque) dev->protocol_features = protocol_features & VHOST_USER_PROTOCOL_FEATURE_MASK; + + if (!dev->config_ops || !dev->config_ops->vhost_dev_config_notifier) { + /* Don't acknowledge CONFIG feature if device doesn't support it */ + dev->protocol_features &= ~(1ULL << VHOST_USER_PROTOCOL_F_CONFIG); + } else if (!(protocol_features & + (1ULL << VHOST_USER_PROTOCOL_F_CONFIG))) { + error_report("Device expects VHOST_USER_PROTOCOL_F_CONFIG " + "but backend does not support it."); + return -1; + } + err = vhost_user_set_protocol_features(dev, dev->protocol_features); if (err < 0) { return err; @@ -1405,6 +1417,11 @@ static int vhost_user_get_config(struct vhost_dev *dev, uint8_t *config, .hdr.size = VHOST_USER_CONFIG_HDR_SIZE + config_len, }; + if (!virtio_has_feature(dev->protocol_features, + VHOST_USER_PROTOCOL_F_CONFIG)) { + return -1; + } + if (config_len > VHOST_USER_MAX_CONFIG_SIZE) { return -1; } @@ -1448,6 +1465,11 @@ static int vhost_user_set_config(struct vhost_dev *dev, const uint8_t *data, .hdr.size = VHOST_USER_CONFIG_HDR_SIZE + size, }; + if (!virtio_has_feature(dev->protocol_features, + VHOST_USER_PROTOCOL_F_CONFIG)) { + return -1; + } + if (reply_supported) { msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK; } diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 250f886..a21a5a2 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -595,10 +595,15 @@ static void vhost_region_add_section(struct vhost_dev *dev, prev_sec->offset_within_address_space, prev_sec->offset_within_region); } else { - error_report("%s: Overlapping but not coherent sections " - "at %"PRIx64, - __func__, mrs_gpa); - return; + /* adjoining regions are fine, but overlapping ones with + * different blocks/offsets shouldn't happen + */ + if (mrs_gpa != prev_gpa_end + 1) { + error_report("%s: Overlapping but not coherent sections " + "at %"PRIx64, + __func__, mrs_gpa); + return; + } } } } @@ -1451,7 +1456,6 @@ int vhost_dev_set_config(struct vhost_dev *hdev, const uint8_t *data, void vhost_dev_set_config_notifier(struct vhost_dev *hdev, const VhostDevConfigOps *ops) { - assert(hdev->vhost_ops); hdev->config_ops = ops; } |