1 /* $NetBSD: rumpuser.h,v 1.117 2023/09/24 09:33:26 martin 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 * for architectures with non-constant page size 172 */ 173 unsigned long rumpuser_getpagesize(void); 174 175 /* 176 * threads, scheduling (host) and synchronization 177 */ 178 int rumpuser_thread_create(void *(*f)(void *), void *, const char *, int, 179 int, int, void **); 180 void rumpuser_thread_exit(void) __dead; 181 int rumpuser_thread_join(void *); 182 183 #if defined(LIBRUMPUSER) || defined(RUMP__CURLWP_PRIVATE) 184 enum rumplwpop { 185 RUMPUSER_LWP_CREATE, RUMPUSER_LWP_DESTROY, 186 RUMPUSER_LWP_SET, RUMPUSER_LWP_CLEAR 187 }; 188 void rumpuser_curlwpop(int, struct lwp *); 189 struct lwp *rumpuser_curlwp(void); 190 #endif /* LIBRUMPUSER || RUMP__CURLWP_PRIVATE */ 191 192 struct rumpuser_mtx; 193 #define RUMPUSER_MTX_SPIN 0x01 194 #define RUMPUSER_MTX_KMUTEX 0x02 195 void rumpuser_mutex_init(struct rumpuser_mtx **, int); 196 void rumpuser_mutex_enter(struct rumpuser_mtx *); 197 void rumpuser_mutex_enter_nowrap(struct rumpuser_mtx *); 198 int rumpuser_mutex_tryenter(struct rumpuser_mtx *); 199 void rumpuser_mutex_exit(struct rumpuser_mtx *); 200 void rumpuser_mutex_destroy(struct rumpuser_mtx *); 201 void rumpuser_mutex_owner(struct rumpuser_mtx *, struct lwp **); 202 int rumpuser_mutex_spin_p(struct rumpuser_mtx *); 203 204 struct rumpuser_rw; 205 enum rumprwlock { RUMPUSER_RW_READER, RUMPUSER_RW_WRITER }; 206 void rumpuser_rw_init(struct rumpuser_rw **); 207 void rumpuser_rw_enter(int, struct rumpuser_rw *); 208 int rumpuser_rw_tryenter(int, struct rumpuser_rw *); 209 int rumpuser_rw_tryupgrade(struct rumpuser_rw *); 210 void rumpuser_rw_downgrade(struct rumpuser_rw *); 211 void rumpuser_rw_exit(struct rumpuser_rw *); 212 void rumpuser_rw_destroy(struct rumpuser_rw *); 213 void rumpuser_rw_held(int, struct rumpuser_rw *, int *); 214 215 struct rumpuser_cv; 216 void rumpuser_cv_init(struct rumpuser_cv **); 217 void rumpuser_cv_destroy(struct rumpuser_cv *); 218 void rumpuser_cv_wait(struct rumpuser_cv *, struct rumpuser_mtx *); 219 void rumpuser_cv_wait_nowrap(struct rumpuser_cv *, struct rumpuser_mtx *); 220 int rumpuser_cv_timedwait(struct rumpuser_cv *, struct rumpuser_mtx *, 221 int64_t, int64_t); 222 void rumpuser_cv_signal(struct rumpuser_cv *); 223 void rumpuser_cv_broadcast(struct rumpuser_cv *); 224 void rumpuser_cv_has_waiters(struct rumpuser_cv *, int *); 225 226 /* 227 * dynloader 228 */ 229 230 struct modinfo; 231 struct rump_component; 232 struct evcnt; 233 typedef void (*rump_modinit_fn)(const struct modinfo *const *, size_t); 234 typedef int (*rump_symload_fn)(void *, uint64_t, char *, uint64_t); 235 typedef void (*rump_compload_fn)(const struct rump_component *); 236 typedef void (*rump_evcntattach_fn)(struct evcnt *); 237 void rumpuser_dl_bootstrap(rump_modinit_fn, rump_symload_fn, rump_compload_fn, 238 rump_evcntattach_fn); 239 240 /* 241 * misc management 242 */ 243 244 int rumpuser_daemonize_begin(void); 245 int rumpuser_daemonize_done(int); 246 247 #if defined(_RUMP_SYSPROXY) || defined(LIBRUMPUSER) 248 /* 249 * syscall proxy 250 */ 251 252 int rumpuser_sp_init(const char *, 253 const char *, const char *, const char *); 254 int rumpuser_sp_copyin(void *, const void *, void *, size_t); 255 int rumpuser_sp_copyinstr(void *, const void *, void *, size_t *); 256 int rumpuser_sp_copyout(void *, const void *, void *, size_t); 257 int rumpuser_sp_copyoutstr(void *, const void *, void *, size_t *); 258 int rumpuser_sp_anonmmap(void *, size_t, void **); 259 int rumpuser_sp_raise(void *, int); 260 void rumpuser_sp_fini(void *); 261 #endif /* _RUMP_SYSPROXY || LIBRUMPUSER */ 262 263 #endif /* _RUMP_RUMPUSER_H_ */ 264