diff options
| author | Michael S. Tsirkin <mst@redhat.com> | 2014-12-11 06:37:13 -0500 |
|---|---|---|
| committer | Michael S. Tsirkin <mst@redhat.com> | 2014-12-11 13:04:38 -0500 |
| commit | 30683a8cce8019aa4314c37e629da5c185017166 (patch) | |
| tree | d918ef1f12562036a27e35aa8d189da03f25ae06 | |
| parent | f01a2a811ae04124fc9382925038fcbbd2f0b7c8 (diff) | |
virtio: set VIRTIO_CONFIG_S_FEATURES_OK on restore
virtio 1.0 devices require that drivers set VIRTIO_CONFIG_S_FEATURES_OK
after finalizing features.
virtio core missed doing this on restore, fix it up.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
| -rw-r--r-- | drivers/virtio/virtio.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c index f22665868781..b9f70dfc4751 100644 --- a/drivers/virtio/virtio.c +++ b/drivers/virtio/virtio.c | |||
| @@ -162,6 +162,27 @@ static void virtio_config_enable(struct virtio_device *dev) | |||
| 162 | spin_unlock_irq(&dev->config_lock); | 162 | spin_unlock_irq(&dev->config_lock); |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | static int virtio_finalize_features(struct virtio_device *dev) | ||
| 166 | { | ||
| 167 | int ret = dev->config->finalize_features(dev); | ||
| 168 | unsigned status; | ||
| 169 | |||
| 170 | if (ret) | ||
| 171 | return ret; | ||
| 172 | |||
| 173 | if (!virtio_has_feature(dev, VIRTIO_F_VERSION_1)) | ||
| 174 | return 0; | ||
| 175 | |||
| 176 | add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK); | ||
| 177 | status = dev->config->get_status(dev); | ||
| 178 | if (!(status & VIRTIO_CONFIG_S_FEATURES_OK)) { | ||
| 179 | dev_err(&dev->dev, "virtio: device refuses features: %x\n", | ||
| 180 | status); | ||
| 181 | return -ENODEV; | ||
| 182 | } | ||
| 183 | return 0; | ||
| 184 | } | ||
| 185 | |||
| 165 | static int virtio_dev_probe(struct device *_d) | 186 | static int virtio_dev_probe(struct device *_d) |
| 166 | { | 187 | { |
| 167 | int err, i; | 188 | int err, i; |
| @@ -170,7 +191,6 @@ static int virtio_dev_probe(struct device *_d) | |||
| 170 | u64 device_features; | 191 | u64 device_features; |
| 171 | u64 driver_features; | 192 | u64 driver_features; |
| 172 | u64 driver_features_legacy; | 193 | u64 driver_features_legacy; |
| 173 | unsigned status; | ||
| 174 | 194 | ||
| 175 | /* We have a driver! */ | 195 | /* We have a driver! */ |
| 176 | add_status(dev, VIRTIO_CONFIG_S_DRIVER); | 196 | add_status(dev, VIRTIO_CONFIG_S_DRIVER); |
| @@ -208,21 +228,10 @@ static int virtio_dev_probe(struct device *_d) | |||
| 208 | if (device_features & (1ULL << i)) | 228 | if (device_features & (1ULL << i)) |
| 209 | __virtio_set_bit(dev, i); | 229 | __virtio_set_bit(dev, i); |
| 210 | 230 | ||
| 211 | err = dev->config->finalize_features(dev); | 231 | err = virtio_finalize_features(dev); |
| 212 | if (err) | 232 | if (err) |
| 213 | goto err; | 233 | goto err; |
| 214 | 234 | ||
| 215 | if (virtio_has_feature(dev, VIRTIO_F_VERSION_1)) { | ||
| 216 | add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK); | ||
| 217 | status = dev->config->get_status(dev); | ||
| 218 | if (!(status & VIRTIO_CONFIG_S_FEATURES_OK)) { | ||
| 219 | dev_err(_d, "virtio: device refuses features: %x\n", | ||
| 220 | status); | ||
| 221 | err = -ENODEV; | ||
| 222 | goto err; | ||
| 223 | } | ||
| 224 | } | ||
| 225 | |||
| 226 | err = drv->probe(dev); | 235 | err = drv->probe(dev); |
| 227 | if (err) | 236 | if (err) |
| 228 | goto err; | 237 | goto err; |
| @@ -372,7 +381,7 @@ int virtio_device_restore(struct virtio_device *dev) | |||
| 372 | /* We have a driver! */ | 381 | /* We have a driver! */ |
| 373 | add_status(dev, VIRTIO_CONFIG_S_DRIVER); | 382 | add_status(dev, VIRTIO_CONFIG_S_DRIVER); |
| 374 | 383 | ||
| 375 | ret = dev->config->finalize_features(dev); | 384 | ret = virtio_finalize_features(dev); |
| 376 | if (ret) | 385 | if (ret) |
| 377 | goto err; | 386 | goto err; |
| 378 | 387 | ||
