| 92 | } |
| 93 | |
| 94 | int |
| 95 | cp_slow0(vm_offset_t uva, size_t len, bool write, |
| 96 | void (*f)(vm_offset_t, void *), void *arg) |
| 97 | { |
| 98 | struct pcpu *pc; |
| 99 | vm_page_t m[2]; |
| 100 | vm_offset_t kaddr; |
| 101 | int error, i, plen; |
| 102 | bool sleepable; |
| 103 | |
| 104 | plen = howmany(uva - trunc_page(uva) + len, PAGE_SIZE); |
| 105 | MPASS(plen <= nitems(m)); |
| 106 | error = 0; |
| 107 | i = vm_fault_quick_hold_pages(&curproc->p_vmspace->vm_map, uva, len, |
| 108 | (write ? VM_PROT_WRITE : VM_PROT_READ) | VM_PROT_QUICK_NOFAULT, |
| 109 | m, nitems(m)); |
| 110 | if (i != plen) |
| 111 | return (EFAULT); |
| 112 | sched_pin(); |
| 113 | pc = get_pcpu(); |
| 114 | if (!THREAD_CAN_SLEEP() || curthread->td_vslock_sz > 0 || |
| 115 | (curthread->td_pflags & TDP_NOFAULTING) != 0) { |
| 116 | sleepable = false; |
| 117 | mtx_lock(&pc->pc_copyout_mlock); |
| 118 | kaddr = pc->pc_copyout_maddr; |
| 119 | } else { |
| 120 | sleepable = true; |
| 121 | sx_xlock(&pc->pc_copyout_slock); |
| 122 | kaddr = pc->pc_copyout_saddr; |
| 123 | } |
| 124 | pmap_cp_slow0_map(kaddr, plen, m); |
| 125 | kaddr += uva - trunc_page(uva); |
| 126 | f(kaddr, arg); |
| 127 | sched_unpin(); |
| 128 | if (sleepable) |
| 129 | sx_xunlock(&pc->pc_copyout_slock); |
| 130 | else |
| 131 | mtx_unlock(&pc->pc_copyout_mlock); |
| 132 | vm_page_unhold_pages(m, plen); |
| 133 | return (error); |
| 134 | } |
| 135 | |
| 136 | struct copyinstr_arg0 { |
| 137 | vm_offset_t kc; |
no test coverage detected