aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2015-04-01 00:13:15 -0400
committerRusty Russell <rusty@rustcorp.com.au>2015-04-01 00:13:34 -0400
commita8557d32fe90a91d70dbbf57a034ad0c660ce237 (patch)
treebbb62a88af00743838db82c35b357c260f013b60
parentc5d4c2c9ce4f4b6980a71dec50f2db4c2e55778d (diff)
virtio_pci_modern: switch to type-safe io accessors
As Rusty noted, we were accessing queue_enable with an incorrect width. Switch to type-safe accessors so we don't make this mistake again in the future. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
-rw-r--r--drivers/virtio/virtio_pci_modern.c83
1 files changed, 42 insertions, 41 deletions
diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c
index 826e500d4819..cb175f7179d1 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -57,6 +57,13 @@ static inline void vp_iowrite32(u32 value, u32 __iomem *addr)
57 iowrite32(value, addr); 57 iowrite32(value, addr);
58} 58}
59 59
60static void vp_iowrite64_twopart(u64 val,
61 __le32 __iomem *lo, __le32 __iomem *hi)
62{
63 vp_iowrite32((u32)val, lo);
64 vp_iowrite32(val >> 32, hi);
65}
66
60static void __iomem *map_capability(struct pci_dev *dev, int off, 67static void __iomem *map_capability(struct pci_dev *dev, int off,
61 size_t minlen, 68 size_t minlen,
62 u32 align, 69 u32 align,
@@ -131,22 +138,16 @@ static void __iomem *map_capability(struct pci_dev *dev, int off,
131 return p; 138 return p;
132} 139}
133 140
134static void iowrite64_twopart(u64 val, __le32 __iomem *lo, __le32 __iomem *hi)
135{
136 iowrite32((u32)val, lo);
137 iowrite32(val >> 32, hi);
138}
139
140/* virtio config->get_features() implementation */ 141/* virtio config->get_features() implementation */
141static u64 vp_get_features(struct virtio_device *vdev) 142static u64 vp_get_features(struct virtio_device *vdev)
142{ 143{
143 struct virtio_pci_device *vp_dev = to_vp_device(vdev); 144 struct virtio_pci_device *vp_dev = to_vp_device(vdev);
144 u64 features; 145 u64 features;
145 146
146 iowrite32(0, &vp_dev->common->device_feature_select); 147 vp_iowrite32(0, &vp_dev->common->device_feature_select);
147 features = ioread32(&vp_dev->common->device_feature); 148 features = vp_ioread32(&vp_dev->common->device_feature);
148 iowrite32(1, &vp_dev->common->device_feature_select); 149 vp_iowrite32(1, &vp_dev->common->device_feature_select);
149 features |= ((u64)ioread32(&vp_dev->common->device_feature) << 32); 150 features |= ((u64)vp_ioread32(&vp_dev->common->device_feature) << 32);
150 151
151 return features; 152 return features;
152} 153}
@@ -165,10 +166,10 @@ static int vp_finalize_features(struct virtio_device *vdev)
165 return -EINVAL; 166 return -EINVAL;
166 } 167 }
167 168
168 iowrite32(0, &vp_dev->common->guest_feature_select); 169 vp_iowrite32(0, &vp_dev->common->guest_feature_select);
169 iowrite32((u32)vdev->features, &vp_dev->common->guest_feature); 170 vp_iowrite32((u32)vdev->features, &vp_dev->common->guest_feature);
170 iowrite32(1, &vp_dev->common->guest_feature_select); 171 vp_iowrite32(1, &vp_dev->common->guest_feature_select);
171 iowrite32(vdev->features >> 32, &vp_dev->common->guest_feature); 172 vp_iowrite32(vdev->features >> 32, &vp_dev->common->guest_feature);
172 173
173 return 0; 174 return 0;
174} 175}
@@ -247,14 +248,14 @@ static void vp_set(struct virtio_device *vdev, unsigned offset,
247static u32 vp_generation(struct virtio_device *vdev) 248static u32 vp_generation(struct virtio_device *vdev)
248{ 249{
249 struct virtio_pci_device *vp_dev = to_vp_device(vdev); 250 struct virtio_pci_device *vp_dev = to_vp_device(vdev);
250 return ioread8(&vp_dev->common->config_generation); 251 return vp_ioread8(&vp_dev->common->config_generation);
251} 252}
252 253
253/* config->{get,set}_status() implementations */ 254/* config->{get,set}_status() implementations */
254static u8 vp_get_status(struct virtio_device *vdev) 255static u8 vp_get_status(struct virtio_device *vdev)
255{ 256{
256 struct virtio_pci_device *vp_dev = to_vp_device(vdev); 257 struct virtio_pci_device *vp_dev = to_vp_device(vdev);
257 return ioread8(&vp_dev->common->device_status); 258 return vp_ioread8(&vp_dev->common->device_status);
258} 259}
259 260
260static void vp_set_status(struct virtio_device *vdev, u8 status) 261static void vp_set_status(struct virtio_device *vdev, u8 status)
@@ -262,17 +263,17 @@ static void vp_set_status(struct virtio_device *vdev, u8 status)
262 struct virtio_pci_device *vp_dev = to_vp_device(vdev); 263 struct virtio_pci_device *vp_dev = to_vp_device(vdev);
263 /* We should never be setting status to 0. */ 264 /* We should never be setting status to 0. */
264 BUG_ON(status == 0); 265 BUG_ON(status == 0);
265 iowrite8(status, &vp_dev->common->device_status); 266 vp_iowrite8(status, &vp_dev->common->device_status);
266} 267}
267 268
268static void vp_reset(struct virtio_device *vdev) 269static void vp_reset(struct virtio_device *vdev)
269{ 270{
270 struct virtio_pci_device *vp_dev = to_vp_device(vdev); 271 struct virtio_pci_device *vp_dev = to_vp_device(vdev);
271 /* 0 status means a reset. */ 272 /* 0 status means a reset. */
272 iowrite8(0, &vp_dev->common->device_status); 273 vp_iowrite8(0, &vp_dev->common->device_status);
273 /* Flush out the status write, and flush in device writes, 274 /* Flush out the status write, and flush in device writes,
274 * including MSI-X interrupts, if any. */ 275 * including MSI-X interrupts, if any. */
275 ioread8(&vp_dev->common->device_status); 276 vp_ioread8(&vp_dev->common->device_status);
276 /* Flush pending VQ/configuration callbacks. */ 277 /* Flush pending VQ/configuration callbacks. */
277 vp_synchronize_vectors(vdev); 278 vp_synchronize_vectors(vdev);
278} 279}
@@ -280,10 +281,10 @@ static void vp_reset(struct virtio_device *vdev)
280static u16 vp_config_vector(struct virtio_pci_device *vp_dev, u16 vector) 281static u16 vp_config_vector(struct virtio_pci_device *vp_dev, u16 vector)
281{ 282{
282 /* Setup the vector used for configuration events */ 283 /* Setup the vector used for configuration events */
283 iowrite16(vector, &vp_dev->common->msix_config); 284 vp_iowrite16(vector, &vp_dev->common->msix_config);
284 /* Verify we had enough resources to assign the vector */ 285 /* Verify we had enough resources to assign the vector */
285 /* Will also flush the write out to device */ 286 /* Will also flush the write out to device */
286 return ioread16(&vp_dev->common->msix_config); 287 return vp_ioread16(&vp_dev->common->msix_config);
287} 288}
288 289
289static size_t vring_pci_size(u16 num) 290static size_t vring_pci_size(u16 num)
@@ -323,15 +324,15 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
323 u16 num, off; 324 u16 num, off;
324 int err; 325 int err;
325 326
326 if (index >= ioread16(&cfg->num_queues)) 327 if (index >= vp_ioread16(&cfg->num_queues))
327 return ERR_PTR(-ENOENT); 328 return ERR_PTR(-ENOENT);
328 329
329 /* Select the queue we're interested in */ 330 /* Select the queue we're interested in */
330 iowrite16(index, &cfg->queue_select); 331 vp_iowrite16(index, &cfg->queue_select);
331 332
332 /* Check if queue is either not available or already active. */ 333 /* Check if queue is either not available or already active. */
333 num = ioread16(&cfg->queue_size); 334 num = vp_ioread16(&cfg->queue_size);
334 if (!num || ioread16(&cfg->queue_enable)) 335 if (!num || vp_ioread16(&cfg->queue_enable))
335 return ERR_PTR(-ENOENT); 336 return ERR_PTR(-ENOENT);
336 337
337 if (num & (num - 1)) { 338 if (num & (num - 1)) {
@@ -340,7 +341,7 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
340 } 341 }
341 342
342 /* get offset of notification word for this vq */ 343 /* get offset of notification word for this vq */
343 off = ioread16(&cfg->queue_notify_off); 344 off = vp_ioread16(&cfg->queue_notify_off);
344 345
345 info->num = num; 346 info->num = num;
346 info->msix_vector = msix_vec; 347 info->msix_vector = msix_vec;
@@ -359,13 +360,13 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
359 } 360 }
360 361
361 /* activate the queue */ 362 /* activate the queue */
362 iowrite16(num, &cfg->queue_size); 363 vp_iowrite16(num, &cfg->queue_size);
363 iowrite64_twopart(virt_to_phys(info->queue), 364 vp_iowrite64_twopart(virt_to_phys(info->queue),
364 &cfg->queue_desc_lo, &cfg->queue_desc_hi); 365 &cfg->queue_desc_lo, &cfg->queue_desc_hi);
365 iowrite64_twopart(virt_to_phys(virtqueue_get_avail(vq)), 366 vp_iowrite64_twopart(virt_to_phys(virtqueue_get_avail(vq)),
366 &cfg->queue_avail_lo, &cfg->queue_avail_hi); 367 &cfg->queue_avail_lo, &cfg->queue_avail_hi);
367 iowrite64_twopart(virt_to_phys(virtqueue_get_used(vq)), 368 vp_iowrite64_twopart(virt_to_phys(virtqueue_get_used(vq)),
368 &cfg->queue_used_lo, &cfg->queue_used_hi); 369 &cfg->queue_used_lo, &cfg->queue_used_hi);
369 370
370 if (vp_dev->notify_base) { 371 if (vp_dev->notify_base) {
371 /* offset should not wrap */ 372 /* offset should not wrap */
@@ -394,8 +395,8 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
394 } 395 }
395 396
396 if (msix_vec != VIRTIO_MSI_NO_VECTOR) { 397 if (msix_vec != VIRTIO_MSI_NO_VECTOR) {
397 iowrite16(msix_vec, &cfg->queue_msix_vector); 398 vp_iowrite16(msix_vec, &cfg->queue_msix_vector);
398 msix_vec = ioread16(&cfg->queue_msix_vector); 399 msix_vec = vp_ioread16(&cfg->queue_msix_vector);
399 if (msix_vec == VIRTIO_MSI_NO_VECTOR) { 400 if (msix_vec == VIRTIO_MSI_NO_VECTOR) {
400 err = -EBUSY; 401 err = -EBUSY;
401 goto err_assign_vector; 402 goto err_assign_vector;
@@ -430,8 +431,8 @@ static int vp_modern_find_vqs(struct virtio_device *vdev, unsigned nvqs,
430 * this, there's no way to go back except reset. 431 * this, there's no way to go back except reset.
431 */ 432 */
432 list_for_each_entry(vq, &vdev->vqs, list) { 433 list_for_each_entry(vq, &vdev->vqs, list) {
433 iowrite16(vq->index, &vp_dev->common->queue_select); 434 vp_iowrite16(vq->index, &vp_dev->common->queue_select);
434 iowrite16(1, &vp_dev->common->queue_enable); 435 vp_iowrite16(1, &vp_dev->common->queue_enable);
435 } 436 }
436 437
437 return 0; 438 return 0;
@@ -442,13 +443,13 @@ static void del_vq(struct virtio_pci_vq_info *info)
442 struct virtqueue *vq = info->vq; 443 struct virtqueue *vq = info->vq;
443 struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev); 444 struct virtio_pci_device *vp_dev = to_vp_device(vq->vdev);
444 445
445 iowrite16(vq->index, &vp_dev->common->queue_select); 446 vp_iowrite16(vq->index, &vp_dev->common->queue_select);
446 447
447 if (vp_dev->msix_enabled) { 448 if (vp_dev->msix_enabled) {
448 iowrite16(VIRTIO_MSI_NO_VECTOR, 449 vp_iowrite16(VIRTIO_MSI_NO_VECTOR,
449 &vp_dev->common->queue_msix_vector); 450 &vp_dev->common->queue_msix_vector);
450 /* Flush the write out to device */ 451 /* Flush the write out to device */
451 ioread16(&vp_dev->common->queue_msix_vector); 452 vp_ioread16(&vp_dev->common->queue_msix_vector);
452 } 453 }
453 454
454 if (!vp_dev->notify_base) 455 if (!vp_dev->notify_base)