123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
- /*
- * Copyright (c) 2023 MediaTek Inc.
- */
- /**
- * DOC: UAPI of GenieZone Hypervisor
- *
- * This file declares common data structure shared among user space,
- * kernel space, and GenieZone hypervisor.
- */
- #ifndef __GZVM_H__
- #define __GZVM_H__
- #include <linux/const.h>
- #include <linux/types.h>
- #include <linux/ioctl.h>
- #define GZVM_CAP_VM_GPA_SIZE 0xa5
- #define GZVM_CAP_PROTECTED_VM 0xffbadab1
- /* query hypervisor supported block-based demand page */
- #define GZVM_CAP_BLOCK_BASED_DEMAND_PAGING 0x9201
- /* sub-commands put in args[0] for GZVM_CAP_PROTECTED_VM */
- #define GZVM_CAP_PVM_SET_PVMFW_GPA 0
- #define GZVM_CAP_PVM_GET_PVMFW_SIZE 1
- /* GZVM_CAP_PVM_SET_PROTECTED_VM only sets protected but not load pvmfw */
- #define GZVM_CAP_PVM_SET_PROTECTED_VM 2
- /*
- * Architecture specific registers are to be defined and ORed with
- * the arch identifier.
- */
- #define GZVM_REG_ARCH_ARM64 0x6000000000000000ULL
- #define GZVM_REG_ARCH_MASK 0xff00000000000000ULL
- /*
- * Reg size = BIT((reg.id & GZVM_REG_SIZE_MASK) >> GZVM_REG_SIZE_SHIFT) bytes
- */
- #define GZVM_REG_SIZE_SHIFT 52
- #define GZVM_REG_SIZE_MASK 0x00f0000000000000ULL
- #define GZVM_REG_SIZE_U8 0x0000000000000000ULL
- #define GZVM_REG_SIZE_U16 0x0010000000000000ULL
- #define GZVM_REG_SIZE_U32 0x0020000000000000ULL
- #define GZVM_REG_SIZE_U64 0x0030000000000000ULL
- #define GZVM_REG_SIZE_U128 0x0040000000000000ULL
- #define GZVM_REG_SIZE_U256 0x0050000000000000ULL
- #define GZVM_REG_SIZE_U512 0x0060000000000000ULL
- #define GZVM_REG_SIZE_U1024 0x0070000000000000ULL
- #define GZVM_REG_SIZE_U2048 0x0080000000000000ULL
- /* Register type definitions */
- #define GZVM_REG_TYPE_SHIFT 16
- /* Register type: general purpose */
- #define GZVM_REG_TYPE_GENERAL (0x10 << GZVM_REG_TYPE_SHIFT)
- /* GZVM ioctls */
- #define GZVM_IOC_MAGIC 0x92 /* gz */
- /* ioctls for /dev/gzvm fds */
- #define GZVM_CREATE_VM _IO(GZVM_IOC_MAGIC, 0x01) /* Returns a Geniezone VM fd */
- /*
- * Check if the given capability is supported or not.
- * The argument is capability. Ex. GZVM_CAP_PROTECTED_VM or GZVM_CAP_VM_GPA_SIZE
- * return is 0 (supported, no error)
- * return is -EOPNOTSUPP (unsupported)
- * return is -EFAULT (failed to get the argument from userspace)
- */
- #define GZVM_CHECK_EXTENSION _IO(GZVM_IOC_MAGIC, 0x03)
- /* ioctls for VM fds */
- /* for GZVM_SET_MEMORY_REGION */
- struct gzvm_memory_region {
- __u32 slot;
- __u32 flags;
- __u64 guest_phys_addr;
- __u64 memory_size; /* bytes */
- };
- #define GZVM_SET_MEMORY_REGION _IOW(GZVM_IOC_MAGIC, 0x40, \
- struct gzvm_memory_region)
- /*
- * GZVM_CREATE_VCPU receives as a parameter the vcpu slot,
- * and returns a vcpu fd.
- */
- #define GZVM_CREATE_VCPU _IO(GZVM_IOC_MAGIC, 0x41)
- /* for GZVM_SET_USER_MEMORY_REGION */
- struct gzvm_userspace_memory_region {
- __u32 slot;
- __u32 flags;
- __u64 guest_phys_addr;
- /* bytes */
- __u64 memory_size;
- /* start of the userspace allocated memory */
- __u64 userspace_addr;
- };
- #define GZVM_SET_USER_MEMORY_REGION _IOW(GZVM_IOC_MAGIC, 0x46, \
- struct gzvm_userspace_memory_region)
- /* for GZVM_IRQ_LINE, irq field index values */
- #define GZVM_IRQ_VCPU_MASK 0xff
- #define GZVM_IRQ_LINE_TYPE GENMASK(27, 24)
- #define GZVM_IRQ_LINE_VCPU GENMASK(23, 16)
- #define GZVM_IRQ_LINE_VCPU2 GENMASK(31, 28)
- #define GZVM_IRQ_LINE_NUM GENMASK(15, 0)
- /* irq_type field */
- #define GZVM_IRQ_TYPE_CPU 0
- #define GZVM_IRQ_TYPE_SPI 1
- #define GZVM_IRQ_TYPE_PPI 2
- /* out-of-kernel GIC cpu interrupt injection irq_number field */
- #define GZVM_IRQ_CPU_IRQ 0
- #define GZVM_IRQ_CPU_FIQ 1
- struct gzvm_irq_level {
- union {
- __u32 irq;
- __s32 status;
- };
- __u32 level;
- };
- #define GZVM_IRQ_LINE _IOW(GZVM_IOC_MAGIC, 0x61, \
- struct gzvm_irq_level)
- enum gzvm_device_type {
- GZVM_DEV_TYPE_ARM_VGIC_V3_DIST = 0,
- GZVM_DEV_TYPE_ARM_VGIC_V3_REDIST = 1,
- GZVM_DEV_TYPE_MAX,
- };
- /**
- * struct gzvm_create_device: For GZVM_CREATE_DEVICE.
- * @dev_type: Device type.
- * @id: Device id.
- * @flags: Bypass to hypervisor to handle them and these are flags of virtual
- * devices.
- * @dev_addr: Device ipa address in VM's view.
- * @dev_reg_size: Device register range size.
- * @attr_addr: If user -> kernel, this is user virtual address of device
- * specific attributes (if needed). If kernel->hypervisor,
- * this is ipa.
- * @attr_size: This attr_size is the buffer size in bytes of each attribute
- * needed from various devices. The attribute here refers to the
- * additional data passed from VMM(e.g. Crosvm) to GenieZone
- * hypervisor when virtual devices were to be created. Thus,
- * we need attr_addr and attr_size in the gzvm_create_device
- * structure to keep track of the attribute mentioned.
- *
- * Store information needed to create device.
- */
- struct gzvm_create_device {
- __u32 dev_type;
- __u32 id;
- __u64 flags;
- __u64 dev_addr;
- __u64 dev_reg_size;
- __u64 attr_addr;
- __u64 attr_size;
- };
- #define GZVM_CREATE_DEVICE _IOWR(GZVM_IOC_MAGIC, 0xe0, \
- struct gzvm_create_device)
- /*
- * ioctls for vcpu fds
- */
- #define GZVM_RUN _IO(GZVM_IOC_MAGIC, 0x80)
- /* VM exit reason */
- enum {
- GZVM_EXIT_UNKNOWN = 0x92920000,
- GZVM_EXIT_MMIO = 0x92920001,
- GZVM_EXIT_HYPERCALL = 0x92920002,
- GZVM_EXIT_IRQ = 0x92920003,
- GZVM_EXIT_EXCEPTION = 0x92920004,
- GZVM_EXIT_DEBUG = 0x92920005,
- GZVM_EXIT_FAIL_ENTRY = 0x92920006,
- GZVM_EXIT_INTERNAL_ERROR = 0x92920007,
- GZVM_EXIT_SYSTEM_EVENT = 0x92920008,
- GZVM_EXIT_SHUTDOWN = 0x92920009,
- GZVM_EXIT_GZ = 0x9292000a,
- };
- /* exception definitions of GZVM_EXIT_EXCEPTION */
- enum {
- GZVM_EXCEPTION_UNKNOWN = 0x0,
- GZVM_EXCEPTION_PAGE_FAULT = 0x1,
- };
- /* hypercall definitions of GZVM_EXIT_HYPERCALL */
- enum {
- GZVM_HVC_MEM_RELINQUISH = 0xc6000009,
- };
- /**
- * struct gzvm_vcpu_run: Same purpose as kvm_run, this struct is
- * shared between userspace, kernel and
- * GenieZone hypervisor
- * @exit_reason: The reason why gzvm_vcpu_run has stopped running the vCPU
- * @immediate_exit: Polled when the vcpu is scheduled.
- * If set, immediately returns -EINTR
- * @padding1: Reserved for future-proof and must be zero filled
- * @mmio: The nested struct in anonymous union. Handle mmio in host side
- * @phys_addr: The address guest tries to access
- * @data: The value to be written (is_write is 1) or
- * be filled by user for reads (is_write is 0)
- * @size: The size of written data.
- * Only the first `size` bytes of `data` are handled
- * @reg_nr: The register number where the data is stored
- * @is_write: 1 for VM to perform a write or 0 for VM to perform a read
- * @fail_entry: The nested struct in anonymous union.
- * Handle invalid entry address at the first run
- * @hardware_entry_failure_reason: The reason codes about hardware entry failure
- * @cpu: The current processor number via smp_processor_id()
- * @exception: The nested struct in anonymous union.
- * Handle exception occurred in VM
- * @exception: Which exception vector
- * @error_code: Exception error codes
- * @fault_gpa: Fault GPA (guest physical address or IPA in ARM)
- * @reserved: Future-proof reservation and reset to zero in hypervisor.
- * Fill up to the union size, 256 bytes.
- * @hypercall: The nested struct in anonymous union.
- * Some hypercalls issued from VM must be handled
- * @args: The hypercall's arguments
- * @internal: The nested struct in anonymous union. The errors from hypervisor
- * @suberror: The errors codes about GZVM_EXIT_INTERNAL_ERROR
- * @ndata: The number of elements used in data[]
- * @data: Keep the detailed information about GZVM_EXIT_INTERNAL_ERROR
- * @system_event: The nested struct in anonymous union.
- * VM's PSCI must be handled by host
- * @type: System event type.
- * Ex. GZVM_SYSTEM_EVENT_SHUTDOWN or GZVM_SYSTEM_EVENT_RESET...etc.
- * @ndata: The number of elements used in data[]
- * @data: Keep the detailed information about GZVM_EXIT_SYSTEM_EVENT
- * @padding: Fix it to a reasonable size future-proof for keeping the same
- * struct size when adding new variables in the union is needed
- *
- * Keep identical layout between the 3 modules
- */
- struct gzvm_vcpu_run {
- /* to userspace */
- __u32 exit_reason;
- __u8 immediate_exit;
- __u8 padding1[3];
- /* union structure of collection of guest exit reason */
- union {
- /* GZVM_EXIT_MMIO */
- struct {
- /* from FAR_EL2 */
- __u64 phys_addr;
- __u8 data[8];
- /* from ESR_EL2 as */
- __u64 size;
- /* from ESR_EL2 */
- __u32 reg_nr;
- /* from ESR_EL2 */
- __u8 is_write;
- } mmio;
- /* GZVM_EXIT_FAIL_ENTRY */
- struct {
- __u64 hardware_entry_failure_reason;
- __u32 cpu;
- } fail_entry;
- /* GZVM_EXIT_EXCEPTION */
- struct {
- __u32 exception;
- __u32 error_code;
- __u64 fault_gpa;
- __u64 reserved[30];
- } exception;
- /* GZVM_EXIT_HYPERCALL */
- struct {
- __u64 args[8]; /* in-out */
- } hypercall;
- /* GZVM_EXIT_INTERNAL_ERROR */
- struct {
- __u32 suberror;
- __u32 ndata;
- __u64 data[16];
- } internal;
- /* GZVM_EXIT_SYSTEM_EVENT */
- struct {
- #define GZVM_SYSTEM_EVENT_SHUTDOWN 1
- #define GZVM_SYSTEM_EVENT_RESET 2
- #define GZVM_SYSTEM_EVENT_CRASH 3
- #define GZVM_SYSTEM_EVENT_WAKEUP 4
- #define GZVM_SYSTEM_EVENT_SUSPEND 5
- #define GZVM_SYSTEM_EVENT_SEV_TERM 6
- #define GZVM_SYSTEM_EVENT_S2IDLE 7
- __u32 type;
- __u32 ndata;
- __u64 data[16];
- } system_event;
- char padding[256];
- };
- };
- /**
- * struct gzvm_enable_cap: The `capability support` on GenieZone hypervisor
- * @cap: `GZVM_CAP_ARM_PROTECTED_VM` or `GZVM_CAP_ARM_VM_IPA_SIZE`
- * @args: x3-x7 registers can be used for additional args
- */
- struct gzvm_enable_cap {
- __u64 cap;
- __u64 args[5];
- };
- #define GZVM_ENABLE_CAP _IOW(GZVM_IOC_MAGIC, 0xa3, \
- struct gzvm_enable_cap)
- /* for GZVM_GET/SET_ONE_REG */
- struct gzvm_one_reg {
- __u64 id;
- __u64 addr;
- };
- #define GZVM_GET_ONE_REG _IOW(GZVM_IOC_MAGIC, 0xab, \
- struct gzvm_one_reg)
- #define GZVM_SET_ONE_REG _IOW(GZVM_IOC_MAGIC, 0xac, \
- struct gzvm_one_reg)
- #define GZVM_REG_GENERIC 0x0000000000000000ULL
- #define GZVM_IRQFD_FLAG_DEASSIGN BIT(0)
- /*
- * GZVM_IRQFD_FLAG_RESAMPLE indicates resamplefd is valid and specifies
- * the irqfd to operate in resampling mode for level triggered interrupt
- * emulation.
- */
- #define GZVM_IRQFD_FLAG_RESAMPLE BIT(1)
- /**
- * struct gzvm_irqfd: gzvm irqfd descriptor
- * @fd: File descriptor.
- * @gsi: Used for level IRQ fast-path.
- * @flags: FLAG_DEASSIGN or FLAG_RESAMPLE.
- * @resamplefd: The file descriptor of the resampler.
- * @pad: Reserved for future-proof.
- */
- struct gzvm_irqfd {
- __u32 fd;
- __u32 gsi;
- __u32 flags;
- __u32 resamplefd;
- __u8 pad[16];
- };
- #define GZVM_IRQFD _IOW(GZVM_IOC_MAGIC, 0x76, struct gzvm_irqfd)
- enum {
- gzvm_ioeventfd_flag_nr_datamatch = 0,
- gzvm_ioeventfd_flag_nr_pio = 1,
- gzvm_ioeventfd_flag_nr_deassign = 2,
- gzvm_ioeventfd_flag_nr_max,
- };
- #define GZVM_IOEVENTFD_FLAG_DATAMATCH (1 << gzvm_ioeventfd_flag_nr_datamatch)
- #define GZVM_IOEVENTFD_FLAG_PIO (1 << gzvm_ioeventfd_flag_nr_pio)
- #define GZVM_IOEVENTFD_FLAG_DEASSIGN (1 << gzvm_ioeventfd_flag_nr_deassign)
- #define GZVM_IOEVENTFD_VALID_FLAG_MASK ((1 << gzvm_ioeventfd_flag_nr_max) - 1)
- struct gzvm_ioeventfd {
- __u64 datamatch;
- /* private: legal pio/mmio address */
- __u64 addr;
- /* private: 1, 2, 4, or 8 bytes; or 0 to ignore length */
- __u32 len;
- __s32 fd;
- __u32 flags;
- __u8 pad[36];
- };
- #define GZVM_IOEVENTFD _IOW(GZVM_IOC_MAGIC, 0x79, struct gzvm_ioeventfd)
- /**
- * struct gzvm_dtb_config: store address and size of dtb passed from userspace
- *
- * @dtb_addr: dtb address set by VMM (guset memory)
- * @dtb_size: dtb size
- */
- struct gzvm_dtb_config {
- __u64 dtb_addr;
- __u64 dtb_size;
- };
- #define GZVM_SET_DTB_CONFIG _IOW(GZVM_IOC_MAGIC, 0xff, \
- struct gzvm_dtb_config)
- #endif /* __GZVM_H__ */
|