drivers/vfio/pci/virtio/migrate.c
Source file repositories/reference/linux-study-clean/drivers/vfio/pci/virtio/migrate.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/vfio/pci/virtio/migrate.c- Extension
.c- Size
- 34243 bytes
- Lines
- 1316
- Domain
- Driver Families
- Bucket
- drivers/vfio
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/device.hlinux/module.hlinux/mutex.hlinux/pci.hlinux/pm_runtime.hlinux/types.hlinux/uaccess.hlinux/vfio.hlinux/vfio_pci_core.hlinux/virtio_pci.hlinux/virtio_net.hlinux/virtio_pci_admin.hlinux/anon_inodes.hcommon.h
Detected Declarations
function virtiovf_get_migration_pagefunction for_each_sgfunction virtiovf_add_migration_pagesfunction virtiovf_free_data_bufferfunction virtiovf_alloc_data_bufferfunction virtiovf_put_data_bufferfunction virtiovf_pci_alloc_obj_idfunction virtiovf_pci_free_obj_idfunction virtiovf_get_data_bufferfunction virtiovf_clean_migf_resourcesfunction virtiovf_disable_fdfunction virtiovf_disable_fdsfunction virtiovf_state_mutex_unlockfunction virtiovf_migration_reset_donefunction virtiovf_release_filefunction virtiovf_get_data_buff_from_posfunction virtiovf_buf_readfunction virtiovf_save_readfunction virtiovf_precopy_ioctlfunction virtiovf_add_buf_headerfunction virtiovf_read_device_context_chunkfunction virtiovf_pci_save_device_final_datafunction virtiovf_pci_save_device_datafunction virtiovf_set_obj_cmd_headerfunction virtiovf_append_page_to_mig_buffunction virtiovf_resume_read_chunkfunction virtiovf_resume_read_header_datafunction virtiovf_resume_read_headerfunction virtiovf_resume_writefunction virtiovf_pci_resume_device_datafunction virtiovf_pci_step_device_state_lockedfunction virtiovf_pci_set_device_statefunction virtiovf_pci_get_device_statefunction virtiovf_pci_get_data_sizefunction virtiovf_set_migratablefunction virtiovf_open_migrationfunction virtiovf_close_migration
Annotated Snippet
static const struct file_operations virtiovf_save_fops = {
.owner = THIS_MODULE,
.read = virtiovf_save_read,
.unlocked_ioctl = virtiovf_precopy_ioctl,
.compat_ioctl = compat_ptr_ioctl,
.release = virtiovf_release_file,
};
static int
virtiovf_add_buf_header(struct virtiovf_data_buffer *header_buf,
u32 data_size)
{
struct virtiovf_migration_file *migf = header_buf->migf;
struct virtiovf_migration_header header = {};
struct page *page;
u8 *to_buff;
header.record_size = cpu_to_le64(data_size);
header.flags = cpu_to_le32(VIRTIOVF_MIGF_HEADER_FLAGS_TAG_MANDATORY);
header.tag = cpu_to_le32(VIRTIOVF_MIGF_HEADER_TAG_DEVICE_DATA);
page = virtiovf_get_migration_page(header_buf, 0);
if (!page)
return -EINVAL;
to_buff = kmap_local_page(page);
memcpy(to_buff, &header, sizeof(header));
kunmap_local(to_buff);
header_buf->length = sizeof(header);
header_buf->start_pos = header_buf->migf->max_pos;
migf->max_pos += header_buf->length;
scoped_guard(mutex, &migf->list_lock)
list_add_tail(&header_buf->buf_elm, &migf->buf_list);
return 0;
}
static int
virtiovf_read_device_context_chunk(struct virtiovf_migration_file *migf,
u32 ctx_size)
{
struct virtiovf_data_buffer *header_buf;
struct virtiovf_data_buffer *buf;
bool unmark_end = false;
struct scatterlist *sg;
unsigned int i;
u32 res_size;
int nent;
int ret;
buf = virtiovf_get_data_buffer(migf, ctx_size);
if (IS_ERR(buf))
return PTR_ERR(buf);
/* Find the total count of SG entries which satisfies the size */
nent = sg_nents_for_len(buf->table.sgt.sgl, ctx_size);
if (nent <= 0) {
ret = -EINVAL;
goto out;
}
/*
* Iterate to that SG entry and mark it as last (if it's not already)
* to let underlay layers iterate only till that entry.
*/
for_each_sg(buf->table.sgt.sgl, sg, nent - 1, i)
;
if (!sg_is_last(sg)) {
unmark_end = true;
sg_mark_end(sg);
}
ret = virtio_pci_admin_dev_parts_get(migf->virtvdev->core_device.pdev,
VIRTIO_RESOURCE_OBJ_DEV_PARTS,
migf->obj_id,
VIRTIO_ADMIN_CMD_DEV_PARTS_GET_TYPE_ALL,
buf->table.sgt.sgl, &res_size);
/* Restore the original SG mark end */
if (unmark_end)
sg_unmark_end(sg);
if (ret)
goto out;
buf->length = res_size;
header_buf = virtiovf_get_data_buffer(migf,
sizeof(struct virtiovf_migration_header));
if (IS_ERR(header_buf)) {
ret = PTR_ERR(header_buf);
goto out;
}
Annotation
- Immediate include surface: `linux/device.h`, `linux/module.h`, `linux/mutex.h`, `linux/pci.h`, `linux/pm_runtime.h`, `linux/types.h`, `linux/uaccess.h`, `linux/vfio.h`.
- Detected declarations: `function virtiovf_get_migration_page`, `function for_each_sg`, `function virtiovf_add_migration_pages`, `function virtiovf_free_data_buffer`, `function virtiovf_alloc_data_buffer`, `function virtiovf_put_data_buffer`, `function virtiovf_pci_alloc_obj_id`, `function virtiovf_pci_free_obj_id`, `function virtiovf_get_data_buffer`, `function virtiovf_clean_migf_resources`.
- Atlas domain: Driver Families / drivers/vfio.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.