Re: [PATCH 4/4] vhost: vdpa: report iova range
On Thu, Aug 06, 2020 at 11:29:16AM +0800, Jason Wang wrote: > > On 2020/8/5 下午8:58, Michael S. Tsirkin wrote: > > On Wed, Jun 17, 2020 at 11:29:47AM +0800, Jason Wang wrote: > > > This patch introduces a new ioctl for vhost-vdpa device that can > > > report the iova range by the device. For device that depends on > > > platform IOMMU, we fetch the iova range via DOMAIN_ATTR_GEOMETRY. For > > > devices that has its own DMA translation unit, we fetch it directly > > > from vDPA bus operation. > > > > > > Signed-off-by: Jason Wang > > > --- > > > drivers/vhost/vdpa.c | 27 +++ > > > include/uapi/linux/vhost.h | 4 > > > include/uapi/linux/vhost_types.h | 5 + > > > 3 files changed, 36 insertions(+) > > > > > > diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c > > > index 77a0c9fb6cc3..ad23e66cbf57 100644 > > > --- a/drivers/vhost/vdpa.c > > > +++ b/drivers/vhost/vdpa.c > > > @@ -332,6 +332,30 @@ static long vhost_vdpa_set_config_call(struct > > > vhost_vdpa *v, u32 __user *argp) > > > return 0; > > > } > > > + > > > +static long vhost_vdpa_get_iova_range(struct vhost_vdpa *v, u32 __user > > > *argp) > > > +{ > > > + struct iommu_domain_geometry geo; > > > + struct vdpa_device *vdpa = v->vdpa; > > > + const struct vdpa_config_ops *ops = vdpa->config; > > > + struct vhost_vdpa_iova_range range; > > > + struct vdpa_iova_range vdpa_range; > > > + > > > + if (!ops->set_map && !ops->dma_map) { > > Why not just check if (ops->get_iova_range) directly? > > > Because set_map || dma_ops is a hint that the device has its own DMA > translation logic. > > Device without get_iova_range does not necessarily meant it use IOMMU > driver. > > Thanks OK let's add some code comments please, and check get_iova_range is actually there before calling. > > > > > > > > > > > > + iommu_domain_get_attr(v->domain, > > > + DOMAIN_ATTR_GEOMETRY, ); > > > + range.start = geo.aperture_start; > > > + range.end = geo.aperture_end; > > > + } else { > > > + vdpa_range = ops->get_iova_range(vdpa); > > > + range.start = vdpa_range.start; > > > + range.end = vdpa_range.end; > > > + } > > > + > > > + return copy_to_user(argp, , sizeof(range)); > > > + > > > +} > > > + > > > static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int > > > cmd, > > > void __user *argp) > > > { > > > @@ -442,6 +466,9 @@ static long vhost_vdpa_unlocked_ioctl(struct file > > > *filep, > > > case VHOST_VDPA_SET_CONFIG_CALL: > > > r = vhost_vdpa_set_config_call(v, argp); > > > break; > > > + case VHOST_VDPA_GET_IOVA_RANGE: > > > + r = vhost_vdpa_get_iova_range(v, argp); > > > + break; > > > default: > > > r = vhost_dev_ioctl(>vdev, cmd, argp); > > > if (r == -ENOIOCTLCMD) > > > diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h > > > index 0c2349612e77..850956980e27 100644 > > > --- a/include/uapi/linux/vhost.h > > > +++ b/include/uapi/linux/vhost.h > > > @@ -144,4 +144,8 @@ > > > /* Set event fd for config interrupt*/ > > > #define VHOST_VDPA_SET_CONFIG_CALL _IOW(VHOST_VIRTIO, 0x77, int) > > > + > > > +/* Get the valid iova range */ > > > +#define VHOST_VDPA_GET_IOVA_RANGE_IOW(VHOST_VIRTIO, 0x78, \ > > > + struct vhost_vdpa_iova_range) > > > #endif > > > diff --git a/include/uapi/linux/vhost_types.h > > > b/include/uapi/linux/vhost_types.h > > > index 669457ce5c48..4025b5a36177 100644 > > > --- a/include/uapi/linux/vhost_types.h > > > +++ b/include/uapi/linux/vhost_types.h > > > @@ -127,6 +127,11 @@ struct vhost_vdpa_config { > > > __u8 buf[0]; > > > }; > > > +struct vhost_vdpa_iova_range { > > > + __u64 start; > > > + __u64 end; > > > +}; > > > + > > > > Pls document fields. And I think first/last is a better API ... > > > > > /* Feature bits */ > > > /* Log all write descriptors. Can be changed while device is active. */ > > > #define VHOST_F_LOG_ALL 26 > > > -- > > > 2.20.1
Re: [PATCH 4/4] vhost: vdpa: report iova range
On 2020/8/5 下午8:58, Michael S. Tsirkin wrote: On Wed, Jun 17, 2020 at 11:29:47AM +0800, Jason Wang wrote: This patch introduces a new ioctl for vhost-vdpa device that can report the iova range by the device. For device that depends on platform IOMMU, we fetch the iova range via DOMAIN_ATTR_GEOMETRY. For devices that has its own DMA translation unit, we fetch it directly from vDPA bus operation. Signed-off-by: Jason Wang --- drivers/vhost/vdpa.c | 27 +++ include/uapi/linux/vhost.h | 4 include/uapi/linux/vhost_types.h | 5 + 3 files changed, 36 insertions(+) diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c index 77a0c9fb6cc3..ad23e66cbf57 100644 --- a/drivers/vhost/vdpa.c +++ b/drivers/vhost/vdpa.c @@ -332,6 +332,30 @@ static long vhost_vdpa_set_config_call(struct vhost_vdpa *v, u32 __user *argp) return 0; } + +static long vhost_vdpa_get_iova_range(struct vhost_vdpa *v, u32 __user *argp) +{ + struct iommu_domain_geometry geo; + struct vdpa_device *vdpa = v->vdpa; + const struct vdpa_config_ops *ops = vdpa->config; + struct vhost_vdpa_iova_range range; + struct vdpa_iova_range vdpa_range; + + if (!ops->set_map && !ops->dma_map) { Why not just check if (ops->get_iova_range) directly? Because set_map || dma_ops is a hint that the device has its own DMA translation logic. Device without get_iova_range does not necessarily meant it use IOMMU driver. Thanks + iommu_domain_get_attr(v->domain, + DOMAIN_ATTR_GEOMETRY, ); + range.start = geo.aperture_start; + range.end = geo.aperture_end; + } else { + vdpa_range = ops->get_iova_range(vdpa); + range.start = vdpa_range.start; + range.end = vdpa_range.end; + } + + return copy_to_user(argp, , sizeof(range)); + +} + static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd, void __user *argp) { @@ -442,6 +466,9 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep, case VHOST_VDPA_SET_CONFIG_CALL: r = vhost_vdpa_set_config_call(v, argp); break; + case VHOST_VDPA_GET_IOVA_RANGE: + r = vhost_vdpa_get_iova_range(v, argp); + break; default: r = vhost_dev_ioctl(>vdev, cmd, argp); if (r == -ENOIOCTLCMD) diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h index 0c2349612e77..850956980e27 100644 --- a/include/uapi/linux/vhost.h +++ b/include/uapi/linux/vhost.h @@ -144,4 +144,8 @@ /* Set event fd for config interrupt*/ #define VHOST_VDPA_SET_CONFIG_CALL_IOW(VHOST_VIRTIO, 0x77, int) + +/* Get the valid iova range */ +#define VHOST_VDPA_GET_IOVA_RANGE _IOW(VHOST_VIRTIO, 0x78, \ +struct vhost_vdpa_iova_range) #endif diff --git a/include/uapi/linux/vhost_types.h b/include/uapi/linux/vhost_types.h index 669457ce5c48..4025b5a36177 100644 --- a/include/uapi/linux/vhost_types.h +++ b/include/uapi/linux/vhost_types.h @@ -127,6 +127,11 @@ struct vhost_vdpa_config { __u8 buf[0]; }; +struct vhost_vdpa_iova_range { + __u64 start; + __u64 end; +}; + Pls document fields. And I think first/last is a better API ... /* Feature bits */ /* Log all write descriptors. Can be changed while device is active. */ #define VHOST_F_LOG_ALL 26 -- 2.20.1
Re: [PATCH 4/4] vhost: vdpa: report iova range
On Wed, Jun 17, 2020 at 11:29:47AM +0800, Jason Wang wrote: > This patch introduces a new ioctl for vhost-vdpa device that can > report the iova range by the device. For device that depends on > platform IOMMU, we fetch the iova range via DOMAIN_ATTR_GEOMETRY. For > devices that has its own DMA translation unit, we fetch it directly > from vDPA bus operation. > > Signed-off-by: Jason Wang > --- > drivers/vhost/vdpa.c | 27 +++ > include/uapi/linux/vhost.h | 4 > include/uapi/linux/vhost_types.h | 5 + > 3 files changed, 36 insertions(+) > > diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c > index 77a0c9fb6cc3..ad23e66cbf57 100644 > --- a/drivers/vhost/vdpa.c > +++ b/drivers/vhost/vdpa.c > @@ -332,6 +332,30 @@ static long vhost_vdpa_set_config_call(struct vhost_vdpa > *v, u32 __user *argp) > > return 0; > } > + > +static long vhost_vdpa_get_iova_range(struct vhost_vdpa *v, u32 __user *argp) > +{ > + struct iommu_domain_geometry geo; > + struct vdpa_device *vdpa = v->vdpa; > + const struct vdpa_config_ops *ops = vdpa->config; > + struct vhost_vdpa_iova_range range; > + struct vdpa_iova_range vdpa_range; > + > + if (!ops->set_map && !ops->dma_map) { Why not just check if (ops->get_iova_range) directly? > + iommu_domain_get_attr(v->domain, > + DOMAIN_ATTR_GEOMETRY, ); > + range.start = geo.aperture_start; > + range.end = geo.aperture_end; > + } else { > + vdpa_range = ops->get_iova_range(vdpa); > + range.start = vdpa_range.start; > + range.end = vdpa_range.end; > + } > + > + return copy_to_user(argp, , sizeof(range)); > + > +} > + > static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd, > void __user *argp) > { > @@ -442,6 +466,9 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep, > case VHOST_VDPA_SET_CONFIG_CALL: > r = vhost_vdpa_set_config_call(v, argp); > break; > + case VHOST_VDPA_GET_IOVA_RANGE: > + r = vhost_vdpa_get_iova_range(v, argp); > + break; > default: > r = vhost_dev_ioctl(>vdev, cmd, argp); > if (r == -ENOIOCTLCMD) > diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h > index 0c2349612e77..850956980e27 100644 > --- a/include/uapi/linux/vhost.h > +++ b/include/uapi/linux/vhost.h > @@ -144,4 +144,8 @@ > > /* Set event fd for config interrupt*/ > #define VHOST_VDPA_SET_CONFIG_CALL _IOW(VHOST_VIRTIO, 0x77, int) > + > +/* Get the valid iova range */ > +#define VHOST_VDPA_GET_IOVA_RANGE_IOW(VHOST_VIRTIO, 0x78, \ > + struct vhost_vdpa_iova_range) > #endif > diff --git a/include/uapi/linux/vhost_types.h > b/include/uapi/linux/vhost_types.h > index 669457ce5c48..4025b5a36177 100644 > --- a/include/uapi/linux/vhost_types.h > +++ b/include/uapi/linux/vhost_types.h > @@ -127,6 +127,11 @@ struct vhost_vdpa_config { > __u8 buf[0]; > }; > > +struct vhost_vdpa_iova_range { > + __u64 start; > + __u64 end; > +}; > + Pls document fields. And I think first/last is a better API ... > /* Feature bits */ > /* Log all write descriptors. Can be changed while device is active. */ > #define VHOST_F_LOG_ALL 26 > -- > 2.20.1
[PATCH 4/4] vhost: vdpa: report iova range
This patch introduces a new ioctl for vhost-vdpa device that can report the iova range by the device. For device that depends on platform IOMMU, we fetch the iova range via DOMAIN_ATTR_GEOMETRY. For devices that has its own DMA translation unit, we fetch it directly from vDPA bus operation. Signed-off-by: Jason Wang --- drivers/vhost/vdpa.c | 27 +++ include/uapi/linux/vhost.h | 4 include/uapi/linux/vhost_types.h | 5 + 3 files changed, 36 insertions(+) diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c index 77a0c9fb6cc3..ad23e66cbf57 100644 --- a/drivers/vhost/vdpa.c +++ b/drivers/vhost/vdpa.c @@ -332,6 +332,30 @@ static long vhost_vdpa_set_config_call(struct vhost_vdpa *v, u32 __user *argp) return 0; } + +static long vhost_vdpa_get_iova_range(struct vhost_vdpa *v, u32 __user *argp) +{ + struct iommu_domain_geometry geo; + struct vdpa_device *vdpa = v->vdpa; + const struct vdpa_config_ops *ops = vdpa->config; + struct vhost_vdpa_iova_range range; + struct vdpa_iova_range vdpa_range; + + if (!ops->set_map && !ops->dma_map) { + iommu_domain_get_attr(v->domain, + DOMAIN_ATTR_GEOMETRY, ); + range.start = geo.aperture_start; + range.end = geo.aperture_end; + } else { + vdpa_range = ops->get_iova_range(vdpa); + range.start = vdpa_range.start; + range.end = vdpa_range.end; + } + + return copy_to_user(argp, , sizeof(range)); + +} + static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd, void __user *argp) { @@ -442,6 +466,9 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep, case VHOST_VDPA_SET_CONFIG_CALL: r = vhost_vdpa_set_config_call(v, argp); break; + case VHOST_VDPA_GET_IOVA_RANGE: + r = vhost_vdpa_get_iova_range(v, argp); + break; default: r = vhost_dev_ioctl(>vdev, cmd, argp); if (r == -ENOIOCTLCMD) diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h index 0c2349612e77..850956980e27 100644 --- a/include/uapi/linux/vhost.h +++ b/include/uapi/linux/vhost.h @@ -144,4 +144,8 @@ /* Set event fd for config interrupt*/ #define VHOST_VDPA_SET_CONFIG_CALL _IOW(VHOST_VIRTIO, 0x77, int) + +/* Get the valid iova range */ +#define VHOST_VDPA_GET_IOVA_RANGE _IOW(VHOST_VIRTIO, 0x78, \ +struct vhost_vdpa_iova_range) #endif diff --git a/include/uapi/linux/vhost_types.h b/include/uapi/linux/vhost_types.h index 669457ce5c48..4025b5a36177 100644 --- a/include/uapi/linux/vhost_types.h +++ b/include/uapi/linux/vhost_types.h @@ -127,6 +127,11 @@ struct vhost_vdpa_config { __u8 buf[0]; }; +struct vhost_vdpa_iova_range { + __u64 start; + __u64 end; +}; + /* Feature bits */ /* Log all write descriptors. Can be changed while device is active. */ #define VHOST_F_LOG_ALL 26 -- 2.20.1