Following the discussion with Michael and Jason [1], I reworked a bit
get/set_config() in vdpa.
I changed vdpa_get_config() to check the boundaries and added vdpa_set_config().
When 'offset' or 'len' parameters exceed boundaries, we limit the reading to
the available configuration space in the device, and we return the amount of
bytes read/written.
In this way the user space can pass buffers bigger than config space.
I also returned the amount of bytes read and written to user space.
Patches also available here:
https://github.com/stefano-garzarella/linux/tree/vdpa-get-set-config-refactoring
Thanks for your comments,
Stefano
[1] https://lkml.org/lkml/2021/2/10/350
Stefano Garzarella (10):
vdpa: add get_config_size callback in vdpa_config_ops
vdpa: check vdpa_get_config() parameters and return bytes read
vdpa: add vdpa_set_config() helper
vdpa: remove param checks in the get/set_config callbacks
vdpa: remove WARN_ON() in the get/set_config callbacks
virtio_vdpa: use vdpa_set_config()
vhost/vdpa: use vdpa_set_config()
vhost/vdpa: allow user space to pass buffers bigger than config space
vhost/vdpa: use get_config_size callback in
vhost_vdpa_config_validate()
vhost/vdpa: return configuration bytes read and written to user space
include/linux/vdpa.h | 22 ++++-------
drivers/vdpa/ifcvf/ifcvf_base.c | 3 +-
drivers/vdpa/ifcvf/ifcvf_main.c | 8 +++-
drivers/vdpa/mlx5/net/mlx5_vnet.c | 9 ++++-
drivers/vdpa/vdpa.c | 51 ++++++++++++++++++++++++
drivers/vdpa/vdpa_sim/vdpa_sim.c | 15 +++++---
drivers/vhost/vdpa.c | 64 ++++++++++++++++---------------
drivers/virtio/virtio_vdpa.c | 3 +-
8 files changed, 116 insertions(+), 59 deletions(-)
--
2.29.2
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
This new callback is used to get the size of the configuration space
of vDPA devices.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
include/linux/vdpa.h | 4 ++++
drivers/vdpa/ifcvf/ifcvf_main.c | 6 ++++++
drivers/vdpa/mlx5/net/mlx5_vnet.c | 6 ++++++
drivers/vdpa/vdpa_sim/vdpa_sim.c | 9 +++++++++
4 files changed, 25 insertions(+)
Now we have the 'get_config_size()' callback available, so we can
check that 'offset' and 'len' parameters are valid.
When these exceed boundaries, we limit the reading to the available
configuration space in the device, and we return the amount of bytes
read.
We also move vdpa_get_config() implementation in drivers/vdpa/vdpa.c,
since the function are growing.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
include/linux/vdpa.h | 16 ++--------------
drivers/vdpa/vdpa.c | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 37 insertions(+), 14 deletions(-)
Let's add a function similar to vpda_get_config() to check the
'offset' and 'len' parameters, call the set_config() device callback,
and return the amount of bytes written.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
include/linux/vdpa.h | 2 ++
drivers/vdpa/vdpa.c | 16 ++++++++++++++++
2 files changed, 18 insertions(+)
vdpa_get_config() and vdpa_set_config() now check parameters before
calling callbacks, so we can remove these warnings.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
Maybe we can skip this patch and leave the WARN_ONs in place.
What do you recommend?
---
drivers/vdpa/ifcvf/ifcvf_base.c | 3 +--
drivers/vdpa/ifcvf/ifcvf_main.c | 2 --
2 files changed, 1 insertion(+), 4 deletions(-)
Instead of calling the 'set_config' callback directly, we call the
new vdpa_set_config() helper which also checks the parameters.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
drivers/virtio/virtio_vdpa.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
Instead of calling the 'set_config' callback directly, we call the
new vdpa_set_config() helper which also checks the parameters.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
drivers/vhost/vdpa.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
vdpa_get_config() and vdpa_set_config() now are able to read/write
only the bytes available in the device configuration space, also if
the buffer provided is bigger than that.
Let's use this feature to allow the user space application to pass any
buffer. We limit the size of the internal bounce buffer allocated with
the device config size.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
drivers/vhost/vdpa.c | 36 ++++++++++++++++++++----------------
1 file changed, 20 insertions(+), 16 deletions(-)
Let's use the new 'get_config_size()' callback available instead of
using the 'virtio_id' to get the size of the device config space.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
drivers/vhost/vdpa.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
vdpa_get_config() and vdpa_set_config() now return the amount
of bytes read and written, so let's return them to the user space.
We also modify vhost_vdpa_config_validate() to return 0 (bytes read
or written) instead of an error, when the buffer length is 0.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
drivers/vhost/vdpa.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
nice ping :-)
On Tue, Feb 16, 2021 at 10:44:44AM +0100, Stefano Garzarella wrote:
Following the discussion with Michael and Jason [1], I reworked a bit
get/set_config() in vdpa.
I changed vdpa_get_config() to check the boundaries and added vdpa_set_config().
When 'offset' or 'len' parameters exceed boundaries, we limit the reading to
the available configuration space in the device, and we return the amount of
bytes read/written.
In this way the user space can pass buffers bigger than config space.
I also returned the amount of bytes read and written to user space.
Patches also available here:
https://github.com/stefano-garzarella/linux/tree/vdpa-get-set-config-refactoring
Thanks for your comments,
Stefano
[1] https://lkml.org/lkml/2021/2/10/350
Stefano Garzarella (10):
vdpa: add get_config_size callback in vdpa_config_ops
vdpa: check vdpa_get_config() parameters and return bytes read
vdpa: add vdpa_set_config() helper
vdpa: remove param checks in the get/set_config callbacks
vdpa: remove WARN_ON() in the get/set_config callbacks
virtio_vdpa: use vdpa_set_config()
vhost/vdpa: use vdpa_set_config()
vhost/vdpa: allow user space to pass buffers bigger than config space
vhost/vdpa: use get_config_size callback in
vhost_vdpa_config_validate()
vhost/vdpa: return configuration bytes read and written to user space
include/linux/vdpa.h | 22 ++++-------
drivers/vdpa/ifcvf/ifcvf_base.c | 3 +-
drivers/vdpa/ifcvf/ifcvf_main.c | 8 +++-
drivers/vdpa/mlx5/net/mlx5_vnet.c | 9 ++++-
drivers/vdpa/vdpa.c | 51 ++++++++++++++++++++++++
drivers/vdpa/vdpa_sim/vdpa_sim.c | 15 +++++---
drivers/vhost/vdpa.c | 64 ++++++++++++++++---------------
drivers/virtio/virtio_vdpa.c | 3 +-
8 files changed, 116 insertions(+), 59 deletions(-)
--
2.29.2
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
From: Jason Wang <hidden> Date: 2021-03-02 08:12:54
On 2021/2/16 5:44 下午, Stefano Garzarella wrote:
quoted hunk
This new callback is used to get the size of the configuration space
of vDPA devices.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
include/linux/vdpa.h | 4 ++++
drivers/vdpa/ifcvf/ifcvf_main.c | 6 ++++++
drivers/vdpa/mlx5/net/mlx5_vnet.c | 6 ++++++
drivers/vdpa/vdpa_sim/vdpa_sim.c | 9 +++++++++
4 files changed, 25 insertions(+)
Rethink about this, how much we could gain by introducing a dedicated
ops here? E.g would it be simpler if we simply introduce a
max_config_size to vdpa device?
Thanks
quoted hunk
* @get_config: Read from device specific configuration space
* @vdev: vdpa device
* @offset: offset from the beginning of
From: Jason Wang <hidden> Date: 2021-03-02 08:12:54
On 2021/2/16 5:44 下午, Stefano Garzarella wrote:
quoted hunk
vdpa_get_config() and vdpa_set_config() now return the amount
of bytes read and written, so let's return them to the user space.
We also modify vhost_vdpa_config_validate() to return 0 (bytes read
or written) instead of an error, when the buffer length is 0.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
drivers/vhost/vdpa.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
On Tue, Mar 02, 2021 at 12:05:35PM +0800, Jason Wang wrote:
On 2021/2/16 5:44 下午, Stefano Garzarella wrote:
quoted
vdpa_get_config() and vdpa_set_config() now return the amount
of bytes read and written, so let's return them to the user space.
We also modify vhost_vdpa_config_validate() to return 0 (bytes read
or written) instead of an error, when the buffer length is 0.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
drivers/vhost/vdpa.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
@@ -204,6 +201,7 @@ static long vhost_vdpa_get_config(struct vhost_vdpa *v,structvhost_vdpa_configconfig;unsignedlongsize=offsetof(structvhost_vdpa_config,buf);ssize_tconfig_size;+longret;u8*buf;if(copy_from_user(&config,c,size))
@@ -217,15 +215,18 @@ static long vhost_vdpa_get_config(struct vhost_vdpa *v,if(!buf)return-ENOMEM;-vdpa_get_config(vdpa,config.off,buf,config_size);--if(copy_to_user(c->buf,buf,config_size)){-kvfree(buf);-return-EFAULT;+ret=vdpa_get_config(vdpa,config.off,buf,config_size);+if(ret<0){+ret=-EFAULT;+gotoout;}+if(copy_to_user(c->buf,buf,config_size))+ret=-EFAULT;++out:kvfree(buf);-return0;+returnret;}staticlongvhost_vdpa_set_config(structvhost_vdpa*v,
@@ -235,6 +236,7 @@ static long vhost_vdpa_set_config(struct vhost_vdpa *v,structvhost_vdpa_configconfig;unsignedlongsize=offsetof(structvhost_vdpa_config,buf);ssize_tconfig_size;+longret;u8*buf;if(copy_from_user(&config,c,size))
@@ -248,10 +250,12 @@ static long vhost_vdpa_set_config(struct vhost_vdpa *v,if(IS_ERR(buf))returnPTR_ERR(buf);-vdpa_set_config(vdpa,config.off,buf,config_size);+ret=vdpa_set_config(vdpa,config.off,buf,config_size);+if(ret<0)+ret=-EFAULT;kvfree(buf);-return0;+returnret;}
So I wonder whether it's worth to return the number of bytes since we
can't propogate the result to driver or driver doesn't care about
that.
Okay, but IIUC user space application that issue VHOST_VDPA_GET_CONFIG
ioctl can use the return value.
Should we change also 'struct virtio_config_ops' to propagate this value
also to virtio drivers?
Thanks,
Stefano
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
On Tue, Mar 02, 2021 at 12:14:13PM +0800, Jason Wang wrote:
On 2021/2/16 5:44 下午, Stefano Garzarella wrote:
quoted
This new callback is used to get the size of the configuration space
of vDPA devices.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
include/linux/vdpa.h | 4 ++++
drivers/vdpa/ifcvf/ifcvf_main.c | 6 ++++++
drivers/vdpa/mlx5/net/mlx5_vnet.c | 6 ++++++
drivers/vdpa/vdpa_sim/vdpa_sim.c | 9 +++++++++
4 files changed, 25 insertions(+)
Rethink about this, how much we could gain by introducing a dedicated
ops here? E.g would it be simpler if we simply introduce a
max_config_size to vdpa device?
Mainly because in this way we don't have to add new parameters to the
vdpa_alloc_device() function.
We do the same for example for 'get_device_id', 'get_vendor_id',
'get_vq_num_max'. All of these are usually static, but we have ops.
I think because it's easier to extend.
I don't know if it's worth adding a new structure for these static
values at this point, like 'struct vdpa_config_params'.
Thanks,
Stefano
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
From: Jason Wang <hidden> Date: 2021-03-04 08:34:20
On 2021/3/2 10:06 下午, Stefano Garzarella wrote:
On Tue, Mar 02, 2021 at 12:05:35PM +0800, Jason Wang wrote:
quoted
On 2021/2/16 5:44 下午, Stefano Garzarella wrote:
quoted
vdpa_get_config() and vdpa_set_config() now return the amount
of bytes read and written, so let's return them to the user space.
We also modify vhost_vdpa_config_validate() to return 0 (bytes read
or written) instead of an error, when the buffer length is 0.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
drivers/vhost/vdpa.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
From: Jason Wang <hidden> Date: 2021-03-04 08:37:32
On 2021/3/2 10:15 下午, Stefano Garzarella wrote:
On Tue, Mar 02, 2021 at 12:14:13PM +0800, Jason Wang wrote:
quoted
On 2021/2/16 5:44 下午, Stefano Garzarella wrote:
quoted
This new callback is used to get the size of the configuration space
of vDPA devices.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
include/linux/vdpa.h | 4 ++++
drivers/vdpa/ifcvf/ifcvf_main.c | 6 ++++++
drivers/vdpa/mlx5/net/mlx5_vnet.c | 6 ++++++
drivers/vdpa/vdpa_sim/vdpa_sim.c | 9 +++++++++
4 files changed, 25 insertions(+)
* @set_status: Set the device status
* @vdev: vdpa device
* @status: virtio device status
+ * @get_config_size: Get the size of the configuration space
+ * @vdev: vdpa device
+ * Returns size_t: configuration size
Rethink about this, how much we could gain by introducing a dedicated
ops here? E.g would it be simpler if we simply introduce a
max_config_size to vdpa device?
Mainly because in this way we don't have to add new parameters to the
vdpa_alloc_device() function.
We do the same for example for 'get_device_id', 'get_vendor_id',
'get_vq_num_max'. All of these are usually static, but we have ops.
I think because it's easier to extend.
I don't know if it's worth adding a new structure for these static
values at this point, like 'struct vdpa_config_params'.
Yes, that's the point. I think for any static values, it should be set
during device allocation.
I'm fine with both.
Thanks
On Thu, Mar 04, 2021 at 04:31:22PM +0800, Jason Wang wrote:
On 2021/3/2 10:06 下午, Stefano Garzarella wrote:
quoted
On Tue, Mar 02, 2021 at 12:05:35PM +0800, Jason Wang wrote:
quoted
On 2021/2/16 5:44 下午, Stefano Garzarella wrote:
quoted
vdpa_get_config() and vdpa_set_config() now return the amount
of bytes read and written, so let's return them to the user space.
We also modify vhost_vdpa_config_validate() to return 0 (bytes read
or written) instead of an error, when the buffer length is 0.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
drivers/vhost/vdpa.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
@@ -204,6 +201,7 @@ static long vhost_vdpa_get_config(struct
vhost_vdpa *v,
struct vhost_vdpa_config config;
unsigned long size = offsetof(struct vhost_vdpa_config, buf);
ssize_t config_size;
+ long ret;
u8 *buf;
if (copy_from_user(&config, c, size))
@@ -217,15 +215,18 @@ static long vhost_vdpa_get_config(struct
vhost_vdpa *v,
if (!buf)
return -ENOMEM;
- vdpa_get_config(vdpa, config.off, buf, config_size);
-
- if (copy_to_user(c->buf, buf, config_size)) {
- kvfree(buf);
- return -EFAULT;
+ ret = vdpa_get_config(vdpa, config.off, buf, config_size);
+ if (ret < 0) {
+ ret = -EFAULT;
+ goto out;
}
+ if (copy_to_user(c->buf, buf, config_size))
+ ret = -EFAULT;
+
+out:
kvfree(buf);
- return 0;
+ return ret;
}
static long vhost_vdpa_set_config(struct vhost_vdpa *v,
@@ -235,6 +236,7 @@ static long vhost_vdpa_set_config(struct
vhost_vdpa *v,
struct vhost_vdpa_config config;
unsigned long size = offsetof(struct vhost_vdpa_config, buf);
ssize_t config_size;
+ long ret;
u8 *buf;
if (copy_from_user(&config, c, size))
@@ -248,10 +250,12 @@ static long vhost_vdpa_set_config(struct
vhost_vdpa *v,
if (IS_ERR(buf))
return PTR_ERR(buf);
- vdpa_set_config(vdpa, config.off, buf, config_size);
+ ret = vdpa_set_config(vdpa, config.off, buf, config_size);
+ if (ret < 0)
+ ret = -EFAULT;
kvfree(buf);
- return 0;
+ return ret;
}
So I wonder whether it's worth to return the number of bytes since
we can't propogate the result to driver or driver doesn't care
about that.
Okay, but IIUC user space application that issue
VHOST_VDPA_GET_CONFIG ioctl can use the return value.
Yes, but it looks to it's too late to change since it's a userspace
noticble behaviour.
Yeah, this is a good point.
I looked at QEMU and we only check if the value is not negative, so it
should work, but for other applications it could be a real change.
Do we leave it as is?
quoted
Should we change also 'struct virtio_config_ops' to propagate this
value also to virtio drivers?
I think not, the reason is the driver doesn't expect the get()/set()
can fail...
On Thu, Mar 04, 2021 at 04:34:52PM +0800, Jason Wang wrote:
On 2021/3/2 10:15 下午, Stefano Garzarella wrote:
quoted
On Tue, Mar 02, 2021 at 12:14:13PM +0800, Jason Wang wrote:
quoted
On 2021/2/16 5:44 下午, Stefano Garzarella wrote:
quoted
This new callback is used to get the size of the configuration space
of vDPA devices.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
include/linux/vdpa.h | 4 ++++
drivers/vdpa/ifcvf/ifcvf_main.c | 6 ++++++
drivers/vdpa/mlx5/net/mlx5_vnet.c | 6 ++++++
drivers/vdpa/vdpa_sim/vdpa_sim.c | 9 +++++++++
4 files changed, 25 insertions(+)
Rethink about this, how much we could gain by introducing a
dedicated ops here? E.g would it be simpler if we simply introduce
a max_config_size to vdpa device?
Mainly because in this way we don't have to add new parameters to
the vdpa_alloc_device() function.
We do the same for example for 'get_device_id', 'get_vendor_id',
'get_vq_num_max'. All of these are usually static, but we have ops.
I think because it's easier to extend.
I don't know if it's worth adding a new structure for these static
values at this point, like 'struct vdpa_config_params'.
Yes, that's the point. I think for any static values, it should be set
during device allocation.
From: Jason Wang <hidden> Date: 2021-03-08 04:00:32
On 2021/3/5 4:37 下午, Stefano Garzarella wrote:
On Thu, Mar 04, 2021 at 04:31:22PM +0800, Jason Wang wrote:
quoted
On 2021/3/2 10:06 下午, Stefano Garzarella wrote:
quoted
On Tue, Mar 02, 2021 at 12:05:35PM +0800, Jason Wang wrote:
quoted
On 2021/2/16 5:44 下午, Stefano Garzarella wrote:
quoted
vdpa_get_config() and vdpa_set_config() now return the amount
of bytes read and written, so let's return them to the user space.
We also modify vhost_vdpa_config_validate() to return 0 (bytes read
or written) instead of an error, when the buffer length is 0.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
drivers/vhost/vdpa.c | 26 +++++++++++++++-----------
1 file changed, 15 insertions(+), 11 deletions(-)
@@ -204,6 +201,7 @@ static long vhost_vdpa_get_config(struct
vhost_vdpa *v,
struct vhost_vdpa_config config;
unsigned long size = offsetof(struct vhost_vdpa_config, buf);
ssize_t config_size;
+ long ret;
u8 *buf;
if (copy_from_user(&config, c, size))
@@ -217,15 +215,18 @@ static long vhost_vdpa_get_config(struct
vhost_vdpa *v,
if (!buf)
return -ENOMEM;
- vdpa_get_config(vdpa, config.off, buf, config_size);
-
- if (copy_to_user(c->buf, buf, config_size)) {
- kvfree(buf);
- return -EFAULT;
+ ret = vdpa_get_config(vdpa, config.off, buf, config_size);
+ if (ret < 0) {
+ ret = -EFAULT;
+ goto out;
}
+ if (copy_to_user(c->buf, buf, config_size))
+ ret = -EFAULT;
+
+out:
kvfree(buf);
- return 0;
+ return ret;
}
static long vhost_vdpa_set_config(struct vhost_vdpa *v,
@@ -235,6 +236,7 @@ static long vhost_vdpa_set_config(struct
vhost_vdpa *v,
struct vhost_vdpa_config config;
unsigned long size = offsetof(struct vhost_vdpa_config, buf);
ssize_t config_size;
+ long ret;
u8 *buf;
if (copy_from_user(&config, c, size))
@@ -248,10 +250,12 @@ static long vhost_vdpa_set_config(struct
vhost_vdpa *v,
if (IS_ERR(buf))
return PTR_ERR(buf);
- vdpa_set_config(vdpa, config.off, buf, config_size);
+ ret = vdpa_set_config(vdpa, config.off, buf, config_size);
+ if (ret < 0)
+ ret = -EFAULT;
kvfree(buf);
- return 0;
+ return ret;
}
So I wonder whether it's worth to return the number of bytes since
we can't propogate the result to driver or driver doesn't care
about that.
Okay, but IIUC user space application that issue
VHOST_VDPA_GET_CONFIG ioctl can use the return value.
Yes, but it looks to it's too late to change since it's a userspace
noticble behaviour.
Yeah, this is a good point.
I looked at QEMU and we only check if the value is not negative, so it
should work, but for other applications it could be a real change.
Do we leave it as is?
Yes, I think we'd better be conservative here.
Thanks
quoted
quoted
Should we change also 'struct virtio_config_ops' to propagate this
value also to virtio drivers?
I think not, the reason is the driver doesn't expect the get()/set()
can fail...