Configure the queues to follow the guest endianness, and make sure
the configuration space is doing the same.

Signed-off-by: Marc Zyngier <marc.zyng...@arm.com>
---
 tools/kvm/virtio/blk.c | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/tools/kvm/virtio/blk.c b/tools/kvm/virtio/blk.c
index 4bed3a9..edfa8e6 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);
        }
 }
 
@@ -152,8 +157,21 @@ static u32 get_host_features(struct kvm *kvm, void *dev)
 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 = virtio_host_to_guest_u64(&bdev->vdev, conf->capacity);
+       conf->size_max = virtio_host_to_guest_u32(&bdev->vdev, conf->size_max);
+       conf->seg_max = virtio_host_to_guest_u32(&bdev->vdev, conf->seg_max);
+
+       /* Geometry */
+       geo->cylinders = virtio_host_to_guest_u16(&bdev->vdev, geo->cylinders);
+
+       conf->blk_size = virtio_host_to_guest_u32(&bdev->vdev, conf->blk_size);
+       conf->min_io_size = virtio_host_to_guest_u16(&bdev->vdev, 
conf->min_io_size);
+       conf->opt_io_size = virtio_host_to_guest_u32(&bdev->vdev, 
conf->opt_io_size);
 }
 
 static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 
align,
@@ -170,6 +188,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);
+       virtio_init_device_vq(&bdev->vdev, queue);
 
        return 0;
 }
-- 
1.8.3.4

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to