nrelease - fix/improve livecd
[dragonfly.git] / lib / libnvmm / libnvmm.3
1 .\"
2 .\" Copyright (c) 2018-2021 Maxime Villard, m00nbsd.net
3 .\" All rights reserved.
4 .\"
5 .\" This code is part of the NVMM hypervisor.
6 .\"
7 .\" Redistribution and use in source and binary forms, with or without
8 .\" modification, are permitted provided that the following conditions
9 .\" are met:
10 .\" 1. Redistributions of source code must retain the above copyright
11 .\"    notice, this list of conditions and the following disclaimer.
12 .\" 2. Redistributions in binary form must reproduce the above copyright
13 .\"    notice, this list of conditions and the following disclaimer in the
14 .\"    documentation and/or other materials provided with the distribution.
15 .\"
16 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 .\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 .\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 .\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 .\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 .\" SUCH DAMAGE.
27 .\"
28 .Dd July 20, 2021
29 .Dt LIBNVMM 3
30 .Os
31 .Sh NAME
32 .Nm libnvmm ,
33 .Nm nvmm_init ,
34 .Nm nvmm_capability ,
35 .Nm nvmm_machine_create ,
36 .Nm nvmm_machine_destroy ,
37 .Nm nvmm_machine_configure ,
38 .Nm nvmm_vcpu_create ,
39 .Nm nvmm_vcpu_destroy ,
40 .Nm nvmm_vcpu_configure ,
41 .Nm nvmm_vcpu_getstate ,
42 .Nm nvmm_vcpu_setstate ,
43 .Nm nvmm_vcpu_inject ,
44 .Nm nvmm_vcpu_run ,
45 .Nm nvmm_hva_map ,
46 .Nm nvmm_hva_unmap ,
47 .Nm nvmm_gpa_map ,
48 .Nm nvmm_gpa_unmap ,
49 .Nm nvmm_gva_to_gpa ,
50 .Nm nvmm_gpa_to_hva ,
51 .Nm nvmm_assist_io ,
52 .Nm nvmm_assist_mem
53 .Nd NVMM Virtualization API
54 .Sh LIBRARY
55 .Lb libnvmm
56 .Sh SYNOPSIS
57 .In nvmm.h
58 .Ft int
59 .Fn nvmm_init "void"
60 .Ft int
61 .Fn nvmm_capability "struct nvmm_capability *cap"
62 .Ft int
63 .Fn nvmm_machine_create "struct nvmm_machine *mach"
64 .Ft int
65 .Fn nvmm_machine_destroy "struct nvmm_machine *mach"
66 .Ft int
67 .Fn nvmm_machine_configure "struct nvmm_machine *mach" "uint64_t op" \
68     "void *conf"
69 .Ft int
70 .Fn nvmm_vcpu_create "struct nvmm_machine *mach" "nvmm_cpuid_t cpuid" \
71     "struct nvmm_vcpu *vcpu"
72 .Ft int
73 .Fn nvmm_vcpu_destroy "struct nvmm_machine *mach" "struct nvmm_vcpu *vcpu"
74 .Ft int
75 .Fn nvmm_vcpu_configure "struct nvmm_machine *mach" "struct nvmm_vcpu *vcpu" \
76     "uint64_t op" "void *conf"
77 .Ft int
78 .Fn nvmm_vcpu_getstate "struct nvmm_machine *mach" "struct nvmm_vcpu *vcpu" \
79     "uint64_t flags"
80 .Ft int
81 .Fn nvmm_vcpu_setstate "struct nvmm_machine *mach" "struct nvmm_vcpu *vcpu" \
82     "uint64_t flags"
83 .Ft int
84 .Fn nvmm_vcpu_inject "struct nvmm_machine *mach" "struct nvmm_vcpu *vcpu"
85 .Ft int
86 .Fn nvmm_vcpu_run "struct nvmm_machine *mach" "struct nvmm_vcpu *vcpu"
87 .Ft int
88 .Fn nvmm_hva_map "struct nvmm_machine *mach" "uintptr_t hva" "size_t size"
89 .Ft int
90 .Fn nvmm_hva_unmap "struct nvmm_machine *mach" "uintptr_t hva" "size_t size"
91 .Ft int
92 .Fn nvmm_gpa_map "struct nvmm_machine *mach" "uintptr_t hva" "gpaddr_t gpa" \
93     "size_t size" "int prot"
94 .Ft int
95 .Fn nvmm_gpa_unmap "struct nvmm_machine *mach" "uintptr_t hva" "gpaddr_t gpa" \
96     "size_t size"
97 .Ft int
98 .Fn nvmm_gva_to_gpa "struct nvmm_machine *mach" "struct nvmm_vcpu *vcpu" \
99     "gvaddr_t gva" "gpaddr_t *gpa" "nvmm_prot_t *prot"
100 .Ft int
101 .Fn nvmm_gpa_to_hva "struct nvmm_machine *mach" "gpaddr_t gpa" \
102     "uintptr_t *hva" "nvmm_prot_t *prot"
103 .Ft int
104 .Fn nvmm_assist_io "struct nvmm_machine *mach" "struct nvmm_vcpu *vcpu"
105 .Ft int
106 .Fn nvmm_assist_mem "struct nvmm_machine *mach" "struct nvmm_vcpu *vcpu"
107 .Sh DESCRIPTION
108 .Nm
109 provides a library for emulator software to handle hardware-accelerated virtual
110 machines in
111 .Nx .
112 A virtual machine is described by an opaque structure,
113 .Vt nvmm_machine .
114 Emulator software should not attempt to modify this structure directly, and
115 should use the API provided by
116 .Nm
117 to manage virtual machines.
118 A virtual CPU is described by a public structure,
119 .Vt nvmm_vcpu .
120 .Pp
121 .Fn nvmm_init
122 initializes NVMM.
123 See
124 .Sx NVMM Initialization
125 below for details.
126 .Pp
127 .Fn nvmm_capability
128 gets the capabilities of NVMM.
129 See
130 .Sx NVMM Capability
131 below for details.
132 .Pp
133 .Fn nvmm_machine_create
134 creates a virtual machine in the kernel.
135 The
136 .Fa mach
137 structure is initialized, and describes the machine.
138 .Pp
139 .Fn nvmm_machine_destroy
140 destroys the virtual machine described in
141 .Fa mach .
142 .Pp
143 .Fn nvmm_machine_configure
144 configures, on the machine
145 .Fa mach ,
146 the parameter indicated in
147 .Fa op .
148 .Fa conf
149 describes the value of the parameter.
150 .Pp
151 .Fn nvmm_vcpu_create
152 creates a virtual CPU in the machine
153 .Fa mach ,
154 giving it the CPU id
155 .Fa cpuid ,
156 and initializes
157 .Fa vcpu .
158 .Pp
159 .Fn nvmm_vcpu_destroy
160 destroys the virtual CPU identified by
161 .Fa vcpu
162 in the machine
163 .Fa mach .
164 .Pp
165 .Fn nvmm_vcpu_configure
166 configures, on the VCPU
167 .Fa vcpu
168 of machine
169 .Fa mach ,
170 the parameter indicated in
171 .Fa op .
172 .Fa conf
173 describes the value of the parameter.
174 .Pp
175 .Fn nvmm_vcpu_getstate
176 gets the state of the virtual CPU identified by
177 .Fa vcpu
178 in the machine
179 .Fa mach .
180 .Fa flags
181 is the bitmap of the components that are to be retrieved.
182 The components are located in
183 .Fa vcpu->state .
184 See
185 .Sx VCPU State Area
186 below for details.
187 .Pp
188 .Fn nvmm_vcpu_setstate
189 sets the state of the virtual CPU identified by
190 .Fa vcpu
191 in the machine
192 .Fa mach .
193 .Fa flags
194 is the bitmap of the components that are to be set.
195 The components are located in
196 .Fa vcpu->state .
197 See
198 .Sx VCPU State Area
199 below for details.
200 .Pp
201 .Fn nvmm_vcpu_inject
202 injects into the CPU identified by
203 .Fa vcpu
204 of the machine
205 .Fa mach
206 an event described by
207 .Fa vcpu->event .
208 See
209 .Sx Event Injection
210 below for details.
211 .Pp
212 .Fn nvmm_vcpu_run
213 runs the CPU identified by
214 .Fa vcpu
215 in the machine
216 .Fa mach ,
217 until a VM exit is triggered.
218 The
219 .Fa vcpu->exit
220 structure is filled to indicate the exit reason, and the associated parameters
221 if any.
222 .Pp
223 .Fn nvmm_hva_map
224 maps at address
225 .Fa hva
226 a buffer of size
227 .Fa size
228 in the calling process' virtual address space.
229 This buffer is allowed to be subsequently mapped in a virtual machine.
230 .Pp
231 .Fn nvmm_hva_unmap
232 unmaps the buffer of size
233 .Fa size
234 at address
235 .Fa hva
236 from the calling process' virtual address space.
237 .Pp
238 .Fn nvmm_gpa_map
239 maps into the guest physical memory beginning on address
240 .Fa gpa
241 the buffer of size
242 .Fa size
243 located at address
244 .Fa hva
245 of the calling process' virtual address space.
246 The
247 .Fa hva
248 parameter must point to a buffer that was previously mapped with
249 .Fn nvmm_hva_map .
250 .Pp
251 .Fn nvmm_gpa_unmap
252 removes the guest physical memory area beginning on address
253 .Fa gpa
254 and of size
255 .Fa size
256 from the machine
257 .Fa mach .
258 .Pp
259 .Fn nvmm_gva_to_gpa
260 translates, on the CPU
261 .Fa vcpu
262 from the machine
263 .Fa mach ,
264 the guest virtual address given in
265 .Fa gva
266 into a guest physical address returned in
267 .Fa gpa .
268 The associated page permissions are returned in
269 .Fa prot .
270 .Fa gva
271 must be page-aligned.
272 .Pp
273 .Fn nvmm_gpa_to_hva
274 translates, on the machine
275 .Fa mach ,
276 the guest physical address indicated in
277 .Fa gpa
278 into a host virtual address returned in
279 .Fa hva .
280 The associated page permissions are returned in
281 .Fa prot .
282 .Fa gpa
283 must be page-aligned.
284 .Pp
285 .Fn nvmm_assist_io
286 emulates the I/O operation described in
287 .Fa vcpu->exit
288 on CPU
289 .Fa vcpu
290 from machine
291 .Fa mach .
292 See
293 .Sx I/O Assist
294 below for details.
295 .Pp
296 .Fn nvmm_assist_mem
297 emulates the Mem operation described in
298 .Fa vcpu->exit
299 on CPU
300 .Fa vcpu
301 from machine
302 .Fa mach .
303 See
304 .Sx Mem Assist
305 below for details.
306 .Ss NVMM Initialization
307 NVMM initialization is performed by the
308 .Fn nvmm_init
309 function, which must be invoked by emulator software before any other NVMM
310 function.
311 .Pp
312 .Fn nvmm_init
313 opens the NVMM device, and expects to have the proper permissions to do so.
314 In a default configuration, this implies being part of the "nvmm" group.
315 If using a special configuration, emulator software should arrange to have the
316 proper permissions before invoking
317 .Fn nvmm_init ,
318 and can drop them after the call has completed.
319 .Pp
320 It is to be noted that
321 .Fn nvmm_init
322 may perform non-re-entrant operations, and should be called only once.
323 .Ss NVMM Capability
324 The
325 .Vt nvmm_capability
326 structure helps emulator software identify the capabilities offered by NVMM on
327 the host:
328 .Bd -literal
329 struct nvmm_capability {
330         uint64_t version;
331         uint64_t state_size;
332         uint64_t comm_size;
333         uint64_t max_machines;
334         uint64_t max_vcpus;
335         uint64_t max_ram;
336         struct {
337                 ...
338         } arch;
339 };
340 .Ed
341 .Pp
342 For example, the
343 .Fa max_machines
344 field indicates the maximum number of virtual machines supported, while
345 .Fa max_vcpus
346 indicates the maximum number of VCPUs supported per virtual machine.
347 .Ss Machine Ownership
348 When a process creates a virtual machine via
349 .Fn nvmm_machine_create ,
350 it is considered the owner of this machine.
351 No other processes than the owner can operate a virtual machine.
352 .Pp
353 When an owner exits, all the virtual machines associated with it are destroyed,
354 if they were not already destroyed by the owner itself via
355 .Fn nvmm_machine_destroy .
356 .Pp
357 Virtual machines are not inherited across
358 .Xr fork 2
359 operations.
360 .Ss Machine Configuration
361 Emulator software can configure several parameters of a virtual machine by using
362 .Fn nvmm_machine_configure .
363 Currently, no parameters are implemented.
364 .Ss VCPU Configuration
365 Emulator software can configure several parameters of a VCPU by using
366 .Fn nvmm_vcpu_configure ,
367 which can take the following operations:
368 .Pp
369 .Bl -bullet -offset indent -compact
370 .It
371 .Dv NVMM_VCPU_CONF_CALLBACKS :
372 register assist callbacks.
373 See
374 .Sx Assist Callbacks
375 below for details.
376 .El
377 .Pp
378 The other fields depend on the architecture.
379 .Pp
380 On x86 there are two additional operations available:
381 .Pp
382 .Bl -bullet -offset indent -compact
383 .It
384 .Dv NVMM_VCPU_CONF_CPUID :
385 configure the information returned to the guest by the CPUID instruction.
386 .It
387 .Dv NVMM_VCPU_CONF_TPR :
388 configure whether to return to the emulator when the guest updates its TPR.
389 .El
390 .Ss Guest-Host Mappings
391 Each virtual machine has an associated guest physical memory.
392 Emulator software is allowed to modify this guest physical memory by mapping
393 it into some parts of its virtual address space.
394 .Pp
395 Emulator software should follow the following steps to achieve that:
396 .Pp
397 .Bl -bullet -offset indent -compact
398 .It
399 Call
400 .Fn nvmm_hva_map
401 to create in the host's virtual address space an area of memory that can
402 be shared with a guest.
403 Typically, the
404 .Fa hva
405 parameter will be a pointer to an area that was previously mapped via
406 .Fn mmap .
407 .Fn nvmm_hva_map
408 will replace the content of the area, and will make it read-write (but not
409 executable).
410 .It
411 Make available in the guest an area of guest physical memory, by calling
412 .Fn nvmm_gpa_map
413 and passing in the
414 .Fa hva
415 parameter the value that was previously given to
416 .Fn nvmm_hva_map .
417 .Fn nvmm_gpa_map
418 does not replace the content of any memory, it only creates a direct link
419 from
420 .Fa gpa
421 into
422 .Fa hva .
423 .Fn nvmm_gpa_unmap
424 removes this link without modifying
425 .Fa hva .
426 .El
427 .Pp
428 The guest will then be able to use the guest physical address passed in the
429 .Fa gpa
430 parameter of
431 .Fn nvmm_gpa_map .
432 Each change the guest makes in
433 .Fa gpa
434 will be reflected in the host's
435 .Fa hva ,
436 and vice versa.
437 .Pp
438 It is illegal for emulator software to use
439 .Fn munmap
440 on an area that was mapped via
441 .Fn nvmm_hva_map .
442 .Ss VCPU State Area
443 A VCPU state area is a structure that entirely defines the content of the
444 registers of a VCPU.
445 Only one such structure exists, for x86:
446 .Bd -literal
447 struct nvmm_x64_state {
448         struct nvmm_x64_state_seg segs[NVMM_X64_NSEG];
449         uint64_t gprs[NVMM_X64_NGPR];
450         uint64_t crs[NVMM_X64_NCR];
451         uint64_t drs[NVMM_X64_NDR];
452         uint64_t msrs[NVMM_X64_NMSR];
453         struct nvmm_x64_state_intr intr;
454         struct nvmm_x64_state_fpu fpu;
455 };
456 #define nvmm_vcpu_state nvmm_x64_state
457 .Ed
458 .Pp
459 Refer to functional examples to see precisely how to use this structure.
460 .Pp
461 A VCPU state area is divided in sub-states.
462 A
463 .Fa flags
464 parameter is used to get and set the VCPU state; it acts as a bitmap which
465 indicates which sub-states to get or set.
466 .Pp
467 During VM exits, a partial VCPU state area is provided in
468 .Va exitstate ,
469 see
470 .Sx Exit Reasons
471 below for details.
472 .Ss VCPU Programming Model
473 A VCPU is described by a public structure,
474 .Vt nvmm_vcpu :
475 .Bd -literal
476 struct nvmm_vcpu {
477         nvmm_cpuid_t cpuid;
478         struct nvmm_vcpu_state *state;
479         struct nvmm_vcpu_event *event;
480         struct nvmm_vcpu_exit *exit;
481 };
482 .Ed
483 .Pp
484 This structure is used both publicly by emulator software and internally by
485 .Nm .
486 Emulator software should not modify the pointers of this structure, because
487 they are initialized to special values by
488 .Nm .
489 .Pp
490 A call to
491 .Fn nvmm_vcpu_getstate
492 will fetch the desired parts of the VCPU state and put them in
493 .Fa vcpu->state .
494 A call to
495 .Fn nvmm_vcpu_setstate
496 will install in the VCPU the desired parts of
497 .Fa vcpu->state .
498 A call to
499 .Fn nvmm_vcpu_inject
500 will inject in the VCPU the event in
501 .Fa vcpu->event .
502 A call to
503 .Fn nvmm_vcpu_run
504 will fill
505 .Fa vcpu->exit
506 with the VCPU exit information.
507 .Pp
508 If emulator software uses several threads, a VCPU should be associated with
509 only one thread, and only this thread should perform VCPU modifications.
510 Emulator software should not modify the state of a VCPU with several
511 different threads.
512 .Ss Exit Reasons
513 The
514 .Vt nvmm_vcpu_exit
515 structure is used to handle VM exits:
516 .Bd -literal
517 /* Generic. */
518 #define NVMM_VCPU_EXIT_NONE             0x0000000000000000ULL
519 #define NVMM_VCPU_EXIT_INVALID          0xFFFFFFFFFFFFFFFFULL
520 /* x86: operations. */
521 #define NVMM_VCPU_EXIT_MEMORY           0x0000000000000001ULL
522 #define NVMM_VCPU_EXIT_IO               0x0000000000000002ULL
523 /* x86: changes in VCPU state. */
524 #define NVMM_VCPU_EXIT_SHUTDOWN         0x0000000000001000ULL
525 #define NVMM_VCPU_EXIT_INT_READY        0x0000000000001001ULL
526 #define NVMM_VCPU_EXIT_NMI_READY        0x0000000000001002ULL
527 #define NVMM_VCPU_EXIT_HALTED           0x0000000000001003ULL
528 #define NVMM_VCPU_EXIT_TPR_CHANGED      0x0000000000001004ULL
529 /* x86: instructions. */
530 #define NVMM_VCPU_EXIT_RDMSR            0x0000000000002000ULL
531 #define NVMM_VCPU_EXIT_WRMSR            0x0000000000002001ULL
532 #define NVMM_VCPU_EXIT_MONITOR          0x0000000000002002ULL
533 #define NVMM_VCPU_EXIT_MWAIT            0x0000000000002003ULL
534 #define NVMM_VCPU_EXIT_CPUID            0x0000000000002004ULL
535
536 struct nvmm_vcpu_exit {
537         uint64_t reason;
538         union {
539                 ...
540         } u;
541         struct {
542                 ...
543         } exitstate;
544 };
545 .Ed
546 .Pp
547 The
548 .Va reason
549 field indicates the reason of the VM exit.
550 Additional parameters describing the exit can be present in
551 .Va u .
552 .Va exitstate
553 contains a partial, implementation-specific VCPU state, usable as a fast-path
554 to retrieve certain state values.
555 .Pp
556 It is possible that a VM exit was caused by a reason internal to the host
557 kernel, and that emulator software should not be concerned with.
558 In this case, the exit reason is set to
559 .Dv NVMM_VCPU_EXIT_NONE .
560 This gives a chance for emulator software to halt the VM in its tracks.
561 .Pp
562 Refer to functional examples to see precisely how to handle VM exits.
563 .Ss Event Injection
564 It is possible to inject an event into a VCPU.
565 An event can be a hardware interrupt, a software interrupt, or a software
566 exception, defined by:
567 .Bd -literal
568 #define NVMM_VCPU_EVENT_EXCP    0
569 #define NVMM_VCPU_EVENT_INTR    1
570
571 struct nvmm_vcpu_event {
572         u_int type;
573         uint8_t vector;
574         union {
575                 struct {
576                         uint64_t error;
577                 } excp;
578         } u;
579 };
580 .Ed
581 .Pp
582 This describes an event of type
583 .Va type ,
584 to be sent to vector number
585 .Va vector ,
586 with a possible additional
587 .Va error
588 code that is implementation-specific.
589 .Pp
590 It is possible that the VCPU is in a state where it cannot receive this
591 event, if:
592 .Pp
593 .Bl -bullet -offset indent -compact
594 .It
595 the event is a hardware interrupt, and the VCPU runs with interrupts disabled,
596 or
597 .It
598 the event is a non-maskable interrupt (NMI), and the VCPU is already in an
599 in-NMI context.
600 .El
601 .Pp
602 Emulator software can manage interrupt and NMI window-exiting via the
603 .Va intr
604 component of the VCPU state.
605 When such window-exiting is enabled, NVMM will cause a VM exit with reason
606 .Dv NVMM_VCPU_EXIT_INT_READY
607 or
608 .Dv NVMM_VCPU_EXIT_NMI_READY
609 to indicate that the guest is now able to handle the corresponding class
610 of interrupts.
611 .Ss Assist Callbacks
612 In order to assist emulation of certain operations,
613 .Nm
614 requires emulator software to register, via
615 .Fn nvmm_vcpu_configure ,
616 a set of callbacks described in the following structure:
617 .Bd -literal
618 struct nvmm_assist_callbacks {
619         void (*io)(struct nvmm_io *);
620         void (*mem)(struct nvmm_mem *);
621 };
622 .Ed
623 .Pp
624 These callbacks are used by
625 .Nm
626 each time
627 .Fn nvmm_assist_io
628 or
629 .Fn nvmm_assist_mem
630 are invoked.
631 Emulator software that does not intend to use either of these assists can put
632 .Dv NULL
633 in the callbacks.
634 .Ss I/O Assist
635 When a VM exit occurs with reason
636 .Dv NVMM_VCPU_EXIT_IO ,
637 it is necessary for emulator software to emulate the associated I/O operation.
638 .Nm
639 provides an easy way for emulator software to perform that.
640 .Pp
641 .Fn nvmm_assist_io
642 will call the registered
643 .Fa io
644 callback function and give it a
645 .Vt nvmm_io
646 structure as argument.
647 This structure describes an I/O transaction:
648 .Bd -literal
649 struct nvmm_io {
650         struct nvmm_machine *mach;
651         struct nvmm_vcpu *vcpu;
652         uint16_t port;
653         bool in;
654         size_t size;
655         uint8_t *data;
656 };
657 .Ed
658 .Pp
659 The callback can emulate the operation using this descriptor, following two
660 unique cases:
661 .Pp
662 .Bl -bullet -offset indent -compact
663 .It
664 The operation is an input.
665 In this case, the callback should fill
666 .Va data
667 with the desired value.
668 .It
669 The operation is an output.
670 In this case, the callback should read
671 .Va data
672 to retrieve the desired value.
673 .El
674 .Pp
675 In either case,
676 .Va port
677 will indicate the I/O port,
678 .Va in
679 will indicate if the operation is an input, and
680 .Va size
681 will indicate the size of the access.
682 .Ss Mem Assist
683 When a VM exit occurs with reason
684 .Dv NVMM_VCPU_EXIT_MEMORY ,
685 it is necessary for emulator software to emulate the associated memory
686 operation.
687 .Nm
688 provides an easy way for emulator software to perform that, similar to the I/O
689 Assist.
690 .Pp
691 .Fn nvmm_assist_mem
692 will call the registered
693 .Fa mem
694 callback function and give it a
695 .Vt nvmm_mem
696 structure as argument.
697 This structure describes a Mem transaction:
698 .Bd -literal
699 struct nvmm_mem {
700         struct nvmm_machine *mach;
701         struct nvmm_vcpu *vcpu;
702         gpaddr_t gpa;
703         bool write;
704         size_t size;
705         uint8_t *data;
706 };
707 .Ed
708 .Pp
709 The callback can emulate the operation using this descriptor, following two
710 unique cases:
711 .Pp
712 .Bl -bullet -offset indent -compact
713 .It
714 The operation is a read.
715 In this case, the callback should fill
716 .Va data
717 with the desired value.
718 .It
719 The operation is a write.
720 In this case, the callback should read
721 .Va data
722 to retrieve the desired value.
723 .El
724 .Pp
725 In either case,
726 .Va gpa
727 will indicate the guest physical address,
728 .Va write
729 will indicate if the access is a write, and
730 .Va size
731 will indicate the size of the access.
732 .Sh RETURN VALUES
733 Upon successful completion, each of these functions returns zero.
734 Otherwise, a value of \-1 is returned and the global
735 variable
736 .Va errno
737 is set to indicate the error.
738 .Sh FILES
739 .Bl -tag -width indent
740 .It Pa src/lib/libnvmm/
741 Source code of the
742 .Nm
743 library.
744 .It Pa src/sys/dev/virtual/nvmm/
745 Source code of the kernel
746 .Xr nvmm 4
747 driver.
748 .It Pa src/test/testcases/libnvmm
749 Regression test cases for the
750 .Nm
751 library.
752 .It Pa src/test/nvmm/calc-vm.c
753 A minimal example that uses the
754 .Nm
755 API to create a VM and perform a calculation within it.
756 .It Pa src/test/nvmm/demo
757 Functional demonstrator.
758 Contains an emulator that uses the
759 .Nm
760 API, and a small kernel that exercises this emulator.
761 .Pp
762 Originally obtained from
763 .Lk https://www.netbsd.org/~maxv/nvmm/nvmm-demo.zip
764 but has been updated to match the current
765 .Nm
766 API, cleaned up, and ported to
767 .Dx .
768 .El
769 .Sh ERRORS
770 These functions will fail if:
771 .Bl -tag -width Er
772 .It Bq Er EEXIST
773 An attempt was made to create a machine or a VCPU that already exists.
774 .It Bq Er EFAULT
775 An attempt was made to emulate a memory-based operation in a guest, and the
776 guest page tables did not have the permissions necessary for the operation
777 to complete successfully.
778 .It Bq Er EINVAL
779 An inappropriate parameter was used.
780 .It Bq Er ENOBUFS
781 The maximum number of machines or VCPUs was reached.
782 .It Bq Er ENOENT
783 A query was made on a machine or a VCPU that does not exist.
784 .It Bq Er EPERM
785 An attempt was made to access a machine that does not belong to the process.
786 .El
787 .Sh SEE ALSO
788 .Xr nvmm 4 ,
789 .Xr nvmmctl 8
790 .Sh AUTHORS
791 NVMM was designed and implemented by
792 .An Maxime Villard .