drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c

Source file repositories/reference/linux-study-clean/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c

File Facts

System
Linux kernel
Corpus path
drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
Extension
.c
Size
46215 bytes
Lines
1742
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.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations hisi_acc_vf_resume_fops = {
	.owner = THIS_MODULE,
	.write = hisi_acc_vf_resume_write,
	.release = hisi_acc_vf_release_file,
};

static struct hisi_acc_vf_migration_file *
hisi_acc_vf_pci_resume(struct hisi_acc_vf_core_device *hisi_acc_vdev)
{
	struct hisi_acc_vf_migration_file *migf;

	migf = kzalloc_obj(*migf, GFP_KERNEL_ACCOUNT);
	if (!migf)
		return ERR_PTR(-ENOMEM);

	migf->filp = anon_inode_getfile("hisi_acc_vf_mig", &hisi_acc_vf_resume_fops, migf,
					O_WRONLY);
	if (IS_ERR(migf->filp)) {
		int err = PTR_ERR(migf->filp);

		kfree(migf);
		return ERR_PTR(err);
	}

	stream_open(migf->filp->f_inode, migf->filp);
	mutex_init(&migf->lock);
	migf->hisi_acc_vdev = hisi_acc_vdev;
	return migf;
}

static long hisi_acc_vf_precopy_ioctl(struct file *filp,
				      unsigned int cmd, unsigned long arg)
{
	struct hisi_acc_vf_migration_file *migf = filp->private_data;
	struct hisi_acc_vf_core_device *hisi_acc_vdev = migf->hisi_acc_vdev;
	loff_t *pos = &filp->f_pos;
	struct vfio_precopy_info info;
	int ret;

	ret = vfio_check_precopy_ioctl(&hisi_acc_vdev->core_device.vdev, cmd,
				       arg, &info);
	if (ret)
		return ret;

	mutex_lock(&hisi_acc_vdev->state_mutex);
	if (hisi_acc_vdev->mig_state != VFIO_DEVICE_STATE_PRE_COPY) {
		mutex_unlock(&hisi_acc_vdev->state_mutex);
		return -EINVAL;
	}

	mutex_lock(&migf->lock);

	if (migf->disabled) {
		ret = -ENODEV;
		goto out;
	}

	if (*pos > migf->total_length) {
		ret = -EINVAL;
		goto out;
	}

	info.dirty_bytes = 0;
	info.initial_bytes = migf->total_length - *pos;
	mutex_unlock(&migf->lock);
	mutex_unlock(&hisi_acc_vdev->state_mutex);

	return copy_to_user((void __user *)arg, &info,
		offsetofend(struct vfio_precopy_info, dirty_bytes)) ? -EFAULT : 0;
out:
	mutex_unlock(&migf->lock);
	mutex_unlock(&hisi_acc_vdev->state_mutex);
	return ret;
}

static ssize_t hisi_acc_vf_save_read(struct file *filp, char __user *buf, size_t len,
				     loff_t *pos)
{
	struct hisi_acc_vf_migration_file *migf = filp->private_data;
	ssize_t done = 0;
	int ret;

	if (pos)
		return -ESPIPE;
	pos = &filp->f_pos;

	mutex_lock(&migf->lock);
	if (*pos > migf->total_length) {
		done = -EINVAL;
		goto out_unlock;

Annotation

Implementation Notes