linux/drivers/iommu/virtio-iommu.c

// SPDX-License-Identifier: GPL-2.0
/*
 * Virtio driver for the paravirtualized IOMMU
 *
 * Copyright (C) 2019 Arm Limited
 */

#define pr_fmt(fmt)

#include <linux/delay.h>
#include <linux/dma-map-ops.h>
#include <linux/freezer.h>
#include <linux/interval_tree.h>
#include <linux/iommu.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pci.h>
#include <linux/virtio.h>
#include <linux/virtio_config.h>
#include <linux/virtio_ids.h>
#include <linux/wait.h>

#include <uapi/linux/virtio_iommu.h>

#include "dma-iommu.h"

#define MSI_IOVA_BASE
#define MSI_IOVA_LENGTH

#define VIOMMU_REQUEST_VQ
#define VIOMMU_EVENT_VQ
#define VIOMMU_NR_VQS

struct viommu_dev {};

struct viommu_mapping {};

struct viommu_domain {};

struct viommu_endpoint {};

struct viommu_request {};

#define VIOMMU_FAULT_RESV_MASK

struct viommu_event {};

#define to_viommu_domain(domain)

static int viommu_get_req_errno(void *buf, size_t len)
{}

static void viommu_set_req_status(void *buf, size_t len, int status)
{}

static off_t viommu_get_write_desc_offset(struct viommu_dev *viommu,
					  struct virtio_iommu_req_head *req,
					  size_t len)
{}

/*
 * __viommu_sync_req - Complete all in-flight requests
 *
 * Wait for all added requests to complete. When this function returns, all
 * requests that were in-flight at the time of the call have completed.
 */
static int __viommu_sync_req(struct viommu_dev *viommu)
{}

static int viommu_sync_req(struct viommu_dev *viommu)
{}

/*
 * __viommu_add_request - Add one request to the queue
 * @buf: pointer to the request buffer
 * @len: length of the request buffer
 * @writeback: copy data back to the buffer when the request completes.
 *
 * Add a request to the queue. Only synchronize the queue if it's already full.
 * Otherwise don't kick the queue nor wait for requests to complete.
 *
 * When @writeback is true, data written by the device, including the request
 * status, is copied into @buf after the request completes. This is unsafe if
 * the caller allocates @buf on stack and drops the lock between add_req() and
 * sync_req().
 *
 * Return 0 if the request was successfully added to the queue.
 */
static int __viommu_add_req(struct viommu_dev *viommu, void *buf, size_t len,
			    bool writeback)
{}

static int viommu_add_req(struct viommu_dev *viommu, void *buf, size_t len)
{}

/*
 * Send a request and wait for it to complete. Return the request status (as an
 * errno)
 */
static int viommu_send_req_sync(struct viommu_dev *viommu, void *buf,
				size_t len)
{}

/*
 * viommu_add_mapping - add a mapping to the internal tree
 *
 * On success, return the new mapping. Otherwise return NULL.
 */
static int viommu_add_mapping(struct viommu_domain *vdomain, u64 iova, u64 end,
			      phys_addr_t paddr, u32 flags)
{}

/*
 * viommu_del_mappings - remove mappings from the internal tree
 *
 * @vdomain: the domain
 * @iova: start of the range
 * @end: end of the range
 *
 * On success, returns the number of unmapped bytes
 */
static size_t viommu_del_mappings(struct viommu_domain *vdomain,
				  u64 iova, u64 end)
{}

/*
 * Fill the domain with identity mappings, skipping the device's reserved
 * regions.
 */
static int viommu_domain_map_identity(struct viommu_endpoint *vdev,
				      struct viommu_domain *vdomain)
{}

/*
 * viommu_replay_mappings - re-send MAP requests
 *
 * When reattaching a domain that was previously detached from all endpoints,
 * mappings were deleted from the device. Re-create the mappings available in
 * the internal tree.
 */
static int viommu_replay_mappings(struct viommu_domain *vdomain)
{}

static int viommu_add_resv_mem(struct viommu_endpoint *vdev,
			       struct virtio_iommu_probe_resv_mem *mem,
			       size_t len)
{}

static int viommu_probe_endpoint(struct viommu_dev *viommu, struct device *dev)
{}

static int viommu_fault_handler(struct viommu_dev *viommu,
				struct virtio_iommu_fault *fault)
{}

static void viommu_event_handler(struct virtqueue *vq)
{}

/* IOMMU API */

static struct iommu_domain *viommu_domain_alloc(unsigned type)
{}

static int viommu_domain_finalise(struct viommu_endpoint *vdev,
				  struct iommu_domain *domain)
{}

static void viommu_domain_free(struct iommu_domain *domain)
{}

static int viommu_attach_dev(struct iommu_domain *domain, struct device *dev)
{}

static void viommu_detach_dev(struct viommu_endpoint *vdev)
{}

static int viommu_map_pages(struct iommu_domain *domain, unsigned long iova,
			    phys_addr_t paddr, size_t pgsize, size_t pgcount,
			    int prot, gfp_t gfp, size_t *mapped)
{}

static size_t viommu_unmap_pages(struct iommu_domain *domain, unsigned long iova,
				 size_t pgsize, size_t pgcount,
				 struct iommu_iotlb_gather *gather)
{}

static phys_addr_t viommu_iova_to_phys(struct iommu_domain *domain,
				       dma_addr_t iova)
{}

static void viommu_iotlb_sync(struct iommu_domain *domain,
			      struct iommu_iotlb_gather *gather)
{}

static int viommu_iotlb_sync_map(struct iommu_domain *domain,
				 unsigned long iova, size_t size)
{}

static void viommu_flush_iotlb_all(struct iommu_domain *domain)
{}

static void viommu_get_resv_regions(struct device *dev, struct list_head *head)
{}

static struct iommu_ops viommu_ops;
static struct virtio_driver virtio_iommu_drv;

static int viommu_match_node(struct device *dev, const void *data)
{}

static struct viommu_dev *viommu_get_by_fwnode(struct fwnode_handle *fwnode)
{}

static struct iommu_device *viommu_probe_device(struct device *dev)
{}

static void viommu_release_device(struct device *dev)
{}

static struct iommu_group *viommu_device_group(struct device *dev)
{}

static int viommu_of_xlate(struct device *dev,
			   const struct of_phandle_args *args)
{}

static bool viommu_capable(struct device *dev, enum iommu_cap cap)
{}

static struct iommu_ops viommu_ops =;

static int viommu_init_vqs(struct viommu_dev *viommu)
{}

static int viommu_fill_evtq(struct viommu_dev *viommu)
{}

static int viommu_probe(struct virtio_device *vdev)
{}

static void viommu_remove(struct virtio_device *vdev)
{}

static void viommu_config_changed(struct virtio_device *vdev)
{}

static unsigned int features[] =;

static struct virtio_device_id id_table[] =;
MODULE_DEVICE_TABLE(virtio, id_table);

static struct virtio_driver virtio_iommu_drv =;

module_virtio_driver();

MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();