1*918835f5Slukem.\" $NetBSD: rumpuser.3,v 1.4 2023/07/14 23:21:53 lukem Exp $ 277e86260Spooka.\" 377e86260Spooka.\" Copyright (c) 2013 Antti Kantee. All rights reserved. 477e86260Spooka.\" 577e86260Spooka.\" Redistribution and use in source and binary forms, with or without 677e86260Spooka.\" modification, are permitted provided that the following conditions 777e86260Spooka.\" are met: 877e86260Spooka.\" 1. Redistributions of source code must retain the above copyright 977e86260Spooka.\" notice, this list of conditions and the following disclaimer. 1077e86260Spooka.\" 2. Redistributions in binary form must reproduce the above copyright 1177e86260Spooka.\" notice, this list of conditions and the following disclaimer in the 1277e86260Spooka.\" documentation and/or other materials provided with the distribution. 1377e86260Spooka.\" 1477e86260Spooka.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1577e86260Spooka.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1677e86260Spooka.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1777e86260Spooka.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1877e86260Spooka.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1977e86260Spooka.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2077e86260Spooka.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2177e86260Spooka.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2277e86260Spooka.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2377e86260Spooka.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2477e86260Spooka.\" SUCH DAMAGE. 2577e86260Spooka.\" 26*918835f5Slukem.Dd July 15, 2023 2777e86260Spooka.Dt RUMPUSER 3 2877e86260Spooka.Os 2977e86260Spooka.Sh NAME 3077e86260Spooka.Nm rumpuser 3177e86260Spooka.Nd rump kernel hypercall interface 3277e86260Spooka.Sh LIBRARY 3377e86260Spookarump User Library (librumpuser, \-lrumpuser) 3477e86260Spooka.Sh SYNOPSIS 3577e86260Spooka.In rump/rumpuser.h 3677e86260Spooka.Sh DESCRIPTION 3777e86260SpookaThe 3877e86260Spooka.Nm 3977e86260Spookahypercall interfaces allow a rump kernel to access host resources. 4077e86260SpookaA hypervisor implementation must implement the routines described in 4177e86260Spookathis document to allow a rump kernel to run on the host. 4277e86260SpookaThe implementation included in 4377e86260Spooka.Nx 4477e86260Spookais for POSIX-like hosts (*BSD, Linux, etc.). 4577e86260SpookaThis document is divided into sections based on the functionality 4677e86260Spookagroup of each hypercall. 4777e86260Spooka.Pp 4877e86260SpookaSince the hypercall interface is a C function interface, both the 4977e86260Spookarump kernel and the hypervisor must conform to the same ABI. 5077e86260SpookaThe interface itself attempts to assume as little as possible from 5177e86260Spookathe type systems, and for example 5277e86260Spooka.Vt off_t 5377e86260Spookais passed as 5477e86260Spooka.Vt int64_t 5577e86260Spookaand enums are passed as ints. 5677e86260SpookaIt is recommended that the hypervisor converts these to the native 5777e86260Spookatypes before starting to process the hypercall, for example by 5877e86260Spookaassigning the ints back to enums. 5977e86260Spooka.Sh UPCALLS AND RUMP KERNEL CONTEXT 6077e86260SpookaA hypercall is always entered with the calling thread scheduled in 6177e86260Spookathe rump kernel. 6277e86260SpookaIn case the hypercall intends to block while waiting for an event, 6377e86260Spookathe hypervisor must first release the rump kernel scheduling context. 6477e86260SpookaIn other words, the rump kernel context is a resource and holding 6577e86260Spookaon to it while waiting for a rump kernel event/resource may lead 6677e86260Spookato a deadlock. 6777e86260SpookaEven when there is no possibility of deadlock in the strict sense 6877e86260Spookaof the term, holding on to the rump kernel context while performing 6977e86260Spookaa slow hypercall such as reading a device will prevent other threads 7077e86260Spooka(including the clock interrupt) from using that rump kernel context. 7177e86260Spooka.Pp 7277e86260SpookaReleasing the context is done by calling the 7377e86260Spooka.Fn hyp_backend_unschedule 7477e86260Spookaupcall which the hypervisor received from rump kernel as a parameter 7577e86260Spookafor 7677e86260Spooka.Fn rumpuser_init . 7777e86260SpookaBefore a hypercall returns back to the rump kernel, the returning thread 7877e86260Spookamust carry a rump kernel context. 7977e86260SpookaIn case the hypercall unscheduled itself, it must reschedule itself 8077e86260Spookaby calling 8177e86260Spooka.Fn hyp_backend_schedule . 8277e86260Spooka.Sh HYPERCALL INTERFACES 8377e86260Spooka.Ss Initialization 8477e86260Spooka.Ft int 8577e86260Spooka.Fn rumpuser_init "int version" "struct rump_hyperup *hyp" 8677e86260Spooka.Pp 8777e86260SpookaInitialize the hypervisor. 8877e86260Spooka.Bl -tag -width "xenum_rumpclock" 8977e86260Spooka.It Fa version 9077e86260Spookahypercall interface version number that the kernel expects to be used. 9177e86260SpookaIn case the hypervisor cannot provide an exact match, this routine must 9277e86260Spookareturn a non-zero value. 9377e86260Spooka.It Fa hyp 9477e86260Spookapointer to a set of upcalls the hypervisor can make into the rump kernel 9577e86260Spooka.El 9677e86260Spooka.Ss Memory allocation 9777e86260Spooka.Ft int 9877e86260Spooka.Fn rumpuser_malloc "size_t len" "int alignment" "void **memp" 9977e86260Spooka.Bl -tag -width "xenum_rumpclock" 10077e86260Spooka.It Fa len 10177e86260Spookaamount of memory to allocate 10277e86260Spooka.It Fa alignment 10377e86260Spookasize the returned memory must be aligned to. 10477e86260SpookaFor example, if the value passed is 4096, the returned memory 10577e86260Spookamust be aligned to a 4k boundary. 10677e86260Spooka.It Fa memp 10777e86260Spookareturn pointer for allocated memory 10877e86260Spooka.El 10977e86260Spooka.Pp 11077e86260Spooka.Ft void 11177e86260Spooka.Fn rumpuser_free "void *mem" "size_t len" 11277e86260Spooka.Bl -tag -width "xenum_rumpclock" 11377e86260Spooka.It Fa mem 11477e86260Spookamemory to free 11577e86260Spooka.It Fa len 11677e86260Spookalength of allocation. 11777e86260SpookaThis is always equal to the amount the caller requested from the 11877e86260Spooka.Fn rumpuser_malloc 11977e86260Spookawhich returned 12077e86260Spooka.Fa mem . 12177e86260Spooka.El 12277e86260Spooka.Ss Files and I/O 12377e86260Spooka.Ft int 12477e86260Spooka.Fn rumpuser_open "const char *name" "int mode" "int *fdp" 12577e86260Spooka.Pp 12677e86260SpookaOpen 12777e86260Spooka.Fa name 12877e86260Spookafor I/O and associate a file descriptor with it. 12977e86260SpookaNotably, there needs to be no mapping between 13077e86260Spooka.Fa name 13177e86260Spookaand the host's file system namespace. 13277e86260SpookaFor example, it is possible to associate the file descriptor with 13377e86260Spookadevice I/O registers for special values of 13477e86260Spooka.Fa name . 13577e86260Spooka.Bl -tag -width "xenum_rumpclock" 13677e86260Spooka.It Fa name 13777e86260Spookathe identifier of the file to open for I/O 13877e86260Spooka.It Fa mode 13977e86260Spookacombination of the following: 14077e86260Spooka.Bl -tag -width "XRUMPUSER_OPEN_CREATE" 14177e86260Spooka.It Dv RUMPUSER_OPEN_RDONLY 14277e86260Spookaopen only for reading 14377e86260Spooka.It Dv RUMPUSER_OPEN_WRONLY 14477e86260Spookaopen only for writing 14577e86260Spooka.It Dv RUMPUSER_OPEN_RDWR 14677e86260Spookaopen for reading and writing 14777e86260Spooka.It Dv RUMPUSER_OPEN_CREATE 14877e86260Spookado not treat missing 14977e86260Spooka.Fa name 15077e86260Spookaas an error 15177e86260Spooka.It Dv RUMPUSER_OPEN_EXCL 15277e86260Spookacombined with 15377e86260Spooka.Dv RUMPUSER_OPEN_CREATE , 15477e86260Spookaflag an error if 15577e86260Spooka.Fa name 15677e86260Spookaalready exists 15777e86260Spooka.It Dv RUMPUSER_OPEN_BIO 15877e86260Spookathe caller will use this file for block I/O, usually used in 15977e86260Spookaconjunction with accessing file system media. 16077e86260SpookaThe hypervisor should treat this flag as advisory and possibly 16177e86260Spookaenable some optimizations for 16277e86260Spooka.Fa *fdp 16377e86260Spookabased on it. 16477e86260Spooka.El 16577e86260SpookaNotably, the permissions of the created file are left up to the 16677e86260Spookahypervisor implementation. 16777e86260Spooka.It Fa fdp 16877e86260SpookaAn integer value denoting the open file is returned here. 16977e86260Spooka.El 17077e86260Spooka.Pp 17177e86260Spooka.Ft int 17277e86260Spooka.Fn rumpuser_close "int fd" 17377e86260Spooka.Pp 17477e86260SpookaClose a previously opened file descriptor. 17577e86260Spooka.Pp 17677e86260Spooka.Ft int 17777e86260Spooka.Fn rumpuser_getfileinfo "const char *name" "uint64_t *size" "int *type" 17877e86260Spooka.Bl -tag -width "xenum_rumpclock" 17977e86260Spooka.It Fa name 18077e86260Spookafile for which information is returned. 18177e86260SpookaThe namespace is equal to that of 18277e86260Spooka.Fn rumpuser_open . 18377e86260Spooka.It Fa size 18477e86260SpookaIf 18577e86260Spooka.Pf non- Dv NULL , 18677e86260Spookasize of the file is returned here. 18777e86260Spooka.It Fa type 18877e86260SpookaIf 18977e86260Spooka.Pf non- Dv NULL , 19077e86260Spookatype of the file is returned here. 19177e86260SpookaThe options are 19277e86260Spooka.Dv RUMPUSER_FT_DIR , 19377e86260Spooka.Dv RUMPUSER_FT_REG , 19477e86260Spooka.Dv RUMPUSER_FT_BLK , 19577e86260Spooka.Dv RUMPUSER_FT_CHR , 19677e86260Spookaor 19777e86260Spooka.Dv RUMPUSER_FT_OTHER 19877e86260Spookafor directory, regular file, block device, character device or unknown, 19977e86260Spookarespectively. 20077e86260Spooka.El 20177e86260Spooka.Pp 20277e86260Spooka.Ft void 20377e86260Spooka.Fo rumpuser_bio 20477e86260Spooka.Fa "int fd" "int op" "void *data" "size_t dlen" "int64_t off" 20577e86260Spooka.Fa "rump_biodone_fn biodone" "void *donearg" 20677e86260Spooka.Fc 20777e86260Spooka.Pp 20877e86260SpookaInitiate block I/O and return immediately. 20977e86260Spooka.Bl -tag -width "xenum_rumpclock" 21077e86260Spooka.It Fa fd 21177e86260Spookaperform I/O on this file descriptor. 21277e86260SpookaThe file descriptor must have been opened with 21377e86260Spooka.Dv RUMPUSER_OPEN_BIO . 21477e86260Spooka.It Fa op 21577e86260SpookaTransfer data from the file descriptor with 21677e86260Spooka.Dv RUMPUSER_BIO_READ 21777e86260Spookaand transfer data to the file descriptor with 21877e86260Spooka.Dv RUMPUSER_BIO_WRITE . 21977e86260SpookaUnless 22077e86260Spooka.Dv RUMPUSER_BIO_SYNC 22177e86260Spookais specified, the hypervisor may cache a write instead of 22277e86260Spookacommitting it to permanent storage. 22377e86260Spooka.It Fa data 22477e86260Spookamemory address to transfer data to/from 22577e86260Spooka.It Fa dlen 22677e86260Spookalength of I/O. 22777e86260SpookaThe length is guaranteed to be a multiple of 512. 22877e86260Spooka.It Fa off 22977e86260Spookaoffset into 23077e86260Spooka.Fa fd 23177e86260Spookawhere I/O is performed 23277e86260Spooka.It Fa biodone 23377e86260SpookaTo be called when the I/O is complete. 23477e86260SpookaAccessing 23577e86260Spooka.Fa data 23677e86260Spookais not legal after the call is made. 23777e86260Spooka.It Fa donearg 23877e86260Spookaopaque arg that must be passed to 23977e86260Spooka.Fa biodone . 24077e86260Spooka.El 24177e86260Spooka.Pp 24277e86260Spooka.Ft int 24377e86260Spooka.Fo rumpuser_iovread 24477e86260Spooka.Fa "int fd" "struct rumpuser_iovec *ruiov" "size_t iovlen" 24577e86260Spooka.Fa "int64_t off" "size_t *retv" 24677e86260Spooka.Fc 24777e86260Spooka.Pp 24877e86260Spooka.Ft int 24977e86260Spooka.Fo rumpuser_iovwrite 25077e86260Spooka.Fa "int fd" "struct rumpuser_iovec *ruiov" "size_t iovlen" 25177e86260Spooka.Fa "int64_t off" "size_t *retv" 25277e86260Spooka.Fc 25377e86260Spooka.Pp 25477e86260SpookaThese routines perform scatter-gather I/O which is not 25577e86260Spookablock I/O by nature and therefore cannot be handled by 25677e86260Spooka.Fn rumpuser_bio . 25777e86260Spooka.Bl -tag -width "xenum_rumpclock" 25877e86260Spooka.It Fa fd 25977e86260Spookafile descriptor to perform I/O on 26077e86260Spooka.It Fa ruiov 26177e86260Spookaan array of I/O descriptors. 26277e86260SpookaIt is defined as follows: 26377e86260Spooka.Bd -literal -offset indent -compact 26477e86260Spookastruct rumpuser_iovec { 26577e86260Spooka void *iov_base; 26677e86260Spooka size_t iov_len; 26777e86260Spooka}; 26877e86260Spooka.Ed 26977e86260Spooka.It Fa iovlen 27077e86260Spookanumber of elements in 27177e86260Spooka.Fa ruiov 27277e86260Spooka.It Fa off 27377e86260Spookaoffset of 27477e86260Spooka.Fa fd 27577e86260Spookato perform I/O on. 27677e86260SpookaThis can either be a non-negative value or 27777e86260Spooka.Dv RUMPUSER_IOV_NOSEEK . 27877e86260SpookaThe latter denotes that no attempt to change the underlying objects 27977e86260Spookaoffset should be made. 28077e86260SpookaUsing both types of offsets on a single instance of 28177e86260Spooka.Fa fd 28277e86260Spookaresults in undefined behavior. 28377e86260Spooka.It Fa retv 28477e86260Spookanumber of bytes successfully transferred is returned here 28577e86260Spooka.El 28677e86260Spooka.Pp 28777e86260Spooka.Ft int 28877e86260Spooka.Fo rumpuser_syncfd 28977e86260Spooka.Fa "int fd" "int flags" "uint64_t start" "uint64_t len" 29077e86260Spooka.Fc 29177e86260Spooka.Pp 29277e86260SpookaSynchronizes 29377e86260Spooka.Fa fd 29477e86260Spookawith respect to backing storage. 29577e86260SpookaThe other arguments are: 29677e86260Spooka.Bl -tag -width "xenum_rumpclock" 29777e86260Spooka.It Fa flags 29877e86260Spookacontrols how synchronization happens. 29977e86260SpookaIt must contain one of the following: 30077e86260Spooka.Bl -tag -width "XRUMPUSER_SYNCFD_BARRIER" 30177e86260Spooka.It Dv RUMPUSER_SYNCFD_READ 30277e86260SpookaMake sure that the next read sees writes from all other parties. 30377e86260SpookaThis is useful for example in the case that 30477e86260Spooka.Fa fd 30577e86260Spookarepresents memory to write a DMA read is being performed. 30677e86260Spooka.It Dv RUMPUSER_SYNCFD_WRITE 30777e86260SpookaFlush cached writes. 30877e86260Spooka.El 30977e86260Spooka.Pp 31077e86260SpookaThe following additional parameters may be passed in 31177e86260Spooka.Fa flags : 31277e86260Spooka.Bl -tag -width "XRUMPUSER_SYNCFD_BARRIER" 31377e86260Spooka.It Dv RUMPUSER_SYNCFD_BARRIER 31477e86260SpookaIssue a barrier. 31577e86260SpookaOutstanding I/O operations which were started before the barrier 31677e86260Spookacomplete before any operations after the barrier are performed. 31777e86260Spooka.It Dv RUMPUSER_SYNCFD_SYNC 31877e86260SpookaWait for the synchronization operation to fully complete before 31977e86260Spookareturning. 32077e86260SpookaFor example, this could mean that the data to be written to a disk 32177e86260Spookahas hit either the disk or non-volatile memory. 32277e86260Spooka.El 32377e86260Spooka.It Fa start 32477e86260Spookaoffset into the object. 32577e86260Spooka.It Fa len 32677e86260Spookathe number of bytes to synchronize. 32777e86260SpookaThe value 0 denotes until the end of the object. 32877e86260Spooka.El 32977e86260Spooka.Ss Clocks 33077e86260SpookaThe hypervisor should support two clocks, one for wall time and one 33177e86260Spookafor monotonically increasing time, the latter of which may be based 33277e86260Spookaon some arbitrary time (e.g. system boot time). 33377e86260SpookaIf this is not possible, the hypervisor must make a reasonable effort to 33477e86260Spookaretain semantics. 33577e86260Spooka.Pp 33677e86260Spooka.Ft int 33777e86260Spooka.Fn rumpuser_clock_gettime "int enum_rumpclock" "int64_t *sec" "long *nsec" 33877e86260Spooka.Bl -tag -width "xenum_rumpclock" 33977e86260Spooka.It Fa enum_rumpclock 34077e86260Spookaspecifies the clock type. 34177e86260SpookaIn case of 34277e86260Spooka.Dv RUMPUSER_CLOCK_RELWALL 34377e86260Spookathe wall time should be returned. 34477e86260SpookaIn case of 34577e86260Spooka.Dv RUMPUSER_CLOCK_ABSMONO 34677e86260Spookathe time of a monotonic clock should be returned. 34777e86260Spooka.It Fa sec 34877e86260Spookareturn value for seconds 34977e86260Spooka.It Fa nsec 35077e86260Spookareturn value for nanoseconds 35177e86260Spooka.El 35277e86260Spooka.Pp 35377e86260Spooka.Ft int 35477e86260Spooka.Fn rumpuser_clock_sleep "int enum_rumpclock" "int64_t sec" "long nsec" 35577e86260Spooka.Bl -tag -width "xenum_rumpclock" 35677e86260Spooka.It Fa enum_rumpclock 35777e86260SpookaIn case of 35877e86260Spooka.Dv RUMPUSER_CLOCK_RELWALL , 35977e86260Spookathe sleep should last at least as long as specified. 36077e86260SpookaIn case of 36177e86260Spooka.Dv RUMPUSER_CLOCK_ABSMONO , 36277e86260Spookathe sleep should last until the hypervisor monotonic clock hits 36377e86260Spookathe specified absolute time. 36477e86260Spooka.It Fa sec 36577e86260Spookasleep duration, seconds. 36677e86260Spookaexact semantics depend on 36777e86260Spooka.Fa clk . 36877e86260Spooka.It Fa nsec 36977e86260Spookasleep duration, nanoseconds. 37077e86260Spookaexact semantics depend on 37177e86260Spooka.Fa clk . 37277e86260Spooka.El 37377e86260Spooka.Ss Parameter retrieval 37477e86260Spooka.Ft int 37577e86260Spooka.Fn rumpuser_getparam "const char *name" "void *buf" "size_t buflen" 37677e86260Spooka.Pp 37777e86260SpookaRetrieve a configuration parameter from the hypervisor. 37877e86260SpookaIt is up to the hypervisor to decide how the parameters can be set. 37977e86260Spooka.Bl -tag -width "xenum_rumpclock" 38077e86260Spooka.It Fa name 38177e86260Spookaname of the parameter. 38277e86260SpookaIf the name starts with an underscore, it means a mandatory parameter. 38377e86260SpookaThe mandatory parameters are 38477e86260Spooka.Dv RUMPUSER_PARAM_NCPU 38577e86260Spookawhich specifies the amount of virtual CPUs bootstrapped by the 38677e86260Spookarump kernel and 38777e86260Spooka.Dv RUMPUSER_PARAM_HOSTNAME 38877e86260Spookawhich returns a preferably unique instance name for the rump kernel. 38977e86260Spooka.It Fa buf 39077e86260Spookabuffer to return the data in as a string 39177e86260Spooka.It Fa buflen 39277e86260Spookalength of buffer 39377e86260Spooka.El 39477e86260Spooka.Ss Termination 39577e86260Spooka.Ft void 39677e86260Spooka.Fn rumpuser_exit "int value" 39777e86260Spooka.Pp 39877e86260SpookaTerminate the rump kernel with exit value 39977e86260Spooka.Fa value . 40077e86260SpookaIf 40177e86260Spooka.Fa value 40277e86260Spookais 40377e86260Spooka.Dv RUMPUSER_PANIC 40477e86260Spookathe hypervisor should attempt to provide something akin to a core dump. 40577e86260Spooka.Ss Console output 40677e86260SpookaConsole output is divided into two routines: a per-character 40777e86260Spookaone and printf-like one. 40877e86260SpookaThe former is used e.g. by the rump kernel's internal printf 40977e86260Spookaroutine. 41077e86260SpookaThe latter can be used for direct debug prints e.g. very early 41177e86260Spookaon in the rump kernel's bootstrap or when using the in-kernel 41277e86260Spookaroutine causes too much skew in the debug print results 41377e86260Spooka(the hypercall runs outside of the rump kernel and therefore does not 41477e86260Spookacause any locking or scheduling events inside the rump kernel). 41577e86260Spooka.Pp 41677e86260Spooka.Ft void 41777e86260Spooka.Fn rumpuser_putchar "int ch" 41877e86260Spooka.Pp 41977e86260SpookaOutput 42077e86260Spooka.Fa ch 42177e86260Spookaon the console. 42277e86260Spooka.Pp 42377e86260Spooka.Ft void 42477e86260Spooka.Fn rumpuser_dprintf "const char *fmt" "..." 42577e86260Spooka.Pp 42677e86260SpookaDo output based on printf-like parameters. 42777e86260Spooka.Ss Signals 42877e86260SpookaA rump kernel should be able to send signals to client programs 42977e86260Spookadue to some standard interfaces including signal delivery in their 43077e86260Spookaspecifications. 43177e86260SpookaExamples of these interfaces include 43277e86260Spooka.Xr setitimer 2 43377e86260Spookaand 43477e86260Spooka.Xr write 2 . 43577e86260SpookaThe 43677e86260Spooka.Fn rumpuser_kill 43777e86260Spookafunction advises the hypercall implementation to raise a signal for the 43877e86260Spookaprocess containing the rump kernel. 43977e86260Spooka.Pp 44077e86260Spooka.Ft int 44177e86260Spooka.Fn rumpuser_kill "int64_t pid" "int sig" 44277e86260Spooka.Bl -tag -width "xenum_rumpclock" 44377e86260Spooka.It Fa pid 44477e86260SpookaThe pid of the rump kernel process that the signal is directed to. 44577e86260SpookaThis value may be used as the hypervisor as a hint on how to deliver 44677e86260Spookathe signal. 44777e86260SpookaThe value 44877e86260Spooka.Dv RUMPUSER_PID_SELF 44977e86260Spookamay also be specified to indicate no hint. 45077e86260SpookaThis value will be removed in a future version of the hypercall interface. 45177e86260Spooka.It Fa sig 45277e86260SpookaNumber of signal to raise. 4538cbebd41SwizThe value is in 4548cbebd41Swiz.Nx 4558cbebd41Swizsignal number namespace. 45677e86260SpookaIn case the host has a native representation for signals, the 45777e86260Spookavalue should be translated before the signal is raised. 45877e86260SpookaIn case there is no mapping between 45977e86260Spooka.Fa sig 46077e86260Spookaand native signals (if any), the behavior is implementation-defined. 46177e86260Spooka.El 46277e86260Spooka.Pp 46377e86260SpookaA rump kernel will ignore the return value of this hypercall. 46477e86260SpookaThe only implication of not implementing 46577e86260Spooka.Fn rumpuser_kill 46677e86260Spookais that some application programs may not experience expected behavior 46777e86260Spookafor standard interfaces. 46877e86260Spooka.Pp 46977e86260SpookaAs an aside,the 47077e86260Spooka.Xr rump_sp 7 47177e86260Spookaprotocol provides equivalent functionality for remote clients. 47277e86260Spooka.Ss Random pool 47377e86260Spooka.Ft int 47477e86260Spooka.Fn rumpuser_getrandom "void *buf" "size_t buflen" "int flags" "size_t *retp" 47577e86260Spooka.Bl -tag -width "xenum_rumpclock" 47677e86260Spooka.It Fa buf 47777e86260Spookabuffer that the randomness is written to 47877e86260Spooka.It Fa buflen 47977e86260Spookanumber of bytes of randomness requested 48077e86260Spooka.It Fa flags 48177e86260SpookaThe value 0 or a combination of 48277e86260Spooka.Dv RUMPUSER_RANDOM_HARD 48377e86260Spooka(return true randomness instead of something from a PRNG) 48477e86260Spookaand 48577e86260Spooka.Dv RUMPUSER_RANDOM_NOWAIT 48677e86260Spooka(do not block in case the requested amount of bytes is not available). 48777e86260Spooka.It Fa retp 48877e86260SpookaThe number of random bytes written into 48977e86260Spooka.Fa buf . 49077e86260Spooka.El 49177e86260Spooka.Ss Threads 49277e86260Spooka.Ft int 49377e86260Spooka.Fo rumpuser_thread_create 49477e86260Spooka.Fa "void *(*fun)(void *)" "void *arg" "const char *thrname" "int mustjoin" 49577e86260Spooka.Fa "int priority" "int cpuidx" "void **cookie" 49677e86260Spooka.Fc 49777e86260Spooka.Pp 49877e86260SpookaCreate a schedulable host thread context. 49977e86260SpookaThe rump kernel will call this interface when it creates a kernel thread. 50077e86260SpookaThe scheduling policy for the new thread is defined by the hypervisor. 50177e86260SpookaIn case the hypervisor wants to optimize the scheduling of the 50277e86260Spookathreads, it can perform heuristics on the 50377e86260Spooka.Fa thrname , 50477e86260Spooka.Fa priority 50577e86260Spookaand 50677e86260Spooka.Fa cpuidx 50777e86260Spookaparameters. 50877e86260Spooka.Bl -tag -width "xenum_rumpclock" 50977e86260Spooka.It Fa fun 51077e86260Spookafunction that the new thread must call. 51177e86260SpookaThis call will never return. 51277e86260Spooka.It Fa arg 51377e86260Spookaargument to be passed to 51477e86260Spooka.Fa fun 51577e86260Spooka.It Fa thrname 51677e86260SpookaName of the new thread. 51777e86260Spooka.It Fa mustjoin 51877e86260SpookaIf 1, the thread will be waited for by 51977e86260Spooka.Fn rumpuser_thread_join 52077e86260Spookawhen the thread exits. 52177e86260Spooka.It Fa priority 52277e86260SpookaThe priority that the kernel requested the thread to be created at. 52377e86260SpookaHigher values mean higher priority. 52477e86260SpookaThe exact kernel semantics for each value are not available through 52577e86260Spookathis interface. 52677e86260Spooka.It Fa cpuidx 52777e86260SpookaThe index of the virtual CPU that the thread is bound to, or \-1 52877e86260Spookaif the thread is not bound. 52977e86260SpookaThe mapping between the virtual CPUs and physical CPUs, if any, 53077e86260Spookais hypervisor implementation specific. 53177e86260Spooka.It Fa cookie 53277e86260SpookaIn case 53377e86260Spooka.Fa mustjoin 53477e86260Spookais set, the value returned in 53577e86260Spooka.Fa cookie 53677e86260Spookawill be passed to 53777e86260Spooka.Fn rumpuser_thread_join . 53877e86260Spooka.El 53977e86260Spooka.Pp 54077e86260Spooka.Ft void 54177e86260Spooka.Fn rumpuser_thread_exit "void" 54277e86260Spooka.Pp 54377e86260SpookaCalled when a thread created with 54477e86260Spooka.Fn rumpuser_thread_create 54577e86260Spookaexits. 54677e86260Spooka.Pp 54777e86260Spooka.Ft int 54877e86260Spooka.Fn rumpuser_thread_join "void *cookie" 54977e86260Spooka.Pp 55077e86260SpookaWait for a joinable thread to exit. 55177e86260SpookaThe cookie matches the value from 55277e86260Spooka.Fn rumpuser_thread_create . 55377e86260Spooka.Pp 55477e86260Spooka.Ft void 55577e86260Spooka.Fn rumpuser_curlwpop "int enum_rumplwpop" "struct lwp *l" 55677e86260Spooka.Pp 55777e86260SpookaManipulate the hypervisor's thread context database. 55877e86260SpookaThe possible operations are create, destroy, and set as specified by 55977e86260Spooka.Fa enum_rumplwpop : 56077e86260Spooka.Bl -tag -width "XRUMPUSER_LWP_DESTROY" 56177e86260Spooka.It Dv RUMPUSER_LWP_CREATE 56277e86260SpookaInform the hypervisor that 56377e86260Spooka.Fa l 56477e86260Spookais now a valid thread context which may be set. 56577e86260SpookaA currently valid value of 56677e86260Spooka.Fa l 56777e86260Spookamay not be specified. 56877e86260SpookaThis operation is informational and does not mandate any action 56977e86260Spookafrom the hypervisor. 57077e86260Spooka.It Dv RUMPUSER_LWP_DESTROY 57177e86260SpookaInform the hypervisor that 57277e86260Spooka.Fa l 57377e86260Spookais no longer a valid thread context. 57477e86260SpookaThis means that it may no longer be set as the current context. 57577e86260SpookaA currently set context or an invalid one may not be destroyed. 57677e86260SpookaThis operation is informational and does not mandate any action 57777e86260Spookafrom the hypervisor. 57877e86260Spooka.It Dv RUMPUSER_LWP_SET 57977e86260SpookaSet 58077e86260Spooka.Fa l 58177e86260Spookaas the current host thread's rump kernel context. 58277e86260SpookaA previous context must not exist. 58377e86260Spooka.It Dv RUMPUSER_LWP_CLEAR 58477e86260SpookaClear the context previous set by 58577e86260Spooka.Dv RUMPUSER_LWP_SET . 58677e86260SpookaThe value passed in 58777e86260Spooka.Fa l 58877e86260Spookais the current thread and is never 58977e86260Spooka.Dv NULL . 59077e86260Spooka.El 59177e86260Spooka.Pp 59277e86260Spooka.Ft struct lwp * 59377e86260Spooka.Fn rumpuser_curlwp "void" 59477e86260Spooka.Pp 59577e86260SpookaRetrieve the rump kernel thread context associated with the current host 59677e86260Spookathread, as set by 59777e86260Spooka.Fn rumpuser_curlwpop . 59877e86260SpookaThis routine may be called when a context is not set and 59977e86260Spookathe routine must return 60077e86260Spooka.Dv NULL 60177e86260Spookain that case. 60277e86260SpookaThis interface is expected to be called very often. 60377e86260SpookaAny optimizations pertaining to the execution speed of this routine 60477e86260Spookashould be done in 60577e86260Spooka.Fn rumpuser_curlwpop . 60677e86260Spooka.Pp 60777e86260Spooka.Ft void 60877e86260Spooka.Fn rumpuser_seterrno "int errno" 60977e86260Spooka.Pp 61077e86260SpookaSet an errno value in the calling thread's TLS. 61177e86260SpookaNote: this is used only if rump kernel clients make rump system calls. 61277e86260Spooka.Ss Mutexes, rwlocks and condition variables 61377e86260SpookaThe locking interfaces have standard semantics, so we will not 61477e86260Spookadiscuss each one in detail. 61577e86260SpookaThe data types 61677e86260Spooka.Vt struct rumpuser_mtx , 61777e86260Spooka.Vt struct rumpuser_rw 61877e86260Spookaand 61977e86260Spooka.Vt struct rumpuser_cv 62077e86260Spookaused by these interfaces are opaque to the rump kernel, i.e. the 62177e86260Spookahypervisor has complete freedom over them. 62277e86260Spooka.Pp 62377e86260SpookaMost of these interfaces will (and must) relinquish the rump kernel 62477e86260SpookaCPU context in case they block (or intend to block). 62577e86260SpookaThe exceptions are the "nowrap" variants of the interfaces which 62677e86260Spookamay not relinquish rump kernel context. 62777e86260Spooka.Pp 62877e86260Spooka.Ft void 62977e86260Spooka.Fn rumpuser_mutex_init "struct rumpuser_mtx **mtxp" "int flags" 63077e86260Spooka.Pp 63177e86260Spooka.Ft void 63277e86260Spooka.Fn rumpuser_mutex_enter "struct rumpuser_mtx *mtx" 63377e86260Spooka.Pp 63477e86260Spooka.Ft void 63577e86260Spooka.Fn rumpuser_mutex_enter_nowrap "struct rumpuser_mtx *mtx" 63677e86260Spooka.Pp 63777e86260Spooka.Ft int 63877e86260Spooka.Fn rumpuser_mutex_tryenter "struct rumpuser_mtx *mtx" 63977e86260Spooka.Pp 64077e86260Spooka.Ft void 64177e86260Spooka.Fn rumpuser_mutex_exit "struct rumpuser_mtx *mtx" 64277e86260Spooka.Pp 64377e86260Spooka.Ft void 64477e86260Spooka.Fn rumpuser_mutex_destroy "struct rumpuser_mtx *mtx" 64577e86260Spooka.Pp 64677e86260Spooka.Ft void 64777e86260Spooka.Fn rumpuser_mutex_owner "struct rumpuser_mtx *mtx" "struct lwp **lp" 64877e86260Spooka.Pp 64977e86260SpookaMutexes provide mutually exclusive locking. 65077e86260SpookaThe flags, of which at least one must be given, are as follows: 65177e86260Spooka.Bl -tag -width "XRUMPUSER_MTX_KMUTEX" 65277e86260Spooka.It Dv RUMPUSER_MTX_SPIN 65377e86260SpookaCreate a spin mutex. 65477e86260SpookaLocking this type of mutex must not relinquish rump kernel context 65577e86260Spookaeven when 65677e86260Spooka.Fn rumpuser_mutex_enter 65777e86260Spookais used. 65877e86260Spooka.It Dv RUMPUSER_MTX_KMUTEX 65977e86260SpookaThe mutex must track and be able to return the rump kernel thread 66077e86260Spookathat owns the mutex (if any). 66177e86260SpookaIf this flag is not specified, 66277e86260Spooka.Fn rumpuser_mutex_owner 66377e86260Spookawill never be called for that particular mutex. 66477e86260Spooka.El 66577e86260Spooka.Pp 66677e86260Spooka.Ft void 66777e86260Spooka.Fn rumpuser_rw_init "struct rumpuser_rw **rwp" 66877e86260Spooka.Pp 66977e86260Spooka.Ft void 67077e86260Spooka.Fn rumpuser_rw_enter "int enum_rumprwlock" "struct rumpuser_rw *rw" 67177e86260Spooka.Pp 67277e86260Spooka.Ft int 67377e86260Spooka.Fn rumpuser_rw_tryenter "int enum_rumprwlock" "struct rumpuser_rw *rw" 67477e86260Spooka.Pp 67577e86260Spooka.Ft int 67677e86260Spooka.Fn rumpuser_rw_tryupgrade "struct rumpuser_rw *rw" 67777e86260Spooka.Pp 67877e86260Spooka.Ft void 67977e86260Spooka.Fn rumpuser_rw_downgrade "struct rumpuser_rw *rw" 68077e86260Spooka.Pp 68177e86260Spooka.Ft void 68277e86260Spooka.Fn rumpuser_rw_exit "struct rumpuser_rw *rw" 68377e86260Spooka.Pp 68477e86260Spooka.Ft void 68577e86260Spooka.Fn rumpuser_rw_destroy "struct rumpuser_rw *rw" 68677e86260Spooka.Pp 68777e86260Spooka.Ft void 68877e86260Spooka.Fo rumpuser_rw_held 68977e86260Spooka.Fa "int enum_rumprwlock" "struct rumpuser_rw *rw" "int *heldp" 69077e86260Spooka.Fc 69177e86260Spooka.Pp 69277e86260SpookaRead/write locks provide either shared or exclusive locking. 69377e86260SpookaThe possible values for 69477e86260Spooka.Fa lk 69577e86260Spookaare 69677e86260Spooka.Dv RUMPUSER_RW_READER 69777e86260Spookaand 69877e86260Spooka.Dv RUMPUSER_RW_WRITER . 69977e86260SpookaUpgrading means trying to migrate from an already owned shared 70077e86260Spookalock to an exclusive lock and downgrading means migrating from 70177e86260Spookaan already owned exclusive lock to a shared lock. 70277e86260Spooka.Pp 70377e86260Spooka.Ft void 70477e86260Spooka.Fn rumpuser_cv_init "struct rumpuser_cv **cvp" 70577e86260Spooka.Pp 70677e86260Spooka.Ft void 70777e86260Spooka.Fn rumpuser_cv_destroy "struct rumpuser_cv *cv" 70877e86260Spooka.Pp 70977e86260Spooka.Ft void 71077e86260Spooka.Fn rumpuser_cv_wait "struct rumpuser_cv *cv" "struct rumpuser_mtx *mtx" 71177e86260Spooka.Pp 71277e86260Spooka.Ft void 71377e86260Spooka.Fn rumpuser_cv_wait_nowrap "struct rumpuser_cv *cv" "struct rumpuser_mtx *mtx" 71477e86260Spooka.Pp 71577e86260Spooka.Ft int 71677e86260Spooka.Fo rumpuser_cv_timedwait 71777e86260Spooka.Fa "struct rumpuser_cv *cv" "struct rumpuser_mtx *mtx" 71877e86260Spooka.Fa "int64_t sec" "int64_t nsec" 71977e86260Spooka.Fc 72077e86260Spooka.Pp 72177e86260Spooka.Ft void 72277e86260Spooka.Fn rumpuser_cv_signal "struct rumpuser_cv *cv" 72377e86260Spooka.Pp 72477e86260Spooka.Ft void 72577e86260Spooka.Fn rumpuser_cv_broadcast "struct rumpuser_cv *cv" 72677e86260Spooka.Pp 72777e86260Spooka.Ft void 72877e86260Spooka.Fn rumpuser_cv_has_waiters "struct rumpuser_cv *cv" "int *waitersp" 72977e86260Spooka.Pp 73077e86260SpookaCondition variables wait for an event. 73177e86260SpookaThe 73277e86260Spooka.Fa mtx 73377e86260Spookainterlock eliminates a race between checking the predicate and 73477e86260Spookasleeping on the condition variable; the mutex should be released 73577e86260Spookafor the duration of the sleep in the normal atomic manner. 73677e86260SpookaThe timedwait variant takes a specifier indicating a relative 73777e86260Spookasleep duration after which the routine will return with 73877e86260Spooka.Er ETIMEDOUT . 73977e86260SpookaIf a timedwait is signaled before the timeout expires, the 74077e86260Spookaroutine will return 0. 74177e86260Spooka.Pp 74277e86260SpookaThe order in which the hypervisor 74377e86260Spookareacquires the rump kernel context and interlock mutex before 74477e86260Spookareturning into the rump kernel is as follows. 74577e86260SpookaIn case the interlock mutex was initialized with both 74677e86260Spooka.Dv RUMPUSER_MTX_SPIN 74777e86260Spookaand 74877e86260Spooka.Dv RUMPUSER_MTX_KMUTEX , 74977e86260Spookathe rump kernel context is scheduled before the mutex is reacquired. 75077e86260SpookaIn case of a purely 75177e86260Spooka.Dv RUMPUSER_MTX_SPIN 75277e86260Spookamutex, the mutex is acquired first. 75377e86260SpookaIn the final case the order is implementation-defined. 75477e86260Spooka.Sh RETURN VALUES 75577e86260SpookaAll routines which return an integer return an errno value. 756c2f2b1bfSmsaitohThe hypervisor must translate the value to the native errno 75777e86260Spookanamespace used by the rump kernel. 75877e86260SpookaRoutines which do not return an integer may never fail. 75977e86260Spooka.Sh SEE ALSO 76077e86260Spooka.Xr rump 3 76177e86260Spooka.Rs 76277e86260Spooka.%A Antti Kantee 76377e86260Spooka.%D 2012 76477e86260Spooka.%J Aalto University Doctoral Dissertations 76577e86260Spooka.%T Flexible Operating System Internals: The Design and Implementation of the Anykernel and Rump Kernels 76677e86260Spooka.%O Section 2.3.2: The Hypercall Interface 76777e86260Spooka.Re 76877e86260Spooka.Pp 76977e86260SpookaFor a list of all known implementations of the 77077e86260Spooka.Nm 77177e86260Spookainterface, see 772*918835f5Slukem.Lk https://github.com/rumpkernel/wiki/wiki/Platforms . 77377e86260Spooka.Sh HISTORY 77477e86260SpookaThe rump kernel hypercall API was first introduced in 77577e86260Spooka.Nx 5.0 . 77677e86260SpookaThe API described above first appeared in 77777e86260Spooka.Nx 7.0 . 778