Lines Matching +full:device +full:- +full:handle

1 // SPDX-License-Identifier: GPL-2.0
10 #include "iommu-sva.h"
15 static int iommu_sva_alloc_pasid(struct mm_struct *mm, struct device *dev) in iommu_sva_alloc_pasid()
21 return -EBUSY; in iommu_sva_alloc_pasid()
26 if (mm->pasid >= dev->iommu->max_pasids) in iommu_sva_alloc_pasid()
27 ret = -EOVERFLOW; in iommu_sva_alloc_pasid()
33 ret = -ENOSPC; in iommu_sva_alloc_pasid()
36 mm->pasid = pasid; in iommu_sva_alloc_pasid()
44 * iommu_sva_bind_device() - Bind a process address space to a device
45 * @dev: the device
48 * Create a bond between device and address space, allowing the device to
50 * bond already exists between @device and @mm, an additional internal
59 struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct mm_struct *mm) in iommu_sva_bind_device()
62 struct iommu_sva *handle; in iommu_sva_bind_device() local
65 /* Allocate mm->pasid if necessary. */ in iommu_sva_bind_device()
70 handle = kzalloc(sizeof(*handle), GFP_KERNEL); in iommu_sva_bind_device()
71 if (!handle) in iommu_sva_bind_device()
72 return ERR_PTR(-ENOMEM); in iommu_sva_bind_device()
76 domain = iommu_get_domain_for_dev_pasid(dev, mm->pasid, in iommu_sva_bind_device()
84 domain->users++; in iommu_sva_bind_device()
88 /* Allocate a new domain and set it on device pasid. */ in iommu_sva_bind_device()
91 ret = -ENOMEM; in iommu_sva_bind_device()
95 ret = iommu_attach_device_pasid(domain, dev, mm->pasid); in iommu_sva_bind_device()
98 domain->users = 1; in iommu_sva_bind_device()
101 handle->dev = dev; in iommu_sva_bind_device()
102 handle->domain = domain; in iommu_sva_bind_device()
104 return handle; in iommu_sva_bind_device()
110 kfree(handle); in iommu_sva_bind_device()
117 * iommu_sva_unbind_device() - Remove a bond created with iommu_sva_bind_device
118 * @handle: the handle returned by iommu_sva_bind_device()
120 * Put reference to a bond between device and address space. The device should
124 void iommu_sva_unbind_device(struct iommu_sva *handle) in iommu_sva_unbind_device() argument
126 struct iommu_domain *domain = handle->domain; in iommu_sva_unbind_device()
127 ioasid_t pasid = domain->mm->pasid; in iommu_sva_unbind_device()
128 struct device *dev = handle->dev; in iommu_sva_unbind_device()
131 if (--domain->users == 0) { in iommu_sva_unbind_device()
136 kfree(handle); in iommu_sva_unbind_device()
140 u32 iommu_sva_get_pasid(struct iommu_sva *handle) in iommu_sva_get_pasid() argument
142 struct iommu_domain *domain = handle->domain; in iommu_sva_get_pasid()
144 return domain->mm->pasid; in iommu_sva_get_pasid()
159 struct iommu_fault_page_request *prm = &fault->prm; in iommu_sva_handle_iopf()
162 if (!(prm->flags & IOMMU_FAULT_PAGE_REQUEST_PASID_VALID)) in iommu_sva_handle_iopf()
170 vma = vma_lookup(mm, prm->addr); in iommu_sva_handle_iopf()
175 if (prm->perm & IOMMU_FAULT_PERM_READ) in iommu_sva_handle_iopf()
178 if (prm->perm & IOMMU_FAULT_PERM_WRITE) { in iommu_sva_handle_iopf()
183 if (prm->perm & IOMMU_FAULT_PERM_EXEC) { in iommu_sva_handle_iopf()
188 if (!(prm->perm & IOMMU_FAULT_PERM_PRIV)) in iommu_sva_handle_iopf()
191 if (access_flags & ~vma->vm_flags) in iommu_sva_handle_iopf()
195 ret = handle_mm_fault(vma, prm->addr, fault_flags, NULL); in iommu_sva_handle_iopf()
211 iommu_free_global_pasid(mm->pasid); in mm_pasid_drop()