/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Userspace interface for /dev/acrn_hsm - ACRN Hypervisor Service Module * * This file can be used by applications that need to communicate with the HSM * via the ioctl interface. * * Copyright (C) 2021 Intel Corporation. All rights reserved. */ #ifndef _UAPI_ACRN_H #define _UAPI_ACRN_H #include <linux/types.h> #define ACRN_IO_REQUEST_MAX … #define ACRN_IOREQ_STATE_PENDING … #define ACRN_IOREQ_STATE_COMPLETE … #define ACRN_IOREQ_STATE_PROCESSING … #define ACRN_IOREQ_STATE_FREE … #define ACRN_IOREQ_TYPE_PORTIO … #define ACRN_IOREQ_TYPE_MMIO … #define ACRN_IOREQ_TYPE_PCICFG … #define ACRN_IOREQ_DIR_READ … #define ACRN_IOREQ_DIR_WRITE … /** * struct acrn_mmio_request - Info of a MMIO I/O request * @direction: Access direction of this request (ACRN_IOREQ_DIR_*) * @reserved: Reserved for alignment and should be 0 * @address: Access address of this MMIO I/O request * @size: Access size of this MMIO I/O request * @value: Read/write value of this MMIO I/O request */ struct acrn_mmio_request { … }; /** * struct acrn_pio_request - Info of a PIO I/O request * @direction: Access direction of this request (ACRN_IOREQ_DIR_*) * @reserved: Reserved for alignment and should be 0 * @address: Access address of this PIO I/O request * @size: Access size of this PIO I/O request * @value: Read/write value of this PIO I/O request */ struct acrn_pio_request { … }; /** * struct acrn_pci_request - Info of a PCI I/O request * @direction: Access direction of this request (ACRN_IOREQ_DIR_*) * @reserved: Reserved for alignment and should be 0 * @size: Access size of this PCI I/O request * @value: Read/write value of this PIO I/O request * @bus: PCI bus value of this PCI I/O request * @dev: PCI device value of this PCI I/O request * @func: PCI function value of this PCI I/O request * @reg: PCI config space offset of this PCI I/O request * * Need keep same header layout with &struct acrn_pio_request. */ struct acrn_pci_request { … }; /** * struct acrn_io_request - 256-byte ACRN I/O request * @type: Type of this request (ACRN_IOREQ_TYPE_*). * @completion_polling: Polling flag. Hypervisor will poll completion of the * I/O request if this flag set. * @reserved0: Reserved fields. * @reqs: Union of different types of request. Byte offset: 64. * @reqs.pio_request: PIO request data of the I/O request. * @reqs.pci_request: PCI configuration space request data of the I/O request. * @reqs.mmio_request: MMIO request data of the I/O request. * @reqs.data: Raw data of the I/O request. * @reserved1: Reserved fields. * @kernel_handled: Flag indicates this request need be handled in kernel. * @processed: The status of this request (ACRN_IOREQ_STATE_*). * * The state transitions of ACRN I/O request: * * FREE -> PENDING -> PROCESSING -> COMPLETE -> FREE -> ... * * An I/O request in COMPLETE or FREE state is owned by the hypervisor. HSM and * ACRN userspace are in charge of processing the others. * * On basis of the states illustrated above, a typical lifecycle of ACRN IO * request would look like: * * Flow (assume the initial state is FREE) * | * | Service VM vCPU 0 Service VM vCPU x User vCPU y * | * | hypervisor: * | fills in type, addr, etc. * | pauses the User VM vCPU y * | sets the state to PENDING (a) * | fires an upcall to Service VM * | * | HSM: * | scans for PENDING requests * | sets the states to PROCESSING (b) * | assigns the requests to clients (c) * V * | client: * | scans for the assigned requests * | handles the requests (d) * | HSM: * | sets states to COMPLETE * | notifies the hypervisor * | * | hypervisor: * | resumes User VM vCPU y (e) * | * | hypervisor: * | post handling (f) * V sets states to FREE * * Note that the procedures (a) to (f) in the illustration above require to be * strictly processed in the order. One vCPU cannot trigger another request of * I/O emulation before completing the previous one. * * Atomic and barriers are required when HSM and hypervisor accessing the state * of &struct acrn_io_request. * */ struct acrn_io_request { … } __attribute__((aligned …)); struct acrn_io_request_buffer { … }; /** * struct acrn_ioreq_notify - The structure of ioreq completion notification * @vmid: User VM ID * @reserved: Reserved and should be 0 * @vcpu: vCPU ID */ struct acrn_ioreq_notify { … }; /** * struct acrn_vm_creation - Info to create a User VM * @vmid: User VM ID returned from the hypervisor * @reserved0: Reserved and must be 0 * @vcpu_num: Number of vCPU in the VM. Return from hypervisor. * @reserved1: Reserved and must be 0 * @uuid: Empty space never to be used again (used to be UUID of the VM) * @vm_flag: Flag of the VM creating. Pass to hypervisor directly. * @ioreq_buf: Service VM GPA of I/O request buffer. Pass to * hypervisor directly. * @cpu_affinity: CPU affinity of the VM. Pass to hypervisor directly. * It's a bitmap which indicates CPUs used by the VM. */ struct acrn_vm_creation { … }; /** * struct acrn_gp_regs - General registers of a User VM * @rax: Value of register RAX * @rcx: Value of register RCX * @rdx: Value of register RDX * @rbx: Value of register RBX * @rsp: Value of register RSP * @rbp: Value of register RBP * @rsi: Value of register RSI * @rdi: Value of register RDI * @r8: Value of register R8 * @r9: Value of register R9 * @r10: Value of register R10 * @r11: Value of register R11 * @r12: Value of register R12 * @r13: Value of register R13 * @r14: Value of register R14 * @r15: Value of register R15 */ struct acrn_gp_regs { … }; /** * struct acrn_descriptor_ptr - Segment descriptor table of a User VM. * @limit: Limit field. * @base: Base field. * @reserved: Reserved and must be 0. */ struct acrn_descriptor_ptr { … } __attribute__ ((packed)); /** * struct acrn_regs - Registers structure of a User VM * @gprs: General registers * @gdt: Global Descriptor Table * @idt: Interrupt Descriptor Table * @rip: Value of register RIP * @cs_base: Base of code segment selector * @cr0: Value of register CR0 * @cr4: Value of register CR4 * @cr3: Value of register CR3 * @ia32_efer: Value of IA32_EFER MSR * @rflags: Value of regsiter RFLAGS * @reserved_64: Reserved and must be 0 * @cs_ar: Attribute field of code segment selector * @cs_limit: Limit field of code segment selector * @reserved_32: Reserved and must be 0 * @cs_sel: Value of code segment selector * @ss_sel: Value of stack segment selector * @ds_sel: Value of data segment selector * @es_sel: Value of extra segment selector * @fs_sel: Value of FS selector * @gs_sel: Value of GS selector * @ldt_sel: Value of LDT descriptor selector * @tr_sel: Value of TSS descriptor selector */ struct acrn_regs { … }; /** * struct acrn_vcpu_regs - Info of vCPU registers state * @vcpu_id: vCPU ID * @reserved: Reserved and must be 0 * @vcpu_regs: vCPU registers state * * This structure will be passed to hypervisor directly. */ struct acrn_vcpu_regs { … }; #define ACRN_MEM_ACCESS_RIGHT_MASK … #define ACRN_MEM_ACCESS_READ … #define ACRN_MEM_ACCESS_WRITE … #define ACRN_MEM_ACCESS_EXEC … #define ACRN_MEM_ACCESS_RWX … #define ACRN_MEM_TYPE_MASK … #define ACRN_MEM_TYPE_WB … #define ACRN_MEM_TYPE_WT … #define ACRN_MEM_TYPE_UC … #define ACRN_MEM_TYPE_WC … #define ACRN_MEM_TYPE_WP … /* Memory mapping types */ #define ACRN_MEMMAP_RAM … #define ACRN_MEMMAP_MMIO … /** * struct acrn_vm_memmap - A EPT memory mapping info for a User VM. * @type: Type of the memory mapping (ACRM_MEMMAP_*). * Pass to hypervisor directly. * @attr: Attribute of the memory mapping. * Pass to hypervisor directly. * @user_vm_pa: Physical address of User VM. * Pass to hypervisor directly. * @service_vm_pa: Physical address of Service VM. * Pass to hypervisor directly. * @vma_base: VMA address of Service VM. Pass to hypervisor directly. * @len: Length of the memory mapping. * Pass to hypervisor directly. */ struct acrn_vm_memmap { … }; /* Type of interrupt of a passthrough device */ #define ACRN_PTDEV_IRQ_INTX … #define ACRN_PTDEV_IRQ_MSI … #define ACRN_PTDEV_IRQ_MSIX … /** * struct acrn_ptdev_irq - Interrupt data of a passthrough device. * @type: Type (ACRN_PTDEV_IRQ_*) * @virt_bdf: Virtual Bus/Device/Function * @phys_bdf: Physical Bus/Device/Function * @intx: Info of interrupt * @intx.virt_pin: Virtual IOAPIC pin * @intx.phys_pin: Physical IOAPIC pin * @intx.is_pic_pin: Is PIC pin or not * * This structure will be passed to hypervisor directly. */ struct acrn_ptdev_irq { … }; /* Type of PCI device assignment */ #define ACRN_PTDEV_QUIRK_ASSIGN … #define ACRN_MMIODEV_RES_NUM … #define ACRN_PCI_NUM_BARS … /** * struct acrn_pcidev - Info for assigning or de-assigning a PCI device * @type: Type of the assignment * @virt_bdf: Virtual Bus/Device/Function * @phys_bdf: Physical Bus/Device/Function * @intr_line: PCI interrupt line * @intr_pin: PCI interrupt pin * @bar: PCI BARs. * * This structure will be passed to hypervisor directly. */ struct acrn_pcidev { … }; /** * struct acrn_mmiodev - Info for assigning or de-assigning a MMIO device * @name: Name of the MMIO device. * @res[].user_vm_pa: Physical address of User VM of the MMIO region * for the MMIO device. * @res[].service_vm_pa: Physical address of Service VM of the MMIO * region for the MMIO device. * @res[].size: Size of the MMIO region for the MMIO device. * @res[].mem_type: Memory type of the MMIO region for the MMIO * device. * * This structure will be passed to hypervisor directly. */ struct acrn_mmiodev { … }; /** * struct acrn_vdev - Info for creating or destroying a virtual device * @id: Union of identifier of the virtual device * @id.value: Raw data of the identifier * @id.fields.vendor: Vendor id of the virtual PCI device * @id.fields.device: Device id of the virtual PCI device * @id.fields.legacy_id: ID of the virtual device if not a PCI device * @slot: Virtual Bus/Device/Function of the virtual * device * @io_base: IO resource base address of the virtual device * @io_size: IO resource size of the virtual device * @args: Arguments for the virtual device creation * * The created virtual device can be a PCI device or a legacy device (e.g. * a virtual UART controller) and it is emulated by the hypervisor. This * structure will be passed to hypervisor directly. */ struct acrn_vdev { … }; /** * struct acrn_msi_entry - Info for injecting a MSI interrupt to a VM * @msi_addr: MSI addr[19:12] with dest vCPU ID * @msi_data: MSI data[7:0] with vector */ struct acrn_msi_entry { … }; struct acrn_acpi_generic_address { … } __attribute__ ((packed)); /** * struct acrn_cstate_data - A C state package defined in ACPI * @cx_reg: Register of the C state object * @type: Type of the C state object * @latency: The worst-case latency to enter and exit this C state * @power: The average power consumption when in this C state */ struct acrn_cstate_data { … }; /** * struct acrn_pstate_data - A P state package defined in ACPI * @core_frequency: CPU frequency (in MHz). * @power: Power dissipation (in milliwatts). * @transition_latency: The worst-case latency in microseconds that CPU is * unavailable during a transition from any P state to * this P state. * @bus_master_latency: The worst-case latency in microseconds that Bus Masters * are prevented from accessing memory during a transition * from any P state to this P state. * @control: The value to be written to Performance Control Register * @status: Transition status. */ struct acrn_pstate_data { … }; #define PMCMD_TYPE_MASK … enum acrn_pm_cmd_type { … }; #define ACRN_IOEVENTFD_FLAG_PIO … #define ACRN_IOEVENTFD_FLAG_DATAMATCH … #define ACRN_IOEVENTFD_FLAG_DEASSIGN … /** * struct acrn_ioeventfd - Data to operate a &struct hsm_ioeventfd * @fd: The fd of eventfd associated with a hsm_ioeventfd * @flags: Logical-OR of ACRN_IOEVENTFD_FLAG_* * @addr: The start address of IO range of ioeventfd * @len: The length of IO range of ioeventfd * @reserved: Reserved and should be 0 * @data: Data for data matching * * Without flag ACRN_IOEVENTFD_FLAG_DEASSIGN, ioctl ACRN_IOCTL_IOEVENTFD * creates a &struct hsm_ioeventfd with properties originated from &struct * acrn_ioeventfd. With flag ACRN_IOEVENTFD_FLAG_DEASSIGN, ioctl * ACRN_IOCTL_IOEVENTFD destroys the &struct hsm_ioeventfd matching the fd. */ struct acrn_ioeventfd { … }; #define ACRN_IRQFD_FLAG_DEASSIGN … /** * struct acrn_irqfd - Data to operate a &struct hsm_irqfd * @fd: The fd of eventfd associated with a hsm_irqfd * @flags: Logical-OR of ACRN_IRQFD_FLAG_* * @msi: Info of MSI associated with the irqfd */ struct acrn_irqfd { … }; /* The ioctl type, documented in ioctl-number.rst */ #define ACRN_IOCTL_TYPE … /* * Common IOCTL IDs definition for ACRN userspace */ #define ACRN_IOCTL_CREATE_VM … #define ACRN_IOCTL_DESTROY_VM … #define ACRN_IOCTL_START_VM … #define ACRN_IOCTL_PAUSE_VM … #define ACRN_IOCTL_RESET_VM … #define ACRN_IOCTL_SET_VCPU_REGS … #define ACRN_IOCTL_INJECT_MSI … #define ACRN_IOCTL_VM_INTR_MONITOR … #define ACRN_IOCTL_SET_IRQLINE … #define ACRN_IOCTL_NOTIFY_REQUEST_FINISH … #define ACRN_IOCTL_CREATE_IOREQ_CLIENT … #define ACRN_IOCTL_ATTACH_IOREQ_CLIENT … #define ACRN_IOCTL_DESTROY_IOREQ_CLIENT … #define ACRN_IOCTL_CLEAR_VM_IOREQ … #define ACRN_IOCTL_SET_MEMSEG … #define ACRN_IOCTL_UNSET_MEMSEG … #define ACRN_IOCTL_SET_PTDEV_INTR … #define ACRN_IOCTL_RESET_PTDEV_INTR … #define ACRN_IOCTL_ASSIGN_PCIDEV … #define ACRN_IOCTL_DEASSIGN_PCIDEV … #define ACRN_IOCTL_ASSIGN_MMIODEV … #define ACRN_IOCTL_DEASSIGN_MMIODEV … #define ACRN_IOCTL_CREATE_VDEV … #define ACRN_IOCTL_DESTROY_VDEV … #define ACRN_IOCTL_PM_GET_CPU_STATE … #define ACRN_IOCTL_IOEVENTFD … #define ACRN_IOCTL_IRQFD … #endif /* _UAPI_ACRN_H */