fac818adb1
Change-Id: I574115f5e44e56ac2baaad71eeab6b9fd7149747
1249 lines
39 KiB
Diff
1249 lines
39 KiB
Diff
From 98a58119c5418b3149a729c2a1515ce9d75e60d0 Mon Sep 17 00:00:00 2001
|
|
From: jiangdongxu <jiangdongxu1@huawei.com>
|
|
Date: Fri, 23 Feb 2024 19:28:06 +0800
|
|
Subject: [PATCH 01/12] vdpa: add log operations
|
|
|
|
Several new interfaces are introduced to allow vdpa
|
|
device logging guest memory during live migration and
|
|
return to the VMM.
|
|
|
|
The set_log_base interface is used to set the base
|
|
address for buffer storing bitmaps.
|
|
|
|
The set_log_size interface is used to set the size
|
|
of buffer used for storing bitmaps.
|
|
|
|
The log_sync interface is used to copy the bitmaps
|
|
from kernel space to user space of VMM.
|
|
|
|
These operations are optional. If they are not implemented,
|
|
these operations will return EOPNOTSUPP.
|
|
|
|
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
|
---
|
|
include/linux/vdpa.h | 14 ++++++++++++++
|
|
1 file changed, 14 insertions(+)
|
|
|
|
diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h
|
|
index 0e652026b776..d2c322a6e4ae 100644
|
|
--- a/include/linux/vdpa.h
|
|
+++ b/include/linux/vdpa.h
|
|
@@ -330,6 +330,15 @@ struct vdpa_map_file {
|
|
* @unbind_mm: Unbind the device from the address space
|
|
* bound using the bind_mm callback. (optional)
|
|
* @vdev: vdpa device
|
|
+ * @set_log_base Set base address for logging. (optional)
|
|
+ * @vdev: vdpa device
|
|
+ * @base: base address
|
|
+ * @set_log_size Set buffer size for logging. (optional)
|
|
+ * @vdev: vdpa device
|
|
+ * @size: logging buffer size
|
|
+ * @log_sync Synchronize logging buffer from kernel space to
|
|
+ * user space. (optional)
|
|
+ * @vdev: vdpa device
|
|
* @free: Free resources that belongs to vDPA (optional)
|
|
* @vdev: vdpa device
|
|
*/
|
|
@@ -400,6 +409,11 @@ struct vdpa_config_ops {
|
|
int (*bind_mm)(struct vdpa_device *vdev, struct mm_struct *mm);
|
|
void (*unbind_mm)(struct vdpa_device *vdev);
|
|
|
|
+ /* Log ops */
|
|
+ int (*set_log_base)(struct vdpa_device *vdev, uint64_t base);
|
|
+ int (*set_log_size)(struct vdpa_device *vdev, uint64_t size);
|
|
+ int (*log_sync)(struct vdpa_device *vdev);
|
|
+
|
|
/* Free device resources */
|
|
void (*free)(struct vdpa_device *vdev);
|
|
};
|
|
--
|
|
Gitee
|
|
|
|
|
|
From 52d87abe520a7d06e908d923bfcd2c5b934e9dd0 Mon Sep 17 00:00:00 2001
|
|
From: jiangdongxu <jiangdongxu1@huawei.com>
|
|
Date: Fri, 23 Feb 2024 19:28:07 +0800
|
|
Subject: [PATCH 02/12] vhost-vdpa: add uAPI for logging
|
|
|
|
These new ioctl add support for setting bitmaps config,
|
|
like base address and buffer size from userspace.
|
|
|
|
When setup migration, VMM will call VHOST_SET_LOG_BASE and
|
|
VHOST_SET_LOG_SIZE to set address and size of buffer used
|
|
for storing bitmaps.
|
|
|
|
Then VMM start live migration, VMM will enable logging
|
|
vhost device by set feature VHOST_F_LOG_ALL.
|
|
|
|
And during live migration iterate, VMM get dirty page info
|
|
from vhost device by calling VHOST_LOG_SYNC.
|
|
|
|
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
|
---
|
|
drivers/vhost/vdpa.c | 49 ++++++++++++++++++++++++++++++++++++++
|
|
include/uapi/linux/vhost.h | 4 ++++
|
|
2 files changed, 53 insertions(+)
|
|
|
|
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
|
|
index fb590e346e43..425850d1c2c7 100644
|
|
--- a/drivers/vhost/vdpa.c
|
|
+++ b/drivers/vhost/vdpa.c
|
|
@@ -567,6 +567,47 @@ static long vhost_vdpa_resume(struct vhost_vdpa *v)
|
|
return ops->resume(vdpa);
|
|
}
|
|
|
|
+static long vhost_vdpa_set_log_base(struct vhost_vdpa *v, u64 __user *argp)
|
|
+{
|
|
+ struct vdpa_device *vdpa = v->vdpa;
|
|
+ const struct vdpa_config_ops *ops = vdpa->config;
|
|
+ u64 log;
|
|
+
|
|
+ if (!ops->set_log_base)
|
|
+ return -EOPNOTSUPP;
|
|
+
|
|
+ if (copy_from_user(&log, argp, sizeof(uint64_t)))
|
|
+ return -EFAULT;
|
|
+
|
|
+ return ops->set_log_base(vdpa, log);
|
|
+}
|
|
+
|
|
+static long vhost_vdpa_set_log_size(struct vhost_vdpa *v, u64 __user *sizep)
|
|
+{
|
|
+ struct vdpa_device *vdpa = v->vdpa;
|
|
+ const struct vdpa_config_ops *ops = vdpa->config;
|
|
+ u64 log_size;
|
|
+
|
|
+ if (!ops->set_log_size)
|
|
+ return -EOPNOTSUPP;
|
|
+
|
|
+ if (copy_from_user(&log_size, sizep, sizeof(log_size)))
|
|
+ return -EFAULT;
|
|
+
|
|
+ return ops->set_log_size(vdpa, log_size);
|
|
+}
|
|
+
|
|
+static long vhost_vdpa_log_sync(struct vhost_vdpa *v)
|
|
+{
|
|
+ struct vdpa_device *vdpa = v->vdpa;
|
|
+ const struct vdpa_config_ops *ops = vdpa->config;
|
|
+
|
|
+ if (!ops->log_sync)
|
|
+ return -EOPNOTSUPP;
|
|
+
|
|
+ return ops->log_sync(vdpa);
|
|
+}
|
|
+
|
|
static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
|
|
void __user *argp)
|
|
{
|
|
@@ -741,6 +782,14 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
|
|
r = -EFAULT;
|
|
break;
|
|
case VHOST_SET_LOG_BASE:
|
|
+ r = vhost_vdpa_set_log_base(v, argp);
|
|
+ break;
|
|
+ case VHOST_SET_LOG_SIZE:
|
|
+ r = vhost_vdpa_set_log_size(v, argp);
|
|
+ break;
|
|
+ case VHOST_LOG_SYNC:
|
|
+ r = vhost_vdpa_log_sync(v);
|
|
+ break;
|
|
case VHOST_SET_LOG_FD:
|
|
r = -ENOIOCTLCMD;
|
|
break;
|
|
diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
|
|
index f5c48b61ab62..ce9d187432d1 100644
|
|
--- a/include/uapi/linux/vhost.h
|
|
+++ b/include/uapi/linux/vhost.h
|
|
@@ -43,6 +43,10 @@
|
|
* The bit is set using an atomic 32 bit operation. */
|
|
/* Set base address for logging. */
|
|
#define VHOST_SET_LOG_BASE _IOW(VHOST_VIRTIO, 0x04, __u64)
|
|
+/* Set buffer size for logging */
|
|
+#define VHOST_SET_LOG_SIZE _IOW(VHOST_VIRTIO, 0x05, __u64)
|
|
+/* Synchronize logging buffer from kernel space to user space */
|
|
+#define VHOST_LOG_SYNC _IO(VHOST_VIRTIO, 0x06)
|
|
/* Specify an eventfd file descriptor to signal on log write. */
|
|
#define VHOST_SET_LOG_FD _IOW(VHOST_VIRTIO, 0x07, int)
|
|
/* By default, a device gets one vhost_worker that its virtqueues share. This
|
|
--
|
|
Gitee
|
|
|
|
|
|
From 396fa0d0428f268d0c08710b721d6c492eb42a6c Mon Sep 17 00:00:00 2001
|
|
From: jiangdongxu <jiangdongxu1@huawei.com>
|
|
Date: Fri, 23 Feb 2024 19:28:08 +0800
|
|
Subject: [PATCH 03/12] vdpa: add device state operations
|
|
|
|
Introduce several interfaces to allow vdpa device save/load device
|
|
status when guest machine resume and suspend.
|
|
|
|
The get_dev_buffer_size interface is used to get the buffer size
|
|
of vdpa device status.
|
|
|
|
The get_dev_buffer interface is used to get the device buffer from
|
|
vdpa device, and VMM can save it.
|
|
|
|
The set_dev_buffer interface is used to set the device status from
|
|
userspace.
|
|
|
|
These operations are optional. If they are not implemented, return
|
|
EOPNOTSUPP.
|
|
|
|
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
|
---
|
|
include/linux/vdpa.h | 20 ++++++++++++++++++++
|
|
1 file changed, 20 insertions(+)
|
|
|
|
diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h
|
|
index d2c322a6e4ae..fffd6cd366bf 100644
|
|
--- a/include/linux/vdpa.h
|
|
+++ b/include/linux/vdpa.h
|
|
@@ -339,6 +339,19 @@ struct vdpa_map_file {
|
|
* @log_sync Synchronize logging buffer from kernel space to
|
|
* user space. (optional)
|
|
* @vdev: vdpa device
|
|
+ * @get_dev_buffer_size Get device state buffer size. (optional)
|
|
+ * @vdev: vdpa device
|
|
+ * Return device status buffer size of vdpa device.
|
|
+ * @get_dev_buffer Get device state buffer. (optional)
|
|
+ * @vdev: vdpa device
|
|
+ * @offset: offset of dest for saving device state.
|
|
+ * @dest: userspace address for saving device state.
|
|
+ * @len: device state buffer length.
|
|
+ * @set_dev_buffer Set device state buffer. (opetional)
|
|
+ * @vdev: vdpa device
|
|
+ * @offset: offset of src addr of device state.
|
|
+ * @src: userspace addr of device state
|
|
+ * @len: device state buffer length.
|
|
* @free: Free resources that belongs to vDPA (optional)
|
|
* @vdev: vdpa device
|
|
*/
|
|
@@ -414,6 +427,13 @@ struct vdpa_config_ops {
|
|
int (*set_log_size)(struct vdpa_device *vdev, uint64_t size);
|
|
int (*log_sync)(struct vdpa_device *vdev);
|
|
|
|
+ /* device state ops */
|
|
+ uint32_t (*get_dev_buffer_size)(struct vdpa_device *vdpa);
|
|
+ int (*get_dev_buffer)(struct vdpa_device *vdev, unsigned int offset,
|
|
+ void __user *dest, unsigned int len);
|
|
+ int (*set_dev_buffer)(struct vdpa_device *vdev, unsigned int offset,
|
|
+ const void __user *src, unsigned int len);
|
|
+
|
|
/* Free device resources */
|
|
void (*free)(struct vdpa_device *vdev);
|
|
};
|
|
--
|
|
Gitee
|
|
|
|
|
|
From a9d33c5eb57fe8d807ae995785d91ee20ea6da9b Mon Sep 17 00:00:00 2001
|
|
From: jiangdongxu <jiangdongxu1@huawei.com>
|
|
Date: Fri, 23 Feb 2024 19:28:09 +0800
|
|
Subject: [PATCH 04/12] vhost-vdpa: add uAPI for device buffer
|
|
|
|
These new ioctl add support for saving/loading device status from
|
|
usersapce.
|
|
|
|
When vhost-vdpa device start migration, VMM need to call these ioctl to
|
|
save/load device status of vhost-vdpa devices if these ops is
|
|
implemented.
|
|
|
|
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
|
---
|
|
drivers/vhost/vdpa.c | 71 ++++++++++++++++++++++++++++++++++++++
|
|
include/uapi/linux/vhost.h | 5 +++
|
|
2 files changed, 76 insertions(+)
|
|
|
|
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
|
|
index 425850d1c2c7..84765b4ec33c 100644
|
|
--- a/drivers/vhost/vdpa.c
|
|
+++ b/drivers/vhost/vdpa.c
|
|
@@ -567,6 +567,68 @@ static long vhost_vdpa_resume(struct vhost_vdpa *v)
|
|
return ops->resume(vdpa);
|
|
}
|
|
|
|
+static int vhost_vdpa_get_dev_buffer_size(struct vhost_vdpa *v,
|
|
+ uint32_t __user *argp)
|
|
+{
|
|
+ struct vdpa_device *vdpa = v->vdpa;
|
|
+ const struct vdpa_config_ops *ops = vdpa->config;
|
|
+ uint32_t size;
|
|
+
|
|
+ if (!ops->get_dev_buffer_size)
|
|
+ return -EOPNOTSUPP;
|
|
+
|
|
+ size = ops->get_dev_buffer_size(vdpa);
|
|
+
|
|
+ if (copy_to_user(argp, &size, sizeof(size)))
|
|
+ return -EFAULT;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int vhost_vdpa_get_dev_buffer(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;
|
|
+ int ret;
|
|
+ unsigned long size = offsetof(struct vhost_vdpa_config, buf);
|
|
+
|
|
+ if (copy_from_user(&config, c, size))
|
|
+ return -EFAULT;
|
|
+
|
|
+ if (!ops->get_dev_buffer)
|
|
+ return -EOPNOTSUPP;
|
|
+
|
|
+ down_read(&vdpa->cf_lock);
|
|
+ ret = ops->get_dev_buffer(vdpa, config.off, c->buf, config.len);
|
|
+ up_read(&vdpa->cf_lock);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int vhost_vdpa_set_dev_buffer(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;
|
|
+ int ret;
|
|
+ unsigned long size = offsetof(struct vhost_vdpa_config, buf);
|
|
+
|
|
+ if (copy_from_user(&config, c, size))
|
|
+ return -EFAULT;
|
|
+
|
|
+ if (!ops->set_dev_buffer)
|
|
+ return -EOPNOTSUPP;
|
|
+
|
|
+ down_write(&vdpa->cf_lock);
|
|
+ ret = ops->set_dev_buffer(vdpa, config.off, c->buf, config.len);
|
|
+ up_write(&vdpa->cf_lock);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static long vhost_vdpa_set_log_base(struct vhost_vdpa *v, u64 __user *argp)
|
|
{
|
|
struct vdpa_device *vdpa = v->vdpa;
|
|
@@ -821,6 +883,15 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
|
|
case VHOST_VDPA_RESUME:
|
|
r = vhost_vdpa_resume(v);
|
|
break;
|
|
+ case VHOST_GET_DEV_BUFFER_SIZE:
|
|
+ r = vhost_vdpa_get_dev_buffer_size(v, argp);
|
|
+ break;
|
|
+ case VHOST_GET_DEV_BUFFER:
|
|
+ r = vhost_vdpa_get_dev_buffer(v, argp);
|
|
+ break;
|
|
+ case VHOST_SET_DEV_BUFFER:
|
|
+ r = vhost_vdpa_set_dev_buffer(v, argp);
|
|
+ break;
|
|
default:
|
|
r = vhost_dev_ioctl(&v->vdev, cmd, argp);
|
|
if (r == -ENOIOCTLCMD)
|
|
diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
|
|
index ce9d187432d1..7307f01cd2fa 100644
|
|
--- a/include/uapi/linux/vhost.h
|
|
+++ b/include/uapi/linux/vhost.h
|
|
@@ -223,4 +223,9 @@
|
|
*/
|
|
#define VHOST_VDPA_RESUME _IO(VHOST_VIRTIO, 0x7E)
|
|
|
|
+/* set and get device buffer */
|
|
+#define VHOST_GET_DEV_BUFFER _IOR(VHOST_VIRTIO, 0xb0, struct vhost_vdpa_config)
|
|
+#define VHOST_SET_DEV_BUFFER _IOW(VHOST_VIRTIO, 0xb1, struct vhost_vdpa_config)
|
|
+#define VHOST_GET_DEV_BUFFER_SIZE _IOR(VHOST_VIRTIO, 0xb3, __u32)
|
|
+
|
|
#endif
|
|
--
|
|
Gitee
|
|
|
|
|
|
From bdf631a310e716487ba6fedb140237cc70de0025 Mon Sep 17 00:00:00 2001
|
|
From: jiangdongxu <jiangdongxu1@huawei.com>
|
|
Date: Fri, 23 Feb 2024 19:28:10 +0800
|
|
Subject: [PATCH 05/12] vdpa: add vdpa device migration status ops
|
|
|
|
Introduce a new interface to set vdpa device migration status, Such as
|
|
migration start/stop, pre_start/pre_stop, etc.
|
|
|
|
Some vdpa device need to do some job in different state. As not all vdpa
|
|
devices need to do this, this interface is optional.
|
|
|
|
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
|
---
|
|
include/linux/vdpa.h | 6 ++++++
|
|
1 file changed, 6 insertions(+)
|
|
|
|
diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h
|
|
index fffd6cd366bf..1ed264ec1ebb 100644
|
|
--- a/include/linux/vdpa.h
|
|
+++ b/include/linux/vdpa.h
|
|
@@ -352,6 +352,9 @@ struct vdpa_map_file {
|
|
* @offset: offset of src addr of device state.
|
|
* @src: userspace addr of device state
|
|
* @len: device state buffer length.
|
|
+ * @set_mig_state Set device migration status. (optional)
|
|
+ * @vdev: vdpa device
|
|
+ * @status: migration status
|
|
* @free: Free resources that belongs to vDPA (optional)
|
|
* @vdev: vdpa device
|
|
*/
|
|
@@ -434,6 +437,9 @@ struct vdpa_config_ops {
|
|
int (*set_dev_buffer)(struct vdpa_device *vdev, unsigned int offset,
|
|
const void __user *src, unsigned int len);
|
|
|
|
+ /* device mig state ops */
|
|
+ int (*set_mig_state)(struct vdpa_device *v, u8 state);
|
|
+
|
|
/* Free device resources */
|
|
void (*free)(struct vdpa_device *vdev);
|
|
};
|
|
--
|
|
Gitee
|
|
|
|
|
|
From 269a8fd61bad289082df2ec7fc3f38adb3afa597 Mon Sep 17 00:00:00 2001
|
|
From: jiangdongxu <jiangdongxu1@huawei.com>
|
|
Date: Fri, 23 Feb 2024 19:28:11 +0800
|
|
Subject: [PATCH 06/12] vhost-vdpa: add uAPI for device migration status
|
|
|
|
These new ioctl add support for setting vhost-vdpa device migration
|
|
state.
|
|
|
|
During migration, there is several migration state such as start/stop,
|
|
pre_start/pre_stop, post_start/post_stop, cancel etc.Some hardware needs
|
|
to do something at these stages, introduce a new ioctl to implement it.
|
|
|
|
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
|
---
|
|
drivers/vhost/vdpa.c | 18 ++++++++++++++++++
|
|
include/uapi/linux/vhost.h | 3 +++
|
|
include/uapi/linux/vhost_types.h | 16 ++++++++++++++++
|
|
3 files changed, 37 insertions(+)
|
|
|
|
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
|
|
index 84765b4ec33c..251d176329d9 100644
|
|
--- a/drivers/vhost/vdpa.c
|
|
+++ b/drivers/vhost/vdpa.c
|
|
@@ -629,6 +629,21 @@ static int vhost_vdpa_set_dev_buffer(struct vhost_vdpa *v,
|
|
return ret;
|
|
}
|
|
|
|
+static int vhost_vdpa_set_mig_state(struct vhost_vdpa *v, u8 __user *c)
|
|
+{
|
|
+ struct vdpa_device *vdpa = v->vdpa;
|
|
+ const struct vdpa_config_ops *ops = vdpa->config;
|
|
+ u8 state;
|
|
+
|
|
+ if (!ops->set_mig_state)
|
|
+ return -EOPNOTSUPP;
|
|
+
|
|
+ if (get_user(state, c))
|
|
+ return -EFAULT;
|
|
+
|
|
+ return ops->set_mig_state(vdpa, state);
|
|
+}
|
|
+
|
|
static long vhost_vdpa_set_log_base(struct vhost_vdpa *v, u64 __user *argp)
|
|
{
|
|
struct vdpa_device *vdpa = v->vdpa;
|
|
@@ -892,6 +907,9 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
|
|
case VHOST_SET_DEV_BUFFER:
|
|
r = vhost_vdpa_set_dev_buffer(v, argp);
|
|
break;
|
|
+ case VHOST_VDPA_SET_MIG_STATE:
|
|
+ r = vhost_vdpa_set_mig_state(v, argp);
|
|
+ break;
|
|
default:
|
|
r = vhost_dev_ioctl(&v->vdev, cmd, argp);
|
|
if (r == -ENOIOCTLCMD)
|
|
diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
|
|
index 7307f01cd2fa..a54098c7b0bc 100644
|
|
--- a/include/uapi/linux/vhost.h
|
|
+++ b/include/uapi/linux/vhost.h
|
|
@@ -228,4 +228,7 @@
|
|
#define VHOST_SET_DEV_BUFFER _IOW(VHOST_VIRTIO, 0xb1, struct vhost_vdpa_config)
|
|
#define VHOST_GET_DEV_BUFFER_SIZE _IOR(VHOST_VIRTIO, 0xb3, __u32)
|
|
|
|
+/* set device migtration state */
|
|
+#define VHOST_VDPA_SET_MIG_STATE _IOW(VHOST_VIRTIO, 0xb2, __u8)
|
|
+
|
|
#endif
|
|
diff --git a/include/uapi/linux/vhost_types.h b/include/uapi/linux/vhost_types.h
|
|
index 2d827d22cd99..13c44c124a48 100644
|
|
--- a/include/uapi/linux/vhost_types.h
|
|
+++ b/include/uapi/linux/vhost_types.h
|
|
@@ -163,6 +163,22 @@ struct vhost_vdpa_iova_range {
|
|
__u64 last;
|
|
};
|
|
|
|
+/* vhost vdpa device migration statue */
|
|
+enum {
|
|
+ VHOST_VDPA_DEVICE_START,
|
|
+ VHOST_VDPA_DEVICE_STOP,
|
|
+ VHOST_VDPA_DEVICE_PRE_START,
|
|
+ VHOST_VDPA_DEVICE_PRE_STOP,
|
|
+ VHOST_VDPA_DEVICE_CANCEL,
|
|
+ VHOST_VDPA_DEVICE_POST_START,
|
|
+ VHOST_VDPA_DEVICE_START_ASYNC,
|
|
+ VHOST_VDPA_DEVICE_STOP_ASYNC,
|
|
+ VHOST_VDPA_DEVICE_PRE_START_ASYNC,
|
|
+ VHOST_VDPA_DEVICE_QUERY_OP_STATE,
|
|
+ VHOST_VDPA_DEVICE_MSIX_MASK,
|
|
+ VHOST_VDPA_DEVICE_MSIX_UNMASK,
|
|
+};
|
|
+
|
|
/* Feature bits */
|
|
/* Log all write descriptors. Can be changed while device is active. */
|
|
#define VHOST_F_LOG_ALL 26
|
|
--
|
|
Gitee
|
|
|
|
|
|
From b1b48dd815c53adfb056c837ae27310c8ac8bdb3 Mon Sep 17 00:00:00 2001
|
|
From: jiangdongxu <jiangdongxu1@huawei.com>
|
|
Date: Fri, 23 Feb 2024 19:28:12 +0800
|
|
Subject: [PATCH 07/12] vhost: add VHOST feature VHOST_BACKEND_F_BYTEMAPLOG
|
|
|
|
Introduce new feature bit VHOST_BACKEND_F_BYTEMAPLOG for negotiating the
|
|
type of dirty pages.
|
|
|
|
As some hardware only support bytemap for logging, introduce a new
|
|
feature bit. When vhost device starte, negotiating dirty page type used
|
|
for logging.
|
|
|
|
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
|
---
|
|
drivers/vhost/vdpa.c | 3 ++-
|
|
include/uapi/linux/vhost_types.h | 3 +++
|
|
2 files changed, 5 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
|
|
index 251d176329d9..9af834fc2a47 100644
|
|
--- a/drivers/vhost/vdpa.c
|
|
+++ b/drivers/vhost/vdpa.c
|
|
@@ -810,7 +810,8 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
|
|
if (features & ~(VHOST_VDPA_BACKEND_FEATURES |
|
|
BIT_ULL(VHOST_BACKEND_F_SUSPEND) |
|
|
BIT_ULL(VHOST_BACKEND_F_RESUME) |
|
|
- BIT_ULL(VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK)))
|
|
+ BIT_ULL(VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK) |
|
|
+ BIT_ULL(VHOST_BACKEND_F_BYTEMAPLOG)))
|
|
return -EOPNOTSUPP;
|
|
if ((features & BIT_ULL(VHOST_BACKEND_F_SUSPEND)) &&
|
|
!vhost_vdpa_can_suspend(v))
|
|
diff --git a/include/uapi/linux/vhost_types.h b/include/uapi/linux/vhost_types.h
|
|
index 13c44c124a48..c7f25b0f7645 100644
|
|
--- a/include/uapi/linux/vhost_types.h
|
|
+++ b/include/uapi/linux/vhost_types.h
|
|
@@ -202,4 +202,7 @@ enum {
|
|
*/
|
|
#define VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK 0x6
|
|
|
|
+/* Device can use bytemap to deal log */
|
|
+#define VHOST_BACKEND_F_BYTEMAPLOG 0x3f
|
|
+
|
|
#endif
|
|
--
|
|
Gitee
|
|
|
|
|
|
From ad31418420ec842ee7c433f3cfd59e210c63b702 Mon Sep 17 00:00:00 2001
|
|
From: jiangdongxu <jiangdongxu1@huawei.com>
|
|
Date: Fri, 23 Feb 2024 19:28:13 +0800
|
|
Subject: [PATCH 08/12] vhost-vdpa: Allow transparent MSI IOV
|
|
|
|
When attach dma_dev to iommu domain, check the device's
|
|
reserved regions and test whether the IOMMU translates
|
|
MSI transactions. If yes, we initialize an IOVA allocator
|
|
through the iommu_get_msi_cookie API. This will allow the
|
|
MSI IOVAs to be transparently allocated on MSI controller's
|
|
compose().
|
|
|
|
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
|
---
|
|
drivers/vhost/vdpa.c | 59 +++++++++++++++++++++++++++++++++++++++++---
|
|
1 file changed, 56 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
|
|
index 9af834fc2a47..b4e24d9fe7fa 100644
|
|
--- a/drivers/vhost/vdpa.c
|
|
+++ b/drivers/vhost/vdpa.c
|
|
@@ -49,6 +49,7 @@ struct vhost_vdpa {
|
|
struct completion completion;
|
|
struct vdpa_device *vdpa;
|
|
struct hlist_head as[VHOST_VDPA_IOTLB_BUCKETS];
|
|
+ struct vhost_iotlb resv_iotlb;
|
|
struct device dev;
|
|
struct cdev cdev;
|
|
atomic_t opened;
|
|
@@ -1254,6 +1255,10 @@ static int vhost_vdpa_process_iotlb_update(struct vhost_vdpa *v,
|
|
msg->iova + msg->size - 1 > v->range.last)
|
|
return -EINVAL;
|
|
|
|
+ if (vhost_iotlb_itree_first(&v->resv_iotlb, msg->iova,
|
|
+ msg->iova + msg->size - 1))
|
|
+ return -EINVAL;
|
|
+
|
|
if (vhost_iotlb_itree_first(iotlb, msg->iova,
|
|
msg->iova + msg->size - 1))
|
|
return -EEXIST;
|
|
@@ -1342,6 +1347,46 @@ static ssize_t vhost_vdpa_chr_write_iter(struct kiocb *iocb,
|
|
return vhost_chr_write_iter(dev, from);
|
|
}
|
|
|
|
+static int vhost_vdpa_resv_iommu_region(struct iommu_domain *domain, struct device *dma_dev,
|
|
+ struct vhost_iotlb *resv_iotlb)
|
|
+{
|
|
+ struct list_head dev_resv_regions;
|
|
+ phys_addr_t resv_msi_base = 0;
|
|
+ struct iommu_resv_region *region;
|
|
+ int ret = 0;
|
|
+ bool with_sw_msi = false;
|
|
+ bool with_hw_msi = false;
|
|
+
|
|
+ INIT_LIST_HEAD(&dev_resv_regions);
|
|
+ iommu_get_resv_regions(dma_dev, &dev_resv_regions);
|
|
+
|
|
+ list_for_each_entry(region, &dev_resv_regions, list) {
|
|
+ ret = vhost_iotlb_add_range_ctx(resv_iotlb, region->start,
|
|
+ region->start + region->length - 1,
|
|
+ 0, 0, NULL);
|
|
+ if (ret) {
|
|
+ vhost_iotlb_reset(resv_iotlb);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (region->type == IOMMU_RESV_MSI)
|
|
+ with_hw_msi = true;
|
|
+
|
|
+ if (region->type == IOMMU_RESV_SW_MSI) {
|
|
+ resv_msi_base = region->start;
|
|
+ with_sw_msi = true;
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ if (!ret && !with_hw_msi && with_sw_msi)
|
|
+ ret = iommu_get_msi_cookie(domain, resv_msi_base);
|
|
+
|
|
+ iommu_put_resv_regions(dma_dev, &dev_resv_regions);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static int vhost_vdpa_alloc_domain(struct vhost_vdpa *v)
|
|
{
|
|
struct vdpa_device *vdpa = v->vdpa;
|
|
@@ -1370,11 +1415,16 @@ static int vhost_vdpa_alloc_domain(struct vhost_vdpa *v)
|
|
|
|
ret = iommu_attach_device(v->domain, dma_dev);
|
|
if (ret)
|
|
- goto err_attach;
|
|
+ goto err_alloc_domain;
|
|
|
|
- return 0;
|
|
+ ret = vhost_vdpa_resv_iommu_region(v->domain, dma_dev, &v->resv_iotlb);
|
|
+ if (ret)
|
|
+ goto err_attach_device;
|
|
|
|
-err_attach:
|
|
+ return 0;
|
|
+err_attach_device:
|
|
+ iommu_detach_device(v->domain, dma_dev);
|
|
+err_alloc_domain:
|
|
iommu_domain_free(v->domain);
|
|
v->domain = NULL;
|
|
return ret;
|
|
@@ -1497,6 +1547,7 @@ static int vhost_vdpa_release(struct inode *inode, struct file *filep)
|
|
vhost_vdpa_unbind_mm(v);
|
|
vhost_vdpa_config_put(v);
|
|
vhost_vdpa_cleanup(v);
|
|
+ vhost_iotlb_reset(&v->resv_iotlb);
|
|
mutex_unlock(&d->mutex);
|
|
|
|
atomic_dec(&v->opened);
|
|
@@ -1629,6 +1680,8 @@ static int vhost_vdpa_probe(struct vdpa_device *vdpa)
|
|
goto err;
|
|
}
|
|
|
|
+ vhost_iotlb_init(&v->resv_iotlb, 0, 0);
|
|
+
|
|
r = dev_set_name(&v->dev, "vhost-vdpa-%u", minor);
|
|
if (r)
|
|
goto err;
|
|
--
|
|
Gitee
|
|
|
|
|
|
From c25c824a2fda53ba590fe10469b788cf5e3b5e07 Mon Sep 17 00:00:00 2001
|
|
From: jiangdongxu <jiangdongxu1@huawei.com>
|
|
Date: Fri, 23 Feb 2024 19:28:14 +0800
|
|
Subject: [PATCH 09/12] vhost-vdpa: fix msi irq request err
|
|
|
|
When we call vhost_vdpa_reset, vdpa device pci driver may request irq,
|
|
at this time, wo have not init msi iova for device, may cause an error,
|
|
call vhost_vdpa_alloc_domain first to avoid this scene.
|
|
|
|
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
|
---
|
|
drivers/vhost/vdpa.c | 11 ++++-------
|
|
1 file changed, 4 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
|
|
index b4e24d9fe7fa..0ad78ea7baea 100644
|
|
--- a/drivers/vhost/vdpa.c
|
|
+++ b/drivers/vhost/vdpa.c
|
|
@@ -1489,6 +1489,9 @@ static int vhost_vdpa_open(struct inode *inode, struct file *filep)
|
|
opened = atomic_cmpxchg(&v->opened, 0, 1);
|
|
if (opened)
|
|
return -EBUSY;
|
|
+ r = vhost_vdpa_alloc_domain(v);
|
|
+ if (r)
|
|
+ return r;
|
|
|
|
nvqs = v->nvqs;
|
|
r = vhost_vdpa_reset(v);
|
|
@@ -1509,19 +1512,14 @@ static int vhost_vdpa_open(struct inode *inode, struct file *filep)
|
|
vhost_dev_init(dev, vqs, nvqs, 0, 0, 0, false,
|
|
vhost_vdpa_process_iotlb_msg);
|
|
|
|
- r = vhost_vdpa_alloc_domain(v);
|
|
- if (r)
|
|
- goto err_alloc_domain;
|
|
-
|
|
vhost_vdpa_set_iova_range(v);
|
|
|
|
filep->private_data = v;
|
|
|
|
return 0;
|
|
|
|
-err_alloc_domain:
|
|
- vhost_vdpa_cleanup(v);
|
|
err:
|
|
+ vhost_vdpa_free_domain(v);
|
|
atomic_dec(&v->opened);
|
|
return r;
|
|
}
|
|
@@ -1547,7 +1545,6 @@ static int vhost_vdpa_release(struct inode *inode, struct file *filep)
|
|
vhost_vdpa_unbind_mm(v);
|
|
vhost_vdpa_config_put(v);
|
|
vhost_vdpa_cleanup(v);
|
|
- vhost_iotlb_reset(&v->resv_iotlb);
|
|
mutex_unlock(&d->mutex);
|
|
|
|
atomic_dec(&v->opened);
|
|
--
|
|
Gitee
|
|
|
|
|
|
From 1ea5627c457f74cc118fb018f29a503d01a9c22f Mon Sep 17 00:00:00 2001
|
|
From: jiangdongxu <jiangdongxu1@huawei.com>
|
|
Date: Fri, 23 Feb 2024 19:28:15 +0800
|
|
Subject: [PATCH 10/12] vhost-vdpa: allow set feature VHOST_F_LOG_ALL when been
|
|
negotiated.
|
|
|
|
It's not allowed to change the features after vhost-vdpa devices have
|
|
been negotiated. But log start/end is allowed. Add exception to feature
|
|
VHOST_F_LOG_ALL.
|
|
|
|
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
|
---
|
|
drivers/vhost/vdpa.c | 13 ++++++++-----
|
|
1 file changed, 8 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
|
|
index 0ad78ea7baea..5f59072fe307 100644
|
|
--- a/drivers/vhost/vdpa.c
|
|
+++ b/drivers/vhost/vdpa.c
|
|
@@ -424,16 +424,19 @@ static long vhost_vdpa_set_features(struct vhost_vdpa *v, u64 __user *featurep)
|
|
u64 features;
|
|
int i;
|
|
|
|
+ if (copy_from_user(&features, featurep, sizeof(features)))
|
|
+ return -EFAULT;
|
|
+
|
|
+ actual_features = ops->get_driver_features(vdpa);
|
|
+
|
|
/*
|
|
* It's not allowed to change the features after they have
|
|
- * been negotiated.
|
|
+ * been negotiated. But log start/end is allowed.
|
|
*/
|
|
- if (ops->get_status(vdpa) & VIRTIO_CONFIG_S_FEATURES_OK)
|
|
+ if ((ops->get_status(vdpa) & VIRTIO_CONFIG_S_FEATURES_OK) &&
|
|
+ (features & ~(BIT_ULL(VHOST_F_LOG_ALL))) != actual_features)
|
|
return -EBUSY;
|
|
|
|
- if (copy_from_user(&features, featurep, sizeof(features)))
|
|
- return -EFAULT;
|
|
-
|
|
if (vdpa_set_features(vdpa, features))
|
|
return -EINVAL;
|
|
|
|
--
|
|
Gitee
|
|
|
|
|
|
From 0d12391bdf3812a6e923f09025ac61d7e085867d Mon Sep 17 00:00:00 2001
|
|
From: jiangdongxu <jiangdongxu1@huawei.com>
|
|
Date: Fri, 23 Feb 2024 19:28:16 +0800
|
|
Subject: [PATCH 11/12] vhost-vdpa: add reset state params to indicate reset
|
|
level
|
|
|
|
When vdpa hardware is used, some hardware initialization may be
|
|
required. Currently, qemu connects to vdpa devices through the vhost
|
|
framework. Since qemu opens the vhost device, the vdpa device cannot
|
|
sense the action of qemu opening, which may cause the hardware status to
|
|
be incorrect.
|
|
|
|
Add the interface parameter state to the vdpa reset interface, which
|
|
respectively identifies the reset when the device is turned on/off
|
|
and the virtio reset issued by the virtual machine.
|
|
|
|
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
|
---
|
|
drivers/vdpa/alibaba/eni_vdpa.c | 2 +-
|
|
drivers/vdpa/ifcvf/ifcvf_main.c | 2 +-
|
|
drivers/vdpa/mlx5/net/mlx5_vnet.c | 2 +-
|
|
drivers/vdpa/pds/vdpa_dev.c | 2 +-
|
|
drivers/vdpa/solidrun/snet_main.c | 2 +-
|
|
drivers/vdpa/vdpa_sim/vdpa_sim.c | 2 +-
|
|
drivers/vdpa/vdpa_user/vduse_dev.c | 2 +-
|
|
drivers/vdpa/virtio_pci/vp_vdpa.c | 2 +-
|
|
drivers/vhost/vdpa.c | 10 +++++-----
|
|
drivers/virtio/virtio_vdpa.c | 2 +-
|
|
include/linux/vdpa.h | 16 +++++++++++++---
|
|
11 files changed, 27 insertions(+), 17 deletions(-)
|
|
|
|
diff --git a/drivers/vdpa/alibaba/eni_vdpa.c b/drivers/vdpa/alibaba/eni_vdpa.c
|
|
index 5a09a09cca70..dd1dfb50a228 100644
|
|
--- a/drivers/vdpa/alibaba/eni_vdpa.c
|
|
+++ b/drivers/vdpa/alibaba/eni_vdpa.c
|
|
@@ -226,7 +226,7 @@ static void eni_vdpa_set_status(struct vdpa_device *vdpa, u8 status)
|
|
eni_vdpa_free_irq(eni_vdpa);
|
|
}
|
|
|
|
-static int eni_vdpa_reset(struct vdpa_device *vdpa)
|
|
+static int eni_vdpa_reset(struct vdpa_device *vdpa, int state)
|
|
{
|
|
struct eni_vdpa *eni_vdpa = vdpa_to_eni(vdpa);
|
|
struct virtio_pci_legacy_device *ldev = &eni_vdpa->ldev;
|
|
diff --git a/drivers/vdpa/ifcvf/ifcvf_main.c b/drivers/vdpa/ifcvf/ifcvf_main.c
|
|
index e98fa8100f3c..ec72505bbe1a 100644
|
|
--- a/drivers/vdpa/ifcvf/ifcvf_main.c
|
|
+++ b/drivers/vdpa/ifcvf/ifcvf_main.c
|
|
@@ -434,7 +434,7 @@ static void ifcvf_vdpa_set_status(struct vdpa_device *vdpa_dev, u8 status)
|
|
ifcvf_set_status(vf, status);
|
|
}
|
|
|
|
-static int ifcvf_vdpa_reset(struct vdpa_device *vdpa_dev)
|
|
+static int ifcvf_vdpa_reset(struct vdpa_device *vdpa_dev, int state)
|
|
{
|
|
struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev);
|
|
u8 status = ifcvf_get_status(vf);
|
|
diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c
|
|
index ca972af3c89a..50031a833ac8 100644
|
|
--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c
|
|
+++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c
|
|
@@ -2861,7 +2861,7 @@ static void init_group_to_asid_map(struct mlx5_vdpa_dev *mvdev)
|
|
mvdev->group2asid[i] = 0;
|
|
}
|
|
|
|
-static int mlx5_vdpa_reset(struct vdpa_device *vdev)
|
|
+static int mlx5_vdpa_reset(struct vdpa_device *vdev, int state)
|
|
{
|
|
struct mlx5_vdpa_dev *mvdev = to_mvdev(vdev);
|
|
struct mlx5_vdpa_net *ndev = to_mlx5_vdpa_ndev(mvdev);
|
|
diff --git a/drivers/vdpa/pds/vdpa_dev.c b/drivers/vdpa/pds/vdpa_dev.c
|
|
index 52b2449182ad..e7aead514000 100644
|
|
--- a/drivers/vdpa/pds/vdpa_dev.c
|
|
+++ b/drivers/vdpa/pds/vdpa_dev.c
|
|
@@ -496,7 +496,7 @@ static void pds_vdpa_init_vqs_entry(struct pds_vdpa_device *pdsv, int qid,
|
|
pdsv->vqs[qid].notify = notify;
|
|
}
|
|
|
|
-static int pds_vdpa_reset(struct vdpa_device *vdpa_dev)
|
|
+static int pds_vdpa_reset(struct vdpa_device *vdpa_dev, int state)
|
|
{
|
|
struct pds_vdpa_device *pdsv = vdpa_to_pdsv(vdpa_dev);
|
|
struct device *dev;
|
|
diff --git a/drivers/vdpa/solidrun/snet_main.c b/drivers/vdpa/solidrun/snet_main.c
|
|
index 99428a04068d..c0ddeb9ded11 100644
|
|
--- a/drivers/vdpa/solidrun/snet_main.c
|
|
+++ b/drivers/vdpa/solidrun/snet_main.c
|
|
@@ -245,7 +245,7 @@ static int snet_reset_dev(struct snet *snet)
|
|
return 0;
|
|
}
|
|
|
|
-static int snet_reset(struct vdpa_device *vdev)
|
|
+static int snet_reset(struct vdpa_device *vdev, int state)
|
|
{
|
|
struct snet *snet = vdpa_to_snet(vdev);
|
|
|
|
diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.c b/drivers/vdpa/vdpa_sim/vdpa_sim.c
|
|
index 76d41058add9..c2ec1bc83170 100644
|
|
--- a/drivers/vdpa/vdpa_sim/vdpa_sim.c
|
|
+++ b/drivers/vdpa/vdpa_sim/vdpa_sim.c
|
|
@@ -480,7 +480,7 @@ static void vdpasim_set_status(struct vdpa_device *vdpa, u8 status)
|
|
mutex_unlock(&vdpasim->mutex);
|
|
}
|
|
|
|
-static int vdpasim_reset(struct vdpa_device *vdpa)
|
|
+static int vdpasim_reset(struct vdpa_device *vdpa, int state)
|
|
{
|
|
struct vdpasim *vdpasim = vdpa_to_sim(vdpa);
|
|
|
|
diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c
|
|
index df7869537ef1..f0c48f9efe4e 100644
|
|
--- a/drivers/vdpa/vdpa_user/vduse_dev.c
|
|
+++ b/drivers/vdpa/vdpa_user/vduse_dev.c
|
|
@@ -704,7 +704,7 @@ static void vduse_vdpa_set_config(struct vdpa_device *vdpa, unsigned int offset,
|
|
/* Now we only support read-only configuration space */
|
|
}
|
|
|
|
-static int vduse_vdpa_reset(struct vdpa_device *vdpa)
|
|
+static int vduse_vdpa_reset(struct vdpa_device *vdpa, int state)
|
|
{
|
|
struct vduse_dev *dev = vdpa_to_vduse(vdpa);
|
|
int ret = vduse_dev_set_status(dev, 0);
|
|
diff --git a/drivers/vdpa/virtio_pci/vp_vdpa.c b/drivers/vdpa/virtio_pci/vp_vdpa.c
|
|
index 281287fae89f..0e16dd08968b 100644
|
|
--- a/drivers/vdpa/virtio_pci/vp_vdpa.c
|
|
+++ b/drivers/vdpa/virtio_pci/vp_vdpa.c
|
|
@@ -222,7 +222,7 @@ static void vp_vdpa_set_status(struct vdpa_device *vdpa, u8 status)
|
|
vp_modern_set_status(mdev, status);
|
|
}
|
|
|
|
-static int vp_vdpa_reset(struct vdpa_device *vdpa)
|
|
+static int vp_vdpa_reset(struct vdpa_device *vdpa, int state)
|
|
{
|
|
struct vp_vdpa *vp_vdpa = vdpa_to_vp(vdpa);
|
|
struct virtio_pci_modern_device *mdev = vp_vdpa_to_mdev(vp_vdpa);
|
|
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
|
|
index 5f59072fe307..7bef364935b2 100644
|
|
--- a/drivers/vhost/vdpa.c
|
|
+++ b/drivers/vhost/vdpa.c
|
|
@@ -211,13 +211,13 @@ static void vhost_vdpa_unsetup_vq_irq(struct vhost_vdpa *v, u16 qid)
|
|
irq_bypass_unregister_producer(&vq->call_ctx.producer);
|
|
}
|
|
|
|
-static int vhost_vdpa_reset(struct vhost_vdpa *v)
|
|
+static int vhost_vdpa_reset(struct vhost_vdpa *v, int state)
|
|
{
|
|
struct vdpa_device *vdpa = v->vdpa;
|
|
|
|
v->in_batch = 0;
|
|
|
|
- return vdpa_reset(vdpa);
|
|
+ return vdpa_reset(vdpa, state);
|
|
}
|
|
|
|
static long vhost_vdpa_bind_mm(struct vhost_vdpa *v)
|
|
@@ -296,7 +296,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp)
|
|
vhost_vdpa_unsetup_vq_irq(v, i);
|
|
|
|
if (status == 0) {
|
|
- ret = vdpa_reset(vdpa);
|
|
+ ret = vdpa_reset(vdpa, VDPA_DEV_RESET_VIRTIO);
|
|
if (ret)
|
|
return ret;
|
|
} else
|
|
@@ -1497,7 +1497,7 @@ static int vhost_vdpa_open(struct inode *inode, struct file *filep)
|
|
return r;
|
|
|
|
nvqs = v->nvqs;
|
|
- r = vhost_vdpa_reset(v);
|
|
+ r = vhost_vdpa_reset(v, VDPA_DEV_RESET_OPEN);
|
|
if (r)
|
|
goto err;
|
|
|
|
@@ -1543,7 +1543,7 @@ static int vhost_vdpa_release(struct inode *inode, struct file *filep)
|
|
mutex_lock(&d->mutex);
|
|
filep->private_data = NULL;
|
|
vhost_vdpa_clean_irq(v);
|
|
- vhost_vdpa_reset(v);
|
|
+ vhost_vdpa_reset(v, VDPA_DEV_RESET_CLOSE);
|
|
vhost_dev_stop(&v->vdev);
|
|
vhost_vdpa_unbind_mm(v);
|
|
vhost_vdpa_config_put(v);
|
|
diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c
|
|
index 06ce6d8c2e00..13f69bfb9c98 100644
|
|
--- a/drivers/virtio/virtio_vdpa.c
|
|
+++ b/drivers/virtio/virtio_vdpa.c
|
|
@@ -100,7 +100,7 @@ static void virtio_vdpa_reset(struct virtio_device *vdev)
|
|
{
|
|
struct vdpa_device *vdpa = vd_get_vdpa(vdev);
|
|
|
|
- vdpa_reset(vdpa);
|
|
+ vdpa_reset(vdpa, VDPA_DEV_RESET_VIRTIO);
|
|
}
|
|
|
|
static bool virtio_vdpa_notify(struct virtqueue *vq)
|
|
diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h
|
|
index 1ed264ec1ebb..3120a1a600dd 100644
|
|
--- a/include/linux/vdpa.h
|
|
+++ b/include/linux/vdpa.h
|
|
@@ -129,6 +129,12 @@ struct vdpa_map_file {
|
|
u64 offset;
|
|
};
|
|
|
|
+enum vdpa_reset_state {
|
|
+ VDPA_DEV_RESET_VIRTIO = 0,
|
|
+ VDPA_DEV_RESET_OPEN = 1,
|
|
+ VDPA_DEV_RESET_CLOSE = 2,
|
|
+};
|
|
+
|
|
/**
|
|
* struct vdpa_config_ops - operations for configuring a vDPA device.
|
|
* Note: vDPA device drivers are required to implement all of the
|
|
@@ -241,6 +247,10 @@ struct vdpa_map_file {
|
|
* @status: virtio device status
|
|
* @reset: Reset device
|
|
* @vdev: vdpa device
|
|
+ * @state: state for reset
|
|
+ * VDPA_DEV_RESET_VIRTIO for virtio reset
|
|
+ * VDPA_DEV_RESET_OPEN for vhost-vdpa device open
|
|
+ * VDPA_DEV_RESET_CLOSE for vhost-vdpa device close
|
|
* Returns integer: success (0) or error (< 0)
|
|
* @suspend: Suspend the device (optional)
|
|
* @vdev: vdpa device
|
|
@@ -397,7 +407,7 @@ struct vdpa_config_ops {
|
|
u32 (*get_vendor_id)(struct vdpa_device *vdev);
|
|
u8 (*get_status)(struct vdpa_device *vdev);
|
|
void (*set_status)(struct vdpa_device *vdev, u8 status);
|
|
- int (*reset)(struct vdpa_device *vdev);
|
|
+ int (*reset)(struct vdpa_device *vdev, int state);
|
|
int (*suspend)(struct vdpa_device *vdev);
|
|
int (*resume)(struct vdpa_device *vdev);
|
|
size_t (*get_config_size)(struct vdpa_device *vdev);
|
|
@@ -525,14 +535,14 @@ static inline struct device *vdpa_get_dma_dev(struct vdpa_device *vdev)
|
|
return vdev->dma_dev;
|
|
}
|
|
|
|
-static inline int vdpa_reset(struct vdpa_device *vdev)
|
|
+static inline int vdpa_reset(struct vdpa_device *vdev, int state)
|
|
{
|
|
const struct vdpa_config_ops *ops = vdev->config;
|
|
int ret;
|
|
|
|
down_write(&vdev->cf_lock);
|
|
vdev->features_valid = false;
|
|
- ret = ops->reset(vdev);
|
|
+ ret = ops->reset(vdev, state);
|
|
up_write(&vdev->cf_lock);
|
|
return ret;
|
|
}
|
|
--
|
|
Gitee
|
|
|
|
|
|
From 1060665642166d24d3bd540251e31776ad8b22b1 Mon Sep 17 00:00:00 2001
|
|
From: jiangdongxu <jiangdongxu1@huawei.com>
|
|
Date: Fri, 23 Feb 2024 19:28:17 +0800
|
|
Subject: [PATCH 12/12] vdpa: add vmstate header file
|
|
|
|
Add the vmstate.h header file to define the structure of vdpa device
|
|
status to achieve live migration of cross-vendor vdpa devices.
|
|
|
|
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
|
|
---
|
|
include/linux/vdpa_vmstate.h | 182 +++++++++++++++++++++++++++++++++++
|
|
1 file changed, 182 insertions(+)
|
|
create mode 100644 include/linux/vdpa_vmstate.h
|
|
|
|
diff --git a/include/linux/vdpa_vmstate.h b/include/linux/vdpa_vmstate.h
|
|
new file mode 100644
|
|
index 000000000000..0e577a9605f1
|
|
--- /dev/null
|
|
+++ b/include/linux/vdpa_vmstate.h
|
|
@@ -0,0 +1,182 @@
|
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
|
+/*
|
|
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify it
|
|
+ * under the terms and conditions of the GNU General Public License,
|
|
+ * version 2, as published by the Free Software Foundation.
|
|
+ *
|
|
+ * This program is distributed in the hope it will be useful, but WITHOUT
|
|
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
+ * for more details.
|
|
+ *
|
|
+ * Description: vdpa vmstate header file
|
|
+ * Author: jiangdongxu
|
|
+ * Create: 2023-12-3
|
|
+ * Note:
|
|
+ * History: 2023-12-3: Create file
|
|
+ */
|
|
+
|
|
+#ifndef VDPA_VMSTATE_H
|
|
+#define VDPA_VMSTATE_H
|
|
+
|
|
+#include <linux/virtio_net.h>
|
|
+#include <linux/virtio_scsi.h>
|
|
+
|
|
+
|
|
+#define VIRTIO_MIG_STATE_TYPE_DEVICE 0
|
|
+#define VIRTIO_MIG_STATE_TYPE_VQ 1
|
|
+#define VIRTIO_MIG_STATE_TYPE_CONFIG 2
|
|
+#define VIRTIO_MIG_STATE_TYPE_FEATURE 3
|
|
+#define VIRTIO_MIG_STATE_TYPE_PLATFORM 4
|
|
+#define VIRTIO_MIG_STATE_TYPE_VENDOR 255
|
|
+
|
|
+#define VIRTIO_MIG_DEVICE_T_COMMON 0
|
|
+#define VIRTIO_MIG_DEVICE_T_NET 1
|
|
+#define VIRTIO_MIG_DEVICE_T_BLK 2
|
|
+#define VIRTIO_MIG_DEVICE_T_SCSI 8
|
|
+
|
|
+#define VIRTIO_MIG_CONFIG_T_NET 1
|
|
+#define VIRTIO_MIG_CONFIG_T_BLK 2
|
|
+#define VIRTIO_MIG_CONFIG_T_SCSI 8
|
|
+
|
|
+#define MAC_LEN 6
|
|
+
|
|
+struct virtio_mig_state_header {
|
|
+ le32 type;
|
|
+ le32 len;
|
|
+};
|
|
+
|
|
+struct virtio_mig_dev_common_data {
|
|
+ le32 vendor_id;
|
|
+ le32 device_id;
|
|
+ le32 device_features_l;
|
|
+ le32 device_features_h;
|
|
+ le32 driver_features_l;
|
|
+ le32 driver_features_h;
|
|
+ le32 status;
|
|
+ le32 generation;
|
|
+ le32 msix_en;
|
|
+};
|
|
+
|
|
+struct virtio_mig_dev_common_state {
|
|
+ struct virtio_mig_state_header hdr;
|
|
+ struct virtio_mig_dev_common_data data;
|
|
+};
|
|
+
|
|
+struct virtio_mig_vq_split_state {
|
|
+ le16 avail_index;
|
|
+ le16 used_index;
|
|
+};
|
|
+struct virtio_mig_vq_packed_state {
|
|
+ le16 avail_wrapped : 1;
|
|
+ le16 avail_index : 15;
|
|
+ le16 used_wrapped : 1;
|
|
+ le16 used_index : 15;
|
|
+};
|
|
+
|
|
+struct virtio_mig_per_vq_data {
|
|
+ le32 qsize;
|
|
+
|
|
+ u8 qenabled;
|
|
+ le16 msix_vector;
|
|
+
|
|
+ le32 desc_l;
|
|
+ le32 desc_h;
|
|
+ le32 avail_l;
|
|
+ le32 avail_h;
|
|
+ le32 used_l;
|
|
+ le32 used_h;
|
|
+ union {
|
|
+ struct virtio_mig_vq_split_state split;
|
|
+ struct virtio_mig_vq_packed_state packed;
|
|
+ } version;
|
|
+};
|
|
+
|
|
+/* vq state */
|
|
+struct virtio_mig_vq_state {
|
|
+ struct virtio_mig_state_header hdr;
|
|
+
|
|
+ le16 msix_config;
|
|
+ le16 valid_queues;
|
|
+
|
|
+ le16 num_queues;
|
|
+
|
|
+ struct virtio_mig_per_vq_data vq_state[];
|
|
+};
|
|
+
|
|
+/* config space */
|
|
+struct virtio_mig_config_state {
|
|
+ struct virtio_mig_state_header hdr;
|
|
+ union {
|
|
+ struct virtio_net_config net;
|
|
+ struct virtio_blk_config blk;
|
|
+ struct virtio_scsi_config scsi;
|
|
+ } dev;
|
|
+};
|
|
+
|
|
+struct virtio_mig_cfg_blk_features {
|
|
+
|
|
+};
|
|
+
|
|
+struct virtio_mig_cfg_scsi_features {
|
|
+
|
|
+};
|
|
+
|
|
+struct virtio_mig_cfg_net_ctrl_guest_offloads {
|
|
+ struct virtio_mig_state_header hdr;
|
|
+ le64 offloads;
|
|
+ le64 reserved;
|
|
+};
|
|
+
|
|
+struct virtio_mig_cfg_net_ctrl_mq_vq_pairs {
|
|
+ struct virtio_mig_state_header hdr;
|
|
+ le16 cur_virtqueue_pairs;
|
|
+};
|
|
+
|
|
+struct virtio_mig_cfg_net_ctrl_mac_table {
|
|
+ struct virtio_mig_state_header hdr;
|
|
+ le16 num_unicast;
|
|
+ /* TODO: need to be implemented later */
|
|
+ // u8 unicast_macs[][6];
|
|
+ le16 num_multicast;
|
|
+ /* TODO: need to be implemented later */
|
|
+ // u8 multicast_macs[][6];
|
|
+};
|
|
+
|
|
+struct virtio_mig_cfg_net_ctrl_vlan {
|
|
+ struct virtio_mig_state_header hdr;
|
|
+ le32 vlans[128];
|
|
+};
|
|
+
|
|
+struct virtio_mig_cfg_net_data {
|
|
+ le32 nfeatures;
|
|
+ struct virtio_mig_cfg_net_ctrl_guest_offloads offloads;
|
|
+ struct virtio_mig_cfg_net_ctrl_mq_vq_pairs mq_pairs;
|
|
+ struct virtio_mig_cfg_net_ctrl_mac_table mac_table;
|
|
+ struct virtio_mig_cfg_net_ctrl_vlan vlan_table;
|
|
+};
|
|
+
|
|
+struct virtio_mig_cfg_net_features {
|
|
+ struct virtio_mig_state_header hdr;
|
|
+ struct virtio_mig_cfg_net_data data;
|
|
+};
|
|
+
|
|
+/* feature */
|
|
+struct virtio_mig_feat_state {
|
|
+ union {
|
|
+ struct virtio_mig_cfg_net_features net;
|
|
+ struct virtio_mig_cfg_blk_features blk;
|
|
+ struct virtio_mig_cfg_scsi_features scsi;
|
|
+ };
|
|
+};
|
|
+
|
|
+struct vdpa_mig_state {
|
|
+ struct virtio_mig_dev_common_state dev_state;
|
|
+ struct virtio_mig_config_state cfg_state;
|
|
+ struct virtio_mig_feat_state feat_state;
|
|
+ struct virtio_mig_vq_state vq_state;
|
|
+};
|
|
+
|
|
+#endif /* VDPA_VMSTATE_H */
|
|
--
|
|
Gitee
|