From: "Jason J. Herne" <jjherne@linux.ibm.com>
To: Anthony Krowiak <akrowiak@linux.ibm.com>,
linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org,
kvm@vger.kernel.org
Cc: borntraeger@de.ibm.com, mjrosato@linux.ibm.com,
pasic@linux.ibm.com, alex@shazbot.org, kwankhede@nvidia.com,
fiuczy@linux.ibm.com, pbonzini@redhat.com, frankja@linux.ibm.com,
imbrenda@linux.ibm.com, agordeev@linux.ibm.com,
hca@linux.ibm.com, gor@linux.ibm.com
Subject: Re: [PATCH v7 10/15] s390/vfio-ap: File ops called to resume the vfio device migration
Date: Wed, 19 Aug 2026 13:49:13 -0400 [thread overview]
Message-ID: <dc3a7703-b4a9-4a7f-9078-f6f874962abf@linux.ibm.com> (raw)
In-Reply-To: <20260807221834.562851-11-akrowiak@linux.ibm.com>
On 8/7/26 6:18 PM, Anthony Krowiak wrote:
> Implements the 'write' callback function that was added to the
> 'file_operations' structure for the file stream created to restore the
> state of the vfio-ap device on the destination system when the migration
> state transitioned from STOP to RESUMING
>
> The write callback retrieves the vfio device migration state saved to the
> file stream created when the vfio device state was transitioned from
> STOP to STOP_COPY. The saved state contains the source guest's AP
> configuration information. This data is copied from the userspace buffer
> passed to the 'write' callback and stored in the vfio_ap_config structure
> used to set the state of the vfio-ap device on the destination host. If the
> source guest's AP configuration is compatible with the AP configuration on
> the destination host, it will be hot plugged into the destination guest.
>
> In order for the source guest's and destination host's AP configurations
> to be considered compatible:
>
> * Each APQN in the source guest's AP configuration must also be in the
> destination host's AP configuration
>
> * Each matching APQN in the destination host's AP configuration must be
> bound to the vfio_ap device driver
>
> * Each matching APQN in the destination host's AP configuration must
> reference a queue device with compatible hardware:
>
> - The source and destination queues must have the same facilities
> installed:
> ~ APSC facility
> ~ APQKM facility
> ~ AP4KC facility
>
> - The source and destination queues must have the same mode:
> ~ Coprocessor-mode
> ~ Accelerator-mode
> ~ XCP-mode
>
> - The source and destination queues must have the same APXA facility
> setting
> ~ If the APXA facility is installed on source queue, it must also
> be installed on the destination queue and vice versa
>
> - The source and destination queues must have a compatible
> classification setting. If the source queue has full native card
> function, then the destination queue must also have full native
> card function. If the source queue has stateless functions, then
> the destination queue can have stateless functions or full native card
> function because the latter includes the stateless functions.
>
> - The binding and associated state for both the source and destination
> queues must indicate that the queue is usable for all messages
> (i.e., BS bits equal to 00).
>
> - The AP type of the destination queue must be the same as or newer than
> the source queue (backward compatibility)
>
> Note: The get_hardware_info_for_queue function that was created in
> a previous patch was modified to take a mediated device name rather
> than an ap_matrix_mdev object because that is what is needed for
> this patch so the function can be executed without holding the
> matrix_dev->mdevs_lock.
>
> Signed-off-by: Anthony Krowiak <akrowiak@linux.ibm.com>
> ---
> drivers/s390/crypto/vfio_ap_migration.c | 1009 ++++++++++++++++++++++-
> 1 file changed, 1001 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/s390/crypto/vfio_ap_migration.c b/drivers/s390/crypto/vfio_ap_migration.c
> index e2e7ae8515e5..4dd7373c3d9d 100644
> --- a/drivers/s390/crypto/vfio_ap_migration.c
> +++ b/drivers/s390/crypto/vfio_ap_migration.c
> ...
> static ssize_t vfio_ap_resuming_write(struct file *filp, const char __user *buf,
> size_t len, loff_t *pos)
> {
> - /* TODO */
> - return -EOPNOTSUPP;
> + struct vfio_ap_config_buffer *resuming_config_buf;
> + struct ap_matrix_mdev *matrix_mdev;
> + struct vfio_ap_config *ap_config;
> + bool new_allocation = false;
> + ssize_t ret, cfg_sz;
> + loff_t write_pos;
> + size_t write_len;
> +
> + /*
> + * This file was opened with stream_open(), so pos should be NULL for
> + * sequential write() calls; a non-NULL pointer will be passed only
> + * for positional pwrite() calls in which case we return an error
> + * indicating broken pipe/illegal seek on a non-seekable file
> + */
> + if (pos)
> + return -ESPIPE;
> +
> + mutex_lock(&matrix_dev->mdevs_lock);
> + pos = &filp->f_pos;
> +
> + ret = validate_resuming_write_parms(filp, len, pos);
> + if (ret) {
> + mutex_unlock(&matrix_dev->mdevs_lock);
> + return ret;
> + }
> +
> + matrix_mdev = filp->private_data;
> + matrix_mdev->mig_data->write_in_progress = true;
> + resuming_config_buf = &matrix_mdev->mig_data->resuming_config_buf;
> +
> + /*
> + * If we have not yet filled the vfio_ap_config_buffer, then we need
> + * to continue filling it with data sent from userspace.
> + */
> + if (!resuming_config_buf->filled) {
> + ret = fill_resuming_config_buffer(resuming_config_buf, buf, len,
> + *pos);
> + if (ret) {
> + matrix_mdev->mig_data->write_in_progress = false;
> + mutex_unlock(&matrix_dev->mdevs_lock);
> + return ret;
> + }
> +
> + /*
> + * If the vfio_ap_config_buffer is not yet filled, we don't
> + * yet have enough data to allocate the vfio_ap_config instance;
> + * otherwise, go ahead and allocate it.
> + */
> + if (!resuming_config_buf->filled) {
> + *pos += len;
> + matrix_mdev->mig_data->write_in_progress = false;
> + mutex_unlock(&matrix_dev->mdevs_lock);
> + return len;
> + }
> +
> + ret = allocate_ap_config(resuming_config_buf, &ap_config);
> + if (ret < 0) {
> + matrix_mdev->mig_data->write_in_progress = false;
> + mutex_unlock(&matrix_dev->mdevs_lock);
> + return ret;
> + }
> +
> + new_allocation = true;
> + cfg_sz = ret;
> + }
> +
> + /*
> + * If this is not a new allocation of the vfio_ap_config object,
> + * then create a copy of it so we can continue filling it in via
> + * the copy_from_user() while the mdevs_lock is dropped.
> + */
> + if (!new_allocation) {
> + cfg_sz = matrix_mdev->mig_data->resuming_mig_file.config_sz;
> + ap_config = kvzalloc(cfg_sz, GFP_KERNEL_ACCOUNT);
> +
> + if (!ap_config) {
> + matrix_mdev->mig_data->write_in_progress = false;
> + mutex_unlock(&matrix_dev->mdevs_lock);
> + return -ENOMEM;
> + }
> +
> + memcpy(ap_config,
> + matrix_mdev->mig_data->resuming_mig_file.ap_config, cfg_sz);
> + }
> +
> + /*
> + * If ap_config is a new allocation, then the contents of the
> + * 'magic', 'version' and 'num_queues' fields will already have
> + * been copied in; so the write_pos must be set to the location
> + * following the 'num_queues' field and the length to be written must be
> + * adjusted accordingly.
> + */
> + if (new_allocation) {
> + size_t nbytes_already_copied = VFIO_AP_CONFIG_BUF_SIZE - *pos;
> +
> + write_pos = VFIO_AP_CONFIG_BUF_SIZE;
> + write_len = len - nbytes_already_copied;
> + buf += nbytes_already_copied;
> + } else {
> + write_pos = *pos;
> + write_len = len;
> + }
> +
> + *pos += len;
> +
> + mutex_unlock(&matrix_dev->mdevs_lock);
> +
> + if (copy_from_user((char *)ap_config + write_pos, buf, write_len)) {
> + if (new_allocation)
> + kvfree(ap_config);
> + ret = -EFAULT;
> + goto out_clear_write_in_progress;
> + }
> +
> + /* Check if we've completed writing the entire configuration */
> + if (write_pos + write_len == cfg_sz) {
> + ret = do_post_copy_processing(matrix_mdev, ap_config);
> +
> + if (ret) {
> + kvfree(ap_config);
> + goto out_clear_write_in_progress;
> + }
> + }
> +
> + ret = set_new_ap_configuration(matrix_mdev, ap_config, cfg_sz);
> + if (ret) {
> + kvfree(ap_config);
> + goto out_clear_write_in_progress;
> + }
> +
> + /*
> + * If this is not a new allocation of vfio_ap_config, then the contents
> + * of ap_config would have been copied into the existing object, so we
> + * can free it so we don't leak the storage.
> + */
> + if (!new_allocation)
> + kvfree(ap_config);
> +
> + ret = len;
> +
> +out_clear_write_in_progress:
> + mutex_lock(&matrix_dev->mdevs_lock);
> + if (matrix_mdev->mig_data)
> + matrix_mdev->mig_data->write_in_progress = false;
> + mutex_unlock(&matrix_dev->mdevs_lock);
> +
> + return ret;
> }
>
> static const struct file_operations vfio_ap_resume_fops = {
Why can't vfio_ap_resuming_write() just copy the data it is given into a
buffer, remembering the next position to write and then exit if the
buffer is not full? If the buffer is full then it can then process that
buffer. Whatever is happening here seems very convoluted.
The AP config for a guest is pretty small. At most it will be 16 bytes *
64k queues = 1 MB. Allocating a max buffer up front would be a
reasonable thing to do, in my opinion. Even if we don't, I feel like
this code could be simplified quite a bit.
I'm imagining an algorithm similar to the this:
read_data();
if (not have_all_data):
return;
post_process_data();
next prev parent reply other threads:[~2026-08-19 17:50 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-07 22:18 [PATCH v7 00/15] s390/vfio-ap: Add live guest migration support Anthony Krowiak
2026-08-07 22:18 ` [PATCH v7 01/15] s390/vfio-ap: Provide function to get the number of queues assigned to mdev Anthony Krowiak
2026-08-10 13:14 ` Jason J. Herne
2026-08-24 15:31 ` Anthony Krowiak
2026-08-07 22:18 ` [PATCH v7 02/15] s390/vfio-ap: Data structures for facilitating vfio device migration Anthony Krowiak
2026-08-10 13:45 ` Jason J. Herne
2026-10-05 15:18 ` Anthony Krowiak
2026-08-07 22:18 ` [PATCH v7 03/15] s390/vfio-ap: Functions to initialize/release vfio device migration data Anthony Krowiak
2026-08-11 13:57 ` Jason J. Herne
2026-10-05 15:24 ` Anthony Krowiak
2026-08-07 22:18 ` [PATCH v7 04/15] s390/vfio-ap: Reset migration state in VFIO_DEVICE_RESET ioctl handler Anthony Krowiak
2026-08-11 17:05 ` Jason J. Herne
2026-10-05 18:52 ` Anthony Krowiak
2026-08-07 22:18 ` [PATCH v7 05/15] s390/vfio-ap: Callback to get/set vfio device mig state during guest migration Anthony Krowiak
2026-08-12 16:04 ` Jason J. Herne
2026-10-05 20:42 ` Anthony Krowiak
2026-08-07 22:18 ` [PATCH v7 06/15] s390/vfio-ap: Transition guest migration state from STOP to STOP_COPY Anthony Krowiak
2026-08-07 22:18 ` [PATCH v7 07/15] s390/vfio-ap: File ops called to save the vfio device migration state Anthony Krowiak
2026-08-13 15:08 ` Jason J. Herne
2026-10-05 21:55 ` Anthony Krowiak
2026-08-07 22:18 ` [PATCH v7 08/15] s390/vfio-ap: Transition device migration state from STOP to RESUMING Anthony Krowiak
2026-08-18 14:47 ` Jason J. Herne
2026-10-06 14:43 ` Anthony Krowiak
2026-08-07 22:18 ` [PATCH v7 09/15] s390/vfio-ap: Add method to set a new guest AP configuration Anthony Krowiak
2026-08-19 13:25 ` Jason J. Herne
2026-08-07 22:18 ` [PATCH v7 10/15] s390/vfio-ap: File ops called to resume the vfio device migration Anthony Krowiak
2026-08-19 17:49 ` Jason J. Herne [this message]
2026-10-06 14:54 ` Anthony Krowiak
2026-08-07 22:18 ` [PATCH v7 11/15] s390/vfio-ap: Transition device migration state to STOP Anthony Krowiak
2026-08-20 12:43 ` Jason J. Herne
2026-08-07 22:18 ` [PATCH v7 12/15] s390/vfio-ap: Transition device migration state from STOP to RUNNING and vice versa Anthony Krowiak
2026-08-20 12:45 ` Jason J. Herne
2026-08-07 22:18 ` [PATCH v7 13/15] s390/vfio-ap: Callback to get the size of data to be migrated during guest migration Anthony Krowiak
2026-08-20 12:52 ` Jason J. Herne
2026-08-07 22:18 ` [PATCH v7 14/15] s390/vfio-ap: Add 'migratable' feature to sysfs 'features' attribute Anthony Krowiak
2026-08-20 13:01 ` Jason J. Herne
2026-10-06 21:16 ` Anthony Krowiak
2026-08-07 22:18 ` [PATCH v7 15/15] s390/vfio-ap: Add live guest migration chapter to vfio-ap.rst Anthony Krowiak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=dc3a7703-b4a9-4a7f-9078-f6f874962abf@linux.ibm.com \
--to=jjherne@linux.ibm.com \
--cc=agordeev@linux.ibm.com \
--cc=akrowiak@linux.ibm.com \
--cc=alex@shazbot.org \
--cc=borntraeger@de.ibm.com \
--cc=fiuczy@linux.ibm.com \
--cc=frankja@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=imbrenda@linux.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=kwankhede@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=mjrosato@linux.ibm.com \
--cc=pasic@linux.ibm.com \
--cc=pbonzini@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®