diff options
| author | Michael S. Tsirkin <mst@redhat.com> | 2015-04-01 00:13:15 -0400 |
|---|---|---|
| committer | Rusty Russell <rusty@rustcorp.com.au> | 2015-04-01 00:13:34 -0400 |
| commit | a8557d32fe90a91d70dbbf57a034ad0c660ce237 (patch) | |
| tree | bbb62a88af00743838db82c35b357c260f013b60 /drivers/virtio | |
| parent | c5d4c2c9ce4f4b6980a71dec50f2db4c2e55778d (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>
Diffstat (limited to 'drivers/virtio')
| -rw-r--r-- | drivers/virtio/virtio_pci_modern.c | 83 |
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 | ||
| 60 | static 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 | |||
| 60 | static void __iomem *map_capability(struct pci_dev *dev, int off, | 67 | static 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 | ||
| 134 | static 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 */ |
| 141 | static u64 vp_get_features(struct virtio_device *vdev) | 142 | static 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, | |||
| 247 | static u32 vp_generation(struct virtio_device *vdev) | 248 | static 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 */ |
| 254 | static u8 vp_get_status(struct virtio_device *vdev) | 255 | static 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 | ||
| 260 | static void vp_set_status(struct virtio_device *vdev, u8 status) | 261 | static 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 | ||
| 268 | static void vp_reset(struct virtio_device *vdev) | 269 | static 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) | |||
| 280 | static u16 vp_config_vector(struct virtio_pci_device *vp_dev, u16 vector) | 281 | static 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 | ||
| 289 | static size_t vring_pci_size(u16 num) | 290 | static 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) |
