* vm_map_madvise: * * This routine traverses a processes map handling the madvise * system call. Advisories are classified as either those effecting * the vm_map_entry structure, or those effecting the underlying * objects. */
| 2946 | * objects. |
| 2947 | */ |
| 2948 | int |
| 2949 | vm_map_madvise( |
| 2950 | vm_map_t map, |
| 2951 | vm_offset_t start, |
| 2952 | vm_offset_t end, |
| 2953 | int behav) |
| 2954 | { |
| 2955 | vm_map_entry_t entry, prev_entry; |
| 2956 | int rv; |
| 2957 | bool modify_map; |
| 2958 | |
| 2959 | /* |
| 2960 | * Some madvise calls directly modify the vm_map_entry, in which case |
| 2961 | * we need to use an exclusive lock on the map and we need to perform |
| 2962 | * various clipping operations. Otherwise we only need a read-lock |
| 2963 | * on the map. |
| 2964 | */ |
| 2965 | switch(behav) { |
| 2966 | case MADV_NORMAL: |
| 2967 | case MADV_SEQUENTIAL: |
| 2968 | case MADV_RANDOM: |
| 2969 | case MADV_NOSYNC: |
| 2970 | case MADV_AUTOSYNC: |
| 2971 | case MADV_NOCORE: |
| 2972 | case MADV_CORE: |
| 2973 | if (start == end) |
| 2974 | return (0); |
| 2975 | modify_map = true; |
| 2976 | vm_map_lock(map); |
| 2977 | break; |
| 2978 | case MADV_WILLNEED: |
| 2979 | case MADV_DONTNEED: |
| 2980 | case MADV_FREE: |
| 2981 | if (start == end) |
| 2982 | return (0); |
| 2983 | modify_map = false; |
| 2984 | vm_map_lock_read(map); |
| 2985 | break; |
| 2986 | default: |
| 2987 | return (EINVAL); |
| 2988 | } |
| 2989 | |
| 2990 | /* |
| 2991 | * Locate starting entry and clip if necessary. |
| 2992 | */ |
| 2993 | VM_MAP_RANGE_CHECK(map, start, end); |
| 2994 | |
| 2995 | if (modify_map) { |
| 2996 | /* |
| 2997 | * madvise behaviors that are implemented in the vm_map_entry. |
| 2998 | * |
| 2999 | * We clip the vm_map_entry so that behavioral changes are |
| 3000 | * limited to the specified address range. |
| 3001 | */ |
| 3002 | rv = vm_map_lookup_clip_start(map, start, &entry, &prev_entry); |
| 3003 | if (rv != KERN_SUCCESS) { |
| 3004 | vm_map_unlock(map); |
| 3005 | return (vm_mmap_to_errno(rv)); |
no test coverage detected