391 lines
13 KiB
C
Executable File
391 lines
13 KiB
C
Executable File
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
|
|
/*
|
|
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
*/
|
|
|
|
#ifndef _UAPI_LINUX_GUNYAH_H
|
|
#define _UAPI_LINUX_GUNYAH_H
|
|
|
|
/*
|
|
* Userspace interface for /dev/gunyah - gunyah based virtual machine
|
|
*/
|
|
|
|
#include <linux/types.h>
|
|
#include <linux/ioctl.h>
|
|
|
|
#define GUNYAH_IOCTL_TYPE 'G'
|
|
|
|
/*
|
|
* ioctls for /dev/gunyah fds:
|
|
*/
|
|
#define GUNYAH_CREATE_VM _IO(GUNYAH_IOCTL_TYPE, 0x0) /* Returns a Gunyah VM fd */
|
|
|
|
/*
|
|
* ioctls for gunyah-vm fds (returned by GUNYAH_CREATE_VM)
|
|
*/
|
|
|
|
/**
|
|
* struct gunyah_vm_dtb_config - Set the location of the VM's devicetree blob
|
|
* @guest_phys_addr: Address of the VM's devicetree in guest memory.
|
|
* @size: Maximum size of the devicetree including space for overlays.
|
|
* Resource manager applies an overlay to the DTB and dtb_size should
|
|
* include room for the overlay. A page of memory is typicaly plenty.
|
|
*/
|
|
struct gunyah_vm_dtb_config {
|
|
__u64 guest_phys_addr;
|
|
__u64 size;
|
|
};
|
|
#define GUNYAH_VM_SET_DTB_CONFIG _IOW(GUNYAH_IOCTL_TYPE, 0x2, struct gunyah_vm_dtb_config)
|
|
|
|
#define GUNYAH_VM_START _IO(GUNYAH_IOCTL_TYPE, 0x3)
|
|
|
|
/**
|
|
* enum gunyah_fn_type - Valid types of Gunyah VM functions
|
|
* @GUNYAH_FN_VCPU: create a vCPU instance to control a vCPU
|
|
* &struct gunyah_fn_desc.arg is a pointer to &struct gunyah_fn_vcpu_arg
|
|
* Return: file descriptor to manipulate the vcpu.
|
|
* @GUNYAH_FN_IRQFD: register eventfd to assert a Gunyah doorbell
|
|
* &struct gunyah_fn_desc.arg is a pointer to &struct gunyah_fn_irqfd_arg
|
|
* @GUNYAH_FN_IOEVENTFD: register ioeventfd to trigger when VM faults on parameter
|
|
* &struct gunyah_fn_desc.arg is a pointer to &struct gunyah_fn_ioeventfd_arg
|
|
*/
|
|
enum gunyah_fn_type {
|
|
GUNYAH_FN_VCPU = 1,
|
|
GUNYAH_FN_IRQFD,
|
|
GUNYAH_FN_IOEVENTFD,
|
|
};
|
|
|
|
#define GUNYAH_FN_MAX_ARG_SIZE 256
|
|
|
|
/**
|
|
* struct gunyah_fn_vcpu_arg - Arguments to create a vCPU.
|
|
* @id: vcpu id
|
|
*
|
|
* Create this function with &GUNYAH_VM_ADD_FUNCTION using type &GUNYAH_FN_VCPU.
|
|
*
|
|
* The vcpu type will register with the VM Manager to expect to control
|
|
* vCPU number `vcpu_id`. It returns a file descriptor allowing interaction with
|
|
* the vCPU. See the Gunyah vCPU API description sections for interacting with
|
|
* the Gunyah vCPU file descriptors.
|
|
*/
|
|
struct gunyah_fn_vcpu_arg {
|
|
__u32 id;
|
|
};
|
|
|
|
/**
|
|
* enum gunyah_irqfd_flags - flags for use in gunyah_fn_irqfd_arg
|
|
* @GUNYAH_IRQFD_FLAGS_LEVEL: make the interrupt operate like a level triggered
|
|
* interrupt on guest side. Triggering IRQFD before
|
|
* guest handles the interrupt causes interrupt to
|
|
* stay asserted.
|
|
*/
|
|
enum gunyah_irqfd_flags {
|
|
GUNYAH_IRQFD_FLAGS_LEVEL = 1UL << 0,
|
|
};
|
|
|
|
/**
|
|
* struct gunyah_fn_irqfd_arg - Arguments to create an irqfd function.
|
|
*
|
|
* Create this function with &GUNYAH_VM_ADD_FUNCTION using type &GUNYAH_FN_IRQFD.
|
|
*
|
|
* Allows setting an eventfd to directly trigger a guest interrupt.
|
|
* irqfd.fd specifies the file descriptor to use as the eventfd.
|
|
* irqfd.label corresponds to the doorbell label used in the guest VM's devicetree.
|
|
*
|
|
* @fd: an eventfd which when written to will raise a doorbell
|
|
* @label: Label of the doorbell created on the guest VM
|
|
* @flags: see &enum gunyah_irqfd_flags
|
|
* @padding: padding bytes
|
|
*/
|
|
struct gunyah_fn_irqfd_arg {
|
|
__u32 fd;
|
|
__u32 label;
|
|
__u32 flags;
|
|
__u32 padding;
|
|
};
|
|
|
|
/**
|
|
* enum gunyah_ioeventfd_flags - flags for use in gunyah_fn_ioeventfd_arg
|
|
* @GUNYAH_IOEVENTFD_FLAGS_DATAMATCH: the event will be signaled only if the
|
|
* written value to the registered address is
|
|
* equal to &struct gunyah_fn_ioeventfd_arg.datamatch
|
|
*/
|
|
enum gunyah_ioeventfd_flags {
|
|
GUNYAH_IOEVENTFD_FLAGS_DATAMATCH = 1UL << 0,
|
|
};
|
|
|
|
/**
|
|
* struct gunyah_fn_ioeventfd_arg - Arguments to create an ioeventfd function
|
|
* @datamatch: data used when GUNYAH_IOEVENTFD_DATAMATCH is set
|
|
* @addr: Address in guest memory
|
|
* @len: Length of access
|
|
* @fd: When ioeventfd is matched, this eventfd is written
|
|
* @flags: See &enum gunyah_ioeventfd_flags
|
|
* @padding: padding bytes
|
|
*
|
|
* Create this function with &GUNYAH_VM_ADD_FUNCTION using type &GUNYAH_FN_IOEVENTFD.
|
|
*
|
|
* Attaches an ioeventfd to a legal mmio address within the guest. A guest write
|
|
* in the registered address will signal the provided event instead of triggering
|
|
* an exit on the GUNYAH_VCPU_RUN ioctl.
|
|
*/
|
|
struct gunyah_fn_ioeventfd_arg {
|
|
__u64 datamatch;
|
|
__u64 addr; /* legal mmio address */
|
|
__u32 len; /* 1, 2, 4, or 8 bytes; or 0 to ignore length */
|
|
__s32 fd;
|
|
__u32 flags;
|
|
__u32 padding;
|
|
};
|
|
|
|
/**
|
|
* struct gunyah_fn_desc - Arguments to create a VM function
|
|
* @type: Type of the function. See &enum gunyah_fn_type.
|
|
* @arg_size: Size of argument to pass to the function. arg_size <= GUNYAH_FN_MAX_ARG_SIZE
|
|
* @arg: Pointer to argument given to the function. See &enum gunyah_fn_type for expected
|
|
* arguments for a function type.
|
|
*/
|
|
struct gunyah_fn_desc {
|
|
__u32 type;
|
|
__u32 arg_size;
|
|
__u64 arg;
|
|
};
|
|
|
|
#define GUNYAH_VM_ADD_FUNCTION _IOW(GUNYAH_IOCTL_TYPE, 0x4, struct gunyah_fn_desc)
|
|
#define GUNYAH_VM_REMOVE_FUNCTION _IOW(GUNYAH_IOCTL_TYPE, 0x7, struct gunyah_fn_desc)
|
|
|
|
/**
|
|
* enum gunyah_map_flags- Possible flags on &struct gunyah_map_mem_args
|
|
* @GUNYAH_MEM_DEFAULT_SHARE: Use default host access for the VM type
|
|
* @GUNYAH_MEM_FORCE_LEND: Force unmapping the memory once the guest starts to use
|
|
* @GUNYAH_MEM_FORCE_SHARE: Allow host to continue accessing memory when guest starts to use
|
|
* @GUNYAH_MEM_ALLOW_READ: Allow guest to read memory
|
|
* @GUNYAH_MEM_ALLOW_WRITE: Allow guest to write to the memory
|
|
* @GUNYAH_MEM_ALLOW_EXEC: Allow guest to execute instructions in the memory
|
|
*/
|
|
enum gunyah_map_flags {
|
|
GUNYAH_MEM_ALLOW_READ = 1UL << 0,
|
|
GUNYAH_MEM_ALLOW_WRITE = 1UL << 1,
|
|
GUNYAH_MEM_ALLOW_EXEC = 1UL << 2,
|
|
GUNYAH_MEM_ALLOW_RWX =
|
|
(GUNYAH_MEM_ALLOW_READ | GUNYAH_MEM_ALLOW_WRITE | GUNYAH_MEM_ALLOW_EXEC),
|
|
GUNYAH_MEM_DEFAULT_ACCESS = 0x00,
|
|
GUNYAH_MEM_FORCE_LEND = 0x10,
|
|
GUNYAH_MEM_FORCE_SHARE = 0x20,
|
|
#define GUNYAH_MEM_ACCESS_MASK 0x70
|
|
|
|
GUNYAH_MEM_UNMAP = 1UL << 8,
|
|
};
|
|
|
|
/**
|
|
* struct gunyah_map_mem_args - Description to provide guest memory into a VM
|
|
* @guest_addr: Location in guest address space to place the memory
|
|
* @flags: See &enum gunyah_map_flags.
|
|
* @guest_mem_fd: File descriptor created by GUNYAH_CREATE_GUEST_MEM
|
|
* @offset: Offset into the guest memory file
|
|
*/
|
|
struct gunyah_map_mem_args {
|
|
__u64 guest_addr;
|
|
__u32 flags;
|
|
__u32 guest_mem_fd;
|
|
__u64 offset;
|
|
__u64 size;
|
|
};
|
|
|
|
#define GUNYAH_VM_MAP_MEM _IOW(GUNYAH_IOCTL_TYPE, 0x9, struct gunyah_map_mem_args)
|
|
|
|
enum gunyah_vm_boot_context_reg {
|
|
REG_SET_X = 0,
|
|
REG_SET_PC = 1,
|
|
REG_SET_SP = 2,
|
|
};
|
|
|
|
#define GUNYAH_VM_BOOT_CONTEXT_REG_SHIFT 8
|
|
#define GUNYAH_VM_BOOT_CONTEXT_REG(reg, idx) (((reg & 0xff) << GUNYAH_VM_BOOT_CONTEXT_REG_SHIFT) |\
|
|
(idx & 0xff))
|
|
|
|
/**
|
|
* struct gunyah_vm_boot_context - Set an initial register for the VM
|
|
* @reg: Register to set. See GUNYAH_VM_BOOT_CONTEXT_REG_* macros
|
|
* @reserved: reserved for alignment
|
|
* @value: value to fill in the register
|
|
*/
|
|
struct gunyah_vm_boot_context {
|
|
__u32 reg;
|
|
__u32 reserved;
|
|
__u64 value;
|
|
};
|
|
#define GUNYAH_VM_SET_BOOT_CONTEXT _IOW(GUNYAH_IOCTL_TYPE, 0xa, struct gunyah_vm_boot_context)
|
|
|
|
/*
|
|
* ioctls for vCPU fds
|
|
*/
|
|
|
|
/**
|
|
* enum gunyah_vm_status - Stores status reason why VM is not runnable (exited).
|
|
* @GUNYAH_VM_STATUS_LOAD_FAILED: VM didn't start because it couldn't be loaded.
|
|
* @GUNYAH_VM_STATUS_EXITED: VM requested shutdown/reboot.
|
|
* Use &struct gunyah_vm_exit_info.reason for further details.
|
|
* @GUNYAH_VM_STATUS_CRASHED: VM state is unknown and has crashed.
|
|
*/
|
|
enum gunyah_vm_status {
|
|
GUNYAH_VM_STATUS_LOAD_FAILED = 1,
|
|
GUNYAH_VM_STATUS_EXITED = 2,
|
|
GUNYAH_VM_STATUS_CRASHED = 3,
|
|
};
|
|
|
|
/*
|
|
* Gunyah presently sends max 4 bytes of exit_reason.
|
|
* If that changes, this macro can be safely increased without breaking
|
|
* userspace so long as struct gunyah_vcpu_run < PAGE_SIZE.
|
|
*/
|
|
#define GUNYAH_VM_MAX_EXIT_REASON_SIZE 8u
|
|
|
|
/**
|
|
* struct gunyah_vm_exit_info - Reason for VM exit as reported by Gunyah
|
|
* See Gunyah documentation for values.
|
|
* @type: Describes how VM exited
|
|
* @padding: padding bytes
|
|
* @reason_size: Number of bytes valid for `reason`
|
|
* @reason: See Gunyah documentation for interpretation. Note: these values are
|
|
* not interpreted by Linux and need to be converted from little-endian
|
|
* as applicable.
|
|
*/
|
|
struct gunyah_vm_exit_info {
|
|
__u16 type;
|
|
__u16 padding;
|
|
__u32 reason_size;
|
|
__u8 reason[GUNYAH_VM_MAX_EXIT_REASON_SIZE];
|
|
};
|
|
|
|
/**
|
|
* enum gunyah_vcpu_exit - Stores reason why &GUNYAH_VCPU_RUN ioctl recently exited with status 0
|
|
* @GUNYAH_VCPU_EXIT_UNKNOWN: Not used, status != 0
|
|
* @GUNYAH_VCPU_EXIT_MMIO: vCPU performed a read or write that could not be handled
|
|
* by hypervisor or Linux. Use @struct gunyah_vcpu_run.mmio for
|
|
* details of the read/write.
|
|
* @GUNYAH_VCPU_EXIT_STATUS: vCPU not able to run because the VM has exited.
|
|
* Use @struct gunyah_vcpu_run.status for why VM has exited.
|
|
* @GUNYAH_VCPU_EXIT_PAGE_FAULT: vCPU tried to execute an instruction at an address
|
|
* for which memory hasn't been provided. Use
|
|
* @struct gunyah_vcpu_run.page_fault for details.
|
|
*/
|
|
enum gunyah_vcpu_exit {
|
|
GUNYAH_VCPU_EXIT_UNKNOWN,
|
|
GUNYAH_VCPU_EXIT_MMIO,
|
|
GUNYAH_VCPU_EXIT_STATUS,
|
|
GUNYAH_VCPU_EXIT_PAGE_FAULT,
|
|
};
|
|
|
|
/**
|
|
* enum gunyah_vcpu_resume_action - Provide resume action after an MMIO or page fault
|
|
* @GUNYAH_VCPU_RESUME_HANDLED: The mmio or page fault has been handled, continue
|
|
* normal operation of vCPU
|
|
* @GUNYAH_VCPU_RESUME_FAULT: The mmio or page fault could not be satisfied and
|
|
* inject the original fault back to the guest.
|
|
* @GUNYAH_VCPU_RESUME_RETRY: Retry the faulting instruction. Perhaps you added
|
|
* memory binding to satisfy the request.
|
|
*/
|
|
enum gunyah_vcpu_resume_action {
|
|
GUNYAH_VCPU_RESUME_HANDLED = 0,
|
|
GUNYAH_VCPU_RESUME_FAULT,
|
|
GUNYAH_VCPU_RESUME_RETRY,
|
|
};
|
|
|
|
/**
|
|
* struct gunyah_vcpu_run - Application code obtains a pointer to the gunyah_vcpu_run
|
|
* structure by mmap()ing a vcpu fd.
|
|
* @immediate_exit: polled when scheduling the vcpu. If set, immediately returns -EINTR.
|
|
* @padding: padding bytes
|
|
* @exit_reason: Set when GUNYAH_VCPU_RUN returns successfully and gives reason why
|
|
* GUNYAH_VCPU_RUN has stopped running the vCPU. See &enum gunyah_vcpu_exit.
|
|
* @mmio: Used when exit_reason == GUNYAH_VCPU_EXIT_MMIO
|
|
* The guest has faulted on an memory-mapped I/O that
|
|
* couldn't be satisfied by gunyah.
|
|
* @mmio.phys_addr: Address guest tried to access
|
|
* @mmio.data: the value that was written if `is_write == 1`. Filled by
|
|
* user for reads (`is_write == 0`).
|
|
* @mmio.len: Length of write. Only the first `len` bytes of `data`
|
|
* are considered by Gunyah.
|
|
* @mmio.is_write: 1 if VM tried to perform a write, 0 for a read
|
|
* @mmio.resume_action: See &enum gunyah_vcpu_resume_action
|
|
* @status: Used when exit_reason == GUNYAH_VCPU_EXIT_STATUS.
|
|
* The guest VM is no longer runnable. This struct informs why.
|
|
* @status.status: See &enum gunyah_vm_status for possible values
|
|
* @status.exit_info: Used when status == GUNYAH_VM_STATUS_EXITED
|
|
* @page_fault: Used when EXIT_REASON == GUNYAH_VCPU_EXIT_PAGE_FAULT
|
|
* The guest has faulted on a region that can only be provided
|
|
* by mapping memory at phys_addr.
|
|
* @page_fault.phys_addr: Address guest tried to access.
|
|
* @page_fault.attempt: Error code why Linux wasn't able to handle fault itself
|
|
* Typically, if no memory was mapped: -ENOENT,
|
|
* If permission bits weren't what the VM wanted: -EPERM
|
|
* @page_fault.resume_action: See &enum gunyah_vcpu_resume_action
|
|
*/
|
|
struct gunyah_vcpu_run {
|
|
/* in */
|
|
__u8 immediate_exit;
|
|
__u8 padding[7];
|
|
|
|
/* out */
|
|
__u32 exit_reason;
|
|
|
|
union {
|
|
struct {
|
|
__u64 phys_addr;
|
|
__u8 data[8];
|
|
__u32 len;
|
|
__u8 is_write;
|
|
__u8 resume_action;
|
|
} mmio;
|
|
|
|
struct {
|
|
enum gunyah_vm_status status;
|
|
struct gunyah_vm_exit_info exit_info;
|
|
} status;
|
|
|
|
struct {
|
|
__u64 phys_addr;
|
|
__s32 attempt;
|
|
__u8 resume_action;
|
|
} page_fault;
|
|
};
|
|
};
|
|
|
|
#define GUNYAH_VCPU_RUN _IO(GUNYAH_IOCTL_TYPE, 0x5)
|
|
#define GUNYAH_VCPU_MMAP_SIZE _IO(GUNYAH_IOCTL_TYPE, 0x6)
|
|
|
|
/**
|
|
* struct gunyah_userspace_memory_region - Userspace memory descripion for GH_VM_SET_USER_MEM_REGION
|
|
* @label: Identifer to the region which is unique to the VM.
|
|
* @flags: Flags for memory parcel behavior. See &enum gh_mem_flags.
|
|
* @guest_phys_addr: Location of the memory region in guest's memory space (page-aligned)
|
|
* @memory_size: Size of the region (page-aligned)
|
|
* @userspace_addr: Location of the memory region in caller (userspace)'s memory
|
|
*
|
|
* See Documentation/virt/gunyah/vm-manager.rst for further details.
|
|
*/
|
|
struct gunyah_userspace_memory_region {
|
|
__u32 label;
|
|
__u32 flags;
|
|
__u64 guest_phys_addr;
|
|
__u64 memory_size;
|
|
__u64 userspace_addr;
|
|
};
|
|
|
|
#define GH_VM_SET_USER_MEM_REGION _IOW(GUNYAH_IOCTL_TYPE, 0x1, \
|
|
struct gunyah_userspace_memory_region)
|
|
#define GH_ANDROID_IOCTL_TYPE 'A'
|
|
|
|
#define GH_VM_ANDROID_LEND_USER_MEM _IOW(GH_ANDROID_IOCTL_TYPE, 0x11, \
|
|
struct gunyah_userspace_memory_region)
|
|
|
|
struct gunyah_vm_firmware_config {
|
|
__u64 guest_phys_addr;
|
|
__u64 size;
|
|
};
|
|
|
|
#define GH_VM_ANDROID_SET_FW_CONFIG _IOW(GH_ANDROID_IOCTL_TYPE, 0x12, \
|
|
struct gunyah_vm_firmware_config)
|
|
#endif
|