"Michael S. Tsirkin" <[email protected]> writes:
> By the way, Gleb pointed out that on older hosts MMIO will
> always be slower since we need to do a shadow page walk to
> translate virtual to physical address.
> Hopefully not a big concern, and after all we are still
> keeping PIO around for use by BIOS ...
Yeah, slow hosts will be slow :)
>> + /* get offset of notification byte for this virtqueue */
>> + off = ioread16(&vp_dev->common->queue_notify_off);
>> + if (off * vp_dev->notify_offset_multiplier > vp_dev->notify_len) {
>
> maybe check there's no overflow too?
> if (UINT32_MAX / vp_dev->notify_offset_multiplier > off)
> return -EINVAL;
I think it's clearer to just do:
if ((u64)off * vp_dev->notify_offset_multiplier > vp_dev->notify_len) {
Since off is 16 bits and notify_offset_multiplier is 32, this catches
overflow.
>> + dev_warn(&vp_dev->pci_dev->dev,
>> + "bad notification offset %u for queue %u (> %u)",
>> + off, index, vp_dev->notify_len);
>> + err = -EINVAL;
>> + goto out_info;
>> + }
>
> I don't know if you want to limit this to "0 or power of two",
> if yes you'd do
> if (vp_dev->notify_offset_multiplier &
> (vp_dev->notify_offset_multiplier - 1))
> return -EINVAL;
>
>> + info->notify = vp_dev->notify_base + off *
>> vp_dev->notify_offset_multiplier;
>>
>> info->queue = alloc_virtqueue_pages(&num);
>> if (info->queue == NULL) {
I don't see a reason to restrict it. It's not like you'll be
calculating this value more than once even in a micro implementation...
Also, let's add 2, since we write a word in there...
Cheers,
Rusty.
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c
index 3d0318d..1c3591a 100644
--- a/drivers/virtio/virtio_pci.c
+++ b/drivers/virtio/virtio_pci.c
@@ -502,12 +502,14 @@ static struct virtqueue *setup_vq(struct virtio_device
*vdev, unsigned index,
info->msix_vector = msix_vec;
- /* get offset of notification byte for this virtqueue */
+ /* get offset of notification word for this vq (shouldn't wrap) */
off = ioread16(&vp_dev->common->queue_notify_off);
- if (off * vp_dev->notify_offset_multiplier + 2 > vp_dev->notify_len) {
+ if ((u64)off * vp_dev->notify_offset_multiplier + 2
+ > vp_dev->notify_len) {
dev_warn(&vp_dev->pci_dev->dev,
- "bad notification offset %u for queue %u (> %u)",
- off, index, vp_dev->notify_len);
+ "bad notification offset %u (x %u) for queue %u > %u",
+ off, vp_dev->notify_offset_multiplier,
+ index, vp_dev->notify_len);
err = -EINVAL;
goto out_info;
}
_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization