| @@ -281,7 +281,7 @@ struct hmm_vma_walk { · 280 unmodified lines |
| 281 | struct dev_pagemap *pgmap; | 281 | struct dev_pagemap *pgmap; |
| 282 | unsigned long last; | 282 | unsigned long last; |
| 283 | bool fault; | 283 | bool fault; |
| 284 | bool block; | 284 | unsigned int flags; |
| 285 | }; | 285 | }; |
| 286 | | 286 | |
| 287 | static int hmm_vma_do_fault(struct mm_walk *walk, unsigned long addr, | 287 | static int hmm_vma_do_fault(struct mm_walk *walk, unsigned long addr, |
| @@ -293,8 +293,11 @@ static int hmm_vma_do_fault(struct mm_walk *walk, unsigned long addr, · 5 unmodified lines |
| 293 | struct vm_area_struct *vma = walk->vma; | 293 | struct vm_area_struct *vma = walk->vma; |
| 294 | vm_fault_t ret; | 294 | vm_fault_t ret; |
| 295 | | 295 | |
| 296 | flags |= hmm_vma_walk->block ? 0 : FAULT_FLAG_ALLOW_RETRY; | 296 | if (hmm_vma_walk->flags & HMM_FAULT_ALLOW_RETRY) |
| 297 | flags |= write_fault ? FAULT_FLAG_WRITE : 0; | 297 | flags |= FAULT_FLAG_ALLOW_RETRY; |
| | 298 | if (write_fault) |
| | 299 | flags |= FAULT_FLAG_WRITE; |
| | 300 | |
| 298 | ret = handle_mm_fault(vma, addr, flags); | 301 | ret = handle_mm_fault(vma, addr, flags); |
| 299 | if (ret & VM_FAULT_RETRY) { | 302 | if (ret & VM_FAULT_RETRY) { |
| 300 | /* Note, handle_mm_fault did up_read(&mm->mmap_sem)) */ | 303 | /* Note, handle_mm_fault did up_read(&mm->mmap_sem)) */ |
| @@ -1012,26 +1015,26 @@ long hmm_range_snapshot(struct hmm_range *range) · 711 unmodified lines |
| 1012 | } | 1015 | } |
| 1013 | EXPORT_SYMBOL(hmm_range_snapshot); | 1016 | EXPORT_SYMBOL(hmm_range_snapshot); |
| 1014 | | 1017 | |
| 1015 | /* | 1018 | /** |
| 1016 | * hmm_range_fault() - try to fault some address in a virtual address range | 1019 | * hmm_range_fault - try to fault some address in a virtual address range |
| 1017 | * @range: range being faulted | 1020 | * @range: range being faulted |
| 1018 | * @block: allow blocking on fault (if true it sleeps and do not drop mmap_sem) | 1021 | * @flags: HMM_FAULT_* flags |
| 1019 | * Return: number of valid pages in range->pfns[] (from range start | | |
| 1020 | * address). This may be zero. If the return value is negative, | | |
| 1021 | * then one of the following values may be returned: | | |
| 1022 | * | 1022 | * |
| 1023 | * -EINVAL invalid arguments or mm or virtual address are in an | 1023 | * Return: the number of valid pages in range->pfns[] (from range start |
| 1024 | * invalid vma (for instance device file vma). | 1024 | * address), which may be zero. On error one of the following status codes |
| 1025 | * -ENOMEM: Out of memory. | 1025 | * can be returned: |
| 1026 | * -EPERM: Invalid permission (for instance asking for write and | 1026 | * |
| 1027 | * range is read only). | 1027 | * -EINVAL: Invalid arguments or mm or virtual address is in an invalid vma |
| 1028 | * -EAGAIN: If you need to retry and mmap_sem was drop. This can only | 1028 | * (e.g., device file vma). |
| 1029 | * happens if block argument is false. | 1029 | * -ENOMEM: Out of memory. |
| 1030 | * -EBUSY: If the the range is being invalidated and you should wait | 1030 | * -EPERM: Invalid permission (e.g., asking for write and range is read |
| 1031 | * for invalidation to finish. | 1031 | * only). |
| 1032 | * -EFAULT: Invalid (ie either no valid vma or it is illegal to access | 1032 | * -EAGAIN: A page fault needs to be retried and mmap_sem was dropped. |
| 1033 | * that range), number of valid pages in range->pfns[] (from | 1033 | * -EBUSY: The range has been invalidated and the caller needs to wait for |
| 1034 | * range start address). | 1034 | * the invalidation to finish. |
| | 1035 | * -EFAULT: Invalid (i.e., either no valid vma or it is illegal to access |
| | 1036 | * that range) number of valid pages in range->pfns[] (from |
| | 1037 | * range start address). |
| 1035 | * | 1038 | * |
| 1036 | * This is similar to a regular CPU page fault except that it will not trigger | 1039 | * This is similar to a regular CPU page fault except that it will not trigger |
| 1037 | * any memory migration if the memory being faulted is not accessible by CPUs | 1040 | * any memory migration if the memory being faulted is not accessible by CPUs |
| @@ -1040,7 +1043,7 @@ EXPORT_SYMBOL(hmm_range_snapshot); · 2 unmodified lines |
| 1040 | * On error, for one virtual address in the range, the function will mark the | 1043 | * On error, for one virtual address in the range, the function will mark the |
| 1041 | * corresponding HMM pfn entry with an error flag. | 1044 | * corresponding HMM pfn entry with an error flag. |
| 1042 | */ | 1045 | */ |
| 1043 | long hmm_range_fault(struct hmm_range *range, bool block) | 1046 | long hmm_range_fault(struct hmm_range *range, unsigned int flags) |
| 1044 | { | 1047 | { |
| 1045 | const unsigned long device_vma = VM_IO | VM_PFNMAP | VM_MIXEDMAP; | 1048 | const unsigned long device_vma = VM_IO | VM_PFNMAP | VM_MIXEDMAP; |
| 1046 | unsigned long start = range->start, end; | 1049 | unsigned long start = range->start, end; |
| @@ -1086,7 +1089,7 @@ long hmm_range_fault(struct hmm_range *range, bool block) · 39 unmodified lines |
| 1086 | hmm_vma_walk.pgmap = NULL; | 1089 | hmm_vma_walk.pgmap = NULL; |
| 1087 | hmm_vma_walk.last = start; | 1090 | hmm_vma_walk.last = start; |
| 1088 | hmm_vma_walk.fault = true; | 1091 | hmm_vma_walk.fault = true; |
| 1089 | hmm_vma_walk.block = block; | 1092 | hmm_vma_walk.flags = flags; |
| 1090 | hmm_vma_walk.range = range; | 1093 | hmm_vma_walk.range = range; |
| 1091 | mm_walk.private = &hmm_vma_walk; | 1094 | mm_walk.private = &hmm_vma_walk; |
| 1092 | end = min(range->end, vma->vm_end); | 1095 | end = min(range->end, vma->vm_end); |
| @@ -1125,25 +1128,22 @@ long hmm_range_fault(struct hmm_range *range, bool block) · 32 unmodified lines |
| 1125 | EXPORT_SYMBOL(hmm_range_fault); | 1128 | EXPORT_SYMBOL(hmm_range_fault); |
| 1126 | | 1129 | |
| 1127 | /** | 1130 | /** |
| 1128 | * hmm_range_dma_map() - hmm_range_fault() and dma map page all in one. | 1131 | * hmm_range_dma_map - hmm_range_fault() and dma map page all in one. |
| 1129 | * @range: range being faulted | 1132 | * @range: range being faulted |
| 1130 | * @device: device against to dma map page to | 1133 | * @device: device to map page to |
| 1131 | * @daddrs: dma address of mapped pages | 1134 | * @daddrs: array of dma addresses for the mapped pages |
| 1132 | * @block: allow blocking on fault (if true it sleeps and do not drop mmap_sem) | 1135 | * @flags: HMM_FAULT_* |
| 1133 | * Return: number of pages mapped on success, -EAGAIN if mmap_sem have been | | |
| 1134 | * drop and you need to try again, some other error value otherwise | | |
| 1135 | * | 1136 | * |
| 1136 | * Note same usage pattern as hmm_range_fault(). | 1137 | * Return: the number of pages mapped on success (including zero), or any |
| | 1138 | * status return from hmm_range_fault() otherwise. |
| 1137 | */ | 1139 | */ |
| 1138 | long hmm_range_dma_map(struct hmm_range *range, | 1140 | long hmm_range_dma_map(struct hmm_range *range, struct device *device, |
| 1139 | struct device *device, | 1141 | dma_addr_t *daddrs, unsigned int flags) |
| 1140 | dma_addr_t *daddrs, | | |
| 1141 | bool block) | | |
| 1142 | { | 1142 | { |
| 1143 | unsigned long i, npages, mapped; | 1143 | unsigned long i, npages, mapped; |
| 1144 | long ret; | 1144 | long ret; |
| 1145 | | 1145 | |
| 1146 | ret = hmm_range_fault(range, block); | 1146 | ret = hmm_range_fault(range, flags); |
| 1147 | if (ret <= 0) | 1147 | if (ret <= 0) |
| 1148 | return ret ? ret : -EBUSY; | 1148 | return ret ? ret : -EBUSY; |
| 1149 | | 1149 | |