diff options
| -rw-r--r-- | drivers/s390/virtio/virtio_ccw.c | 30 |
1 files changed, 11 insertions, 19 deletions
diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c index 74c328321889..2c66941ef3d0 100644 --- a/drivers/s390/virtio/virtio_ccw.c +++ b/drivers/s390/virtio/virtio_ccw.c | |||
| @@ -108,7 +108,6 @@ struct virtio_rev_info { | |||
| 108 | struct virtio_ccw_vq_info { | 108 | struct virtio_ccw_vq_info { |
| 109 | struct virtqueue *vq; | 109 | struct virtqueue *vq; |
| 110 | int num; | 110 | int num; |
| 111 | void *queue; | ||
| 112 | union { | 111 | union { |
| 113 | struct vq_info_block s; | 112 | struct vq_info_block s; |
| 114 | struct vq_info_block_legacy l; | 113 | struct vq_info_block_legacy l; |
| @@ -423,7 +422,6 @@ static void virtio_ccw_del_vq(struct virtqueue *vq, struct ccw1 *ccw) | |||
| 423 | struct virtio_ccw_device *vcdev = to_vc_device(vq->vdev); | 422 | struct virtio_ccw_device *vcdev = to_vc_device(vq->vdev); |
| 424 | struct virtio_ccw_vq_info *info = vq->priv; | 423 | struct virtio_ccw_vq_info *info = vq->priv; |
| 425 | unsigned long flags; | 424 | unsigned long flags; |
| 426 | unsigned long size; | ||
| 427 | int ret; | 425 | int ret; |
| 428 | unsigned int index = vq->index; | 426 | unsigned int index = vq->index; |
| 429 | 427 | ||
| @@ -461,8 +459,6 @@ static void virtio_ccw_del_vq(struct virtqueue *vq, struct ccw1 *ccw) | |||
| 461 | ret, index); | 459 | ret, index); |
| 462 | 460 | ||
| 463 | vring_del_virtqueue(vq); | 461 | vring_del_virtqueue(vq); |
| 464 | size = PAGE_ALIGN(vring_size(info->num, KVM_VIRTIO_CCW_RING_ALIGN)); | ||
| 465 | free_pages_exact(info->queue, size); | ||
| 466 | kfree(info->info_block); | 462 | kfree(info->info_block); |
| 467 | kfree(info); | 463 | kfree(info); |
| 468 | } | 464 | } |
| @@ -494,8 +490,9 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev, | |||
| 494 | int err; | 490 | int err; |
| 495 | struct virtqueue *vq = NULL; | 491 | struct virtqueue *vq = NULL; |
| 496 | struct virtio_ccw_vq_info *info; | 492 | struct virtio_ccw_vq_info *info; |
| 497 | unsigned long size = 0; /* silence the compiler */ | 493 | u64 queue; |
| 498 | unsigned long flags; | 494 | unsigned long flags; |
| 495 | bool may_reduce; | ||
| 499 | 496 | ||
| 500 | /* Allocate queue. */ | 497 | /* Allocate queue. */ |
| 501 | info = kzalloc(sizeof(struct virtio_ccw_vq_info), GFP_KERNEL); | 498 | info = kzalloc(sizeof(struct virtio_ccw_vq_info), GFP_KERNEL); |
| @@ -516,33 +513,30 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev, | |||
| 516 | err = info->num; | 513 | err = info->num; |
| 517 | goto out_err; | 514 | goto out_err; |
| 518 | } | 515 | } |
| 519 | size = PAGE_ALIGN(vring_size(info->num, KVM_VIRTIO_CCW_RING_ALIGN)); | 516 | may_reduce = vcdev->revision > 0; |
| 520 | info->queue = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO); | 517 | vq = vring_create_virtqueue(i, info->num, KVM_VIRTIO_CCW_RING_ALIGN, |
| 521 | if (info->queue == NULL) { | 518 | vdev, true, may_reduce, ctx, |
| 522 | dev_warn(&vcdev->cdev->dev, "no queue\n"); | 519 | virtio_ccw_kvm_notify, callback, name); |
| 523 | err = -ENOMEM; | ||
| 524 | goto out_err; | ||
| 525 | } | ||
| 526 | 520 | ||
| 527 | vq = vring_new_virtqueue(i, info->num, KVM_VIRTIO_CCW_RING_ALIGN, vdev, | ||
| 528 | true, ctx, info->queue, virtio_ccw_kvm_notify, | ||
| 529 | callback, name); | ||
| 530 | if (!vq) { | 521 | if (!vq) { |
| 531 | /* For now, we fail if we can't get the requested size. */ | 522 | /* For now, we fail if we can't get the requested size. */ |
| 532 | dev_warn(&vcdev->cdev->dev, "no vq\n"); | 523 | dev_warn(&vcdev->cdev->dev, "no vq\n"); |
| 533 | err = -ENOMEM; | 524 | err = -ENOMEM; |
| 534 | goto out_err; | 525 | goto out_err; |
| 535 | } | 526 | } |
| 527 | /* it may have been reduced */ | ||
| 528 | info->num = virtqueue_get_vring_size(vq); | ||
| 536 | 529 | ||
| 537 | /* Register it with the host. */ | 530 | /* Register it with the host. */ |
| 531 | queue = virtqueue_get_desc_addr(vq); | ||
| 538 | if (vcdev->revision == 0) { | 532 | if (vcdev->revision == 0) { |
| 539 | info->info_block->l.queue = (__u64)info->queue; | 533 | info->info_block->l.queue = queue; |
| 540 | info->info_block->l.align = KVM_VIRTIO_CCW_RING_ALIGN; | 534 | info->info_block->l.align = KVM_VIRTIO_CCW_RING_ALIGN; |
| 541 | info->info_block->l.index = i; | 535 | info->info_block->l.index = i; |
| 542 | info->info_block->l.num = info->num; | 536 | info->info_block->l.num = info->num; |
| 543 | ccw->count = sizeof(info->info_block->l); | 537 | ccw->count = sizeof(info->info_block->l); |
| 544 | } else { | 538 | } else { |
| 545 | info->info_block->s.desc = (__u64)info->queue; | 539 | info->info_block->s.desc = queue; |
| 546 | info->info_block->s.index = i; | 540 | info->info_block->s.index = i; |
| 547 | info->info_block->s.num = info->num; | 541 | info->info_block->s.num = info->num; |
| 548 | info->info_block->s.avail = (__u64)virtqueue_get_avail(vq); | 542 | info->info_block->s.avail = (__u64)virtqueue_get_avail(vq); |
| @@ -572,8 +566,6 @@ out_err: | |||
| 572 | if (vq) | 566 | if (vq) |
| 573 | vring_del_virtqueue(vq); | 567 | vring_del_virtqueue(vq); |
| 574 | if (info) { | 568 | if (info) { |
| 575 | if (info->queue) | ||
| 576 | free_pages_exact(info->queue, size); | ||
| 577 | kfree(info->info_block); | 569 | kfree(info->info_block); |
| 578 | } | 570 | } |
| 579 | kfree(info); | 571 | kfree(info); |
