xref: /netbsd-src/sys/rump/share/man/man3/rumpuser.3 (revision 918835f5c686a7f0379246d8b9f47d768fe512eb)
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