Hypercall APIs

This section contains APIs for the hypercall services. Sources for the Device Model are found in the ACRN Hypervisor GitHub repo

group acrn_hypercall

Hypercall.

Defines

GSI_SET_HIGH

Operation types for setting IRQ line

GSI_SET_LOW
GSI_RAISING_PULSE
GSI_FALLING_PULSE
SPACE_SYSTEM_MEMORY

Info The power state data of a VCPU.

SPACE_SYSTEM_IO
SPACE_PCI_CONFIG
SPACE_Embedded_Control
SPACE_SMBUS
SPACE_PLATFORM_COMM
SPACE_FFixedHW
PMCMD_VMID_MASK

Info PM command from DM/VHM.

The command would specify request type(e.g. get px count or data) for specific VM and specific VCPU with specific state number. For Px, PMCMD_STATE_NUM means Px number from 0 to (MAX_PSTATE - 1), For Cx, PMCMD_STATE_NUM means Cx entry index from 1 to MAX_CX_ENTRY.

PMCMD_VCPUID_MASK
PMCMD_STATE_NUM_MASK
PMCMD_TYPE_MASK
PMCMD_VMID_SHIFT
PMCMD_VCPUID_SHIFT
PMCMD_STATE_NUM_SHIFT
MAX_PTDEV_NUM

Info to get a VM interrupt count data.

the parameter for HC_VM_INTR_MONITOR hypercall

INTR_CMD_GET_DATA

cmd for intr monitor

INTR_CMD_DELAY_INT
MMIODEV_RES_NUM

Enums

enum pm_cmd_type

Values:

enumerator PMCMD_GET_PX_CNT
enumerator PMCMD_GET_PX_DATA
enumerator PMCMD_GET_CX_CNT
enumerator PMCMD_GET_CX_DATA

Functions

int32_t hcall_sos_offline_cpu(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

offline vcpu from SOS

The function offline specific vcpu from SOS.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: not used

  • param1: lapic id of the vcpu which wants to offline

  • param2: not used

int32_t hcall_get_api_version(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

Get hypervisor api version.

The function only return api version information when VM is SOS_VM.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: not used

  • param1: guest physical memory address. The api version returned will be copied to this gpa

  • param2: not used

int32_t hcall_get_platform_info(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

Get basic platform information.

The function returns basic hardware or configuration information for the current platform.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, -1 in case of error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall.

  • target_vm: not used

  • param1: GPA pointer to struct hc_platform_info.

  • param2: not used

int32_t hcall_create_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

create virtual machine

Create a virtual machine based on parameter, currently there is no limitation for calling times of this function, will add MAX_VM_NUM support later.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: guest physical memory address. This gpa points to struct acrn_create_vm

  • param2: not used

int32_t hcall_destroy_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

destroy virtual machine

Destroy a virtual machine, it will pause target VM then shutdown it. The function will return -1 if the target VM does not exist.

Return

0 on success, non-zero on error.

Parameters
  • vcpu: not used

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: not used

int32_t hcall_reset_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

reset virtual machine

Reset a virtual machine, it will make target VM rerun from pre-defined entry. Comparing to start vm, this function reset each vcpu state and do some initialization for guest. The function will return -1 if the target VM does not exist.

Return

0 on success, non-zero on error.

Parameters
  • vcpu: not used

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: not used

int32_t hcall_start_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

start virtual machine

Start a virtual machine, it will schedule target VM’s vcpu to run. The function will return -1 if the target VM does not exist or the IOReq buffer page for the VM is not ready.

Return

0 on success, non-zero on error.

Parameters
  • vcpu: not used

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: not used

int32_t hcall_pause_vm(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

pause virtual machine

Pause a virtual machine, if the VM is already paused, the function will return 0 directly for success. The function will return -1 if the target VM does not exist.

Return

0 on success, non-zero on error.

Parameters
  • vcpu: not used

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: not used

int32_t hcall_set_vcpu_regs(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

set vcpu regs

Set the vcpu regs. It will set the vcpu init regs from DM. Now, it’s only applied to BSP. AP always uses fixed init regs. The function will return -1 if the targat VM or BSP doesn’t exist.

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: guest physical address. This gpa points to struct acrn_vcpu_regs

int32_t hcall_set_irqline(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

set or clear IRQ line

Set or clear a virtual IRQ line for a VM, which could be from ISA or IOAPIC, normally it triggers an edge IRQ. The function will return -1 if the target VM does not exist.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: info for irqline

int32_t hcall_inject_msi(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

inject MSI interrupt

Inject a MSI interrupt for a VM. The function will return -1 if the target VM does not exist.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: guest physical address. This gpa points to struct acrn_msi_entry

int32_t hcall_set_ioreq_buffer(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

set ioreq shared buffer

Set the ioreq share buffer for a VM. The function will return -1 if the target VM does not exist.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: guest physical address. This gpa points to struct acrn_set_ioreq_buffer

int32_t hcall_notify_ioreq_finish(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

notify request done

Notify the requestor VCPU for the completion of an ioreq. The function will return -1 if the target VM does not exist.

Return

0 on success, non-zero on error.

Parameters
  • vcpu: not used

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: vcpu ID of the requestor

int32_t hcall_set_vm_memory_regions(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

setup ept memory mapping for multi regions

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: guest physical address. This gpa points to struct set_memmaps

  • param2: not used

int32_t hcall_write_protect_page(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

change guest memory page write permission

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: guest physical address. This gpa points to struct wp_data

int32_t hcall_gpa_to_hpa(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

translate guest physical address to host physical address

Translate guest physical address to host physical address for a VM. The function will return -1 if the target VM does not exist.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: guest physical address. This gpa points to struct vm_gpa2hpa

int32_t hcall_assign_pcidev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

Assign one PCI dev to VM.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: guest physical address. This gpa points to data structure of acrn_assign_pcidev including assign PCI device info

int32_t hcall_deassign_pcidev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

Deassign one PCI dev to VM.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: guest physical address. This gpa points to data structure of acrn_assign_pcidev including deassign PCI device info

int32_t hcall_assign_mmiodev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

Assign one MMIO dev to VM.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: guest physical address. This gpa points to data structure of acrn_mmiodev including assign MMIO device info

int32_t hcall_deassign_mmiodev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

Deassign one MMIO dev to VM.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: guest physical address. This gpa points to data structure of acrn_mmiodev including deassign MMIO device info

int32_t hcall_add_vdev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

Add an emulated device in hypervisor.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: guest physical address. This gpa points to data structure of acrn_emul_dev including information about PCI or legacy devices

int32_t hcall_remove_vdev(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

Remove an emulated device in hypervisor.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: guest physical address. This gpa points to data structure of acrn_emul_dev including information about PCI or legacy devices

int32_t hcall_set_ptdev_intr_info(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

Set interrupt mapping info of ptdev.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: guest physical address. This gpa points to data structure of hc_ptdev_irq including intr remapping info

int32_t hcall_reset_ptdev_intr_info(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

Clear interrupt mapping info of ptdev.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: guest physical address. This gpa points to data structure of hc_ptdev_irq including intr remapping info

int32_t hcall_get_cpu_pm_state(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

Get VCPU Power state.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: cmd to show get which VCPU power state data

  • param2: VCPU power state data

int32_t hcall_vm_intr_monitor(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

Get VCPU a VM’s interrupt count data.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: Pointer to target VM data structure

  • param1: not used

  • param2: guest physical address. This gpa points to data structure of acrn_intr_monitor

int32_t hcall_set_callback_vector(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

set upcall notifier vector

This is the API that helps to switch the notifer vecotr. If this API is not called, the hypervisor will use the default notifier vector(0xF7) to notify the SOS kernel.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: not used

  • target_vm: not used

  • param1: the expected notifier vector from guest

  • param2: not used

int32_t hcall_setup_sbuf(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

Setup a share buffer for a VM.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: not used

  • param1: guest physical address. This gpa points to struct sbuf_setup_param

  • param2: not used

int32_t hcall_setup_hv_npk_log(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

Setup the hypervisor NPK log.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: not used

  • param1: guest physical address. This gpa points to struct hv_npk_log_param

  • param2: not used

int32_t hcall_get_hw_info(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

Get hardware related info.

Preconditions

vm shall point to SOS_VM

Preconditions

param1 shall be a valid physical address

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: not used

  • param1: Guest physical address pointing to struct acrn_hw_info

  • param2: not used

Return Value
  • 0: on success

  • -1: in case of error

int32_t hcall_profiling_ops(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)

Execute profiling operation.

Preconditions

is_sos_vm(vcpu->vm)

Return

0 on success, non-zero on error.

Parameters
  • vcpu: Pointer to vCPU that initiates the hypercall

  • target_vm: not used

  • param1: profiling command to be executed

  • param2: guest physical address. This gpa points to data structure required by each command

int32_t hcall_create_vcpu(struct acrn_vcpu *vcpu, struct acrn_vm *target_vm, uint64_t param1, uint64_t param2)
struct mmio_request
#include <acrn_common.h>

Representation of a MMIO request.

struct pio_request
#include <acrn_common.h>

Representation of a port I/O request.

struct pci_request
#include <acrn_common.h>

Representation of a PCI configuration space access.

union vhm_io_request
#include <acrn_common.h>

Public Members

struct pio_request pio
struct pci_request pci
struct mmio_request mmio
int64_t reserved1[8]
struct vhm_request
#include <acrn_common.h>

256-byte VHM requests

The state transitions of a VHM request are:

FREE -> PENDING -> PROCESSING -> COMPLETE -> FREE -> …

When a request is in COMPLETE or FREE state, the request is owned by the hypervisor. SOS (VHM or DM) shall not read or write the internals of the request except the state.

When a request is in PENDING or PROCESSING state, the request is owned by SOS. The hypervisor shall not read or write the request other than the state.

Based on the rules above, a typical VHM request lifecycle should looks like the following.

SOS vCPU 0

SOS vCPU x

UOS vCPU y

Hypervisor:

  • Fill in type, addr, etc.

  • Pause UOS vCPU y

  • Set state to PENDING (a)

  • Fire upcall to SOS vCPU 0

VHM:

  • Scan for pending requests

  • Set state to PROCESSING (b)

  • Assign requests to clients (c)

Client:

  • Scan for assigned requests

  • Handle the requests (d)

  • Set state to COMPLETE

  • Notify the hypervisor

Hypervisor:

  • resume UOS vCPU y (e)

Hypervisor:

  • Post-work (f)

  • set state to FREE

Note that the following shall hold.

  1. (a) happens before (b)

  2. (c) happens before (d)

  3. (e) happens before (f)

  4. One vCPU cannot trigger another I/O request before the previous one has completed (i.e. the state switched to FREE)

Accesses to the state of a vhm_request shall be atomic and proper barriers are needed to ensure that:

  1. Setting state to PENDING is the last operation when issuing a request in the hypervisor, as the hypervisor shall not access the request any more.

  2. Due to similar reasons, setting state to COMPLETE is the last operation of request handling in VHM or clients in SOS.

union vhm_request_buffer
#include <acrn_common.h>

Public Members

struct vhm_request req_queue[VHM_REQUEST_MAX]
int8_t reserved[4096]
struct acrn_create_vm
#include <acrn_common.h>

Info to create a VM, the parameter for HC_CREATE_VM hypercall.

struct acrn_create_vcpu
#include <acrn_common.h>

Info to create a VCPU (deprecated)

the parameter for HC_CREATE_VCPU hypercall

struct acrn_gp_regs
#include <acrn_common.h>
struct acrn_descriptor_ptr
#include <acrn_common.h>
struct acrn_vcpu_regs
#include <acrn_common.h>

registers info for vcpu.

struct acrn_set_vcpu_regs
#include <acrn_common.h>

Info to set vcpu state.

the pamameter for HC_SET_VCPU_STATE

struct acrn_set_ioreq_buffer
#include <acrn_common.h>

Info to set ioreq buffer for a created VM.

the parameter for HC_SET_IOREQ_BUFFER hypercall

struct acrn_irqline_ops
#include <acrn_common.h>

Info to Set/Clear/Pulse a virtual IRQ line for a VM.

the parameter for HC_SET_IRQLINE hypercall

struct acrn_msi_entry
#include <acrn_common.h>

Info to inject a MSI interrupt to VM.

the parameter for HC_INJECT_MSI hypercall

struct acrn_nmi_entry
#include <acrn_common.h>

Info to inject a NMI interrupt for a VM.

struct acrn_vm_pci_msix_remap
#include <acrn_common.h>

Info to remap pass-through PCI MSI for a VM.

the parameter for HC_VM_PCI_MSIX_REMAP hypercall

struct acpi_generic_address
#include <acrn_common.h>
struct cpu_cx_data
#include <acrn_common.h>
struct cpu_px_data
#include <acrn_common.h>
struct acpi_sx_pkg
#include <acrn_common.h>
struct pm_s_state_data
#include <acrn_common.h>
struct acrn_intr_monitor
#include <acrn_common.h>
struct vrp_config
#include <acrn_common.h>

Info to configure virtual root port.

Configuration passed to hv when adding a virtual root port which is used as PTM root

struct vm_memory_region
#include <acrn_hv_defs.h>

Info to set guest memory region mapping.

the parameter for HC_VM_SET_MEMORY_REGION hypercall

struct set_regions
#include <acrn_hv_defs.h>

set multi memory regions, used for HC_VM_SET_MEMORY_REGIONS

struct wp_data
#include <acrn_hv_defs.h>

Info to change guest one page write protect permission.

the parameter for HC_VM_WRITE_PROTECT_PAGE hypercall

struct sbuf_setup_param
#include <acrn_hv_defs.h>

Setup parameter for share buffer, used for HC_SETUP_SBUF hypercall

struct hv_npk_log_param
#include <acrn_hv_defs.h>

Info to setup the hypervisor NPK log.

the parameter for HC_SETUP_HV_NPK_LOG hypercall

struct acrn_hw_info
#include <acrn_hv_defs.h>

the parameter for HC_GET_HW_INFO hypercall

struct vm_gpa2hpa
#include <acrn_hv_defs.h>

Gpa to hpa translation parameter, used for HC_VM_GPA2HPA hypercall

struct hc_ptdev_irq
#include <acrn_hv_defs.h>

Intr mapping info per ptdev, the parameter for HC_SET_PTDEV_INTR_INFO hypercall

struct acrn_assign_pcidev
#include <acrn_hv_defs.h>

Info to assign or deassign PCI for a VM.

the parameter for HC_ASSIGN_PCIDEV or HC_DEASSIGN_PCIDEV hypercall

struct acrn_mmiodev
#include <acrn_hv_defs.h>

Info to assign or deassign a MMIO device for a VM.

the parameter for HC_ASSIGN_MMIODEV or HC_DEASSIGN_MMIODEV hypercall

struct acrn_emul_dev
#include <acrn_hv_defs.h>

Info to create or destroy a virtual PCI or legacy device for a VM.

the parameter for HC_ADD_VDEV or HC_REMOVE_VDEV hypercall

the parameter for HC_CREATE_VDEV or HC_DESTROY_VDEV hypercall

struct hc_api_version
#include <acrn_hv_defs.h>

Hypervisor api version info, return it for HC_GET_API_VERSION hypercall

struct hc_platform_info
#include <acrn_hv_defs.h>

Hypervisor API, return it for HC_GET_PLATFORM_INFO hypercall

struct trusty_boot_param
#include <acrn_hv_defs.h>

Trusty boot params, used for HC_INITIALIZE_TRUSTY