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 109provides a library for emulator software to handle hardware-accelerated virtual 110machines in 111.Nx . 112A virtual machine is described by an opaque structure, 113.Vt nvmm_machine . 114Emulator software should not attempt to modify this structure directly, and 115should use the API provided by 116.Nm 117to manage virtual machines. 118A virtual CPU is described by a public structure, 119.Vt nvmm_vcpu . 120.Pp 121.Fn nvmm_init 122initializes NVMM. 123See 124.Sx NVMM Initialization 125below for details. 126.Pp 127.Fn nvmm_capability 128gets the capabilities of NVMM. 129See 130.Sx NVMM Capability 131below for details. 132.Pp 133.Fn nvmm_machine_create 134creates a virtual machine in the kernel. 135The 136.Fa mach 137structure is initialized, and describes the machine. 138.Pp 139.Fn nvmm_machine_destroy 140destroys the virtual machine described in 141.Fa mach . 142.Pp 143.Fn nvmm_machine_configure 144configures, on the machine 145.Fa mach , 146the parameter indicated in 147.Fa op . 148.Fa conf 149describes the value of the parameter. 150.Pp 151.Fn nvmm_vcpu_create 152creates a virtual CPU in the machine 153.Fa mach , 154giving it the CPU id 155.Fa cpuid , 156and initializes 157.Fa vcpu . 158.Pp 159.Fn nvmm_vcpu_destroy 160destroys the virtual CPU identified by 161.Fa vcpu 162in the machine 163.Fa mach . 164.Pp 165.Fn nvmm_vcpu_configure 166configures, on the VCPU 167.Fa vcpu 168of machine 169.Fa mach , 170the parameter indicated in 171.Fa op . 172.Fa conf 173describes the value of the parameter. 174.Pp 175.Fn nvmm_vcpu_getstate 176gets the state of the virtual CPU identified by 177.Fa vcpu 178in the machine 179.Fa mach . 180.Fa flags 181is the bitmap of the components that are to be retrieved. 182The components are located in 183.Fa vcpu->state . 184See 185.Sx VCPU State Area 186below for details. 187.Pp 188.Fn nvmm_vcpu_setstate 189sets the state of the virtual CPU identified by 190.Fa vcpu 191in the machine 192.Fa mach . 193.Fa flags 194is the bitmap of the components that are to be set. 195The components are located in 196.Fa vcpu->state . 197See 198.Sx VCPU State Area 199below for details. 200.Pp 201.Fn nvmm_vcpu_inject 202injects into the CPU identified by 203.Fa vcpu 204of the machine 205.Fa mach 206an event described by 207.Fa vcpu->event . 208See 209.Sx Event Injection 210below for details. 211.Pp 212.Fn nvmm_vcpu_run 213runs the CPU identified by 214.Fa vcpu 215in the machine 216.Fa mach , 217until a VM exit is triggered. 218The 219.Fa vcpu->exit 220structure is filled to indicate the exit reason, and the associated parameters 221if any. 222.Pp 223.Fn nvmm_hva_map 224maps at address 225.Fa hva 226a buffer of size 227.Fa size 228in the calling process' virtual address space. 229This buffer is allowed to be subsequently mapped in a virtual machine. 230.Pp 231.Fn nvmm_hva_unmap 232unmaps the buffer of size 233.Fa size 234at address 235.Fa hva 236from the calling process' virtual address space. 237.Pp 238.Fn nvmm_gpa_map 239maps into the guest physical memory beginning on address 240.Fa gpa 241the buffer of size 242.Fa size 243located at address 244.Fa hva 245of the calling process' virtual address space. 246The 247.Fa hva 248parameter must point to a buffer that was previously mapped with 249.Fn nvmm_hva_map . 250.Pp 251.Fn nvmm_gpa_unmap 252removes the guest physical memory area beginning on address 253.Fa gpa 254and of size 255.Fa size 256from the machine 257.Fa mach . 258.Pp 259.Fn nvmm_gva_to_gpa 260translates, on the CPU 261.Fa vcpu 262from the machine 263.Fa mach , 264the guest virtual address given in 265.Fa gva 266into a guest physical address returned in 267.Fa gpa . 268The associated page permissions are returned in 269.Fa prot . 270.Fa gva 271must be page-aligned. 272.Pp 273.Fn nvmm_gpa_to_hva 274translates, on the machine 275.Fa mach , 276the guest physical address indicated in 277.Fa gpa 278into a host virtual address returned in 279.Fa hva . 280The associated page permissions are returned in 281.Fa prot . 282.Fa gpa 283must be page-aligned. 284.Pp 285.Fn nvmm_assist_io 286emulates the I/O operation described in 287.Fa vcpu->exit 288on CPU 289.Fa vcpu 290from machine 291.Fa mach . 292See 293.Sx I/O Assist 294below for details. 295.Pp 296.Fn nvmm_assist_mem 297emulates the Mem operation described in 298.Fa vcpu->exit 299on CPU 300.Fa vcpu 301from machine 302.Fa mach . 303See 304.Sx Mem Assist 305below for details. 306.Ss NVMM Initialization 307NVMM initialization is performed by the 308.Fn nvmm_init 309function, which must be invoked by emulator software before any other NVMM 310function. 311.Pp 312.Fn nvmm_init 313opens the NVMM device, and expects to have the proper permissions to do so. 314In a default configuration, this implies being part of the "nvmm" group. 315If using a special configuration, emulator software should arrange to have the 316proper permissions before invoking 317.Fn nvmm_init , 318and can drop them after the call has completed. 319.Pp 320It is to be noted that 321.Fn nvmm_init 322may perform non-re-entrant operations, and should be called only once. 323.Ss NVMM Capability 324The 325.Vt nvmm_capability 326structure helps emulator software identify the capabilities offered by NVMM on 327the host: 328.Bd -literal 329struct 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 342For example, the 343.Fa max_machines 344field indicates the maximum number of virtual machines supported, while 345.Fa max_vcpus 346indicates the maximum number of VCPUs supported per virtual machine. 347.Ss Machine Ownership 348When a process creates a virtual machine via 349.Fn nvmm_machine_create , 350it is considered the owner of this machine. 351No other processes than the owner can operate a virtual machine. 352.Pp 353When an owner exits, all the virtual machines associated with it are destroyed, 354if they were not already destroyed by the owner itself via 355.Fn nvmm_machine_destroy . 356.Pp 357Virtual machines are not inherited across 358.Xr fork 2 359operations. 360.Ss Machine Configuration 361Emulator software can configure several parameters of a virtual machine by using 362.Fn nvmm_machine_configure . 363Currently, no parameters are implemented. 364.Ss VCPU Configuration 365Emulator software can configure several parameters of a VCPU by using 366.Fn nvmm_vcpu_configure , 367which can take the following operations: 368.Pp 369.Bl -bullet -offset indent -compact 370.It 371.Dv NVMM_VCPU_CONF_CALLBACKS : 372register assist callbacks. 373See 374.Sx Assist Callbacks 375below for details. 376.El 377.Pp 378The other fields depend on the architecture. 379.Pp 380On x86 there are two additional operations available: 381.Pp 382.Bl -bullet -offset indent -compact 383.It 384.Dv NVMM_VCPU_CONF_CPUID : 385configure the information returned to the guest by the CPUID instruction. 386.It 387.Dv NVMM_VCPU_CONF_TPR : 388configure whether to return to the emulator when the guest updates its TPR. 389.El 390.Ss Guest-Host Mappings 391Each virtual machine has an associated guest physical memory. 392Emulator software is allowed to modify this guest physical memory by mapping 393it into some parts of its virtual address space. 394.Pp 395Emulator software should follow the following steps to achieve that: 396.Pp 397.Bl -bullet -offset indent -compact 398.It 399Call 400.Fn nvmm_hva_map 401to create in the host's virtual address space an area of memory that can 402be shared with a guest. 403Typically, the 404.Fa hva 405parameter will be a pointer to an area that was previously mapped via 406.Fn mmap . 407.Fn nvmm_hva_map 408will replace the content of the area, and will make it read-write (but not 409executable). 410.It 411Make available in the guest an area of guest physical memory, by calling 412.Fn nvmm_gpa_map 413and passing in the 414.Fa hva 415parameter the value that was previously given to 416.Fn nvmm_hva_map . 417.Fn nvmm_gpa_map 418does not replace the content of any memory, it only creates a direct link 419from 420.Fa gpa 421into 422.Fa hva . 423.Fn nvmm_gpa_unmap 424removes this link without modifying 425.Fa hva . 426.El 427.Pp 428The guest will then be able to use the guest physical address passed in the 429.Fa gpa 430parameter of 431.Fn nvmm_gpa_map . 432Each change the guest makes in 433.Fa gpa 434will be reflected in the host's 435.Fa hva , 436and vice versa. 437.Pp 438It is illegal for emulator software to use 439.Fn munmap 440on an area that was mapped via 441.Fn nvmm_hva_map . 442.Ss VCPU State Area 443A VCPU state area is a structure that entirely defines the content of the 444registers of a VCPU. 445Only one such structure exists, for x86: 446.Bd -literal 447struct 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 459Refer to functional examples to see precisely how to use this structure. 460.Pp 461A VCPU state area is divided in sub-states. 462A 463.Fa flags 464parameter is used to get and set the VCPU state; it acts as a bitmap which 465indicates which sub-states to get or set. 466.Pp 467During VM exits, a partial VCPU state area is provided in 468.Va exitstate , 469see 470.Sx Exit Reasons 471below for details. 472.Ss VCPU Programming Model 473A VCPU is described by a public structure, 474.Vt nvmm_vcpu : 475.Bd -literal 476struct 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 484This structure is used both publicly by emulator software and internally by 485.Nm . 486Emulator software should not modify the pointers of this structure, because 487they are initialized to special values by 488.Nm . 489.Pp 490A call to 491.Fn nvmm_vcpu_getstate 492will fetch the desired parts of the VCPU state and put them in 493.Fa vcpu->state . 494A call to 495.Fn nvmm_vcpu_setstate 496will install in the VCPU the desired parts of 497.Fa vcpu->state . 498A call to 499.Fn nvmm_vcpu_inject 500will inject in the VCPU the event in 501.Fa vcpu->event . 502A call to 503.Fn nvmm_vcpu_run 504will fill 505.Fa vcpu->exit 506with the VCPU exit information. 507.Pp 508If emulator software uses several threads, a VCPU should be associated with 509only one thread, and only this thread should perform VCPU modifications. 510Emulator software should not modify the state of a VCPU with several 511different threads. 512.Ss Exit Reasons 513The 514.Vt nvmm_vcpu_exit 515structure 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 536struct nvmm_vcpu_exit { 537 uint64_t reason; 538 union { 539 ... 540 } u; 541 struct { 542 ... 543 } exitstate; 544}; 545.Ed 546.Pp 547The 548.Va reason 549field indicates the reason of the VM exit. 550Additional parameters describing the exit can be present in 551.Va u . 552.Va exitstate 553contains a partial, implementation-specific VCPU state, usable as a fast-path 554to retrieve certain state values. 555.Pp 556It is possible that a VM exit was caused by a reason internal to the host 557kernel, and that emulator software should not be concerned with. 558In this case, the exit reason is set to 559.Dv NVMM_VCPU_EXIT_NONE . 560This gives a chance for emulator software to halt the VM in its tracks. 561.Pp 562Refer to functional examples to see precisely how to handle VM exits. 563.Ss Event Injection 564It is possible to inject an event into a VCPU. 565An event can be a hardware interrupt, a software interrupt, or a software 566exception, defined by: 567.Bd -literal 568#define NVMM_VCPU_EVENT_EXCP 0 569#define NVMM_VCPU_EVENT_INTR 1 570 571struct 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 582This describes an event of type 583.Va type , 584to be sent to vector number 585.Va vector , 586with a possible additional 587.Va error 588code that is implementation-specific. 589.Pp 590It is possible that the VCPU is in a state where it cannot receive this 591event, if: 592.Pp 593.Bl -bullet -offset indent -compact 594.It 595the event is a hardware interrupt, and the VCPU runs with interrupts disabled, 596or 597.It 598the event is a non-maskable interrupt (NMI), and the VCPU is already in an 599in-NMI context. 600.El 601.Pp 602Emulator software can manage interrupt and NMI window-exiting via the 603.Va intr 604component of the VCPU state. 605When such window-exiting is enabled, NVMM will cause a VM exit with reason 606.Dv NVMM_VCPU_EXIT_INT_READY 607or 608.Dv NVMM_VCPU_EXIT_NMI_READY 609to indicate that the guest is now able to handle the corresponding class 610of interrupts. 611.Ss Assist Callbacks 612In order to assist emulation of certain operations, 613.Nm 614requires emulator software to register, via 615.Fn nvmm_vcpu_configure , 616a set of callbacks described in the following structure: 617.Bd -literal 618struct nvmm_assist_callbacks { 619 void (*io)(struct nvmm_io *); 620 void (*mem)(struct nvmm_mem *); 621}; 622.Ed 623.Pp 624These callbacks are used by 625.Nm 626each time 627.Fn nvmm_assist_io 628or 629.Fn nvmm_assist_mem 630are invoked. 631Emulator software that does not intend to use either of these assists can put 632.Dv NULL 633in the callbacks. 634.Ss I/O Assist 635When a VM exit occurs with reason 636.Dv NVMM_VCPU_EXIT_IO , 637it is necessary for emulator software to emulate the associated I/O operation. 638.Nm 639provides an easy way for emulator software to perform that. 640.Pp 641.Fn nvmm_assist_io 642will call the registered 643.Fa io 644callback function and give it a 645.Vt nvmm_io 646structure as argument. 647This structure describes an I/O transaction: 648.Bd -literal 649struct 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 659The callback can emulate the operation using this descriptor, following two 660unique cases: 661.Pp 662.Bl -bullet -offset indent -compact 663.It 664The operation is an input. 665In this case, the callback should fill 666.Va data 667with the desired value. 668.It 669The operation is an output. 670In this case, the callback should read 671.Va data 672to retrieve the desired value. 673.El 674.Pp 675In either case, 676.Va port 677will indicate the I/O port, 678.Va in 679will indicate if the operation is an input, and 680.Va size 681will indicate the size of the access. 682.Ss Mem Assist 683When a VM exit occurs with reason 684.Dv NVMM_VCPU_EXIT_MEMORY , 685it is necessary for emulator software to emulate the associated memory 686operation. 687.Nm 688provides an easy way for emulator software to perform that, similar to the I/O 689Assist. 690.Pp 691.Fn nvmm_assist_mem 692will call the registered 693.Fa mem 694callback function and give it a 695.Vt nvmm_mem 696structure as argument. 697This structure describes a Mem transaction: 698.Bd -literal 699struct 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 709The callback can emulate the operation using this descriptor, following two 710unique cases: 711.Pp 712.Bl -bullet -offset indent -compact 713.It 714The operation is a read. 715In this case, the callback should fill 716.Va data 717with the desired value. 718.It 719The operation is a write. 720In this case, the callback should read 721.Va data 722to retrieve the desired value. 723.El 724.Pp 725In either case, 726.Va gpa 727will indicate the guest physical address, 728.Va write 729will indicate if the access is a write, and 730.Va size 731will indicate the size of the access. 732.Sh RETURN VALUES 733Upon successful completion, each of these functions returns zero. 734Otherwise, a value of \-1 is returned and the global 735variable 736.Va errno 737is set to indicate the error. 738.Sh FILES 739.Bl -tag -width indent 740.It Pa src/lib/libnvmm/ 741Source code of the 742.Nm 743library. 744.It Pa src/sys/dev/virtual/nvmm/ 745Source code of the kernel 746.Xr nvmm 4 747driver. 748.It Pa src/test/testcases/libnvmm 749Regression test cases for the 750.Nm 751library. 752.It Pa src/test/nvmm/calc-vm.c 753A minimal example that uses the 754.Nm 755API to create a VM and perform a calculation within it. 756.It Pa src/test/nvmm/demo 757Functional demonstrator. 758Contains an emulator that uses the 759.Nm 760API, and a small kernel that exercises this emulator. 761.Pp 762Originally obtained from 763.Lk https://www.netbsd.org/~maxv/nvmm/nvmm-demo.zip 764but has been updated to match the current 765.Nm 766API, cleaned up, and ported to 767.Dx . 768.El 769.Sh ERRORS 770These functions will fail if: 771.Bl -tag -width Er 772.It Bq Er EEXIST 773An attempt was made to create a machine or a VCPU that already exists. 774.It Bq Er EFAULT 775An attempt was made to emulate a memory-based operation in a guest, and the 776guest page tables did not have the permissions necessary for the operation 777to complete successfully. 778.It Bq Er EINVAL 779An inappropriate parameter was used. 780.It Bq Er ENOBUFS 781The maximum number of machines or VCPUs was reached. 782.It Bq Er ENOENT 783A query was made on a machine or a VCPU that does not exist. 784.It Bq Er EPERM 785An 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 791NVMM was designed and implemented by 792.An Maxime Villard . 793