[PATCH v1 06/24] s390/vfio-ap: A sysfs 'migratable' attribute to enable/disable migration of guest

Anthony Krowiak
2026-03-25T21:02:06Z

This patch creates a new R/W sysfs attribute of the vfio-ap mediated device
that will ultimately be used to enable and disable migration of the guest
to which the mediated device is attached. The value for this attribute is
an int to be stored with the mediated device. A value of 1 indicates the
vfio device can be migrated, and a value of 0 indicates migration is
blocked. The initial value will be set to 0.

Signed-off-by: Anthony Krowiak <akrowiak@linux.ibm.com>
---
drivers/s390/crypto/vfio_ap_ops.c | 46 +++++++++++++++++++++++++++
drivers/s390/crypto/vfio_ap_private.h | 3 ++
2 files changed, 49 insertions(+)

diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index cd85866b81a0..97ec1f2fdbd1 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -32,6 +32,8 @@

#define AP_RESET_INTERVAL 20 /* Reset sleep interval (20ms) */

+#define VFIO_AP_DEVICE_MIGRATABLE_DEFAULT 0
+
static int vfio_ap_mdev_reset_queues(struct ap_matrix_mdev *matrix_mdev);
static int vfio_ap_mdev_reset_qlist(struct list_head *qlist);
static struct vfio_ap_queue *vfio_ap_find_queue(int apqn);
@@ -802,6 +804,7 @@ static int vfio_ap_mdev_probe(struct mdev_device *mdev)
goto err_put_vdev;
matrix_mdev->req_trigger = NULL;
matrix_mdev->cfg_chg_trigger = NULL;
+ matrix_mdev->migratable = VFIO_AP_DEVICE_MIGRATABLE_DEFAULT;
dev_set_drvdata(&mdev->dev, matrix_mdev);
mutex_lock(&matrix_dev->mdevs_lock);
list_add(&matrix_mdev->node, &matrix_dev->mdev_list);
@@ -1785,6 +1788,48 @@ static ssize_t ap_config_store(struct device *dev, struct device_attribute *attr
}
static DEVICE_ATTR_RW(ap_config);

+static ssize_t migratable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ap_matrix_mdev *matrix_mdev;
+ size_t nchars;
+
+ mutex_lock(&matrix_dev->mdevs_lock);
+ matrix_mdev = dev_get_drvdata(dev);
+ nchars = sysfs_emit(buf, "%d\n", matrix_mdev->migratable);
+ mutex_unlock(&matrix_dev->mdevs_lock);
+
+ return nchars;
+}
+
+static ssize_t migratable_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ap_matrix_mdev *matrix_mdev;
+ int migratable;
+ int ret;
+
+ mutex_lock(&matrix_dev->mdevs_lock);
+ matrix_mdev = dev_get_drvdata(dev);
+
+ ret = kstrtoint(buf, 10, &migratable);
+ if (ret)
+ goto out_unlock;
+
+ if (migratable != 0 && migratable != 1) {
+ ret = -EINVAL;
+ goto out_unlock;
+ }
+
+ matrix_mdev->migratable = migratable;
+ ret = count;
+out_unlock:
+ mutex_unlock(&matrix_dev->mdevs_lock);
+
+ return ret;
+}
+static DEVICE_ATTR_RW(migratable);
+
static struct attribute *vfio_ap_mdev_attrs[] = {
&dev_attr_assign_adapter.attr,
&dev_attr_unassign_adapter.attr,
@@ -1796,6 +1841,7 @@ static struct attribute *vfio_ap_mdev_attrs[] = {
&dev_attr_control_domains.attr,
&dev_attr_matrix.attr,
&dev_attr_guest_matrix.attr,
+ &dev_attr_migratable.attr,
NULL,
};

diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h
index d66586825ef4..b75299c9c1d0 100644
--- a/drivers/s390/crypto/vfio_ap_private.h
+++ b/drivers/s390/crypto/vfio_ap_private.h
@@ -104,6 +104,8 @@ struct ap_queue_table {
* PQAP(AQIC) instruction.
* @mdev: the mediated device
* @qtable: table of queues (struct vfio_ap_queue) assigned to the mdev
+ * @migratable: an int value indicating whether the vfio device can be
+ * migrated (1) or not (0)
* @req_trigger eventfd ctx for signaling userspace to return a device
* @cfg_chg_trigger eventfd ctx to signal AP config changed to userspace
* @apm_add: bitmap of APIDs added to the host's AP configuration
@@ -120,6 +122,7 @@ struct ap_matrix_mdev {
crypto_hook pqap_hook;
struct mdev_device *mdev;
struct ap_queue_table qtable;
+ int migratable;
struct eventfd_ctx *req_trigger;
struct eventfd_ctx *cfg_chg_trigger;
DECLARE_BITMAP(apm_add, AP_DEVICES);
--
2.52.0