vdpa: Introduce and use vdpa device get, set config helpers
authorParav Pandit <parav@nvidia.com>
Tue, 26 Oct 2021 17:55:12 +0000 (20:55 +0300)
committerMichael S. Tsirkin <mst@redhat.com>
Mon, 1 Nov 2021 09:26:49 +0000 (05:26 -0400)
Subsequent patches enable get and set configuration either
via management device or via vdpa device' config ops.

This requires synchronization between multiple callers to get and set
config callbacks. Features setting also influence the layout of the
configuration fields endianness.

To avoid exposing synchronization primitives to callers, introduce
helper for setting the configuration and use it.

Signed-off-by: Parav Pandit <parav@nvidia.com>
Reviewed-by: Eli Cohen <elic@nvidia.com>
Acked-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Link: https://lore.kernel.org/r/20211026175519.87795-2-parav@nvidia.com
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
drivers/vdpa/vdpa.c
drivers/vhost/vdpa.c
drivers/virtio/virtio_vdpa.c
include/linux/vdpa.h

index fcf02a36487893d5e8d07774ce63768a60eb2213..cbc8fc69cf9b48d7081eb5eaa63fdf4cdaa20340 100644 (file)
@@ -297,6 +297,42 @@ void vdpa_mgmtdev_unregister(struct vdpa_mgmt_dev *mdev)
 }
 EXPORT_SYMBOL_GPL(vdpa_mgmtdev_unregister);
 
+/**
+ * vdpa_get_config - Get one or more device configuration fields.
+ * @vdev: vdpa device to operate on
+ * @offset: starting byte offset of the field
+ * @buf: buffer pointer to read to
+ * @len: length of the configuration fields in bytes
+ */
+void vdpa_get_config(struct vdpa_device *vdev, unsigned int offset,
+                    void *buf, unsigned int len)
+{
+       const struct vdpa_config_ops *ops = vdev->config;
+
+       /*
+        * Config accesses aren't supposed to trigger before features are set.
+        * If it does happen we assume a legacy guest.
+        */
+       if (!vdev->features_valid)
+               vdpa_set_features(vdev, 0);
+       ops->get_config(vdev, offset, buf, len);
+}
+EXPORT_SYMBOL_GPL(vdpa_get_config);
+
+/**
+ * vdpa_set_config - Set one or more device configuration fields.
+ * @vdev: vdpa device to operate on
+ * @offset: starting byte offset of the field
+ * @buf: buffer pointer to read from
+ * @length: length of the configuration fields in bytes
+ */
+void vdpa_set_config(struct vdpa_device *vdev, unsigned int offset,
+                    const void *buf, unsigned int length)
+{
+       vdev->config->set_config(vdev, offset, buf, length);
+}
+EXPORT_SYMBOL_GPL(vdpa_set_config);
+
 static bool mgmtdev_handle_match(const struct vdpa_mgmt_dev *mdev,
                                 const char *busname, const char *devname)
 {
index 39039e0461175be42386471b3f7e2c204d0b7089..01c59ce7e2508008e3b1de849a13a0253c55a9df 100644 (file)
@@ -237,7 +237,6 @@ static long vhost_vdpa_set_config(struct vhost_vdpa *v,
                                  struct vhost_vdpa_config __user *c)
 {
        struct vdpa_device *vdpa = v->vdpa;
-       const struct vdpa_config_ops *ops = vdpa->config;
        struct vhost_vdpa_config config;
        unsigned long size = offsetof(struct vhost_vdpa_config, buf);
        u8 *buf;
@@ -251,7 +250,7 @@ static long vhost_vdpa_set_config(struct vhost_vdpa *v,
        if (IS_ERR(buf))
                return PTR_ERR(buf);
 
-       ops->set_config(vdpa, config.off, buf, config.len);
+       vdpa_set_config(vdpa, config.off, buf, config.len);
 
        kvfree(buf);
        return 0;
index 6b62aaf08cc53e07fba7e2b09f81b7340a60314b..f85f860bc10bd33b27e29d96096b6322b6e23907 100644 (file)
@@ -65,9 +65,8 @@ static void virtio_vdpa_set(struct virtio_device *vdev, unsigned offset,
                            const void *buf, unsigned len)
 {
        struct vdpa_device *vdpa = vd_get_vdpa(vdev);
-       const struct vdpa_config_ops *ops = vdpa->config;
 
-       ops->set_config(vdpa, offset, buf, len);
+       vdpa_set_config(vdpa, offset, buf, len);
 }
 
 static u32 virtio_vdpa_generation(struct virtio_device *vdev)
index 30864848950b77af16d72401e2b206583dc9cd02..267236aab34c56a12a547788e504a30464a77d95 100644 (file)
@@ -386,21 +386,10 @@ static inline int vdpa_set_features(struct vdpa_device *vdev, u64 features)
        return ops->set_features(vdev, features);
 }
 
-static inline void vdpa_get_config(struct vdpa_device *vdev,
-                                  unsigned int offset, void *buf,
-                                  unsigned int len)
-{
-       const struct vdpa_config_ops *ops = vdev->config;
-
-       /*
-        * Config accesses aren't supposed to trigger before features are set.
-        * If it does happen we assume a legacy guest.
-        */
-       if (!vdev->features_valid)
-               vdpa_set_features(vdev, 0);
-       ops->get_config(vdev, offset, buf, len);
-}
-
+void vdpa_get_config(struct vdpa_device *vdev, unsigned int offset,
+                    void *buf, unsigned int len);
+void vdpa_set_config(struct vdpa_device *dev, unsigned int offset,
+                    const void *buf, unsigned int length);
 /**
  * struct vdpa_mgmtdev_ops - vdpa device ops
  * @dev_add: Add a vdpa device using alloc and register