Home | History | Annotate | Line # | Download | only in rump
      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