1/*- 2 * Copyright (c) 2015 Nuxi, https://nuxi.nl/ 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26#include <sys/cdefs.h> 27__FBSDID("$FreeBSD: releng/11.0/sys/compat/cloudabi/cloudabi_mem.c 297247 2016-03-24 21:47:15Z ed $"); 28 29#include <sys/param.h> 30#include <sys/mman.h> 31#include <sys/sysproto.h> 32 33#include <contrib/cloudabi/cloudabi_types_common.h> 34 35#include <compat/cloudabi/cloudabi_proto.h> 36 37/* Converts CloudABI's memory protection flags to FreeBSD's. */ 38static int 39convert_mprot(cloudabi_mprot_t in, int *out) 40{ 41 42 /* Unknown protection flags. */ 43 if ((in & ~(CLOUDABI_PROT_EXEC | CLOUDABI_PROT_WRITE | 44 CLOUDABI_PROT_READ)) != 0) 45 return (ENOTSUP); 46 /* W^X: Write and exec cannot be enabled at the same time. */ 47 if ((in & (CLOUDABI_PROT_EXEC | CLOUDABI_PROT_WRITE)) == 48 (CLOUDABI_PROT_EXEC | CLOUDABI_PROT_WRITE)) 49 return (ENOTSUP); 50 51 *out = 0; 52 if (in & CLOUDABI_PROT_EXEC) 53 *out |= PROT_EXEC; 54 if (in & CLOUDABI_PROT_WRITE) 55 *out |= PROT_WRITE; 56 if (in & CLOUDABI_PROT_READ) 57 *out |= PROT_READ; 58 return (0); 59} 60 61int 62cloudabi_sys_mem_advise(struct thread *td, 63 struct cloudabi_sys_mem_advise_args *uap) 64{ 65 struct madvise_args madvise_args = { 66 .addr = uap->addr, 67 .len = uap->len 68 }; 69 70 switch (uap->advice) { 71 case CLOUDABI_ADVICE_DONTNEED: 72 madvise_args.behav = MADV_DONTNEED; 73 break; 74 case CLOUDABI_ADVICE_NORMAL: 75 madvise_args.behav = MADV_NORMAL; 76 break; 77 case CLOUDABI_ADVICE_RANDOM: 78 madvise_args.behav = MADV_RANDOM; 79 break; 80 case CLOUDABI_ADVICE_SEQUENTIAL: 81 madvise_args.behav = MADV_SEQUENTIAL; 82 break; 83 case CLOUDABI_ADVICE_WILLNEED: 84 madvise_args.behav = MADV_WILLNEED; 85 break; 86 default: 87 return (EINVAL); 88 } 89 90 return (sys_madvise(td, &madvise_args)); 91} 92 93int 94cloudabi_sys_mem_lock(struct thread *td, struct cloudabi_sys_mem_lock_args *uap) 95{ 96 struct mlock_args mlock_args = { 97 .addr = uap->addr, 98 .len = uap->len 99 }; 100 101 return (sys_mlock(td, &mlock_args)); 102} 103 104int 105cloudabi_sys_mem_map(struct thread *td, struct cloudabi_sys_mem_map_args *uap) 106{ 107 struct mmap_args mmap_args = { 108 .addr = uap->addr, 109 .len = uap->len, 110 .fd = uap->fd, 111 .pos = uap->off 112 }; 113 int error; 114 115 /* Translate flags. */ 116 if (uap->flags & CLOUDABI_MAP_ANON) 117 mmap_args.flags |= MAP_ANON; 118 if (uap->flags & CLOUDABI_MAP_FIXED) 119 mmap_args.flags |= MAP_FIXED; 120 if (uap->flags & CLOUDABI_MAP_PRIVATE) 121 mmap_args.flags |= MAP_PRIVATE; 122 if (uap->flags & CLOUDABI_MAP_SHARED) 123 mmap_args.flags |= MAP_SHARED; 124 125 /* Translate protection. */ 126 error = convert_mprot(uap->prot, &mmap_args.prot); 127 if (error != 0) 128 return (error); 129 130 return (sys_mmap(td, &mmap_args)); 131} 132 133int 134cloudabi_sys_mem_protect(struct thread *td, 135 struct cloudabi_sys_mem_protect_args *uap) 136{ 137 struct mprotect_args mprotect_args = { 138 .addr = uap->addr, 139 .len = uap->len, 140 }; 141 int error; 142 143 /* Translate protection. */ 144 error = convert_mprot(uap->prot, &mprotect_args.prot); 145 if (error != 0) 146 return (error); 147 148 return (sys_mprotect(td, &mprotect_args)); 149} 150 151int 152cloudabi_sys_mem_sync(struct thread *td, struct cloudabi_sys_mem_sync_args *uap) 153{ 154 struct msync_args msync_args = { 155 .addr = uap->addr, 156 .len = uap->len, 157 }; 158 159 /* Convert flags. */ 160 switch (uap->flags & (CLOUDABI_MS_ASYNC | CLOUDABI_MS_SYNC)) { 161 case CLOUDABI_MS_ASYNC: 162 msync_args.flags |= MS_ASYNC; 163 break; 164 case CLOUDABI_MS_SYNC: 165 msync_args.flags |= MS_SYNC; 166 break; 167 default: 168 return (EINVAL); 169 } 170 if ((uap->flags & CLOUDABI_MS_INVALIDATE) != 0) 171 msync_args.flags |= MS_INVALIDATE; 172 173 return (sys_msync(td, &msync_args)); 174} 175 176int 177cloudabi_sys_mem_unlock(struct thread *td, 178 struct cloudabi_sys_mem_unlock_args *uap) 179{ 180 struct munlock_args munlock_args = { 181 .addr = uap->addr, 182 .len = uap->len 183 }; 184 185 return (sys_munlock(td, &munlock_args)); 186} 187 188int 189cloudabi_sys_mem_unmap(struct thread *td, 190 struct cloudabi_sys_mem_unmap_args *uap) 191{ 192 struct munmap_args munmap_args = { 193 .addr = uap->addr, 194 .len = uap->len 195 }; 196 197 return (sys_munmap(td, &munmap_args)); 198} 199