| 1056 | } |
| 1057 | |
| 1058 | int |
| 1059 | kern_mlock(struct proc *proc, struct ucred *cred, uintptr_t addr0, size_t len) |
| 1060 | { |
| 1061 | vm_offset_t addr, end, last, start; |
| 1062 | vm_size_t npages, size; |
| 1063 | vm_map_t map; |
| 1064 | unsigned long nsize; |
| 1065 | int error; |
| 1066 | |
| 1067 | error = priv_check_cred(cred, PRIV_VM_MLOCK); |
| 1068 | if (error) |
| 1069 | return (error); |
| 1070 | addr = addr0; |
| 1071 | size = len; |
| 1072 | last = addr + size; |
| 1073 | start = trunc_page(addr); |
| 1074 | end = round_page(last); |
| 1075 | if (last < addr || end < addr) |
| 1076 | return (EINVAL); |
| 1077 | npages = atop(end - start); |
| 1078 | if (npages > vm_page_max_user_wired) |
| 1079 | return (ENOMEM); |
| 1080 | map = &proc->p_vmspace->vm_map; |
| 1081 | PROC_LOCK(proc); |
| 1082 | nsize = ptoa(npages + pmap_wired_count(map->pmap)); |
| 1083 | if (nsize > lim_cur_proc(proc, RLIMIT_MEMLOCK)) { |
| 1084 | PROC_UNLOCK(proc); |
| 1085 | return (ENOMEM); |
| 1086 | } |
| 1087 | PROC_UNLOCK(proc); |
| 1088 | #ifdef RACCT |
| 1089 | if (racct_enable) { |
| 1090 | PROC_LOCK(proc); |
| 1091 | error = racct_set(proc, RACCT_MEMLOCK, nsize); |
| 1092 | PROC_UNLOCK(proc); |
| 1093 | if (error != 0) |
| 1094 | return (ENOMEM); |
| 1095 | } |
| 1096 | #endif |
| 1097 | error = vm_map_wire(map, start, end, |
| 1098 | VM_MAP_WIRE_USER | VM_MAP_WIRE_NOHOLES); |
| 1099 | #ifdef RACCT |
| 1100 | if (racct_enable && error != KERN_SUCCESS) { |
| 1101 | PROC_LOCK(proc); |
| 1102 | racct_set(proc, RACCT_MEMLOCK, |
| 1103 | ptoa(pmap_wired_count(map->pmap))); |
| 1104 | PROC_UNLOCK(proc); |
| 1105 | } |
| 1106 | #endif |
| 1107 | switch (error) { |
| 1108 | case KERN_SUCCESS: |
| 1109 | return (0); |
| 1110 | case KERN_INVALID_ARGUMENT: |
| 1111 | return (EINVAL); |
| 1112 | default: |
| 1113 | return (ENOMEM); |
| 1114 | } |
| 1115 | } |
no test coverage detected