diff mbox series

[RFC,v3,13/29] vhost: Add vhost_get_iova_range operation

Message ID 20210519162903.1172366-14-eperezma@redhat.com (mailing list archive)
State New, archived
Headers show
Series vDPA software assisted live migration | expand

Commit Message

Eugenio Perez Martin May 19, 2021, 4:28 p.m. UTC
For simplicity, If a device does not support this operation it means
that it can handle full (uint64_t)-1 iova address.

Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
---
 include/hw/virtio/vhost-backend.h |  5 +++++
 hw/virtio/vhost-vdpa.c            | 18 ++++++++++++++++++
 hw/virtio/trace-events            |  1 +
 3 files changed, 24 insertions(+)

Comments

Jason Wang May 26, 2021, 1:14 a.m. UTC | #1
在 2021/5/20 上午12:28, Eugenio Pérez 写道:
> For simplicity, If a device does not support this operation it means
> that it can handle full (uint64_t)-1 iova address.


Note that, we probably need a separated patch for this.

And we need to this during vhost-vdpa initialization. If GPA is out of 
the range, we need to fail the start of vhost-vdpa.

THanks


>
> Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
> ---
>   include/hw/virtio/vhost-backend.h |  5 +++++
>   hw/virtio/vhost-vdpa.c            | 18 ++++++++++++++++++
>   hw/virtio/trace-events            |  1 +
>   3 files changed, 24 insertions(+)
>
> diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> index 94d3323905..bcb112c166 100644
> --- a/include/hw/virtio/vhost-backend.h
> +++ b/include/hw/virtio/vhost-backend.h
> @@ -36,6 +36,7 @@ struct vhost_vring_addr;
>   struct vhost_scsi_target;
>   struct vhost_iotlb_msg;
>   struct vhost_virtqueue;
> +struct vhost_vdpa_iova_range;
>   
>   typedef int (*vhost_backend_init)(struct vhost_dev *dev, void *opaque);
>   typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev);
> @@ -127,6 +128,9 @@ typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev);
>   
>   typedef int (*vhost_vring_pause_op)(struct vhost_dev *dev);
>   
> +typedef int (*vhost_get_iova_range)(struct vhost_dev *dev,
> +                                    hwaddr *first, hwaddr *last);
> +
>   typedef struct VhostOps {
>       VhostBackendType backend_type;
>       vhost_backend_init vhost_backend_init;
> @@ -173,6 +177,7 @@ typedef struct VhostOps {
>       vhost_get_device_id_op vhost_get_device_id;
>       vhost_vring_pause_op vhost_vring_pause;
>       vhost_force_iommu_op vhost_force_iommu;
> +    vhost_get_iova_range vhost_get_iova_range;
>   } VhostOps;
>   
>   extern const VhostOps user_ops;
> diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
> index 01d2101d09..74fe92935e 100644
> --- a/hw/virtio/vhost-vdpa.c
> +++ b/hw/virtio/vhost-vdpa.c
> @@ -579,6 +579,23 @@ static bool  vhost_vdpa_force_iommu(struct vhost_dev *dev)
>       return true;
>   }
>   
> +static int vhost_vdpa_get_iova_range(struct vhost_dev *dev,
> +                                     hwaddr *first, hwaddr *last)
> +{
> +    int ret;
> +    struct vhost_vdpa_iova_range range;
> +
> +    ret = vhost_vdpa_call(dev, VHOST_VDPA_GET_IOVA_RANGE, &range);
> +    if (ret != 0) {
> +        return ret;
> +    }
> +
> +    *first = range.first;
> +    *last = range.last;
> +    trace_vhost_vdpa_get_iova_range(dev, *first, *last);
> +    return ret;
> +}
> +
>   const VhostOps vdpa_ops = {
>           .backend_type = VHOST_BACKEND_TYPE_VDPA,
>           .vhost_backend_init = vhost_vdpa_init,
> @@ -611,4 +628,5 @@ const VhostOps vdpa_ops = {
>           .vhost_get_device_id = vhost_vdpa_get_device_id,
>           .vhost_vq_get_addr = vhost_vdpa_vq_get_addr,
>           .vhost_force_iommu = vhost_vdpa_force_iommu,
> +        .vhost_get_iova_range = vhost_vdpa_get_iova_range,
>   };
> diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
> index c62727f879..5debe3a681 100644
> --- a/hw/virtio/trace-events
> +++ b/hw/virtio/trace-events
> @@ -52,6 +52,7 @@ vhost_vdpa_set_vring_call(void *dev, unsigned int index, int fd) "dev: %p index:
>   vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRIx64
>   vhost_vdpa_set_owner(void *dev) "dev: %p"
>   vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64
> +vhost_vdpa_get_iova_range(void *dev, uint64_t first, uint64_t last) "dev: %p first: 0x%"PRIx64" last: 0x%"PRIx64
>   
>   # virtio.c
>   virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u"
Eugenio Perez Martin May 26, 2021, 5:49 p.m. UTC | #2
On Wed, May 26, 2021 at 3:14 AM Jason Wang <jasowang@redhat.com> wrote:
>
>
> 在 2021/5/20 上午12:28, Eugenio Pérez 写道:
> > For simplicity, If a device does not support this operation it means
> > that it can handle full (uint64_t)-1 iova address.
>
>
> Note that, we probably need a separated patch for this.
>

Actually the comment is not in the right commit, the next one is the
one that uses it. Is that what you mean?

> And we need to this during vhost-vdpa initialization. If GPA is out of
> the range, we need to fail the start of vhost-vdpa.
>

Right, that is still to-do.

Maybe a series with just these two commits and failing the start if
GPA is not in the range, as you say, would help to split the amount of
changes.

I will send it if no more comments arise about it.

Thanks!

> THanks
>
>
> >
> > Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
> > ---
> >   include/hw/virtio/vhost-backend.h |  5 +++++
> >   hw/virtio/vhost-vdpa.c            | 18 ++++++++++++++++++
> >   hw/virtio/trace-events            |  1 +
> >   3 files changed, 24 insertions(+)
> >
> > diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> > index 94d3323905..bcb112c166 100644
> > --- a/include/hw/virtio/vhost-backend.h
> > +++ b/include/hw/virtio/vhost-backend.h
> > @@ -36,6 +36,7 @@ struct vhost_vring_addr;
> >   struct vhost_scsi_target;
> >   struct vhost_iotlb_msg;
> >   struct vhost_virtqueue;
> > +struct vhost_vdpa_iova_range;
> >
> >   typedef int (*vhost_backend_init)(struct vhost_dev *dev, void *opaque);
> >   typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev);
> > @@ -127,6 +128,9 @@ typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev);
> >
> >   typedef int (*vhost_vring_pause_op)(struct vhost_dev *dev);
> >
> > +typedef int (*vhost_get_iova_range)(struct vhost_dev *dev,
> > +                                    hwaddr *first, hwaddr *last);
> > +
> >   typedef struct VhostOps {
> >       VhostBackendType backend_type;
> >       vhost_backend_init vhost_backend_init;
> > @@ -173,6 +177,7 @@ typedef struct VhostOps {
> >       vhost_get_device_id_op vhost_get_device_id;
> >       vhost_vring_pause_op vhost_vring_pause;
> >       vhost_force_iommu_op vhost_force_iommu;
> > +    vhost_get_iova_range vhost_get_iova_range;
> >   } VhostOps;
> >
> >   extern const VhostOps user_ops;
> > diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
> > index 01d2101d09..74fe92935e 100644
> > --- a/hw/virtio/vhost-vdpa.c
> > +++ b/hw/virtio/vhost-vdpa.c
> > @@ -579,6 +579,23 @@ static bool  vhost_vdpa_force_iommu(struct vhost_dev *dev)
> >       return true;
> >   }
> >
> > +static int vhost_vdpa_get_iova_range(struct vhost_dev *dev,
> > +                                     hwaddr *first, hwaddr *last)
> > +{
> > +    int ret;
> > +    struct vhost_vdpa_iova_range range;
> > +
> > +    ret = vhost_vdpa_call(dev, VHOST_VDPA_GET_IOVA_RANGE, &range);
> > +    if (ret != 0) {
> > +        return ret;
> > +    }
> > +
> > +    *first = range.first;
> > +    *last = range.last;
> > +    trace_vhost_vdpa_get_iova_range(dev, *first, *last);
> > +    return ret;
> > +}
> > +
> >   const VhostOps vdpa_ops = {
> >           .backend_type = VHOST_BACKEND_TYPE_VDPA,
> >           .vhost_backend_init = vhost_vdpa_init,
> > @@ -611,4 +628,5 @@ const VhostOps vdpa_ops = {
> >           .vhost_get_device_id = vhost_vdpa_get_device_id,
> >           .vhost_vq_get_addr = vhost_vdpa_vq_get_addr,
> >           .vhost_force_iommu = vhost_vdpa_force_iommu,
> > +        .vhost_get_iova_range = vhost_vdpa_get_iova_range,
> >   };
> > diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
> > index c62727f879..5debe3a681 100644
> > --- a/hw/virtio/trace-events
> > +++ b/hw/virtio/trace-events
> > @@ -52,6 +52,7 @@ vhost_vdpa_set_vring_call(void *dev, unsigned int index, int fd) "dev: %p index:
> >   vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRIx64
> >   vhost_vdpa_set_owner(void *dev) "dev: %p"
> >   vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64
> > +vhost_vdpa_get_iova_range(void *dev, uint64_t first, uint64_t last) "dev: %p first: 0x%"PRIx64" last: 0x%"PRIx64
> >
> >   # virtio.c
> >   virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u"
>
Jason Wang May 27, 2021, 4:51 a.m. UTC | #3
在 2021/5/27 上午1:49, Eugenio Perez Martin 写道:
> On Wed, May 26, 2021 at 3:14 AM Jason Wang <jasowang@redhat.com> wrote:
>>
>> 在 2021/5/20 上午12:28, Eugenio Pérez 写道:
>>> For simplicity, If a device does not support this operation it means
>>> that it can handle full (uint64_t)-1 iova address.
>>
>> Note that, we probably need a separated patch for this.
>>
> Actually the comment is not in the right commit, the next one is the
> one that uses it. Is that what you mean?


No, it's about the following suggestions.


>
>> And we need to this during vhost-vdpa initialization. If GPA is out of
>> the range, we need to fail the start of vhost-vdpa.


Note that this is for non-IOMMU case. For the case of vIOMMU we probably 
need to validate it against address width or other similar attributes.

Thanks


>>
> Right, that is still to-do.
>
> Maybe a series with just these two commits and failing the start if
> GPA is not in the range, as you say, would help to split the amount of
> changes.
>
> I will send it if no more comments arise about it.
>
> Thanks!
>
>> THanks
>>
>>
>>> Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
>>> ---
>>>    include/hw/virtio/vhost-backend.h |  5 +++++
>>>    hw/virtio/vhost-vdpa.c            | 18 ++++++++++++++++++
>>>    hw/virtio/trace-events            |  1 +
>>>    3 files changed, 24 insertions(+)
>>>
>>> diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
>>> index 94d3323905..bcb112c166 100644
>>> --- a/include/hw/virtio/vhost-backend.h
>>> +++ b/include/hw/virtio/vhost-backend.h
>>> @@ -36,6 +36,7 @@ struct vhost_vring_addr;
>>>    struct vhost_scsi_target;
>>>    struct vhost_iotlb_msg;
>>>    struct vhost_virtqueue;
>>> +struct vhost_vdpa_iova_range;
>>>
>>>    typedef int (*vhost_backend_init)(struct vhost_dev *dev, void *opaque);
>>>    typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev);
>>> @@ -127,6 +128,9 @@ typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev);
>>>
>>>    typedef int (*vhost_vring_pause_op)(struct vhost_dev *dev);
>>>
>>> +typedef int (*vhost_get_iova_range)(struct vhost_dev *dev,
>>> +                                    hwaddr *first, hwaddr *last);
>>> +
>>>    typedef struct VhostOps {
>>>        VhostBackendType backend_type;
>>>        vhost_backend_init vhost_backend_init;
>>> @@ -173,6 +177,7 @@ typedef struct VhostOps {
>>>        vhost_get_device_id_op vhost_get_device_id;
>>>        vhost_vring_pause_op vhost_vring_pause;
>>>        vhost_force_iommu_op vhost_force_iommu;
>>> +    vhost_get_iova_range vhost_get_iova_range;
>>>    } VhostOps;
>>>
>>>    extern const VhostOps user_ops;
>>> diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
>>> index 01d2101d09..74fe92935e 100644
>>> --- a/hw/virtio/vhost-vdpa.c
>>> +++ b/hw/virtio/vhost-vdpa.c
>>> @@ -579,6 +579,23 @@ static bool  vhost_vdpa_force_iommu(struct vhost_dev *dev)
>>>        return true;
>>>    }
>>>
>>> +static int vhost_vdpa_get_iova_range(struct vhost_dev *dev,
>>> +                                     hwaddr *first, hwaddr *last)
>>> +{
>>> +    int ret;
>>> +    struct vhost_vdpa_iova_range range;
>>> +
>>> +    ret = vhost_vdpa_call(dev, VHOST_VDPA_GET_IOVA_RANGE, &range);
>>> +    if (ret != 0) {
>>> +        return ret;
>>> +    }
>>> +
>>> +    *first = range.first;
>>> +    *last = range.last;
>>> +    trace_vhost_vdpa_get_iova_range(dev, *first, *last);
>>> +    return ret;
>>> +}
>>> +
>>>    const VhostOps vdpa_ops = {
>>>            .backend_type = VHOST_BACKEND_TYPE_VDPA,
>>>            .vhost_backend_init = vhost_vdpa_init,
>>> @@ -611,4 +628,5 @@ const VhostOps vdpa_ops = {
>>>            .vhost_get_device_id = vhost_vdpa_get_device_id,
>>>            .vhost_vq_get_addr = vhost_vdpa_vq_get_addr,
>>>            .vhost_force_iommu = vhost_vdpa_force_iommu,
>>> +        .vhost_get_iova_range = vhost_vdpa_get_iova_range,
>>>    };
>>> diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
>>> index c62727f879..5debe3a681 100644
>>> --- a/hw/virtio/trace-events
>>> +++ b/hw/virtio/trace-events
>>> @@ -52,6 +52,7 @@ vhost_vdpa_set_vring_call(void *dev, unsigned int index, int fd) "dev: %p index:
>>>    vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRIx64
>>>    vhost_vdpa_set_owner(void *dev) "dev: %p"
>>>    vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64
>>> +vhost_vdpa_get_iova_range(void *dev, uint64_t first, uint64_t last) "dev: %p first: 0x%"PRIx64" last: 0x%"PRIx64
>>>
>>>    # virtio.c
>>>    virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u"
Eugenio Perez Martin June 1, 2021, 7:17 a.m. UTC | #4
On Thu, May 27, 2021 at 6:51 AM Jason Wang <jasowang@redhat.com> wrote:
>
>
> 在 2021/5/27 上午1:49, Eugenio Perez Martin 写道:
> > On Wed, May 26, 2021 at 3:14 AM Jason Wang <jasowang@redhat.com> wrote:
> >>
> >> 在 2021/5/20 上午12:28, Eugenio Pérez 写道:
> >>> For simplicity, If a device does not support this operation it means
> >>> that it can handle full (uint64_t)-1 iova address.
> >>
> >> Note that, we probably need a separated patch for this.
> >>
> > Actually the comment is not in the right commit, the next one is the
> > one that uses it. Is that what you mean?
>
>
> No, it's about the following suggestions.
>
>
> >
> >> And we need to this during vhost-vdpa initialization. If GPA is out of
> >> the range, we need to fail the start of vhost-vdpa.
>
>
> Note that this is for non-IOMMU case. For the case of vIOMMU we probably
> need to validate it against address width or other similar attributes.
>

Right.

What should qemu do if the memory of the guest gets expanded outside
of the range? I think there is not a clear way to fail the memory
addition, isn't it?

> Thanks
>
>
> >>
> > Right, that is still to-do.
> >
> > Maybe a series with just these two commits and failing the start if
> > GPA is not in the range, as you say, would help to split the amount of
> > changes.
> >
> > I will send it if no more comments arise about it.
> >
> > Thanks!
> >
> >> THanks
> >>
> >>
> >>> Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
> >>> ---
> >>>    include/hw/virtio/vhost-backend.h |  5 +++++
> >>>    hw/virtio/vhost-vdpa.c            | 18 ++++++++++++++++++
> >>>    hw/virtio/trace-events            |  1 +
> >>>    3 files changed, 24 insertions(+)
> >>>
> >>> diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
> >>> index 94d3323905..bcb112c166 100644
> >>> --- a/include/hw/virtio/vhost-backend.h
> >>> +++ b/include/hw/virtio/vhost-backend.h
> >>> @@ -36,6 +36,7 @@ struct vhost_vring_addr;
> >>>    struct vhost_scsi_target;
> >>>    struct vhost_iotlb_msg;
> >>>    struct vhost_virtqueue;
> >>> +struct vhost_vdpa_iova_range;
> >>>
> >>>    typedef int (*vhost_backend_init)(struct vhost_dev *dev, void *opaque);
> >>>    typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev);
> >>> @@ -127,6 +128,9 @@ typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev);
> >>>
> >>>    typedef int (*vhost_vring_pause_op)(struct vhost_dev *dev);
> >>>
> >>> +typedef int (*vhost_get_iova_range)(struct vhost_dev *dev,
> >>> +                                    hwaddr *first, hwaddr *last);
> >>> +
> >>>    typedef struct VhostOps {
> >>>        VhostBackendType backend_type;
> >>>        vhost_backend_init vhost_backend_init;
> >>> @@ -173,6 +177,7 @@ typedef struct VhostOps {
> >>>        vhost_get_device_id_op vhost_get_device_id;
> >>>        vhost_vring_pause_op vhost_vring_pause;
> >>>        vhost_force_iommu_op vhost_force_iommu;
> >>> +    vhost_get_iova_range vhost_get_iova_range;
> >>>    } VhostOps;
> >>>
> >>>    extern const VhostOps user_ops;
> >>> diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
> >>> index 01d2101d09..74fe92935e 100644
> >>> --- a/hw/virtio/vhost-vdpa.c
> >>> +++ b/hw/virtio/vhost-vdpa.c
> >>> @@ -579,6 +579,23 @@ static bool  vhost_vdpa_force_iommu(struct vhost_dev *dev)
> >>>        return true;
> >>>    }
> >>>
> >>> +static int vhost_vdpa_get_iova_range(struct vhost_dev *dev,
> >>> +                                     hwaddr *first, hwaddr *last)
> >>> +{
> >>> +    int ret;
> >>> +    struct vhost_vdpa_iova_range range;
> >>> +
> >>> +    ret = vhost_vdpa_call(dev, VHOST_VDPA_GET_IOVA_RANGE, &range);
> >>> +    if (ret != 0) {
> >>> +        return ret;
> >>> +    }
> >>> +
> >>> +    *first = range.first;
> >>> +    *last = range.last;
> >>> +    trace_vhost_vdpa_get_iova_range(dev, *first, *last);
> >>> +    return ret;
> >>> +}
> >>> +
> >>>    const VhostOps vdpa_ops = {
> >>>            .backend_type = VHOST_BACKEND_TYPE_VDPA,
> >>>            .vhost_backend_init = vhost_vdpa_init,
> >>> @@ -611,4 +628,5 @@ const VhostOps vdpa_ops = {
> >>>            .vhost_get_device_id = vhost_vdpa_get_device_id,
> >>>            .vhost_vq_get_addr = vhost_vdpa_vq_get_addr,
> >>>            .vhost_force_iommu = vhost_vdpa_force_iommu,
> >>> +        .vhost_get_iova_range = vhost_vdpa_get_iova_range,
> >>>    };
> >>> diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
> >>> index c62727f879..5debe3a681 100644
> >>> --- a/hw/virtio/trace-events
> >>> +++ b/hw/virtio/trace-events
> >>> @@ -52,6 +52,7 @@ vhost_vdpa_set_vring_call(void *dev, unsigned int index, int fd) "dev: %p index:
> >>>    vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRIx64
> >>>    vhost_vdpa_set_owner(void *dev) "dev: %p"
> >>>    vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64
> >>> +vhost_vdpa_get_iova_range(void *dev, uint64_t first, uint64_t last) "dev: %p first: 0x%"PRIx64" last: 0x%"PRIx64
> >>>
> >>>    # virtio.c
> >>>    virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u"
>
Jason Wang June 3, 2021, 3:13 a.m. UTC | #5
在 2021/6/1 下午3:17, Eugenio Perez Martin 写道:
> On Thu, May 27, 2021 at 6:51 AM Jason Wang <jasowang@redhat.com> wrote:
>>
>> 在 2021/5/27 上午1:49, Eugenio Perez Martin 写道:
>>> On Wed, May 26, 2021 at 3:14 AM Jason Wang <jasowang@redhat.com> wrote:
>>>> 在 2021/5/20 上午12:28, Eugenio Pérez 写道:
>>>>> For simplicity, If a device does not support this operation it means
>>>>> that it can handle full (uint64_t)-1 iova address.
>>>> Note that, we probably need a separated patch for this.
>>>>
>>> Actually the comment is not in the right commit, the next one is the
>>> one that uses it. Is that what you mean?
>>
>> No, it's about the following suggestions.
>>
>>
>>>> And we need to this during vhost-vdpa initialization. If GPA is out of
>>>> the range, we need to fail the start of vhost-vdpa.
>>
>> Note that this is for non-IOMMU case. For the case of vIOMMU we probably
>> need to validate it against address width or other similar attributes.
>>
> Right.
>
> What should qemu do if the memory of the guest gets expanded outside
> of the range? I think there is not a clear way to fail the memory
> addition, isn't it?


I'm not sure, but I guess there should be a way to fail the memory hot-add.

(otherwise we can introduce the error reporting for them)

Thanks


>
>> Thanks
>>
>>
>>> Right, that is still to-do.
>>>
>>> Maybe a series with just these two commits and failing the start if
>>> GPA is not in the range, as you say, would help to split the amount of
>>> changes.
>>>
>>> I will send it if no more comments arise about it.
>>>
>>> Thanks!
>>>
>>>> THanks
>>>>
>>>>
>>>>> Signed-off-by: Eugenio Pérez <eperezma@redhat.com>
>>>>> ---
>>>>>     include/hw/virtio/vhost-backend.h |  5 +++++
>>>>>     hw/virtio/vhost-vdpa.c            | 18 ++++++++++++++++++
>>>>>     hw/virtio/trace-events            |  1 +
>>>>>     3 files changed, 24 insertions(+)
>>>>>
>>>>> diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
>>>>> index 94d3323905..bcb112c166 100644
>>>>> --- a/include/hw/virtio/vhost-backend.h
>>>>> +++ b/include/hw/virtio/vhost-backend.h
>>>>> @@ -36,6 +36,7 @@ struct vhost_vring_addr;
>>>>>     struct vhost_scsi_target;
>>>>>     struct vhost_iotlb_msg;
>>>>>     struct vhost_virtqueue;
>>>>> +struct vhost_vdpa_iova_range;
>>>>>
>>>>>     typedef int (*vhost_backend_init)(struct vhost_dev *dev, void *opaque);
>>>>>     typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev);
>>>>> @@ -127,6 +128,9 @@ typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev);
>>>>>
>>>>>     typedef int (*vhost_vring_pause_op)(struct vhost_dev *dev);
>>>>>
>>>>> +typedef int (*vhost_get_iova_range)(struct vhost_dev *dev,
>>>>> +                                    hwaddr *first, hwaddr *last);
>>>>> +
>>>>>     typedef struct VhostOps {
>>>>>         VhostBackendType backend_type;
>>>>>         vhost_backend_init vhost_backend_init;
>>>>> @@ -173,6 +177,7 @@ typedef struct VhostOps {
>>>>>         vhost_get_device_id_op vhost_get_device_id;
>>>>>         vhost_vring_pause_op vhost_vring_pause;
>>>>>         vhost_force_iommu_op vhost_force_iommu;
>>>>> +    vhost_get_iova_range vhost_get_iova_range;
>>>>>     } VhostOps;
>>>>>
>>>>>     extern const VhostOps user_ops;
>>>>> diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
>>>>> index 01d2101d09..74fe92935e 100644
>>>>> --- a/hw/virtio/vhost-vdpa.c
>>>>> +++ b/hw/virtio/vhost-vdpa.c
>>>>> @@ -579,6 +579,23 @@ static bool  vhost_vdpa_force_iommu(struct vhost_dev *dev)
>>>>>         return true;
>>>>>     }
>>>>>
>>>>> +static int vhost_vdpa_get_iova_range(struct vhost_dev *dev,
>>>>> +                                     hwaddr *first, hwaddr *last)
>>>>> +{
>>>>> +    int ret;
>>>>> +    struct vhost_vdpa_iova_range range;
>>>>> +
>>>>> +    ret = vhost_vdpa_call(dev, VHOST_VDPA_GET_IOVA_RANGE, &range);
>>>>> +    if (ret != 0) {
>>>>> +        return ret;
>>>>> +    }
>>>>> +
>>>>> +    *first = range.first;
>>>>> +    *last = range.last;
>>>>> +    trace_vhost_vdpa_get_iova_range(dev, *first, *last);
>>>>> +    return ret;
>>>>> +}
>>>>> +
>>>>>     const VhostOps vdpa_ops = {
>>>>>             .backend_type = VHOST_BACKEND_TYPE_VDPA,
>>>>>             .vhost_backend_init = vhost_vdpa_init,
>>>>> @@ -611,4 +628,5 @@ const VhostOps vdpa_ops = {
>>>>>             .vhost_get_device_id = vhost_vdpa_get_device_id,
>>>>>             .vhost_vq_get_addr = vhost_vdpa_vq_get_addr,
>>>>>             .vhost_force_iommu = vhost_vdpa_force_iommu,
>>>>> +        .vhost_get_iova_range = vhost_vdpa_get_iova_range,
>>>>>     };
>>>>> diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
>>>>> index c62727f879..5debe3a681 100644
>>>>> --- a/hw/virtio/trace-events
>>>>> +++ b/hw/virtio/trace-events
>>>>> @@ -52,6 +52,7 @@ vhost_vdpa_set_vring_call(void *dev, unsigned int index, int fd) "dev: %p index:
>>>>>     vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRIx64
>>>>>     vhost_vdpa_set_owner(void *dev) "dev: %p"
>>>>>     vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64
>>>>> +vhost_vdpa_get_iova_range(void *dev, uint64_t first, uint64_t last) "dev: %p first: 0x%"PRIx64" last: 0x%"PRIx64
>>>>>
>>>>>     # virtio.c
>>>>>     virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u"
diff mbox series

Patch

diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index 94d3323905..bcb112c166 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -36,6 +36,7 @@  struct vhost_vring_addr;
 struct vhost_scsi_target;
 struct vhost_iotlb_msg;
 struct vhost_virtqueue;
+struct vhost_vdpa_iova_range;
 
 typedef int (*vhost_backend_init)(struct vhost_dev *dev, void *opaque);
 typedef int (*vhost_backend_cleanup)(struct vhost_dev *dev);
@@ -127,6 +128,9 @@  typedef bool (*vhost_force_iommu_op)(struct vhost_dev *dev);
 
 typedef int (*vhost_vring_pause_op)(struct vhost_dev *dev);
 
+typedef int (*vhost_get_iova_range)(struct vhost_dev *dev,
+                                    hwaddr *first, hwaddr *last);
+
 typedef struct VhostOps {
     VhostBackendType backend_type;
     vhost_backend_init vhost_backend_init;
@@ -173,6 +177,7 @@  typedef struct VhostOps {
     vhost_get_device_id_op vhost_get_device_id;
     vhost_vring_pause_op vhost_vring_pause;
     vhost_force_iommu_op vhost_force_iommu;
+    vhost_get_iova_range vhost_get_iova_range;
 } VhostOps;
 
 extern const VhostOps user_ops;
diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c
index 01d2101d09..74fe92935e 100644
--- a/hw/virtio/vhost-vdpa.c
+++ b/hw/virtio/vhost-vdpa.c
@@ -579,6 +579,23 @@  static bool  vhost_vdpa_force_iommu(struct vhost_dev *dev)
     return true;
 }
 
+static int vhost_vdpa_get_iova_range(struct vhost_dev *dev,
+                                     hwaddr *first, hwaddr *last)
+{
+    int ret;
+    struct vhost_vdpa_iova_range range;
+
+    ret = vhost_vdpa_call(dev, VHOST_VDPA_GET_IOVA_RANGE, &range);
+    if (ret != 0) {
+        return ret;
+    }
+
+    *first = range.first;
+    *last = range.last;
+    trace_vhost_vdpa_get_iova_range(dev, *first, *last);
+    return ret;
+}
+
 const VhostOps vdpa_ops = {
         .backend_type = VHOST_BACKEND_TYPE_VDPA,
         .vhost_backend_init = vhost_vdpa_init,
@@ -611,4 +628,5 @@  const VhostOps vdpa_ops = {
         .vhost_get_device_id = vhost_vdpa_get_device_id,
         .vhost_vq_get_addr = vhost_vdpa_vq_get_addr,
         .vhost_force_iommu = vhost_vdpa_force_iommu,
+        .vhost_get_iova_range = vhost_vdpa_get_iova_range,
 };
diff --git a/hw/virtio/trace-events b/hw/virtio/trace-events
index c62727f879..5debe3a681 100644
--- a/hw/virtio/trace-events
+++ b/hw/virtio/trace-events
@@ -52,6 +52,7 @@  vhost_vdpa_set_vring_call(void *dev, unsigned int index, int fd) "dev: %p index:
 vhost_vdpa_get_features(void *dev, uint64_t features) "dev: %p features: 0x%"PRIx64
 vhost_vdpa_set_owner(void *dev) "dev: %p"
 vhost_vdpa_vq_get_addr(void *dev, void *vq, uint64_t desc_user_addr, uint64_t avail_user_addr, uint64_t used_user_addr) "dev: %p vq: %p desc_user_addr: 0x%"PRIx64" avail_user_addr: 0x%"PRIx64" used_user_addr: 0x%"PRIx64
+vhost_vdpa_get_iova_range(void *dev, uint64_t first, uint64_t last) "dev: %p first: 0x%"PRIx64" last: 0x%"PRIx64
 
 # virtio.c
 virtqueue_alloc_element(void *elem, size_t sz, unsigned in_num, unsigned out_num) "elem %p size %zd in_num %u out_num %u"