* Implement uiomove(9) from physical memory using the direct map to * avoid the creation and destruction of ephemeral mappings. */
| 58 | * avoid the creation and destruction of ephemeral mappings. |
| 59 | */ |
| 60 | int |
| 61 | uiomove_fromphys(vm_page_t ma[], vm_offset_t offset, int n, struct uio *uio) |
| 62 | { |
| 63 | struct thread *td = curthread; |
| 64 | struct iovec *iov; |
| 65 | void *cp; |
| 66 | vm_offset_t page_offset, vaddr; |
| 67 | size_t cnt; |
| 68 | int error = 0; |
| 69 | int save = 0; |
| 70 | boolean_t mapped; |
| 71 | |
| 72 | KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE, |
| 73 | ("uiomove_fromphys: mode")); |
| 74 | KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread, |
| 75 | ("uiomove_fromphys proc")); |
| 76 | save = td->td_pflags & TDP_DEADLKTREAT; |
| 77 | td->td_pflags |= TDP_DEADLKTREAT; |
| 78 | mapped = FALSE; |
| 79 | while (n > 0 && uio->uio_resid) { |
| 80 | iov = uio->uio_iov; |
| 81 | cnt = iov->iov_len; |
| 82 | if (cnt == 0) { |
| 83 | uio->uio_iov++; |
| 84 | uio->uio_iovcnt--; |
| 85 | continue; |
| 86 | } |
| 87 | if (cnt > n) |
| 88 | cnt = n; |
| 89 | page_offset = offset & PAGE_MASK; |
| 90 | cnt = min(cnt, PAGE_SIZE - page_offset); |
| 91 | if (uio->uio_segflg != UIO_NOCOPY) { |
| 92 | mapped = pmap_map_io_transient( |
| 93 | &ma[offset >> PAGE_SHIFT], &vaddr, 1, TRUE); |
| 94 | cp = (char *)vaddr + page_offset; |
| 95 | } |
| 96 | switch (uio->uio_segflg) { |
| 97 | case UIO_USERSPACE: |
| 98 | maybe_yield(); |
| 99 | if (uio->uio_rw == UIO_READ) |
| 100 | error = copyout(cp, iov->iov_base, cnt); |
| 101 | else |
| 102 | error = copyin(iov->iov_base, cp, cnt); |
| 103 | if (error) |
| 104 | goto out; |
| 105 | break; |
| 106 | case UIO_SYSSPACE: |
| 107 | if (uio->uio_rw == UIO_READ) |
| 108 | bcopy(cp, iov->iov_base, cnt); |
| 109 | else |
| 110 | bcopy(iov->iov_base, cp, cnt); |
| 111 | break; |
| 112 | case UIO_NOCOPY: |
| 113 | break; |
| 114 | } |
| 115 | if (__predict_false(mapped)) { |
| 116 | pmap_unmap_io_transient(&ma[offset >> PAGE_SHIFT], |
| 117 | &vaddr, 1, TRUE); |
nothing calls this directly
no test coverage detected