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 | ||