123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- /* 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 GH_IOCTL_TYPE 'G'
- /*
- * ioctls for /dev/gunyah fds:
- */
- #define GH_CREATE_VM _IO(GH_IOCTL_TYPE, 0x0) /* Returns a Gunyah VM fd */
- /*
- * ioctls for VM fds
- */
- /**
- * enum gh_mem_flags - Possible flags on &struct gh_userspace_memory_region
- * @GH_MEM_ALLOW_READ: Allow guest to read the memory
- * @GH_MEM_ALLOW_WRITE: Allow guest to write to the memory
- * @GH_MEM_ALLOW_EXEC: Allow guest to execute instructions in the memory
- */
- enum gh_mem_flags {
- GH_MEM_ALLOW_READ = 1UL << 0,
- GH_MEM_ALLOW_WRITE = 1UL << 1,
- GH_MEM_ALLOW_EXEC = 1UL << 2,
- };
- /**
- * struct gh_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 gh_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(GH_IOCTL_TYPE, 0x1, \
- struct gh_userspace_memory_region)
- /**
- * struct gh_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 gh_vm_dtb_config {
- __u64 guest_phys_addr;
- __u64 size;
- };
- #define GH_VM_SET_DTB_CONFIG _IOW(GH_IOCTL_TYPE, 0x2, struct gh_vm_dtb_config)
- #define GH_VM_START _IO(GH_IOCTL_TYPE, 0x3)
- /**
- * enum gh_fn_type - Valid types of Gunyah VM functions
- * @GH_FN_VCPU: create a vCPU instance to control a vCPU
- * &struct gh_fn_desc.arg is a pointer to &struct gh_fn_vcpu_arg
- * Return: file descriptor to manipulate the vcpu.
- * @GH_FN_IRQFD: register eventfd to assert a Gunyah doorbell
- * &struct gh_fn_desc.arg is a pointer to &struct gh_fn_irqfd_arg
- * @GH_FN_IOEVENTFD: register ioeventfd to trigger when VM faults on parameter
- * &struct gh_fn_desc.arg is a pointer to &struct gh_fn_ioeventfd_arg
- */
- enum gh_fn_type {
- GH_FN_VCPU = 1,
- GH_FN_IRQFD,
- GH_FN_IOEVENTFD,
- };
- #define GH_FN_MAX_ARG_SIZE 256
- /**
- * struct gh_fn_vcpu_arg - Arguments to create a vCPU.
- * @id: vcpu id
- *
- * Create this function with &GH_VM_ADD_FUNCTION using type &GH_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 gh_fn_vcpu_arg {
- __u32 id;
- };
- /**
- * enum gh_irqfd_flags - flags for use in gh_fn_irqfd_arg
- * @GH_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 gh_irqfd_flags {
- GH_IRQFD_FLAGS_LEVEL = 1UL << 0,
- };
- /**
- * struct gh_fn_irqfd_arg - Arguments to create an irqfd function.
- *
- * Create this function with &GH_VM_ADD_FUNCTION using type &GH_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 gh_irqfd_flags
- * @padding: padding bytes
- */
- struct gh_fn_irqfd_arg {
- __u32 fd;
- __u32 label;
- __u32 flags;
- __u32 padding;
- };
- /**
- * enum gh_ioeventfd_flags - flags for use in gh_fn_ioeventfd_arg
- * @GH_IOEVENTFD_FLAGS_DATAMATCH: the event will be signaled only if the
- * written value to the registered address is
- * equal to &struct gh_fn_ioeventfd_arg.datamatch
- */
- enum gh_ioeventfd_flags {
- GH_IOEVENTFD_FLAGS_DATAMATCH = 1UL << 0,
- };
- /**
- * struct gh_fn_ioeventfd_arg - Arguments to create an ioeventfd function
- * @datamatch: data used when GH_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 gh_ioeventfd_flags
- * @padding: padding bytes
- *
- * Create this function with &GH_VM_ADD_FUNCTION using type &GH_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 GH_VCPU_RUN ioctl.
- */
- struct gh_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 gh_fn_desc - Arguments to create a VM function
- * @type: Type of the function. See &enum gh_fn_type.
- * @arg_size: Size of argument to pass to the function. arg_size <= GH_FN_MAX_ARG_SIZE
- * @arg: Pointer to argument given to the function. See &enum gh_fn_type for expected
- * arguments for a function type.
- */
- struct gh_fn_desc {
- __u32 type;
- __u32 arg_size;
- __u64 arg;
- };
- #define GH_VM_ADD_FUNCTION _IOW(GH_IOCTL_TYPE, 0x4, struct gh_fn_desc)
- #define GH_VM_REMOVE_FUNCTION _IOW(GH_IOCTL_TYPE, 0x7, struct gh_fn_desc)
- /*
- * ioctls for vCPU fds
- */
- /**
- * enum gh_vm_status - Stores status reason why VM is not runnable (exited).
- * @GH_VM_STATUS_LOAD_FAILED: VM didn't start because it couldn't be loaded.
- * @GH_VM_STATUS_EXITED: VM requested shutdown/reboot.
- * Use &struct gh_vm_exit_info.reason for further details.
- * @GH_VM_STATUS_CRASHED: VM state is unknown and has crashed.
- */
- enum gh_vm_status {
- GH_VM_STATUS_LOAD_FAILED = 1,
- GH_VM_STATUS_EXITED = 2,
- GH_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 gh_vcpu_run < PAGE_SIZE.
- */
- #define GH_VM_MAX_EXIT_REASON_SIZE 8u
- /**
- * struct gh_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 gh_vm_exit_info {
- __u16 type;
- __u16 padding;
- __u32 reason_size;
- __u8 reason[GH_VM_MAX_EXIT_REASON_SIZE];
- };
- /**
- * enum gh_vcpu_exit - Stores reason why &GH_VCPU_RUN ioctl recently exited with status 0
- * @GH_VCPU_EXIT_UNKNOWN: Not used, status != 0
- * @GH_VCPU_EXIT_MMIO: vCPU performed a read or write that could not be handled
- * by hypervisor or Linux. Use @struct gh_vcpu_run.mmio for
- * details of the read/write.
- * @GH_VCPU_EXIT_STATUS: vCPU not able to run because the VM has exited.
- * Use @struct gh_vcpu_run.status for why VM has exited.
- */
- enum gh_vcpu_exit {
- GH_VCPU_EXIT_UNKNOWN,
- GH_VCPU_EXIT_MMIO,
- GH_VCPU_EXIT_STATUS,
- };
- /**
- * struct gh_vcpu_run - Application code obtains a pointer to the gh_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 GH_VCPU_RUN returns successfully and gives reason why
- * GH_VCPU_RUN has stopped running the vCPU. See &enum gh_vcpu_exit.
- * @mmio: Used when exit_reason == GH_VCPU_EXIT_MMIO
- * The guest has faulted on an memory-mapped I/O instruction 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
- * @status: Used when exit_reason == GH_VCPU_EXIT_STATUS.
- * The guest VM is no longer runnable. This struct informs why.
- * @status.status: See &enum gh_vm_status for possible values
- * @status.exit_info: Used when status == GH_VM_STATUS_EXITED
- */
- struct gh_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;
- } mmio;
- struct {
- enum gh_vm_status status;
- struct gh_vm_exit_info exit_info;
- } status;
- };
- };
- #define GH_VCPU_RUN _IO(GH_IOCTL_TYPE, 0x5)
- #define GH_VCPU_MMAP_SIZE _IO(GH_IOCTL_TYPE, 0x6)
- /**
- * ANDROID: android14-6.1 unfortunately contains UAPI that won't be carried
- * in kernel.org. Expose orthogonal ioctls that will never conflict with
- * kernel.org for these UAPIs. See b/268234781.
- */
- #define GH_ANDROID_IOCTL_TYPE 'A'
- #define GH_VM_ANDROID_LEND_USER_MEM _IOW(GH_ANDROID_IOCTL_TYPE, 0x11, \
- struct gh_userspace_memory_region)
- struct gh_vm_firmware_config {
- __u64 guest_phys_addr;
- __u64 size;
- };
- #define GH_VM_ANDROID_SET_FW_CONFIG _IOW(GH_ANDROID_IOCTL_TYPE, 0x12, \
- struct gh_vm_firmware_config)
- #endif
|