@@ -39,13 +39,20 @@ enum {
39
39
HMM_NEED_ALL_BITS = HMM_NEED_FAULT | HMM_NEED_WRITE_FAULT ,
40
40
};
41
41
42
+ enum {
43
+ /* These flags are carried from input-to-output */
44
+ HMM_PFN_INOUT_FLAGS = HMM_PFN_DMA_MAPPED ,
45
+ };
46
+
42
47
static int hmm_pfns_fill (unsigned long addr , unsigned long end ,
43
48
struct hmm_range * range , unsigned long cpu_flags )
44
49
{
45
50
unsigned long i = (addr - range -> start ) >> PAGE_SHIFT ;
46
51
47
- for (; addr < end ; addr += PAGE_SIZE , i ++ )
48
- range -> hmm_pfns [i ] = cpu_flags ;
52
+ for (; addr < end ; addr += PAGE_SIZE , i ++ ) {
53
+ range -> hmm_pfns [i ] &= HMM_PFN_INOUT_FLAGS ;
54
+ range -> hmm_pfns [i ] |= cpu_flags ;
55
+ }
49
56
return 0 ;
50
57
}
51
58
@@ -202,8 +209,10 @@ static int hmm_vma_handle_pmd(struct mm_walk *walk, unsigned long addr,
202
209
return hmm_vma_fault (addr , end , required_fault , walk );
203
210
204
211
pfn = pmd_pfn (pmd ) + ((addr & ~PMD_MASK ) >> PAGE_SHIFT );
205
- for (i = 0 ; addr < end ; addr += PAGE_SIZE , i ++ , pfn ++ )
206
- hmm_pfns [i ] = pfn | cpu_flags ;
212
+ for (i = 0 ; addr < end ; addr += PAGE_SIZE , i ++ , pfn ++ ) {
213
+ hmm_pfns [i ] &= HMM_PFN_INOUT_FLAGS ;
214
+ hmm_pfns [i ] |= pfn | cpu_flags ;
215
+ }
207
216
return 0 ;
208
217
}
209
218
#else /* CONFIG_TRANSPARENT_HUGEPAGE */
@@ -230,14 +239,14 @@ static int hmm_vma_handle_pte(struct mm_walk *walk, unsigned long addr,
230
239
unsigned long cpu_flags ;
231
240
pte_t pte = ptep_get (ptep );
232
241
uint64_t pfn_req_flags = * hmm_pfn ;
242
+ uint64_t new_pfn_flags = 0 ;
233
243
234
244
if (pte_none_mostly (pte )) {
235
245
required_fault =
236
246
hmm_pte_need_fault (hmm_vma_walk , pfn_req_flags , 0 );
237
247
if (required_fault )
238
248
goto fault ;
239
- * hmm_pfn = 0 ;
240
- return 0 ;
249
+ goto out ;
241
250
}
242
251
243
252
if (!pte_present (pte )) {
@@ -253,16 +262,14 @@ static int hmm_vma_handle_pte(struct mm_walk *walk, unsigned long addr,
253
262
cpu_flags = HMM_PFN_VALID ;
254
263
if (is_writable_device_private_entry (entry ))
255
264
cpu_flags |= HMM_PFN_WRITE ;
256
- * hmm_pfn = swp_offset_pfn (entry ) | cpu_flags ;
257
- return 0 ;
265
+ new_pfn_flags = swp_offset_pfn (entry ) | cpu_flags ;
266
+ goto out ;
258
267
}
259
268
260
269
required_fault =
261
270
hmm_pte_need_fault (hmm_vma_walk , pfn_req_flags , 0 );
262
- if (!required_fault ) {
263
- * hmm_pfn = 0 ;
264
- return 0 ;
265
- }
271
+ if (!required_fault )
272
+ goto out ;
266
273
267
274
if (!non_swap_entry (entry ))
268
275
goto fault ;
@@ -304,11 +311,13 @@ static int hmm_vma_handle_pte(struct mm_walk *walk, unsigned long addr,
304
311
pte_unmap (ptep );
305
312
return - EFAULT ;
306
313
}
307
- * hmm_pfn = HMM_PFN_ERROR ;
308
- return 0 ;
314
+ new_pfn_flags = HMM_PFN_ERROR ;
315
+ goto out ;
309
316
}
310
317
311
- * hmm_pfn = pte_pfn (pte ) | cpu_flags ;
318
+ new_pfn_flags = pte_pfn (pte ) | cpu_flags ;
319
+ out :
320
+ * hmm_pfn = (* hmm_pfn & HMM_PFN_INOUT_FLAGS ) | new_pfn_flags ;
312
321
return 0 ;
313
322
314
323
fault :
@@ -448,8 +457,10 @@ static int hmm_vma_walk_pud(pud_t *pudp, unsigned long start, unsigned long end,
448
457
}
449
458
450
459
pfn = pud_pfn (pud ) + ((addr & ~PUD_MASK ) >> PAGE_SHIFT );
451
- for (i = 0 ; i < npages ; ++ i , ++ pfn )
452
- hmm_pfns [i ] = pfn | cpu_flags ;
460
+ for (i = 0 ; i < npages ; ++ i , ++ pfn ) {
461
+ hmm_pfns [i ] &= HMM_PFN_INOUT_FLAGS ;
462
+ hmm_pfns [i ] |= pfn | cpu_flags ;
463
+ }
453
464
goto out_unlock ;
454
465
}
455
466
@@ -507,8 +518,10 @@ static int hmm_vma_walk_hugetlb_entry(pte_t *pte, unsigned long hmask,
507
518
}
508
519
509
520
pfn = pte_pfn (entry ) + ((start & ~hmask ) >> PAGE_SHIFT );
510
- for (; addr < end ; addr += PAGE_SIZE , i ++ , pfn ++ )
511
- range -> hmm_pfns [i ] = pfn | cpu_flags ;
521
+ for (; addr < end ; addr += PAGE_SIZE , i ++ , pfn ++ ) {
522
+ range -> hmm_pfns [i ] &= HMM_PFN_INOUT_FLAGS ;
523
+ range -> hmm_pfns [i ] |= pfn | cpu_flags ;
524
+ }
512
525
513
526
spin_unlock (ptl );
514
527
return 0 ;
0 commit comments