// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2021-2022, NVIDIA CORPORATION & AFFILIATES
 */
#include <linux/vfio.h>
#include <linux/iommufd.h>

#include "vfio.h"

MODULE_IMPORT_NS("IOMMUFD");
MODULE_IMPORT_NS("IOMMUFD_VFIO");

bool vfio_iommufd_device_has_compat_ioas(struct vfio_device *vdev,
					 struct iommufd_ctx *ictx)
{
	u32 ioas_id;

	return !iommufd_vfio_compat_ioas_get_id(ictx, &ioas_id);
}

int vfio_df_iommufd_bind(struct vfio_device_file *df)
{
	struct vfio_device *vdev = df->device;
	struct iommufd_ctx *ictx = df->iommufd;

	lockdep_assert_held(&vdev->dev_set->lock);

	/* Returns 0 to permit device opening under noiommu mode */
	if (vfio_device_is_noiommu(vdev))
		return 0;

	return vdev->ops->bind_iommufd(vdev, ictx, &df->devid);
}

int vfio_iommufd_compat_attach_ioas(struct vfio_device *vdev,
				    struct iommufd_ctx *ictx)
{
	u32 ioas_id;
	int ret;

	lockdep_assert_held(&vdev->dev_set->lock);

	/* compat noiommu does not need to do ioas attach */
	if (vfio_device_is_noiommu(vdev))
		return 0;

	ret = iommufd_vfio_compat_ioas_get_id(ictx, &ioas_id);
	if (ret)
		return ret;

	/* The legacy path has no way to return the selected pt_id */
	return vdev->ops->attach_ioas(vdev, &ioas_id);
}

void vfio_df_iommufd_unbind(struct vfio_device_file *df)
{
	struct vfio_device *vdev = df->device;

	lockdep_assert_held(&vdev->dev_set->lock);

	if (vfio_device_is_noiommu(vdev))
		return;

	if (vdev->ops->unbind_iommufd)
		vdev->ops->unbind_iommufd(vdev);
}

struct iommufd_ctx *vfio_iommufd_device_ictx(struct vfio_device *vdev)
{
	if (vdev->iommufd_device)
		return iommufd_device_to_ictx(vdev->iommufd_device);
	return NULL;
}
EXPORT_SYMBOL_GPL(vfio_iommufd_device_ictx);

static int vfio_iommufd_device_id(struct vfio_device *vdev)
{
	if (vdev->iommufd_device)
		return iommufd_device_to_id(vdev->iommufd_device);
	return -EINVAL;
}

/*
 * Return devid for a device.
 *  valid ID for the device that is owned by the ictx
 *  -ENOENT = device is owned but there is no ID
 *  -ENODEV or other error = device is not owned
 */
int vfio_iommufd_get_dev_id(struct vfio_device *vdev, struct iommufd_ctx *ictx)
{
	struct iommu_group *group;
	int devid;

	if (vfio_iommufd_device_ictx(vdev) == ictx)
		return vfio_iommufd_device_id(vdev);

	group = iommu_group_get(vdev->dev);
	if (!group)
		return -ENODEV;

	if (iommufd_ctx_has_group(ictx, group))
		devid = -ENOENT;
	else
		devid = -ENODEV;

	iommu_group_put(group);

	return devid;
}
EXPORT_SYMBOL_GPL(vfio_iommufd_get_dev_id);

/*
 * The physical standard ops mean that the iommufd_device is bound to the
 * physical device vdev->dev that was provided to vfio_init_group_dev(). Drivers
 * using this ops set should call vfio_register_group_dev()
 */
int vfio_iommufd_physical_bind(struct vfio_device *vdev,
			       struct iommufd_ctx *ictx, u32 *out_device_id)
{
	struct iommufd_device *idev;

	idev = iommufd_device_bind(ictx, vdev->dev, out_device_id);
	if (IS_ERR(idev))
		return PTR_ERR(idev);
	vdev->iommufd_device = idev;
	ida_init(&vdev->pasids);
	return 0;
}
EXPORT_SYMBOL_GPL(vfio_iommufd_physical_bind);

void vfio_iommufd_physical_unbind(struct vfio_device *vdev)
{
	int pasid;

	lockdep_assert_held(&vdev->dev_set->lock);

	while ((pasid = ida_find_first(&vdev->pasids)) >= 0) {
		iommufd_device_detach(vdev->iommufd_device, pasid);
		ida_free(&vdev->pasids, pasid);
	}

	if (vdev->iommufd_attached) {
		iommufd_device_detach(vdev->iommufd_device, IOMMU_NO_PASID);
		vdev->iommufd_attached = false;
	}
	iommufd_device_unbind(vdev->iommufd_device);
	vdev->iommufd_device = NULL;
}
EXPORT_SYMBOL_GPL(vfio_iommufd_physical_unbind);

int vfio_iommufd_physical_attach_ioas(struct vfio_device *vdev, u32 *pt_id)
{
	int rc;

	lockdep_assert_held(&vdev->dev_set->lock);

	if (WARN_ON(!vdev->iommufd_device))
		return -EINVAL;

	if (vdev->iommufd_attached)
		rc = iommufd_device_replace(vdev->iommufd_device,
					    IOMMU_NO_PASID, pt_id);
	else
		rc = iommufd_device_attach(vdev->iommufd_device,
					   IOMMU_NO_PASID, pt_id);
	if (rc)
		return rc;
	vdev->iommufd_attached = true;
	return 0;
}
EXPORT_SYMBOL_GPL(vfio_iommufd_physical_attach_ioas);

void vfio_iommufd_physical_detach_ioas(struct vfio_device *vdev)
{
	lockdep_assert_held(&vdev->dev_set->lock);

	if (WARN_ON(!vdev->iommufd_device) || !vdev->iommufd_attached)
		return;

	iommufd_device_detach(vdev->iommufd_device, IOMMU_NO_PASID);
	vdev->iommufd_attached = false;
}
EXPORT_SYMBOL_GPL(vfio_iommufd_physical_detach_ioas);

int vfio_iommufd_physical_pasid_attach_ioas(struct vfio_device *vdev,
					    u32 pasid, u32 *pt_id)
{
	int rc;

	lockdep_assert_held(&vdev->dev_set->lock);

	if (WARN_ON(!vdev->iommufd_device))
		return -EINVAL;

	if (ida_exists(&vdev->pasids, pasid))
		return iommufd_device_replace(vdev->iommufd_device,
					      pasid, pt_id);

	rc = ida_alloc_range(&vdev->pasids, pasid, pasid, GFP_KERNEL);
	if (rc < 0)
		return rc;

	rc = iommufd_device_attach(vdev->iommufd_device, pasid, pt_id);
	if (rc)
		ida_free(&vdev->pasids, pasid);

	return rc;
}
EXPORT_SYMBOL_GPL(vfio_iommufd_physical_pasid_attach_ioas);

void vfio_iommufd_physical_pasid_detach_ioas(struct vfio_device *vdev,
					     u32 pasid)
{
	lockdep_assert_held(&vdev->dev_set->lock);

	if (WARN_ON(!vdev->iommufd_device))
		return;

	if (!ida_exists(&vdev->pasids, pasid))
		return;

	iommufd_device_detach(vdev->iommufd_device, pasid);
	ida_free(&vdev->pasids, pasid);
}
EXPORT_SYMBOL_GPL(vfio_iommufd_physical_pasid_detach_ioas);

/*
 * The emulated standard ops mean that vfio_device is going to use the
 * "mdev path" and will call vfio_pin_pages()/vfio_dma_rw(). Drivers using this
 * ops set should call vfio_register_emulated_iommu_dev(). Drivers that do
 * not call vfio_pin_pages()/vfio_dma_rw() have no need to provide dma_unmap.
 */

static void vfio_emulated_unmap(void *data, unsigned long iova,
				unsigned long length)
{
	struct vfio_device *vdev = data;

	if (vdev->ops->dma_unmap)
		vdev->ops->dma_unmap(vdev, iova, length);
}

static const struct iommufd_access_ops vfio_user_ops = {
	.needs_pin_pages = 1,
	.unmap = vfio_emulated_unmap,
};

int vfio_iommufd_emulated_bind(struct vfio_device *vdev,
			       struct iommufd_ctx *ictx, u32 *out_device_id)
{
	struct iommufd_access *user;

	lockdep_assert_held(&vdev->dev_set->lock);

	user = iommufd_access_create(ictx, &vfio_user_ops, vdev, out_device_id);
	if (IS_ERR(user))
		return PTR_ERR(user);
	vdev->iommufd_access = user;
	return 0;
}
EXPORT_SYMBOL_GPL(vfio_iommufd_emulated_bind);

void vfio_iommufd_emulated_unbind(struct vfio_device *vdev)
{
	lockdep_assert_held(&vdev->dev_set->lock);

	if (vdev->iommufd_access) {
		iommufd_access_destroy(vdev->iommufd_access);
		vdev->iommufd_attached = false;
		vdev->iommufd_access = NULL;
	}
}
EXPORT_SYMBOL_GPL(vfio_iommufd_emulated_unbind);

int vfio_iommufd_emulated_attach_ioas(struct vfio_device *vdev, u32 *pt_id)
{
	int rc;

	lockdep_assert_held(&vdev->dev_set->lock);

	if (vdev->iommufd_attached)
		rc = iommufd_access_replace(vdev->iommufd_access, *pt_id);
	else
		rc = iommufd_access_attach(vdev->iommufd_access, *pt_id);
	if (rc)
		return rc;
	vdev->iommufd_attached = true;
	return 0;
}
EXPORT_SYMBOL_GPL(vfio_iommufd_emulated_attach_ioas);

void vfio_iommufd_emulated_detach_ioas(struct vfio_device *vdev)
{
	lockdep_assert_held(&vdev->dev_set->lock);

	if (WARN_ON(!vdev->iommufd_access) ||
	    !vdev->iommufd_attached)
		return;

	iommufd_access_detach(vdev->iommufd_access);
	vdev->iommufd_attached = false;
}
EXPORT_SYMBOL_GPL(vfio_iommufd_emulated_detach_ioas);
