在 2022/7/11 17:43, Eugenio Perez Martin 写道:
> On Mon, Jul 11, 2022 at 11:14 AM Jason Wang <jasowang@redhat.com> wrote:
>>
>> 在 2022/7/7 02:39, Eugenio Pérez 写道:
>>> This allows qemu to inject buffers to the device.
>>
>> Not a native speaker but we probably need a better terminology than
>> inject here.
>>
>> Since the CVQ is totally under the control of the Qemu anyhow.
>>
> I'm totally fine to change terminology
>
>>> Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
>>> ---
>>> hw/virtio/vhost-shadow-virtqueue.h | 2 ++
>>> hw/virtio/vhost-shadow-virtqueue.c | 34 ++++++++++++++++++++++++++++++
>>> 2 files changed, 36 insertions(+)
>>>
>>> diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-shadow-virtqueue.h
>>> index a811f90e01..d01d2370db 100644
>>> --- a/hw/virtio/vhost-shadow-virtqueue.h
>>> +++ b/hw/virtio/vhost-shadow-virtqueue.h
>>> @@ -98,6 +98,8 @@ bool vhost_svq_valid_features(uint64_t features, Error **errp);
>>>
>>> void vhost_svq_push_elem(VhostShadowVirtqueue *svq,
>>> const VirtQueueElement *elem, uint32_t len);
>>> +int vhost_svq_inject(VhostShadowVirtqueue *svq, const struct iovec *iov,
>>> + size_t out_num, size_t in_num, void *opaque);
>>> void vhost_svq_set_svq_kick_fd(VhostShadowVirtqueue *svq, int svq_kick_fd);
>>> void vhost_svq_set_svq_call_fd(VhostShadowVirtqueue *svq, int call_fd);
>>> void vhost_svq_get_vring_addr(const VhostShadowVirtqueue *svq,
>>> diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-shadow-virtqueue.c
>>> index 492bb12b5f..bd9e34b413 100644
>>> --- a/hw/virtio/vhost-shadow-virtqueue.c
>>> +++ b/hw/virtio/vhost-shadow-virtqueue.c
>>> @@ -283,6 +283,40 @@ static bool vhost_svq_add_element(VhostShadowVirtqueue *svq,
>>> return ok;
>>> }
>>>
>>> +/**
>>> + * Inject a chain of buffers to the device
>>> + *
>>> + * @svq: Shadow VirtQueue
>>> + * @iov: I/O vector
>>> + * @out_num: Number of front out descriptors
>>> + * @in_num: Number of last input descriptors
>>> + * @opaque: Contextual data to store in descriptor
>>> + *
>>> + * Return 0 on success, -ENOMEM if cannot inject
>>> + */
>>> +int vhost_svq_inject(VhostShadowVirtqueue *svq, const struct iovec *iov,
>>> + size_t out_num, size_t in_num, void *opaque)
>>
>> If we manage to embed opaque into VirtqueueElement, we can simply use
>> vhost_svq_add() here.
>>
> That works fine as long as SVQ only forwards elements, but it needs to
> do more than that: We need to inject new elements without guest
> notice.
>
> How could we track elements that do not have corresponding
> VirtQueueElement, like the elements sent to restore the status at the
> LM destination?
Having a token for each VirtQueueElement will work? Or maybe I can ask
differently, what kind of extra state that need to be tracked here?
(For virtio state it should be handled by shadow virtqueue core).
Thanks
>
> I'll try to make it clearer in the patch message.
>
> Thanks!
>
>> Thanks
>>
>>
>>> +{
>>> + bool ok;
>>> +
>>> + /*
>>> + * All vhost_svq_inject calls are controlled by qemu so we won't hit this
>>> + * assertions.
>>> + */
>>> + assert(out_num || in_num);
>>> + assert(svq->ops);
>>> +
>>> + if (unlikely(svq->next_guest_avail_elem)) {
>>> + error_report("Injecting in a full queue");
>>> + return -ENOMEM;
>>> + }
>>> +
>>> + ok = vhost_svq_add(svq, iov, out_num, iov + out_num, in_num, opaque);
>>> + assert(ok);
>>> + vhost_svq_kick(svq);
>>> + return 0;
>>> +}
>>> +
>>> /**
>>> * Forward available buffers.
>>> *