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 39struct 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 */ 52struct 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}; 68int rumpuser_init(int, const struct rumpuser_hyperup *); 69 70/* 71 * memory allocation 72 */ 73 74int rumpuser_malloc(size_t, int, void **); 75void rumpuser_free(void *, size_t); 76int rumpuser_anonmmap(void *, size_t, int, int, void **); 77void 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 */ 90int rumpuser_open(const char *, int, int *); 91int 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 98int 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 103typedef void (*rump_biodone_fn)(void *, size_t, int); 104void rumpuser_bio(int, int, void *, size_t, int64_t, rump_biodone_fn, void *); 105 106/* this one "accidentally" matches the NetBSD kernel ... */ 107struct rumpuser_iovec { 108 void *iov_base; 109 size_t iov_len; 110}; 111#define RUMPUSER_IOV_NOSEEK -1 112int rumpuser_iovread(int, struct rumpuser_iovec *, size_t, int64_t, size_t *); 113int 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 121int rumpuser_syncfd(int, int, uint64_t, uint64_t); 122 123/* 124 * clock and zzz 125 */ 126 127enum rumpclock { RUMPUSER_CLOCK_RELWALL, RUMPUSER_CLOCK_ABSMONO }; 128int rumpuser_clock_gettime(int, int64_t *, long *); 129int 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" 137int rumpuser_getparam(const char *, void *, size_t); 138 139/* 140 * system call emulation, set errno is TLS 141 */ 142 143void rumpuser_seterrno(int); 144 145/* 146 * termination 147 */ 148 149#define RUMPUSER_PID_SELF ((int64_t)-1) 150int rumpuser_kill(int64_t, int); 151#define RUMPUSER_PANIC (-1) 152void rumpuser_exit(int) __dead; 153 154/* 155 * console output 156 */ 157 158void rumpuser_putchar(int); 159void 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 168int rumpuser_getrandom(void *, size_t, int, size_t *); 169 170/* 171 * for architectures with non-constant page size 172 */ 173unsigned long rumpuser_getpagesize(void); 174 175/* 176 * threads, scheduling (host) and synchronization 177 */ 178int rumpuser_thread_create(void *(*f)(void *), void *, const char *, int, 179 int, int, void **); 180void rumpuser_thread_exit(void) __dead; 181int rumpuser_thread_join(void *); 182 183#if defined(LIBRUMPUSER) || defined(RUMP__CURLWP_PRIVATE) 184enum rumplwpop { 185 RUMPUSER_LWP_CREATE, RUMPUSER_LWP_DESTROY, 186 RUMPUSER_LWP_SET, RUMPUSER_LWP_CLEAR 187}; 188void rumpuser_curlwpop(int, struct lwp *); 189struct lwp *rumpuser_curlwp(void); 190#endif /* LIBRUMPUSER || RUMP__CURLWP_PRIVATE */ 191 192struct rumpuser_mtx; 193#define RUMPUSER_MTX_SPIN 0x01 194#define RUMPUSER_MTX_KMUTEX 0x02 195void rumpuser_mutex_init(struct rumpuser_mtx **, int); 196void rumpuser_mutex_enter(struct rumpuser_mtx *); 197void rumpuser_mutex_enter_nowrap(struct rumpuser_mtx *); 198int rumpuser_mutex_tryenter(struct rumpuser_mtx *); 199void rumpuser_mutex_exit(struct rumpuser_mtx *); 200void rumpuser_mutex_destroy(struct rumpuser_mtx *); 201void rumpuser_mutex_owner(struct rumpuser_mtx *, struct lwp **); 202int rumpuser_mutex_spin_p(struct rumpuser_mtx *); 203 204struct rumpuser_rw; 205enum rumprwlock { RUMPUSER_RW_READER, RUMPUSER_RW_WRITER }; 206void rumpuser_rw_init(struct rumpuser_rw **); 207void rumpuser_rw_enter(int, struct rumpuser_rw *); 208int rumpuser_rw_tryenter(int, struct rumpuser_rw *); 209int rumpuser_rw_tryupgrade(struct rumpuser_rw *); 210void rumpuser_rw_downgrade(struct rumpuser_rw *); 211void rumpuser_rw_exit(struct rumpuser_rw *); 212void rumpuser_rw_destroy(struct rumpuser_rw *); 213void rumpuser_rw_held(int, struct rumpuser_rw *, int *); 214 215struct rumpuser_cv; 216void rumpuser_cv_init(struct rumpuser_cv **); 217void rumpuser_cv_destroy(struct rumpuser_cv *); 218void rumpuser_cv_wait(struct rumpuser_cv *, struct rumpuser_mtx *); 219void rumpuser_cv_wait_nowrap(struct rumpuser_cv *, struct rumpuser_mtx *); 220int rumpuser_cv_timedwait(struct rumpuser_cv *, struct rumpuser_mtx *, 221 int64_t, int64_t); 222void rumpuser_cv_signal(struct rumpuser_cv *); 223void rumpuser_cv_broadcast(struct rumpuser_cv *); 224void rumpuser_cv_has_waiters(struct rumpuser_cv *, int *); 225 226/* 227 * dynloader 228 */ 229 230struct modinfo; 231struct rump_component; 232struct evcnt; 233typedef void (*rump_modinit_fn)(const struct modinfo *const *, size_t); 234typedef int (*rump_symload_fn)(void *, uint64_t, char *, uint64_t); 235typedef void (*rump_compload_fn)(const struct rump_component *); 236typedef void (*rump_evcntattach_fn)(struct evcnt *); 237void rumpuser_dl_bootstrap(rump_modinit_fn, rump_symload_fn, rump_compload_fn, 238 rump_evcntattach_fn); 239 240/* 241 * misc management 242 */ 243 244int rumpuser_daemonize_begin(void); 245int rumpuser_daemonize_done(int); 246 247#if defined(_RUMP_SYSPROXY) || defined(LIBRUMPUSER) 248/* 249 * syscall proxy 250 */ 251 252int rumpuser_sp_init(const char *, 253 const char *, const char *, const char *); 254int rumpuser_sp_copyin(void *, const void *, void *, size_t); 255int rumpuser_sp_copyinstr(void *, const void *, void *, size_t *); 256int rumpuser_sp_copyout(void *, const void *, void *, size_t); 257int rumpuser_sp_copyoutstr(void *, const void *, void *, size_t *); 258int rumpuser_sp_anonmmap(void *, size_t, void **); 259int rumpuser_sp_raise(void *, int); 260void rumpuser_sp_fini(void *); 261#endif /* _RUMP_SYSPROXY || LIBRUMPUSER */ 262 263#endif /* _RUMP_RUMPUSER_H_ */ 264