aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2014-10-07 10:39:51 -0400
committerMichael S. Tsirkin <mst@redhat.com>2014-12-09 05:05:26 -0500
commitd4674240f31f8c4289abba07d64291c6ddce51bc (patch)
treef4ddf856acbd9d29156998bc4cc59ee55bf10fe7 /drivers/s390
parent6bb2c835c78add24d01351e8c7b040e670c31a46 (diff)
KVM: s390: virtio-ccw revision 1 SET_VQ
The CCW_CMD_SET_VQ command has a different format for revision 1+ devices, allowing to specify a more complex virtqueue layout. For now, we stay however with the old layout and simply use the new command format for virtio-1 devices. Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/kvm/virtio_ccw.c54
1 files changed, 42 insertions, 12 deletions
diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c
index f6eb47b4775b..1c21c08f33be 100644
--- a/drivers/s390/kvm/virtio_ccw.c
+++ b/drivers/s390/kvm/virtio_ccw.c
@@ -68,13 +68,22 @@ struct virtio_ccw_device {
68 void *airq_info; 68 void *airq_info;
69}; 69};
70 70
71struct vq_info_block { 71struct vq_info_block_legacy {
72 __u64 queue; 72 __u64 queue;
73 __u32 align; 73 __u32 align;
74 __u16 index; 74 __u16 index;
75 __u16 num; 75 __u16 num;
76} __packed; 76} __packed;
77 77
78struct vq_info_block {
79 __u64 desc;
80 __u32 res0;
81 __u16 index;
82 __u16 num;
83 __u64 avail;
84 __u64 used;
85} __packed;
86
78struct virtio_feature_desc { 87struct virtio_feature_desc {
79 __u32 features; 88 __u32 features;
80 __u8 index; 89 __u8 index;
@@ -100,7 +109,10 @@ struct virtio_ccw_vq_info {
100 struct virtqueue *vq; 109 struct virtqueue *vq;
101 int num; 110 int num;
102 void *queue; 111 void *queue;
103 struct vq_info_block *info_block; 112 union {
113 struct vq_info_block s;
114 struct vq_info_block_legacy l;
115 } *info_block;
104 int bit_nr; 116 int bit_nr;
105 struct list_head node; 117 struct list_head node;
106 long cookie; 118 long cookie;
@@ -411,13 +423,22 @@ static void virtio_ccw_del_vq(struct virtqueue *vq, struct ccw1 *ccw)
411 spin_unlock_irqrestore(&vcdev->lock, flags); 423 spin_unlock_irqrestore(&vcdev->lock, flags);
412 424
413 /* Release from host. */ 425 /* Release from host. */
414 info->info_block->queue = 0; 426 if (vcdev->revision == 0) {
415 info->info_block->align = 0; 427 info->info_block->l.queue = 0;
416 info->info_block->index = index; 428 info->info_block->l.align = 0;
417 info->info_block->num = 0; 429 info->info_block->l.index = index;
430 info->info_block->l.num = 0;
431 ccw->count = sizeof(info->info_block->l);
432 } else {
433 info->info_block->s.desc = 0;
434 info->info_block->s.index = index;
435 info->info_block->s.num = 0;
436 info->info_block->s.avail = 0;
437 info->info_block->s.used = 0;
438 ccw->count = sizeof(info->info_block->s);
439 }
418 ccw->cmd_code = CCW_CMD_SET_VQ; 440 ccw->cmd_code = CCW_CMD_SET_VQ;
419 ccw->flags = 0; 441 ccw->flags = 0;
420 ccw->count = sizeof(*info->info_block);
421 ccw->cda = (__u32)(unsigned long)(info->info_block); 442 ccw->cda = (__u32)(unsigned long)(info->info_block);
422 ret = ccw_io_helper(vcdev, ccw, 443 ret = ccw_io_helper(vcdev, ccw,
423 VIRTIO_CCW_DOING_SET_VQ | index); 444 VIRTIO_CCW_DOING_SET_VQ | index);
@@ -500,13 +521,22 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
500 } 521 }
501 522
502 /* Register it with the host. */ 523 /* Register it with the host. */
503 info->info_block->queue = (__u64)info->queue; 524 if (vcdev->revision == 0) {
504 info->info_block->align = KVM_VIRTIO_CCW_RING_ALIGN; 525 info->info_block->l.queue = (__u64)info->queue;
505 info->info_block->index = i; 526 info->info_block->l.align = KVM_VIRTIO_CCW_RING_ALIGN;
506 info->info_block->num = info->num; 527 info->info_block->l.index = i;
528 info->info_block->l.num = info->num;
529 ccw->count = sizeof(info->info_block->l);
530 } else {
531 info->info_block->s.desc = (__u64)info->queue;
532 info->info_block->s.index = i;
533 info->info_block->s.num = info->num;
534 info->info_block->s.avail = (__u64)virtqueue_get_avail(vq);
535 info->info_block->s.used = (__u64)virtqueue_get_used(vq);
536 ccw->count = sizeof(info->info_block->s);
537 }
507 ccw->cmd_code = CCW_CMD_SET_VQ; 538 ccw->cmd_code = CCW_CMD_SET_VQ;
508 ccw->flags = 0; 539 ccw->flags = 0;
509 ccw->count = sizeof(*info->info_block);
510 ccw->cda = (__u32)(unsigned long)(info->info_block); 540 ccw->cda = (__u32)(unsigned long)(info->info_block);
511 err = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_SET_VQ | i); 541 err = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_SET_VQ | i);
512 if (err) { 542 if (err) {