Lines Matching refs:pa
44 * @pa: pfn_array on which to perform the operation
56 * -EINVAL if pa->pa_nr is not initially zero, or pa->pa_iova_pfn is not NULL
59 static int pfn_array_alloc(struct pfn_array *pa, u64 iova, unsigned int len)
63 if (pa->pa_nr || pa->pa_iova_pfn)
66 pa->pa_iova = iova;
68 pa->pa_nr = ((iova & ~PAGE_MASK) + len + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
69 if (!pa->pa_nr)
72 pa->pa_iova_pfn = kcalloc(pa->pa_nr,
73 sizeof(*pa->pa_iova_pfn) +
74 sizeof(*pa->pa_pfn),
76 if (unlikely(!pa->pa_iova_pfn)) {
77 pa->pa_nr = 0;
80 pa->pa_pfn = pa->pa_iova_pfn + pa->pa_nr;
82 pa->pa_iova_pfn[0] = pa->pa_iova >> PAGE_SHIFT;
83 pa->pa_pfn[0] = -1ULL;
84 for (i = 1; i < pa->pa_nr; i++) {
85 pa->pa_iova_pfn[i] = pa->pa_iova_pfn[i - 1] + 1;
86 pa->pa_pfn[i] = -1ULL;
94 * @pa: pfn_array on which to perform the operation
101 static int pfn_array_pin(struct pfn_array *pa, struct device *mdev)
105 ret = vfio_pin_pages(mdev, pa->pa_iova_pfn, pa->pa_nr,
106 IOMMU_READ | IOMMU_WRITE, pa->pa_pfn);
110 } else if (ret > 0 && ret != pa->pa_nr) {
111 vfio_unpin_pages(mdev, pa->pa_iova_pfn, ret);
119 pa->pa_nr = 0;
125 static void pfn_array_unpin_free(struct pfn_array *pa, struct device *mdev)
128 if (pa->pa_nr)
129 vfio_unpin_pages(mdev, pa->pa_iova_pfn, pa->pa_nr);
130 pa->pa_nr = 0;
131 kfree(pa->pa_iova_pfn);
134 static bool pfn_array_iova_pinned(struct pfn_array *pa, unsigned long iova)
139 for (i = 0; i < pa->pa_nr; i++)
140 if (pa->pa_iova_pfn[i] == iova_pfn)
147 struct pfn_array *pa,
160 for (i = 0; i < pa->pa_nr; i++)
161 idaws[i] = pa->pa_pfn[i] << PAGE_SHIFT;
164 idaws[0] += pa->pa_iova & (PAGE_SIZE - 1);
197 struct pfn_array pa = {0};
202 ret = pfn_array_alloc(&pa, iova, n);
206 ret = pfn_array_pin(&pa, mdev);
208 pfn_array_unpin_free(&pa, mdev);
213 for (i = 0; i < pa.pa_nr; i++) {
214 from = pa.pa_pfn[i] << PAGE_SHIFT;
229 pfn_array_unpin_free(&pa, mdev);
512 struct pfn_array *pa;
551 pa = chain->ch_pa + idx;
552 ret = pfn_array_alloc(pa, iova, bytes);
567 pa->pa_iova_pfn[i] = idaws[i] >> PAGE_SHIFT;
577 ret = pfn_array_pin(pa, cp->mdev);
581 pa->pa_nr = 0;
588 pfn_array_idal_create_words(pa, idaws);
593 pfn_array_unpin_free(pa, cp->mdev);