[PATCH 5/7] kvmtool: convert blk backend to support bi-endianness

Marc Zyngier marc.zyngier at arm.com
Fri Oct 11 10:36:33 EDT 2013


Advertise bi-endianness support in the feature flags, and provide
byte-swapping of the config structure depending on the guest selection.

Cc: Pekka Enberg <penberg at kernel.org>
Cc: Will Deacon <will.deacon at arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier at arm.com>
---
 tools/kvm/virtio/blk.c | 34 +++++++++++++++++++++++++++-------
 1 file changed, 27 insertions(+), 7 deletions(-)

diff --git a/tools/kvm/virtio/blk.c b/tools/kvm/virtio/blk.c
index ab18716..237bf56 100644
--- a/tools/kvm/virtio/blk.c
+++ b/tools/kvm/virtio/blk.c
@@ -77,13 +77,15 @@ void virtio_blk_complete(void *param, long len)
 		bdev->vdev.ops->signal_vq(req->kvm, &bdev->vdev, queueid);
 }
 
-static void virtio_blk_do_io_request(struct kvm *kvm, struct blk_dev_req *req)
+static void virtio_blk_do_io_request(struct kvm *kvm, struct virt_queue *vq, struct blk_dev_req *req)
 {
 	struct virtio_blk_outhdr *req_hdr;
 	ssize_t block_cnt;
 	struct blk_dev *bdev;
 	struct iovec *iov;
 	u16 out, in;
+	u32 type;
+	u64 sector;
 
 	block_cnt	= -1;
 	bdev		= req->bdev;
@@ -92,13 +94,16 @@ static void virtio_blk_do_io_request(struct kvm *kvm, struct blk_dev_req *req)
 	in		= req->in;
 	req_hdr		= iov[0].iov_base;
 
-	switch (req_hdr->type) {
+	type = virtio_guest_to_host_u32(vq, req_hdr->type);
+	sector = virtio_guest_to_host_u64(vq, req_hdr->sector);
+
+	switch (type) {
 	case VIRTIO_BLK_T_IN:
-		block_cnt = disk_image__read(bdev->disk, req_hdr->sector,
+		block_cnt = disk_image__read(bdev->disk, sector,
 				iov + 1, in + out - 2, req);
 		break;
 	case VIRTIO_BLK_T_OUT:
-		block_cnt = disk_image__write(bdev->disk, req_hdr->sector,
+		block_cnt = disk_image__write(bdev->disk, sector,
 				iov + 1, in + out - 2, req);
 		break;
 	case VIRTIO_BLK_T_FLUSH:
@@ -112,7 +117,7 @@ static void virtio_blk_do_io_request(struct kvm *kvm, struct blk_dev_req *req)
 		virtio_blk_complete(req, block_cnt);
 		break;
 	default:
-		pr_warning("request type %d", req_hdr->type);
+		pr_warning("request type %d", type);
 		block_cnt	= -1;
 		break;
 	}
@@ -130,7 +135,7 @@ static void virtio_blk_do_io(struct kvm *kvm, struct virt_queue *vq, struct blk_
 					&req->in, head, kvm);
 		req->vq		= vq;
 
-		virtio_blk_do_io_request(kvm, req);
+		virtio_blk_do_io_request(kvm, vq, req);
 	}
 }
 
@@ -146,14 +151,28 @@ static u32 get_host_features(struct kvm *kvm, void *dev)
 	return	1UL << VIRTIO_BLK_F_SEG_MAX
 		| 1UL << VIRTIO_BLK_F_FLUSH
 		| 1UL << VIRTIO_RING_F_EVENT_IDX
-		| 1UL << VIRTIO_RING_F_INDIRECT_DESC;
+		| 1UL << VIRTIO_RING_F_INDIRECT_DESC
+		| VIRTIO_RING_ENDIAN;
 }
 
 static void set_guest_features(struct kvm *kvm, void *dev, u32 features)
 {
 	struct blk_dev *bdev = dev;
+	struct virtio_blk_config *conf = &bdev->blk_config;
+	struct virtio_blk_geometry *geo = &conf->geometry;
 
 	bdev->features = features;
+
+	conf->capacity = htole64(conf->capacity);
+	conf->size_max = htole32(conf->size_max);
+	conf->seg_max = htole32(conf->seg_max);
+
+	/* Geometry */
+	geo->cylinders = htole16(geo->cylinders);
+
+	conf->blk_size = htole32(conf->blk_size);
+	conf->min_io_size = htole16(conf->min_io_size);
+	conf->opt_io_size = htole32(conf->opt_io_size);
 }
 
 static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
@@ -170,6 +189,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
 	p		= virtio_get_vq(kvm, queue->pfn, page_size);
 
 	vring_init(&queue->vring, VIRTIO_BLK_QUEUE_SIZE, p, align);
+	virt_queue__init(queue, bdev->features);
 
 	return 0;
 }
-- 
1.8.2.3





More information about the linux-arm-kernel mailing list