Commit d4674240 authored by Cornelia Huck's avatar Cornelia Huck Committed by Michael S. Tsirkin
Browse files

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: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Reviewed-by: default avatarDavid Hildenbrand <dahi@linux.vnet.ibm.com>


parent 6bb2c835
Loading
Loading
Loading
Loading
+42 −12
Original line number Diff line number Diff line
@@ -68,13 +68,22 @@ struct virtio_ccw_device {
	void *airq_info;
};

struct vq_info_block {
struct vq_info_block_legacy {
	__u64 queue;
	__u32 align;
	__u16 index;
	__u16 num;
} __packed;

struct vq_info_block {
	__u64 desc;
	__u32 res0;
	__u16 index;
	__u16 num;
	__u64 avail;
	__u64 used;
} __packed;

struct virtio_feature_desc {
	__u32 features;
	__u8 index;
@@ -100,7 +109,10 @@ struct virtio_ccw_vq_info {
	struct virtqueue *vq;
	int num;
	void *queue;
	struct vq_info_block *info_block;
	union {
		struct vq_info_block s;
		struct vq_info_block_legacy l;
	} *info_block;
	int bit_nr;
	struct list_head node;
	long cookie;
@@ -411,13 +423,22 @@ static void virtio_ccw_del_vq(struct virtqueue *vq, struct ccw1 *ccw)
	spin_unlock_irqrestore(&vcdev->lock, flags);

	/* Release from host. */
	info->info_block->queue = 0;
	info->info_block->align = 0;
	info->info_block->index = index;
	info->info_block->num = 0;
	if (vcdev->revision == 0) {
		info->info_block->l.queue = 0;
		info->info_block->l.align = 0;
		info->info_block->l.index = index;
		info->info_block->l.num = 0;
		ccw->count = sizeof(info->info_block->l);
	} else {
		info->info_block->s.desc = 0;
		info->info_block->s.index = index;
		info->info_block->s.num = 0;
		info->info_block->s.avail = 0;
		info->info_block->s.used = 0;
		ccw->count = sizeof(info->info_block->s);
	}
	ccw->cmd_code = CCW_CMD_SET_VQ;
	ccw->flags = 0;
	ccw->count = sizeof(*info->info_block);
	ccw->cda = (__u32)(unsigned long)(info->info_block);
	ret = ccw_io_helper(vcdev, ccw,
			    VIRTIO_CCW_DOING_SET_VQ | index);
@@ -500,13 +521,22 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev,
	}

	/* Register it with the host. */
	info->info_block->queue = (__u64)info->queue;
	info->info_block->align = KVM_VIRTIO_CCW_RING_ALIGN;
	info->info_block->index = i;
	info->info_block->num = info->num;
	if (vcdev->revision == 0) {
		info->info_block->l.queue = (__u64)info->queue;
		info->info_block->l.align = KVM_VIRTIO_CCW_RING_ALIGN;
		info->info_block->l.index = i;
		info->info_block->l.num = info->num;
		ccw->count = sizeof(info->info_block->l);
	} else {
		info->info_block->s.desc = (__u64)info->queue;
		info->info_block->s.index = i;
		info->info_block->s.num = info->num;
		info->info_block->s.avail = (__u64)virtqueue_get_avail(vq);
		info->info_block->s.used = (__u64)virtqueue_get_used(vq);
		ccw->count = sizeof(info->info_block->s);
	}
	ccw->cmd_code = CCW_CMD_SET_VQ;
	ccw->flags = 0;
	ccw->count = sizeof(*info->info_block);
	ccw->cda = (__u32)(unsigned long)(info->info_block);
	err = ccw_io_helper(vcdev, ccw, VIRTIO_CCW_DOING_SET_VQ | i);
	if (err) {