Skip to content

Commit 1331460

Browse files
nicolincawilliam
authored andcommitted
vfio/ccw: Change pa_pfn list to pa_iova list
The vfio_ccw_cp code maintains both iova and its PFN list because the vfio_pin/unpin_pages API wanted pfn list. Since vfio_pin/unpin_pages() now accept "iova", change to maintain only pa_iova list and rename all "pfn_array" strings to "page_array", so as to simplify the code. Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Eric Farman <farman@linux.ibm.com> Tested-by: Eric Farman <farman@linux.ibm.com> Signed-off-by: Nicolin Chen <nicolinc@nvidia.com> Link: https://lore.kernel.org/r/20220723020256.30081-8-nicolinc@nvidia.com Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
1 parent 3fad3a2 commit 1331460

File tree

1 file changed

+64
-71
lines changed

1 file changed

+64
-71
lines changed

drivers/s390/cio/vfio_ccw_cp.c

Lines changed: 64 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@
1818
#include "vfio_ccw_cp.h"
1919
#include "vfio_ccw_private.h"
2020

21-
struct pfn_array {
22-
/* Starting guest physical I/O address. */
23-
unsigned long pa_iova;
24-
/* Array that stores PFNs of the pages need to pin. */
25-
unsigned long *pa_iova_pfn;
21+
struct page_array {
22+
/* Array that stores pages need to pin. */
23+
dma_addr_t *pa_iova;
2624
/* Array that receives PFNs of the pages pinned. */
2725
unsigned long *pa_pfn;
2826
/* Number of pages pinned from @pa_iova. */
@@ -37,84 +35,81 @@ struct ccwchain {
3735
/* Count of the valid ccws in chain. */
3836
int ch_len;
3937
/* Pinned PAGEs for the original data. */
40-
struct pfn_array *ch_pa;
38+
struct page_array *ch_pa;
4139
};
4240

4341
/*
44-
* pfn_array_alloc() - alloc memory for PFNs
45-
* @pa: pfn_array on which to perform the operation
42+
* page_array_alloc() - alloc memory for page array
43+
* @pa: page_array on which to perform the operation
4644
* @iova: target guest physical address
4745
* @len: number of bytes that should be pinned from @iova
4846
*
49-
* Attempt to allocate memory for PFNs.
47+
* Attempt to allocate memory for page array.
5048
*
51-
* Usage of pfn_array:
52-
* We expect (pa_nr == 0) and (pa_iova_pfn == NULL), any field in
49+
* Usage of page_array:
50+
* We expect (pa_nr == 0) and (pa_iova == NULL), any field in
5351
* this structure will be filled in by this function.
5452
*
5553
* Returns:
56-
* 0 if PFNs are allocated
57-
* -EINVAL if pa->pa_nr is not initially zero, or pa->pa_iova_pfn is not NULL
54+
* 0 if page array is allocated
55+
* -EINVAL if pa->pa_nr is not initially zero, or pa->pa_iova is not NULL
5856
* -ENOMEM if alloc failed
5957
*/
60-
static int pfn_array_alloc(struct pfn_array *pa, u64 iova, unsigned int len)
58+
static int page_array_alloc(struct page_array *pa, u64 iova, unsigned int len)
6159
{
6260
int i;
6361

64-
if (pa->pa_nr || pa->pa_iova_pfn)
62+
if (pa->pa_nr || pa->pa_iova)
6563
return -EINVAL;
6664

67-
pa->pa_iova = iova;
68-
6965
pa->pa_nr = ((iova & ~PAGE_MASK) + len + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
7066
if (!pa->pa_nr)
7167
return -EINVAL;
7268

73-
pa->pa_iova_pfn = kcalloc(pa->pa_nr,
74-
sizeof(*pa->pa_iova_pfn) +
75-
sizeof(*pa->pa_pfn),
76-
GFP_KERNEL);
77-
if (unlikely(!pa->pa_iova_pfn)) {
69+
pa->pa_iova = kcalloc(pa->pa_nr,
70+
sizeof(*pa->pa_iova) + sizeof(*pa->pa_pfn),
71+
GFP_KERNEL);
72+
if (unlikely(!pa->pa_iova)) {
7873
pa->pa_nr = 0;
7974
return -ENOMEM;
8075
}
81-
pa->pa_pfn = pa->pa_iova_pfn + pa->pa_nr;
76+
pa->pa_pfn = (unsigned long *)&pa->pa_iova[pa->pa_nr];
8277

83-
pa->pa_iova_pfn[0] = pa->pa_iova >> PAGE_SHIFT;
78+
pa->pa_iova[0] = iova;
8479
pa->pa_pfn[0] = -1ULL;
8580
for (i = 1; i < pa->pa_nr; i++) {
86-
pa->pa_iova_pfn[i] = pa->pa_iova_pfn[i - 1] + 1;
81+
pa->pa_iova[i] = pa->pa_iova[i - 1] + PAGE_SIZE;
8782
pa->pa_pfn[i] = -1ULL;
8883
}
8984

9085
return 0;
9186
}
9287

9388
/*
94-
* pfn_array_unpin() - Unpin user pages in memory
95-
* @pa: pfn_array on which to perform the operation
89+
* page_array_unpin() - Unpin user pages in memory
90+
* @pa: page_array on which to perform the operation
9691
* @vdev: the vfio device to perform the operation
9792
* @pa_nr: number of user pages to unpin
9893
*
9994
* Only unpin if any pages were pinned to begin with, i.e. pa_nr > 0,
10095
* otherwise only clear pa->pa_nr
10196
*/
102-
static void pfn_array_unpin(struct pfn_array *pa,
103-
struct vfio_device *vdev, int pa_nr)
97+
static void page_array_unpin(struct page_array *pa,
98+
struct vfio_device *vdev, int pa_nr)
10499
{
105100
int unpinned = 0, npage = 1;
106101

107102
while (unpinned < pa_nr) {
108-
unsigned long *first = &pa->pa_iova_pfn[unpinned];
109-
unsigned long *last = &first[npage];
103+
dma_addr_t *first = &pa->pa_iova[unpinned];
104+
dma_addr_t *last = &first[npage];
110105

111106
if (unpinned + npage < pa_nr &&
112-
*first + npage == *last) {
107+
*first + npage * PAGE_SIZE == *last) {
113108
npage++;
114109
continue;
115110
}
116111

117-
vfio_unpin_pages(vdev, *first << PAGE_SHIFT, npage);
112+
vfio_unpin_pages(vdev, *first, npage);
118113
unpinned += npage;
119114
npage = 1;
120115
}
@@ -123,30 +118,30 @@ static void pfn_array_unpin(struct pfn_array *pa,
123118
}
124119

125120
/*
126-
* pfn_array_pin() - Pin user pages in memory
127-
* @pa: pfn_array on which to perform the operation
121+
* page_array_pin() - Pin user pages in memory
122+
* @pa: page_array on which to perform the operation
128123
* @mdev: the mediated device to perform pin operations
129124
*
130125
* Returns number of pages pinned upon success.
131126
* If the pin request partially succeeds, or fails completely,
132127
* all pages are left unpinned and a negative error value is returned.
133128
*/
134-
static int pfn_array_pin(struct pfn_array *pa, struct vfio_device *vdev)
129+
static int page_array_pin(struct page_array *pa, struct vfio_device *vdev)
135130
{
136131
int pinned = 0, npage = 1;
137132
int ret = 0;
138133

139134
while (pinned < pa->pa_nr) {
140-
unsigned long *first = &pa->pa_iova_pfn[pinned];
141-
unsigned long *last = &first[npage];
135+
dma_addr_t *first = &pa->pa_iova[pinned];
136+
dma_addr_t *last = &first[npage];
142137

143138
if (pinned + npage < pa->pa_nr &&
144-
*first + npage == *last) {
139+
*first + npage * PAGE_SIZE == *last) {
145140
npage++;
146141
continue;
147142
}
148143

149-
ret = vfio_pin_pages(vdev, *first << PAGE_SHIFT, npage,
144+
ret = vfio_pin_pages(vdev, *first, npage,
150145
IOMMU_READ | IOMMU_WRITE,
151146
&pa->pa_pfn[pinned]);
152147
if (ret < 0) {
@@ -163,32 +158,30 @@ static int pfn_array_pin(struct pfn_array *pa, struct vfio_device *vdev)
163158
return ret;
164159

165160
err_out:
166-
pfn_array_unpin(pa, vdev, pinned);
161+
page_array_unpin(pa, vdev, pinned);
167162
return ret;
168163
}
169164

170165
/* Unpin the pages before releasing the memory. */
171-
static void pfn_array_unpin_free(struct pfn_array *pa, struct vfio_device *vdev)
166+
static void page_array_unpin_free(struct page_array *pa, struct vfio_device *vdev)
172167
{
173-
pfn_array_unpin(pa, vdev, pa->pa_nr);
174-
kfree(pa->pa_iova_pfn);
168+
page_array_unpin(pa, vdev, pa->pa_nr);
169+
kfree(pa->pa_iova);
175170
}
176171

177-
static bool pfn_array_iova_pinned(struct pfn_array *pa, unsigned long iova)
172+
static bool page_array_iova_pinned(struct page_array *pa, unsigned long iova)
178173
{
179-
unsigned long iova_pfn = iova >> PAGE_SHIFT;
180174
int i;
181175

182176
for (i = 0; i < pa->pa_nr; i++)
183-
if (pa->pa_iova_pfn[i] == iova_pfn)
177+
if (pa->pa_iova[i] == iova)
184178
return true;
185179

186180
return false;
187181
}
188-
/* Create the list of IDAL words for a pfn_array. */
189-
static inline void pfn_array_idal_create_words(
190-
struct pfn_array *pa,
191-
unsigned long *idaws)
182+
/* Create the list of IDAL words for a page_array. */
183+
static inline void page_array_idal_create_words(struct page_array *pa,
184+
unsigned long *idaws)
192185
{
193186
int i;
194187

@@ -204,7 +197,7 @@ static inline void pfn_array_idal_create_words(
204197
idaws[i] = pa->pa_pfn[i] << PAGE_SHIFT;
205198

206199
/* Adjust the first IDAW, since it may not start on a page boundary */
207-
idaws[0] += pa->pa_iova & (PAGE_SIZE - 1);
200+
idaws[0] += pa->pa_iova[0] & (PAGE_SIZE - 1);
208201
}
209202

210203
static void convert_ccw0_to_ccw1(struct ccw1 *source, unsigned long len)
@@ -236,18 +229,18 @@ static void convert_ccw0_to_ccw1(struct ccw1 *source, unsigned long len)
236229
static long copy_from_iova(struct vfio_device *vdev, void *to, u64 iova,
237230
unsigned long n)
238231
{
239-
struct pfn_array pa = {0};
232+
struct page_array pa = {0};
240233
u64 from;
241234
int i, ret;
242235
unsigned long l, m;
243236

244-
ret = pfn_array_alloc(&pa, iova, n);
237+
ret = page_array_alloc(&pa, iova, n);
245238
if (ret < 0)
246239
return ret;
247240

248-
ret = pfn_array_pin(&pa, vdev);
241+
ret = page_array_pin(&pa, vdev);
249242
if (ret < 0) {
250-
pfn_array_unpin_free(&pa, vdev);
243+
page_array_unpin_free(&pa, vdev);
251244
return ret;
252245
}
253246

@@ -268,7 +261,7 @@ static long copy_from_iova(struct vfio_device *vdev, void *to, u64 iova,
268261
break;
269262
}
270263

271-
pfn_array_unpin_free(&pa, vdev);
264+
page_array_unpin_free(&pa, vdev);
272265

273266
return l;
274267
}
@@ -371,7 +364,7 @@ static struct ccwchain *ccwchain_alloc(struct channel_program *cp, int len)
371364
chain->ch_ccw = (struct ccw1 *)data;
372365

373366
data = (u8 *)(chain->ch_ccw) + sizeof(*chain->ch_ccw) * len;
374-
chain->ch_pa = (struct pfn_array *)data;
367+
chain->ch_pa = (struct page_array *)data;
375368

376369
chain->ch_len = len;
377370

@@ -555,7 +548,7 @@ static int ccwchain_fetch_direct(struct ccwchain *chain,
555548
struct vfio_device *vdev =
556549
&container_of(cp, struct vfio_ccw_private, cp)->vdev;
557550
struct ccw1 *ccw;
558-
struct pfn_array *pa;
551+
struct page_array *pa;
559552
u64 iova;
560553
unsigned long *idaws;
561554
int ret;
@@ -589,13 +582,13 @@ static int ccwchain_fetch_direct(struct ccwchain *chain,
589582
}
590583

591584
/*
592-
* Allocate an array of pfn's for pages to pin/translate.
585+
* Allocate an array of pages to pin/translate.
593586
* The number of pages is actually the count of the idaws
594587
* required for the data transfer, since we only only support
595588
* 4K IDAWs today.
596589
*/
597590
pa = chain->ch_pa + idx;
598-
ret = pfn_array_alloc(pa, iova, bytes);
591+
ret = page_array_alloc(pa, iova, bytes);
599592
if (ret < 0)
600593
goto out_free_idaws;
601594

@@ -606,21 +599,21 @@ static int ccwchain_fetch_direct(struct ccwchain *chain,
606599
goto out_unpin;
607600

608601
/*
609-
* Copy guest IDAWs into pfn_array, in case the memory they
602+
* Copy guest IDAWs into page_array, in case the memory they
610603
* occupy is not contiguous.
611604
*/
612605
for (i = 0; i < idaw_nr; i++)
613-
pa->pa_iova_pfn[i] = idaws[i] >> PAGE_SHIFT;
606+
pa->pa_iova[i] = idaws[i];
614607
} else {
615608
/*
616-
* No action is required here; the iova addresses in pfn_array
617-
* were initialized sequentially in pfn_array_alloc() beginning
609+
* No action is required here; the iova addresses in page_array
610+
* were initialized sequentially in page_array_alloc() beginning
618611
* with the contents of ccw->cda.
619612
*/
620613
}
621614

622615
if (ccw_does_data_transfer(ccw)) {
623-
ret = pfn_array_pin(pa, vdev);
616+
ret = page_array_pin(pa, vdev);
624617
if (ret < 0)
625618
goto out_unpin;
626619
} else {
@@ -630,13 +623,13 @@ static int ccwchain_fetch_direct(struct ccwchain *chain,
630623
ccw->cda = (__u32) virt_to_phys(idaws);
631624
ccw->flags |= CCW_FLAG_IDA;
632625

633-
/* Populate the IDAL with pinned/translated addresses from pfn */
634-
pfn_array_idal_create_words(pa, idaws);
626+
/* Populate the IDAL with pinned/translated addresses from page */
627+
page_array_idal_create_words(pa, idaws);
635628

636629
return 0;
637630

638631
out_unpin:
639-
pfn_array_unpin_free(pa, vdev);
632+
page_array_unpin_free(pa, vdev);
640633
out_free_idaws:
641634
kfree(idaws);
642635
out_init:
@@ -742,7 +735,7 @@ void cp_free(struct channel_program *cp)
742735
cp->initialized = false;
743736
list_for_each_entry_safe(chain, temp, &cp->ccwchain_list, next) {
744737
for (i = 0; i < chain->ch_len; i++) {
745-
pfn_array_unpin_free(chain->ch_pa + i, vdev);
738+
page_array_unpin_free(chain->ch_pa + i, vdev);
746739
ccwchain_cda_free(chain, i);
747740
}
748741
ccwchain_free(chain);
@@ -918,7 +911,7 @@ bool cp_iova_pinned(struct channel_program *cp, u64 iova)
918911

919912
list_for_each_entry(chain, &cp->ccwchain_list, next) {
920913
for (i = 0; i < chain->ch_len; i++)
921-
if (pfn_array_iova_pinned(chain->ch_pa + i, iova))
914+
if (page_array_iova_pinned(chain->ch_pa + i, iova))
922915
return true;
923916
}
924917

0 commit comments

Comments
 (0)