Re: [PATCH RFC 04/12] vdpa: add vdpa simulator for block device

Stefano Garzarella
2020-11-18T11:39:42Z

On Wed, Nov 18, 2020 at 11:23:55AM +0000, Stefan Hajnoczi wrote:
>On Tue, Nov 17, 2020 at 06:38:11PM +0100, Stefano Garzarella wrote:
>> On Tue, Nov 17, 2020 at 04:43:42PM +0000, Stefan Hajnoczi wrote:
>> > On Tue, Nov 17, 2020 at 03:16:20PM +0100, Stefano Garzarella wrote:
>> > > On Tue, Nov 17, 2020 at 11:11:21AM +0000, Stefan Hajnoczi wrote:
>> > > > On Fri, Nov 13, 2020 at 02:47:04PM +0100, Stefano Garzarella wrote:
>> > > > > +static void vdpasim_blk_work(struct work_struct *work)
>> > > > > +{
>> > > > > + struct vdpasim *vdpasim = container_of(work, struct vdpasim, work);
>> > > > > + u8 status = VIRTIO_BLK_S_OK;
>> > > > > + int i;
>> > > > > +
>> > > > > + spin_lock(&vdpasim->lock);
>> > > > > +
>> > > > > + if (!(vdpasim->status & VIRTIO_CONFIG_S_DRIVER_OK))
>> > > > > + goto out;
>> > > > > +
>> > > > > + for (i = 0; i < VDPASIM_BLK_VQ_NUM; i++) {
>> > > > > + struct vdpasim_virtqueue *vq = &vdpasim->vqs[i];
>> > > > > +
>> > > > > + if (!vq->ready)
>> > > > > + continue;
>> > > > > +
>> > > > > + while (vringh_getdesc_iotlb(&vq->vring, &vq->iov, &vq->iov,
>> > > > > + &vq->head, GFP_ATOMIC) > 0) {
>> > > > > +
>> > > > > + int write;
>> > > > > +
>> > > > > + vq->iov.i = vq->iov.used - 1;
>> > > > > + write = vringh_iov_push_iotlb(&vq->vring, &vq->iov, &status, 1);
>> > > > > + if (write <= 0)
>> > > > > + break;
>> > > >
>> > > > We're lucky the guest driver doesn't crash after VIRTIO_BLK_T_GET_ID? :)
>> > >
>> > > The crash could happen if the simulator doesn't put the string terminator,
>> > > but in virtio_blk.c, the serial_show() initialize the buffer putting the
>> > > string terminator in the VIRTIO_BLK_ID_BYTES element:
>> > >
>> > > buf[VIRTIO_BLK_ID_BYTES] = '\0';
>> > > err = virtblk_get_id(disk, buf);
>> > >
>> > > This should prevent the issue, right?
>> > >
>> > > However in the last patch of this series I implemented VIRTIO_BLK_T_GET_ID
>> > > support :-)
>> >
>> > Windows, BSD, macOS, etc guest drivers aren't necessarily going to
>> > terminate or initialize the serial string buffer.
>>
>> Unfortunately I discovered that VIRTIO_BLK_T_GET_ID is not in the VIRTIO
>> specs, so, just for curiosity, I checked the QEMU code and I found this:
>>
>> case VIRTIO_BLK_T_GET_ID:
>> {
>> /*
>> * NB: per existing s/n string convention the string is
>> * terminated by '\0' only when shorter than buffer.
>> */
>> const char *serial = s->conf.serial ? s->conf.serial : "";
>> size_t size = MIN(strlen(serial) + 1,
>> MIN(iov_size(in_iov, in_num),
>> VIRTIO_BLK_ID_BYTES));
>> iov_from_buf(in_iov, in_num, 0, serial, size);
>> virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
>> virtio_blk_free_request(req);
>> break;
>> }
>>
>> It seems that the device emulation in QEMU expects that the driver
>> terminates the serial string buffer.
>>
>> Do you know why VIRTIO_BLK_T_GET_ID is not in the specs?
>> Should we add it?
>
>It's about to be merged into the VIRTIO spec:
>https://github.com/oasis-tcs/virtio-spec/issues/63
>

Great! Thanks for the link!

Stefano