Commit e7e2950a authored by Sasha Levin's avatar Sasha Levin Committed by Will Deacon
Browse files

kvm tools: fix boot of guests with more than 4gb of ram



Commit "kvm tools: virtio: remove hardcoded assumptions
about guest page size" has introduced a bug that prevented
guests with more than 4gb of ram from booting.

The issue is that 'pfn' is a 32bit integer, so when multiplying
it by page size to get the actual page will cause an overflow if
the pfn referred to a memory area above 4gb.

Acked-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarSasha Levin <sasha.levin@oracle.com>
Signed-off-by: default avatarPekka Enberg <penberg@kernel.org>
parent e2b98125
......@@ -90,4 +90,10 @@ int virtio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
struct virtio_ops *ops, enum virtio_trans trans,
int device_id, int subsys_id, int class);
int virtio_compat_add_message(const char *device, const char *config);
static inline void *virtio_get_vq(struct kvm *kvm, u32 pfn, u32 page_size)
{
return guest_flat_to_host(kvm, (u64)pfn * page_size);
}
#endif /* KVM__VIRTIO_H */
......@@ -1267,7 +1267,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
queue = &p9dev->vqs[vq];
queue->pfn = pfn;
p = guest_flat_to_host(kvm, queue->pfn * page_size);
p = virtio_get_vq(kvm, queue->pfn, page_size);
job = &p9dev->jobs[vq];
vring_init(&queue->vring, VIRTQUEUE_NUM, p, align);
......
......@@ -204,7 +204,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
queue = &bdev->vqs[vq];
queue->pfn = pfn;
p = guest_flat_to_host(kvm, queue->pfn * page_size);
p = virtio_get_vq(kvm, queue->pfn, page_size);
thread_pool__init_job(&bdev->jobs[vq], kvm, virtio_bln_do_io, queue);
vring_init(&queue->vring, VIRTIO_BLN_QUEUE_SIZE, p, align);
......
......@@ -167,7 +167,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
queue = &bdev->vqs[vq];
queue->pfn = pfn;
p = guest_flat_to_host(kvm, queue->pfn * page_size);
p = virtio_get_vq(kvm, queue->pfn, page_size);
vring_init(&queue->vring, VIRTIO_BLK_QUEUE_SIZE, p, align);
......
......@@ -137,7 +137,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
queue = &cdev.vqs[vq];
queue->pfn = pfn;
p = guest_flat_to_host(kvm, queue->pfn * page_size);
p = virtio_get_vq(kvm, queue->pfn, page_size);
vring_init(&queue->vring, VIRTIO_CONSOLE_QUEUE_SIZE, p, align);
......
......@@ -410,7 +410,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
queue = &ndev->vqs[vq];
queue->pfn = pfn;
p = guest_flat_to_host(kvm, queue->pfn * page_size);
p = virtio_get_vq(kvm, queue->pfn, page_size);
vring_init(&queue->vring, VIRTIO_NET_QUEUE_SIZE, p, align);
......
......@@ -98,7 +98,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
queue = &rdev->vqs[vq];
queue->pfn = pfn;
p = guest_flat_to_host(kvm, queue->pfn * page_size);
p = virtio_get_vq(kvm, queue->pfn, page_size);
job = &rdev->jobs[vq];
......
......@@ -63,7 +63,7 @@ static int init_vq(struct kvm *kvm, void *dev, u32 vq, u32 page_size, u32 align,
queue = &sdev->vqs[vq];
queue->pfn = pfn;
p = guest_flat_to_host(kvm, queue->pfn * page_size);
p = virtio_get_vq(kvm, queue->pfn, page_size);
vring_init(&queue->vring, VIRTIO_SCSI_QUEUE_SIZE, p, align);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment