@@ -119,7 +119,13 @@ static inline void vring_init(struct vring *vr, unsigned int num, void *p,
static inline unsigned vring_size(unsigned int num, unsigned long align)
{
- return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (2 + num)
+#ifdef __KERNEL__
+ /* Older versions did not have used_event field at the end of the
+ * avail ring. Used ring offset must be compatible with such devices. */
+ size_t s = sizeof(struct vring_desc) * num + sizeof(__u16) * (2 + num);
+ BUG_ON(ALIGN(s, align) != ALIGN(s + sizeof(__u16), align));
+#endif
+ return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (3 + num)
+ align - 1) & ~(align - 1))
+ sizeof(__u16) * 3 + sizeof(struct vring_used_elem) * num;
}
Nothing's wrong with vring_size as is, but it's nice to check that the new field in the avail ring won't overlow into the used ring. Reported-by: Tom Lendacky <tahm@linux.vnet.ibm.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> --- include/linux/virtio_ring.h | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletions(-)