1 /* $NetBSD: rumpuser.h,v 1.116 2020/03/22 13:30:10 pgoyette Exp $ */ 2 3 /* 4 * Copyright (c) 2007-2013 Antti Kantee. All Rights Reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #ifndef _RUMP_RUMPUSER_H_ 29 #define _RUMP_RUMPUSER_H_ 30 31 /* 32 * Do not include any headers here! Implementation must take care of 33 * having stdint or equivalent included before including this header. 34 */ 35 36 #if !defined(_KERNEL) && !defined(LIBRUMPUSER) 37 #error The rump/rumpuser.h interface is not for non-kernel consumers 38 #endif 39 struct lwp; 40 41 /* 42 * init 43 */ 44 45 /* 46 * Bumping this causes all kinds of havoc for implementations 47 * outside of the NetBSD tree, so try to avoid it. 48 */ 49 #define RUMPUSER_VERSION 17 50 51 /* hypervisor upcall routines */ 52 struct rumpuser_hyperup { 53 void (*hyp_schedule)(void); 54 void (*hyp_unschedule)(void); 55 void (*hyp_backend_unschedule)(int, int *, void *); 56 void (*hyp_backend_schedule)(int, void *); 57 void (*hyp_lwproc_switch)(struct lwp *); 58 void (*hyp_lwproc_release)(void); 59 int (*hyp_lwproc_rfork)(void *, int, const char *); 60 int (*hyp_lwproc_newlwp)(pid_t); 61 struct lwp * (*hyp_lwproc_curlwp)(void); 62 int (*hyp_syscall)(int, void *, long *); 63 void (*hyp_lwpexit)(void); 64 void (*hyp_execnotify)(const char *); 65 pid_t (*hyp_getpid)(void); 66 void *hyp__extra[8]; 67 }; 68 int rumpuser_init(int, const struct rumpuser_hyperup *); 69 70 /* 71 * memory allocation 72 */ 73 74 int rumpuser_malloc(size_t, int, void **); 75 void rumpuser_free(void *, size_t); 76 int rumpuser_anonmmap(void *, size_t, int, int, void **); 77 void rumpuser_unmap(void *, size_t); 78 79 /* 80 * files and I/O 81 */ 82 83 #define RUMPUSER_OPEN_RDONLY 0x0000 84 #define RUMPUSER_OPEN_WRONLY 0x0001 85 #define RUMPUSER_OPEN_RDWR 0x0002 86 #define RUMPUSER_OPEN_ACCMODE 0x0003 /* "yay" */ 87 #define RUMPUSER_OPEN_CREATE 0x0004 /* create file if it doesn't exist */ 88 #define RUMPUSER_OPEN_EXCL 0x0008 /* exclusive open */ 89 #define RUMPUSER_OPEN_BIO 0x0010 /* open device for block i/o */ 90 int rumpuser_open(const char *, int, int *); 91 int rumpuser_close(int); 92 93 #define RUMPUSER_FT_OTHER 0 94 #define RUMPUSER_FT_DIR 1 95 #define RUMPUSER_FT_REG 2 96 #define RUMPUSER_FT_BLK 3 97 #define RUMPUSER_FT_CHR 4 98 int rumpuser_getfileinfo(const char *, uint64_t *, int *); 99 100 #define RUMPUSER_BIO_READ 0x01 101 #define RUMPUSER_BIO_WRITE 0x02 102 #define RUMPUSER_BIO_SYNC 0x04 103 typedef void (*rump_biodone_fn)(void *, size_t, int); 104 void rumpuser_bio(int, int, void *, size_t, int64_t, rump_biodone_fn, void *); 105 106 /* this one "accidentally" matches the NetBSD kernel ... */ 107 struct rumpuser_iovec { 108 void *iov_base; 109 size_t iov_len; 110 }; 111 #define RUMPUSER_IOV_NOSEEK -1 112 int rumpuser_iovread(int, struct rumpuser_iovec *, size_t, int64_t, size_t *); 113 int rumpuser_iovwrite(int, const struct rumpuser_iovec *, size_t, 114 int64_t, size_t *); 115 116 #define RUMPUSER_SYNCFD_READ 0x01 117 #define RUMPUSER_SYNCFD_WRITE 0x02 118 #define RUMPUSER_SYNCFD_BOTH (RUMPUSER_SYNCFD_READ | RUMPUSER_SYNCFD_WRITE) 119 #define RUMPUSER_SYNCFD_BARRIER 0x04 120 #define RUMPUSER_SYNCFD_SYNC 0x08 121 int rumpuser_syncfd(int, int, uint64_t, uint64_t); 122 123 /* 124 * clock and zzz 125 */ 126 127 enum rumpclock { RUMPUSER_CLOCK_RELWALL, RUMPUSER_CLOCK_ABSMONO }; 128 int rumpuser_clock_gettime(int, int64_t *, long *); 129 int rumpuser_clock_sleep(int, int64_t, long); 130 131 /* 132 * host information retrieval 133 */ 134 135 #define RUMPUSER_PARAM_NCPU "_RUMPUSER_NCPU" 136 #define RUMPUSER_PARAM_HOSTNAME "_RUMPUSER_HOSTNAME" 137 int rumpuser_getparam(const char *, void *, size_t); 138 139 /* 140 * system call emulation, set errno is TLS 141 */ 142 143 void rumpuser_seterrno(int); 144 145 /* 146 * termination 147 */ 148 149 #define RUMPUSER_PID_SELF ((int64_t)-1) 150 int rumpuser_kill(int64_t, int); 151 #define RUMPUSER_PANIC (-1) 152 void rumpuser_exit(int) __dead; 153 154 /* 155 * console output 156 */ 157 158 void rumpuser_putchar(int); 159 void rumpuser_dprintf(const char *, ...) __printflike(1, 2); 160 161 /* 162 * access to host random pool 163 */ 164 165 /* always succeeds unless NOWAIT is given */ 166 #define RUMPUSER_RANDOM_HARD 0x01 167 #define RUMPUSER_RANDOM_NOWAIT 0x02 168 int rumpuser_getrandom(void *, size_t, int, size_t *); 169 170 /* 171 * threads, scheduling (host) and synchronization 172 */ 173 int rumpuser_thread_create(void *(*f)(void *), void *, const char *, int, 174 int, int, void **); 175 void rumpuser_thread_exit(void) __dead; 176 int rumpuser_thread_join(void *); 177 178 #if defined(LIBRUMPUSER) || defined(RUMP__CURLWP_PRIVATE) 179 enum rumplwpop { 180 RUMPUSER_LWP_CREATE, RUMPUSER_LWP_DESTROY, 181 RUMPUSER_LWP_SET, RUMPUSER_LWP_CLEAR 182 }; 183 void rumpuser_curlwpop(int, struct lwp *); 184 struct lwp *rumpuser_curlwp(void); 185 #endif /* LIBRUMPUSER || RUMP__CURLWP_PRIVATE */ 186 187 struct rumpuser_mtx; 188 #define RUMPUSER_MTX_SPIN 0x01 189 #define RUMPUSER_MTX_KMUTEX 0x02 190 void rumpuser_mutex_init(struct rumpuser_mtx **, int); 191 void rumpuser_mutex_enter(struct rumpuser_mtx *); 192 void rumpuser_mutex_enter_nowrap(struct rumpuser_mtx *); 193 int rumpuser_mutex_tryenter(struct rumpuser_mtx *); 194 void rumpuser_mutex_exit(struct rumpuser_mtx *); 195 void rumpuser_mutex_destroy(struct rumpuser_mtx *); 196 void rumpuser_mutex_owner(struct rumpuser_mtx *, struct lwp **); 197 int rumpuser_mutex_spin_p(struct rumpuser_mtx *); 198 199 struct rumpuser_rw; 200 enum rumprwlock { RUMPUSER_RW_READER, RUMPUSER_RW_WRITER }; 201 void rumpuser_rw_init(struct rumpuser_rw **); 202 void rumpuser_rw_enter(int, struct rumpuser_rw *); 203 int rumpuser_rw_tryenter(int, struct rumpuser_rw *); 204 int rumpuser_rw_tryupgrade(struct rumpuser_rw *); 205 void rumpuser_rw_downgrade(struct rumpuser_rw *); 206 void rumpuser_rw_exit(struct rumpuser_rw *); 207 void rumpuser_rw_destroy(struct rumpuser_rw *); 208 void rumpuser_rw_held(int, struct rumpuser_rw *, int *); 209 210 struct rumpuser_cv; 211 void rumpuser_cv_init(struct rumpuser_cv **); 212 void rumpuser_cv_destroy(struct rumpuser_cv *); 213 void rumpuser_cv_wait(struct rumpuser_cv *, struct rumpuser_mtx *); 214 void rumpuser_cv_wait_nowrap(struct rumpuser_cv *, struct rumpuser_mtx *); 215 int rumpuser_cv_timedwait(struct rumpuser_cv *, struct rumpuser_mtx *, 216 int64_t, int64_t); 217 void rumpuser_cv_signal(struct rumpuser_cv *); 218 void rumpuser_cv_broadcast(struct rumpuser_cv *); 219 void rumpuser_cv_has_waiters(struct rumpuser_cv *, int *); 220 221 /* 222 * dynloader 223 */ 224 225 struct modinfo; 226 struct rump_component; 227 struct evcnt; 228 typedef void (*rump_modinit_fn)(const struct modinfo *const *, size_t); 229 typedef int (*rump_symload_fn)(void *, uint64_t, char *, uint64_t); 230 typedef void (*rump_compload_fn)(const struct rump_component *); 231 typedef void (*rump_evcntattach_fn)(struct evcnt *); 232 void rumpuser_dl_bootstrap(rump_modinit_fn, rump_symload_fn, rump_compload_fn, 233 rump_evcntattach_fn); 234 235 /* 236 * misc management 237 */ 238 239 int rumpuser_daemonize_begin(void); 240 int rumpuser_daemonize_done(int); 241 242 #if defined(_RUMP_SYSPROXY) || defined(LIBRUMPUSER) 243 /* 244 * syscall proxy 245 */ 246 247 int rumpuser_sp_init(const char *, 248 const char *, const char *, const char *); 249 int rumpuser_sp_copyin(void *, const void *, void *, size_t); 250 int rumpuser_sp_copyinstr(void *, const void *, void *, size_t *); 251 int rumpuser_sp_copyout(void *, const void *, void *, size_t); 252 int rumpuser_sp_copyoutstr(void *, const void *, void *, size_t *); 253 int rumpuser_sp_anonmmap(void *, size_t, void **); 254 int rumpuser_sp_raise(void *, int); 255 void rumpuser_sp_fini(void *); 256 #endif /* _RUMP_SYSPROXY || LIBRUMPUSER */ 257 258 #endif /* _RUMP_RUMPUSER_H_ */ 259