diff --git a/include/linux/gunyah/gh_common.h b/include/linux/gunyah/gh_common.h new file mode 100644 index 000000000000..e4f97e58f979 --- /dev/null +++ b/include/linux/gunyah/gh_common.h @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + */ + +#ifndef __GH_COMMON_H +#define __GH_COMMON_H + +#include + +/* Common Gunyah types */ +typedef u16 gh_vmid_t; +typedef u32 gh_rm_msgid_t; +typedef u32 gh_virq_handle_t; +typedef u32 gh_label_t; +typedef u32 gh_memparcel_handle_t; +typedef u64 gh_capid_t; +typedef u64 gh_dbl_flags_t; + +struct gh_vminfo { + u8 *guid; + char *uri; + char *name; + char *sign_auth; +}; + +/* Common Gunyah macros */ +#define GH_CAPID_INVAL U64_MAX +#define GH_VMID_INVAL U16_MAX + +enum gh_vm_names { + /* + * GH_SELF_VM is an alias for VMID 0. Useful for RM APIs which allow + * operations on current VM such as console + */ + GH_SELF_VM, + GH_PRIMARY_VM, + GH_TRUSTED_VM, + GH_CPUSYS_VM, + GH_OEM_VM, + GH_VM_MAX +}; + +#endif diff --git a/include/linux/gunyah/gh_dbl.h b/include/linux/gunyah/gh_dbl.h new file mode 100644 index 000000000000..ea2776c7d5c0 --- /dev/null +++ b/include/linux/gunyah/gh_dbl.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef __GH_DBL_H +#define __GH_DBL_H + +#include "gh_common.h" + +typedef void (*dbl_rx_cb_t)(int irq, void *priv_data); + +enum gh_dbl_label { + GH_DBL_TUI_LABEL, + GH_DBL_TUI_NEURON_BLK0, + GH_DBL_TUI_NEURON_BLK1, + GH_DBL_TUI_QRTR, + GH_DBL_TEST_TUIVM, + GH_DBL_TEST_OEMVM, + GH_DBL_HW_FENCE, + GH_DBL_TUI_DDUMP, + GH_DBL_OEMVM_QRTR, + GH_DBL_LABEL_MAX +}; + +/* Possible flags to pass for send, set_mask, read, reset */ +#define GH_DBL_NONBLOCK BIT(32) + +#if IS_ENABLED(CONFIG_GH_DBL) +void *gh_dbl_tx_register(enum gh_dbl_label label); +void *gh_dbl_rx_register(enum gh_dbl_label label, dbl_rx_cb_t rx_cb, + void *priv); + +int gh_dbl_tx_unregister(void *dbl_client_desc); +int gh_dbl_rx_unregister(void *dbl_client_desc); + +int gh_dbl_send(void *dbl_client_desc, uint64_t *newflags, + const unsigned long flags); +int gh_dbl_set_mask(void *dbl_client_desc, gh_dbl_flags_t enable_mask, + gh_dbl_flags_t ack_mask, const unsigned long flags); +int gh_dbl_read_and_clean(void *dbl_client_desc, gh_dbl_flags_t *clear_flags, + const unsigned long flags); +int gh_dbl_reset(void *dbl_client_desc, const unsigned long flags); +int gh_dbl_populate_cap_info(enum gh_dbl_label label, u64 cap_id, + int direction, int rx_irq); +int gh_dbl_reset_cap_info(enum gh_dbl_label label, int direction, int *irq); +#else +static inline void *gh_dbl_tx_register(enum gh_dbl_label label) +{ + return ERR_PTR(-ENODEV); +} + +static inline void *gh_dbl_rx_register(enum gh_dbl_label label, + dbl_rx_cb_t rx_cb, + void *priv) +{ + return ERR_PTR(-ENODEV); +} + +static inline int gh_dbl_tx_unregister(void *dbl_client_desc) +{ + return -EINVAL; +} + +static inline int gh_dbl_rx_unregister(void *dbl_client_desc) +{ + return -EINVAL; +} + +static inline int gh_dbl_send(void *dbl_client_desc, uint64_t *newflags, + const unsigned long flags) +{ + return -EINVAL; +} + +static inline int gh_dbl_set_mask(void *dbl_client_desc, + gh_dbl_flags_t enable_mask, + gh_dbl_flags_t ack_mask, + const unsigned long flags) +{ + return -EINVAL; +} + +static inline int gh_dbl_read_and_clean(void *dbl_client_desc, + gh_dbl_flags_t *clear_flags, + const unsigned long flags) +{ + return -EINVAL; +} + +static inline int gh_dbl_reset(void *dbl_client_desc, const unsigned long flags) +{ + return -EINVAL; +} + +static inline int gh_dbl_populate_cap_info(enum gh_dbl_label label, u64 cap_id, + int direction, int rx_irq) +{ + return -EINVAL; +} + +static inline +int gh_dbl_reset_cap_info(enum gh_dbl_label label, int direction, int *irq) +{ + return -EINVAL; +} +#endif +#endif diff --git a/include/linux/gunyah/gh_irq_lend.h b/include/linux/gunyah/gh_irq_lend.h new file mode 100644 index 000000000000..0aca1327ab6d --- /dev/null +++ b/include/linux/gunyah/gh_irq_lend.h @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + */ + +#ifndef __GH_IRQ_LEND_H +#define __GH_IRQ_LEND_H + +#include + +#include "gh_common.h" +#include "gh_rm_drv.h" + +enum gh_irq_label { + GH_IRQ_LABEL_SDE, + GH_IRQ_LABEL_TRUSTED_TOUCH_PRIMARY, + GH_IRQ_LABEL_TRUSTED_TOUCH_SECONDARY, + GH_IRQ_LABEL_TEST_TUIVM, + GH_IRQ_LABEL_TEST_OEMVM, + GH_IRQ_LABEL_MAX +}; + + +typedef void (*gh_irq_handle_fn)(void *req, enum gh_irq_label label); +typedef void (*gh_irq_handle_fn_v2)(void *req, unsigned long notif_type, + enum gh_irq_label label); + +#if IS_ENABLED(CONFIG_GH_IRQ_LEND) +int gh_irq_lend(enum gh_irq_label label, enum gh_vm_names name, + int hw_irq, gh_irq_handle_fn cb_handle, void *data); +int gh_irq_lend_v2(enum gh_irq_label label, enum gh_vm_names name, + int hw_irq, gh_irq_handle_fn_v2 cb_handle, void *data); +int gh_irq_lend_notify(enum gh_irq_label label); +int gh_irq_reclaim(enum gh_irq_label label); +int gh_irq_wait_for_lend(enum gh_irq_label label, enum gh_vm_names name, + gh_irq_handle_fn on_lend, void *data); +int gh_irq_wait_for_lend_v2(enum gh_irq_label label, enum gh_vm_names name, + gh_irq_handle_fn_v2 on_lend, void *data); +int gh_irq_accept(enum gh_irq_label label, int irq, int type); +int gh_irq_accept_notify(enum gh_irq_label label); +int gh_irq_release(enum gh_irq_label label); +int gh_irq_release_notify(enum gh_irq_label label); +#else + +int gh_irq_lend(enum gh_irq_label label, enum gh_vm_names name, + int hw_irq, gh_irq_handle_fn cb_handle, void *data) +{ + return -EINVAL; +} + +int gh_irq_lend_v2(enum gh_irq_label label, enum gh_vm_names name, + int hw_irq, gh_irq_handle_fn_v2 cb_handle, void *data) +{ + return -EINVAL; +} + +int gh_irq_lend_notify(enum gh_irq_label label) +{ + return -EINVAL; +} + +int gh_irq_reclaim(enum gh_irq_label label) +{ + return -EINVAL; +} + +int gh_irq_wait_for_lend(enum gh_irq_label label, enum gh_vm_names name, + gh_irq_handle_fn on_lend, void *data) +{ + return -EINVAL; +} + +int gh_irq_wait_for_lend_v2(enum gh_irq_label label, enum gh_vm_names name, + gh_irq_handle_fn_v2 on_lend, void *data) +{ + return -EINVAL; +} + +int gh_irq_accept(enum gh_irq_label label, int irq, int type) +{ + return -EINVAL; +} + +int gh_irq_accept_notify(enum gh_irq_label label) +{ + return -EINVAL; +} + +int gh_irq_release(enum gh_irq_label label) +{ + return -EINVAL; +} + +int gh_irq_release_notify(enum gh_irq_label label) +{ + return -EINVAL; +} + +#endif + +#endif diff --git a/include/linux/gunyah/gh_mem_notifier.h b/include/linux/gunyah/gh_mem_notifier.h new file mode 100644 index 000000000000..92973e8d335e --- /dev/null +++ b/include/linux/gunyah/gh_mem_notifier.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + */ + +#ifndef __GH_MEM_NOTIFIER_H +#define __GH_MEM_NOTIFIER_H + +#include +#include +#include +#include + +enum gh_mem_notifier_tag { + GH_MEM_NOTIFIER_TAG_DISPLAY, + GH_MEM_NOTIFIER_TAG_TOUCH_PRIMARY, + GH_MEM_NOTIFIER_TAG_TOUCH_SECONDARY, + GH_MEM_NOTIFIER_TAG_TLMM, + GH_MEM_NOTIFIER_TAG_TEST_TLMM, + GH_MEM_NOTIFIER_TAG_TEST_TUIVM, + GH_MEM_NOTIFIER_TAG_TEST_OEMVM, + GH_MEM_NOTIFIER_TAG_MAX +}; + +typedef void (*gh_mem_notifier_handler)(enum gh_mem_notifier_tag tag, + unsigned long notif_type, + void *entry_data, void *notif_msg); + +#if IS_ENABLED(CONFIG_GH_MEM_NOTIFIER) +void *gh_mem_notifier_register(enum gh_mem_notifier_tag tag, + gh_mem_notifier_handler notif_handler, + void *data); +void gh_mem_notifier_unregister(void *cookie); +#else +static void *gh_mem_notifier_register(enum gh_mem_notifier_tag tag, + gh_mem_notifier_handler notif_handler, + void *data) +{ + return ERR_PTR(-EOPNOTSUPP); +} + +static void gh_mem_notifier_unregister(void *cookie) +{ +} +#endif +#endif diff --git a/include/linux/gunyah/gh_msgq.h b/include/linux/gunyah/gh_msgq.h new file mode 100644 index 000000000000..a773feba397b --- /dev/null +++ b/include/linux/gunyah/gh_msgq.h @@ -0,0 +1,92 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * + */ + +#ifndef __GH_MSGQ_H +#define __GH_MSGQ_H + +#include +#include + +#include "gh_common.h" + +enum gh_msgq_label { + GH_MSGQ_LABEL_RM, + GH_MSGQ_LABEL_MEMBUF, + GH_MSGQ_LABEL_DISPLAY, + GH_MSGQ_LABEL_VSOCK, + GH_MSGQ_LABEL_TEST_TUIVM, + GH_MSGQ_LABEL_TEST_OEMVM, + GH_MSGQ_LABEL_MMRM, + GH_MSGQ_LABEL_EVA, + GH_MSGQ_VCPU_SCHED_TEST, + GH_MSGQ_LABEL_MAX +}; + +#define GH_MSGQ_MAX_MSG_SIZE_BYTES 240 + +#define GH_MSGQ_DIRECTION_TX 0 +#define GH_MSGQ_DIRECTION_RX 1 + +/* Possible flags to pass for Tx or Rx */ +#define GH_MSGQ_TX_PUSH BIT(0) +#define GH_MSGQ_NONBLOCK BIT(32) + +#if IS_ENABLED(CONFIG_GH_MSGQ) +void *gh_msgq_register(int label); +int gh_msgq_unregister(void *msgq_client_desc); +int gh_msgq_send(void *msgq_client_desc, + void *buff, size_t size, unsigned long flags); +int gh_msgq_recv(void *msgq_client_desc, + void *buff, size_t buff_size, + size_t *recv_size, unsigned long flags); + +int gh_msgq_populate_cap_info(int label, u64 cap_id, + int direction, int irq); +int gh_msgq_probe(struct platform_device *pdev, int label); +int gh_msgq_reset_cap_info(enum gh_msgq_label label, int direction, int *irq); +#else +static inline void *gh_msgq_register(int label) +{ + return ERR_PTR(-ENODEV); +} + +static inline int gh_msgq_unregister(void *msgq_client_desc) +{ + return -EINVAL; +} + +static inline int gh_msgq_send(void *msgq_client_desc, + void *buff, size_t size, unsigned long flags) +{ + return -EINVAL; +} + +static inline int gh_msgq_recv(void *msgq_client_desc, + void *buff, size_t buff_size, + size_t *recv_size, unsigned long flags) +{ + return -EINVAL; +} + +static inline int gh_msgq_populate_cap_info(int label, u64 cap_id, + int direction, int irq) +{ + return -EINVAL; +} + +static inline +int gh_msgq_reset_cap_info(enum gh_msgq_label label, int direction, int *irq) +{ + return -EINVAL; +} + +static inline int gh_msgq_probe(struct platform_device *pdev, int label) +{ + return -ENODEV; +} +#endif +#endif diff --git a/include/linux/gunyah/gh_rm_drv.h b/include/linux/gunyah/gh_rm_drv.h new file mode 100644 index 000000000000..557656797fc8 --- /dev/null +++ b/include/linux/gunyah/gh_rm_drv.h @@ -0,0 +1,695 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * + */ + +#ifndef __GH_RM_DRV_H +#define __GH_RM_DRV_H + +#include +#include +#include + +#include "gh_common.h" + +/* Notification type Message IDs */ +/* Memory APIs */ +#define GH_RM_NOTIF_MEM_SHARED 0x51100011 +#define GH_RM_NOTIF_MEM_RELEASED 0x51100012 +#define GH_RM_NOTIF_MEM_ACCEPTED 0x51100013 + +#define GH_RM_MEM_TYPE_NORMAL 0 +#define GH_RM_MEM_TYPE_IO 1 + +#define GH_RM_TRANS_TYPE_DONATE 0 +#define GH_RM_TRANS_TYPE_LEND 1 +#define GH_RM_TRANS_TYPE_SHARE 2 + +#define GH_RM_ACL_X BIT(0) +#define GH_RM_ACL_W BIT(1) +#define GH_RM_ACL_R BIT(2) + +#define GH_RM_MEM_RELEASE_CLEAR BIT(0) +#define GH_RM_MEM_RECLAIM_CLEAR BIT(0) + +#define GH_RM_MEM_ACCEPT_VALIDATE_SANITIZED BIT(0) +#define GH_RM_MEM_ACCEPT_VALIDATE_ACL_ATTRS BIT(1) +#define GH_RM_MEM_ACCEPT_VALIDATE_LABEL BIT(2) +#define GH_RM_MEM_ACCEPT_MAP_IPA_CONTIGUOUS BIT(4) +#define GH_RM_MEM_ACCEPT_DONE BIT(7) + +#define GH_RM_MEM_SHARE_SANITIZE BIT(0) +#define GH_RM_MEM_SHARE_APPEND BIT(1) +#define GH_RM_MEM_LEND_SANITIZE BIT(0) +#define GH_RM_MEM_LEND_APPEND BIT(1) +#define GH_RM_MEM_DONATE_SANITIZE BIT(0) +#define GH_RM_MEM_DONATE_APPEND BIT(1) + +#define GH_RM_MEM_APPEND_END BIT(0) + +#define GH_RM_MEM_NOTIFY_RECIPIENT_SHARED BIT(0) +#define GH_RM_MEM_NOTIFY_RECIPIENT GH_RM_MEM_NOTIFY_RECIPIENT_SHARED +#define GH_RM_MEM_NOTIFY_OWNER_RELEASED BIT(1) +#define GH_RM_MEM_NOTIFY_OWNER GH_RM_MEM_NOTIFY_OWNER_RELEASED +#define GH_RM_MEM_NOTIFY_OWNER_ACCEPTED BIT(2) + +#define MAX_EXIT_REASON_SIZE 4 + +struct gh_rm_mem_shared_acl_entry; +struct gh_rm_mem_shared_sgl_entry; +struct gh_rm_mem_shared_attr_entry; + +struct gh_rm_notif_mem_shared_payload { + u32 mem_handle; + u8 mem_type; + u8 trans_type; + u8 flags; + u8 reserved1; + u16 owner_vmid; + u16 reserved2; + u32 label; + gh_label_t mem_info_tag; + /* TODO: How to arrange multiple variable length struct arrays? */ +} __packed; + +struct gh_rm_mem_shared_acl_entry { + u16 acl_vmid; + u8 acl_rights; + u8 reserved; +} __packed; + +struct gh_rm_mem_shared_sgl_entry { + u32 sgl_size_low; + u32 sgl_size_high; +} __packed; + +struct gh_rm_mem_shared_attr_entry { + u16 attributes; + u16 attributes_vmid; +} __packed; + +struct gh_rm_notif_mem_released_payload { + u32 mem_handle; + u16 participant_vmid; + u16 reserved; + gh_label_t mem_info_tag; +} __packed; + +struct gh_rm_notif_mem_accepted_payload { + u32 mem_handle; + u16 participant_vmid; + u16 reserved; + gh_label_t mem_info_tag; +} __packed; + +struct gh_acl_entry { + u16 vmid; + u8 perms; + u8 reserved; +} __packed; + +struct gh_sgl_entry { + u64 ipa_base; + u64 size; +} __packed; + +struct gh_mem_attr_entry { + u16 attr; + u16 vmid; +} __packed; + +struct gh_acl_desc { + u32 n_acl_entries; + struct gh_acl_entry acl_entries[]; +} __packed; + +struct gh_sgl_desc { + u16 n_sgl_entries; + u16 reserved; + struct gh_sgl_entry sgl_entries[]; +} __packed; + +struct gh_mem_attr_desc { + u16 n_mem_attr_entries; + u16 reserved; + struct gh_mem_attr_entry attr_entries[]; +} __packed; + +struct gh_notify_vmid_entry { + u16 vmid; + u16 reserved; +} __packed; + +struct gh_notify_vmid_desc { + u16 n_vmid_entries; + u16 reserved; + struct gh_notify_vmid_entry vmid_entries[]; +} __packed; + +/* VM APIs */ +#define GH_RM_NOTIF_VM_EXITED 0x56100001 +#define GH_RM_NOTIF_VM_SHUTDOWN 0x56100002 +#define GH_RM_NOTIF_VM_STATUS 0x56100008 +#define GH_RM_NOTIF_VM_IRQ_LENT 0x56100011 +#define GH_RM_NOTIF_VM_IRQ_RELEASED 0x56100012 +#define GH_RM_NOTIF_VM_IRQ_ACCEPTED 0x56100013 + +/* AUTH mechanisms */ +#define GH_VM_UNAUTH 0 +#define GH_VM_AUTH_PIL_ELF 1 +#define GH_VM_AUTH_ANDROID_PVM 2 + +/* AUTH_PARAM_TYPE mechanisms */ +#define GH_VM_AUTH_PARAM_PAS_ID 0 /* Used to pass peripheral auth id */ + +#define GH_RM_VM_STATUS_NO_STATE 0 +#define GH_RM_VM_STATUS_INIT 1 +#define GH_RM_VM_STATUS_READY 2 +#define GH_RM_VM_STATUS_RUNNING 3 +#define GH_RM_VM_STATUS_PAUSED 4 +#define GH_RM_VM_STATUS_LOAD 5 +#define GH_RM_VM_STATUS_AUTH 6 +/* 7 is reserved */ +#define GH_RM_VM_STATUS_INIT_FAILED 8 +#define GH_RM_VM_STATUS_EXITED 9 +#define GH_RM_VM_STATUS_RESETTING 10 +#define GH_RM_VM_STATUS_RESET 11 + +#define GH_RM_OS_STATUS_NONE 0 +#define GH_RM_OS_STATUS_EARLY_BOOT 1 +#define GH_RM_OS_STATUS_BOOT 2 +#define GH_RM_OS_STATUS_INIT 3 +#define GH_RM_OS_STATUS_RUN 4 + +#define GH_RM_APP_STATUS_TUI_SERVICE_BOOT 1 + +#define GH_RM_VM_STOP_FLAG_FORCE_STOP 0x01 + +#define GH_RM_VM_EXIT_TYPE_VM_EXIT 0 +#define GH_RM_VM_EXIT_TYPE_SYSTEM_OFF 1 +#define GH_RM_VM_EXIT_TYPE_SYSTEM_RESET 2 +#define GH_RM_VM_EXIT_TYPE_SYSTEM_RESET2 3 +#define GH_RM_VM_EXIT_TYPE_WDT_BITE 4 +#define GH_RM_VM_EXIT_TYPE_HYP_ERROR 5 +#define GH_RM_VM_EXIT_TYPE_ASYNC_EXT_ABORT 6 +#define GH_RM_VM_EXIT_TYPE_VM_STOP_FORCED 7 + +/* GH_RM_VM_EXIT_TYPE_VM_EXIT */ +struct gh_vm_exit_reason_vm_exit { + u16 exit_flags; + /* GH_VM_EXIT_EXIT_FLAG_* are bit representations */ +#define GH_VM_EXIT_EXIT_FLAG_TYPE 0x1 +#define GH_VM_EXIT_POWEROFF 0 /* Value at bit:0 */ +#define GH_VM_EXIT_RESTART 1 /* Value at bit:0 */ +#define GH_VM_EXIT_EXIT_FLAG_SYSTEM 0x2 +#define GH_VM_EXIT_EXIT_FLAG_WARM 0x4 +#define GH_VM_EXIT_EXIT_FLAG_DUMP 0x8 + + u8 exit_code; + /* Exit codes */ +#define GH_VM_EXIT_CODE_NORMAL 0 +#define GH_VM_EXIT_SOFTWARE_ERR 1 +#define GH_VM_EXIT_BUS_ERR 2 +#define GH_VM_EXIT_DEVICE_ERR 3 + + u8 reserved; +} __packed; + +/* Reasons for VM_STOP */ +#define GH_VM_STOP_SHUTDOWN 0 +#define GH_VM_STOP_RESTART 1 +#define GH_VM_STOP_CRASH 2 +#define GH_VM_STOP_FORCE_STOP 3 +#define GH_VM_STOP_MAX 4 +struct gh_rm_notif_vm_exited_payload { + gh_vmid_t vmid; + u16 exit_type; + u32 exit_reason_size; + u32 exit_reason[0]; +} __packed; + +struct gh_rm_notif_vm_shutdown_payload { + u32 stop_reason; +} __packed; + +struct gh_rm_notif_vm_status_payload { + gh_vmid_t vmid; + u16 reserved; + u8 vm_status; + u8 os_status; + u16 app_status; +} __packed; + +struct gh_rm_notif_vm_irq_lent_payload { + gh_vmid_t owner_vmid; + u16 reserved; + gh_virq_handle_t virq_handle; + gh_label_t virq_label; +} __packed; + +struct gh_rm_notif_vm_irq_released_payload { + gh_virq_handle_t virq_handle; +} __packed; + +struct gh_rm_notif_vm_irq_accepted_payload { + gh_virq_handle_t virq_handle; +} __packed; + +struct gh_vm_auth_param_entry { + u32 auth_param_type; + u32 auth_param; +} __packed; + +/* Arch specific APIs */ +#if IS_ENABLED(CONFIG_GH_ARM64_DRV) +/* IRQ APIs */ +int gh_get_irq(u32 virq, u32 type, struct fwnode_handle *handle); +int gh_put_irq(int irq); +int gh_get_virq(int base_virq, int virq); +int gh_put_virq(int irq); +int gh_arch_validate_vm_exited_notif(size_t buff_size, size_t hdr_size, + struct gh_rm_notif_vm_exited_payload *payload); +#else +static inline int gh_get_irq(u32 virq, u32 type, + struct fwnode_handle *handle) +{ + return -EINVAL; +} +static inline int gh_put_irq(int irq) +{ + return -EINVAL; +} +static inline int gh_get_virq(int base_virq, int virq) +{ + return -EINVAL; +} +static inline int gh_put_virq(int irq) +{ + return -EINVAL; +} +static inline int gh_arch_validate_vm_exited_notif(size_t buff_size, + size_t hdr_size, struct gh_rm_notif_vm_exited_payload *payload) +{ + return -EINVAL; +} +#endif +/* VM Services */ +#define GH_RM_NOTIF_VM_CONSOLE_CHARS 0X56100080 + +struct gh_rm_notif_vm_console_chars { + gh_vmid_t vmid; + u16 num_bytes; + u8 bytes[0]; +} __packed; + +struct gh_vm_status { + u8 vm_status; + u8 os_status; + u16 app_status; +} __packed; + +struct notifier_block; + +typedef int (*gh_virtio_mmio_cb_t)(gh_vmid_t peer, const char *vm_name, + gh_label_t label, gh_capid_t cap_id, int linux_irq, u64 base, u64 size); +typedef int (*gh_vcpu_affinity_set_cb_t)(gh_vmid_t vmid, gh_label_t label, + gh_capid_t cap_id, int linux_irq); +typedef int (*gh_vcpu_affinity_reset_cb_t)(gh_vmid_t vmid, gh_label_t label, + gh_capid_t cap_id, int *linux_irq); +typedef int (*gh_vpm_grp_set_cb_t)(gh_vmid_t vmid, gh_capid_t cap_id, int linux_irq); +typedef int (*gh_vpm_grp_reset_cb_t)(gh_vmid_t vmid, int *linux_irq); +typedef void (*gh_all_res_populated_cb_t)(gh_vmid_t vmid, bool res_populated); + +#if IS_ENABLED(CONFIG_GH_RM_DRV) +/* RM client registration APIs */ +int gh_rm_register_notifier(struct notifier_block *nb); +int gh_rm_unregister_notifier(struct notifier_block *nb); + +/* Client APIs for IRQ management */ +int gh_rm_virq_to_irq(u32 virq, u32 type); +int gh_rm_irq_to_virq(int irq, u32 *virq); + +int gh_rm_vm_irq_lend(gh_vmid_t vmid, + int virq, + int label, + gh_virq_handle_t *virq_handle); +int gh_rm_vm_irq_lend_notify(gh_vmid_t vmid, gh_virq_handle_t virq_handle); +int gh_rm_vm_irq_accept(gh_virq_handle_t virq_handle, int virq); +int gh_rm_vm_irq_accept_notify(gh_vmid_t vmid, gh_virq_handle_t virq_handle); +int gh_rm_vm_irq_release(gh_virq_handle_t virq_handle); +int gh_rm_vm_irq_release_notify(gh_vmid_t vmid, gh_virq_handle_t virq_handle); + + +int gh_rm_vm_irq_reclaim(gh_virq_handle_t virq_handle); + +int gh_rm_set_virtio_mmio_cb(gh_virtio_mmio_cb_t fnptr); +void gh_rm_unset_virtio_mmio_cb(void); +int gh_rm_set_vcpu_affinity_cb(gh_vcpu_affinity_set_cb_t fnptr); +int gh_rm_reset_vcpu_affinity_cb(gh_vcpu_affinity_reset_cb_t fnptr); +int gh_rm_set_vpm_grp_cb(gh_vpm_grp_set_cb_t fnptr); +int gh_rm_reset_vpm_grp_cb(gh_vpm_grp_reset_cb_t fnptr); +int gh_rm_all_res_populated_cb(gh_all_res_populated_cb_t fnptr); + +/* Client APIs for VM management */ +int gh_rm_vm_alloc_vmid(enum gh_vm_names vm_name, int *vmid); +int gh_rm_vm_dealloc_vmid(gh_vmid_t vmid); +int gh_rm_vm_config_image(gh_vmid_t vmid, u16 auth_mech, u32 mem_handle, + u64 image_offset, u64 image_size, u64 dtb_offset, u64 dtb_size); +int gh_rm_vm_auth_image(gh_vmid_t vmid, ssize_t n_entries, + struct gh_vm_auth_param_entry *entry); +int gh_rm_vm_init(gh_vmid_t vmid); +int gh_rm_get_vmid(enum gh_vm_names vm_name, gh_vmid_t *vmid); +int gh_rm_get_vm_id_info(gh_vmid_t vmid); +int gh_rm_get_vm_name(gh_vmid_t vmid, enum gh_vm_names *vm_name); +int gh_rm_get_vminfo(enum gh_vm_names vm_name, struct gh_vminfo *vminfo); +int gh_rm_vm_start(int vmid); +enum gh_vm_names gh_get_image_name(const char *str); +enum gh_vm_names gh_get_vm_name(const char *str); +int gh_rm_vm_stop(gh_vmid_t vmid, u32 stop_reason, u8 flags); +int gh_rm_vm_reset(gh_vmid_t vmid); + +/* Client APIs for VM query */ +int gh_rm_populate_hyp_res(gh_vmid_t vmid, const char *vm_name); +int gh_rm_unpopulate_hyp_res(gh_vmid_t vmid, const char *vm_name); + +/* Client APIs for VM Services */ +struct gh_vm_status *gh_rm_vm_get_status(gh_vmid_t vmid); +int gh_rm_vm_set_status(struct gh_vm_status gh_vm_status); +int gh_rm_vm_set_vm_status(u8 vm_status); +int gh_rm_vm_set_os_status(u8 os_status); +int gh_rm_vm_set_app_status(u16 app_status); +int gh_rm_console_open(gh_vmid_t vmid); +int gh_rm_console_close(gh_vmid_t vmid); +int gh_rm_console_write(gh_vmid_t vmid, const char *buf, size_t size); +int gh_rm_console_flush(gh_vmid_t vmid); +int gh_rm_mem_qcom_lookup_sgl(u8 mem_type, gh_label_t label, + struct gh_acl_desc *acl_desc, + struct gh_sgl_desc *sgl_desc, + struct gh_mem_attr_desc *mem_attr_desc, + gh_memparcel_handle_t *handle); +int gh_rm_mem_release(gh_memparcel_handle_t handle, u8 flags); +int gh_rm_mem_reclaim(gh_memparcel_handle_t handle, u8 flags); +struct gh_sgl_desc *gh_rm_mem_accept(gh_memparcel_handle_t handle, u8 mem_type, + u8 trans_type, u8 flags, gh_label_t label, + struct gh_acl_desc *acl_desc, + struct gh_sgl_desc *sgl_desc, + struct gh_mem_attr_desc *mem_attr_desc, + u16 map_vmid); +int gh_rm_mem_share(u8 mem_type, u8 flags, gh_label_t label, + struct gh_acl_desc *acl_desc, struct gh_sgl_desc *sgl_desc, + struct gh_mem_attr_desc *mem_attr_desc, + gh_memparcel_handle_t *handle); +int gh_rm_mem_lend(u8 mem_type, u8 flags, gh_label_t label, + struct gh_acl_desc *acl_desc, struct gh_sgl_desc *sgl_desc, + struct gh_mem_attr_desc *mem_attr_desc, + gh_memparcel_handle_t *handle); +int gh_rm_mem_donate(u8 mem_type, u8 flags, gh_label_t label, + struct gh_acl_desc *acl_desc, struct gh_sgl_desc *sgl_desc, + struct gh_mem_attr_desc *mem_attr_desc, + gh_memparcel_handle_t *handle); +int gh_rm_mem_notify(gh_memparcel_handle_t handle, u8 flags, + gh_label_t mem_info_tag, + struct gh_notify_vmid_desc *vmid_desc); + +/* API to set time base */ +int gh_rm_vm_set_time_base(gh_vmid_t vmid); + +#else +/* RM client register notifications APIs */ +static inline int gh_rm_register_notifier(struct notifier_block *nb) +{ + return -ENODEV; +} + +static inline int gh_rm_unregister_notifier(struct notifier_block *nb) +{ + return -ENODEV; +} + +/* Client APIs for IRQ management */ +static inline int gh_rm_virq_to_irq(u32 virq) +{ + return -EINVAL; +} + +static inline int gh_rm_vm_irq_lend(gh_vmid_t vmid, + int virq, + int label, + gh_virq_handle_t *virq_handle) +{ + return -EINVAL; +} + +static inline int gh_rm_irq_to_virq(int irq, u32 *virq) +{ + return -EINVAL; +} + +static inline int gh_rm_vm_irq_lend_notify(gh_vmid_t vmid, + gh_virq_handle_t virq_handle) +{ + return -EINVAL; +} + +static inline int gh_rm_vm_irq_accept(gh_virq_handle_t virq_handle, int virq) +{ + return -EINVAL; + +} + +static inline int gh_rm_vm_irq_accept_notify(gh_vmid_t vmid, + gh_virq_handle_t virq_handle) +{ + return -EINVAL; +} + +static inline int gh_rm_vm_irq_release(gh_virq_handle_t virq_handle) +{ + return -EINVAL; +} + +static inline int gh_rm_vm_irq_release_notify(gh_vmid_t vmid, + gh_virq_handle_t virq_handle) +{ + return -EINVAL; +} + +static inline int gh_rm_vm_irq_reclaim(gh_virq_handle_t virq_handle) +{ + return -EINVAL; +} + +/* Client APIs for VM management */ +static inline int gh_rm_vm_alloc_vmid(enum gh_vm_names vm_name, int *vmid) +{ + return -EINVAL; +} + +static inline int gh_rm_vm_dealloc_vmid(gh_vmid_t vmid) +{ + return -EINVAL; +} + +static inline int gh_rm_vm_config_image(gh_vmid_t vmid, u16 auth_mech, + u32 mem_handle, u64 image_offset, u64 image_size, + u64 dtb_offset, u64 dtb_size) +{ + return -EINVAL; +} + +static inline int gh_rm_vm_auth_image(gh_vmid_t vmid, ssize_t n_entries, + struct gh_vm_auth_param_entry *entry) +{ + return -EINVAL; +} + +static inline int gh_rm_vm_init(gh_vmid_t vmid) +{ + return -EINVAL; +} + +static inline int gh_rm_get_vmid(enum gh_vm_names vm_name, gh_vmid_t *vmid) +{ + return -EINVAL; +} + +static inline int gh_rm_get_vm_name(gh_vmid_t vmid, enum gh_vm_names *vm_name) +{ + return -EINVAL; +} + +static inline int gh_rm_get_vminfo(enum gh_vm_names vm_name, struct gh_vminfo *vminfo) +{ + return -EINVAL; +} + +static inline int gh_rm_vm_start(int vmid) +{ + return -EINVAL; +} + +static inline int gh_rm_get_vm_id_info(gh_vmid_t vmid) +{ + return -EINVAL; +} + +static inline int gh_rm_vm_stop(gh_vmid_t vmid, u32 stop_reason, u8 flags) +{ + return -EINVAL; +} + +static inline int gh_rm_vm_reset(gh_vmid_t vmid) +{ + return -EINVAL; +} + +/* Client APIs for VM query */ +static inline int gh_rm_populate_hyp_res(gh_vmid_t vmid, const char *vm_name) +{ + return -EINVAL; +} + +/* Client APIs for VM Services */ +static inline struct gh_vm_status *gh_rm_vm_get_status(gh_vmid_t vmid) +{ + return ERR_PTR(-EINVAL); +} + +static inline int gh_rm_vm_set_status(struct gh_vm_status gh_vm_status) +{ + return -EINVAL; +} + +static inline int gh_rm_vm_set_vm_status(u8 vm_status) +{ + return -EINVAL; +} + +static inline int gh_rm_vm_set_os_status(u8 os_status) +{ + return -EINVAL; +} + +static inline int gh_rm_vm_set_app_status(u16 app_status) +{ + return -EINVAL; +} + +static inline int gh_rm_console_open(gh_vmid_t vmid) +{ + return -EINVAL; +} + +static inline int gh_rm_console_close(gh_vmid_t vmid) +{ + return -EINVAL; +} + +static inline int gh_rm_console_write(gh_vmid_t vmid, const char *buf, + size_t size) +{ + return -EINVAL; +} + +static inline int gh_rm_console_flush(gh_vmid_t vmid) +{ + return -EINVAL; +} + +static inline int gh_rm_mem_qcom_lookup_sgl(u8 mem_type, gh_label_t label, + struct gh_acl_desc *acl_desc, + struct gh_sgl_desc *sgl_desc, + struct gh_mem_attr_desc *mem_attr_desc, + gh_memparcel_handle_t *handle) +{ + return -EINVAL; +} + +static inline int gh_rm_mem_release(gh_memparcel_handle_t handle, u8 flags) +{ + return -EINVAL; +} + +static inline int gh_rm_mem_reclaim(gh_memparcel_handle_t handle, u8 flags) +{ + return -EINVAL; +} + +static inline struct gh_sgl_desc *gh_rm_mem_accept(gh_memparcel_handle_t handle, + u8 mem_type, + u8 trans_type, u8 flags, gh_label_t label, + struct gh_acl_desc *acl_desc, + struct gh_sgl_desc *sgl_desc, + struct gh_mem_attr_desc *mem_attr_desc, + u16 map_vmid) +{ + return ERR_PTR(-EINVAL); +} + +static inline int gh_rm_mem_share(u8 mem_type, u8 flags, gh_label_t label, + struct gh_acl_desc *acl_desc, struct gh_sgl_desc *sgl_desc, + struct gh_mem_attr_desc *mem_attr_desc, + gh_memparcel_handle_t *handle) +{ + return -EINVAL; +} + +static inline int gh_rm_mem_lend(u8 mem_type, u8 flags, gh_label_t label, + struct gh_acl_desc *acl_desc, struct gh_sgl_desc *sgl_desc, + struct gh_mem_attr_desc *mem_attr_desc, + gh_memparcel_handle_t *handle) +{ + return -EINVAL; +} + +static inline int gh_rm_mem_notify(gh_memparcel_handle_t handle, u8 flags, + gh_label_t mem_info_tag, + struct gh_notify_vmid_desc *vmid_desc) +{ + return -EINVAL; +} + +static inline int gh_rm_set_virtio_mmio_cb(gh_virtio_mmio_cb_t fnptr) +{ + return -EINVAL; +} + +static inline void gh_rm_unset_virtio_mmio_cb(void) +{ + +} + +static inline int gh_rm_set_vcpu_affinity_cb(gh_vcpu_affinity_set_cb_t fnptr) +{ + return -EINVAL; +} + +static inline int gh_rm_reset_vcpu_affinity_cb(gh_vcpu_affinity_reset_cb_t fnptr) +{ + return -EINVAL; +} + +static inline int gh_rm_set_vpm_grp_cb(gh_vpm_grp_set_cb_t fnptr) +{ + return -EINVAL; +} + +static inline int gh_rm_reset_vpm_grp_cb(gh_vpm_grp_reset_cb_t fnptr) +{ + return -EINVAL; +} + +static inline int gh_rm_all_res_populated_cb(gh_all_res_populated_cb_t fnptr) +{ + return -EINVAL; +} + +/* API to set time base */ +static inline int gh_rm_vm_set_time_base(gh_vmid_t vmid) +{ + return -EINVAL; +} +#endif +#endif diff --git a/include/linux/gunyah/gh_vm.h b/include/linux/gunyah/gh_vm.h new file mode 100644 index 000000000000..e22bd4324681 --- /dev/null +++ b/include/linux/gunyah/gh_vm.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _GH_VM_H +#define _GH_VM_H + +int gh_register_vm_notifier(struct notifier_block *nb); +int gh_unregister_vm_notifier(struct notifier_block *nb); + +/* VM power notifications */ +#define GH_VM_BEFORE_POWERUP 0x1 +#define GH_VM_POWERUP_FAIL 0x2 +#define GH_VM_EARLY_POWEROFF 0x3 +#define GH_VM_POWEROFF 0x4 + +#endif /* _GH_VM_H */ diff --git a/include/linux/gunyah/hcall_common.h b/include/linux/gunyah/hcall_common.h new file mode 100644 index 000000000000..6efdf9bcdc22 --- /dev/null +++ b/include/linux/gunyah/hcall_common.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + */ +#ifndef __GH_HCALL_COMMON_H +#define __GH_HCALL_COMMON_H + +#include + +struct gh_hcall_args { + unsigned long arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7; +}; + +struct gh_hcall_resp { + unsigned long resp0, resp1, resp2, resp3, resp4, resp5, resp6, resp7; +}; + +typedef u16 gh_hcall_fnid_t; + +#endif diff --git a/include/linux/mem-buf-exporter.h b/include/linux/mem-buf-exporter.h index d1b86d36691d..9ff6e4491d84 100644 --- a/include/linux/mem-buf-exporter.h +++ b/include/linux/mem-buf-exporter.h @@ -7,6 +7,7 @@ #define _MEM_BUF_EXPORTER_H #include +#include #include int mem_buf_dma_buf_attach(struct dma_buf *dmabuf, @@ -54,6 +55,13 @@ struct mem_buf_vmperm *mem_buf_vmperm_alloc(struct sg_table *sgt); struct mem_buf_vmperm *mem_buf_vmperm_alloc_staticvm(struct sg_table *sgt, int *vmids, int *perms, u32 nr_acl_entries); +/* + * A dmabuf in the "MEMACCEPT" state. + */ +struct mem_buf_vmperm *mem_buf_vmperm_alloc_accept(struct sg_table *sgt, + gh_memparcel_handle_t memparcel_hdl); + + /* * Performs the expected close step based on whether the dmabuf * is of the "STATICVM" "MEMACCEPT" or "DEFAULT" type. diff --git a/include/linux/mem-buf.h b/include/linux/mem-buf.h new file mode 100644 index 000000000000..a018fe1c89eb --- /dev/null +++ b/include/linux/mem-buf.h @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + */ + +#ifndef _MEM_BUF_H +#define _MEM_BUF_H + +#include +#include +#include +#include +#include +#include + +/* Used to obtain the underlying vmperm struct of a DMA-BUF */ +struct mem_buf_vmperm *to_mem_buf_vmperm(struct dma_buf *dmabuf); + +/* Returns true if the local VM has exclusive access and is the owner */ +bool mem_buf_dma_buf_exclusive_owner(struct dma_buf *dmabuf); + +/* + * Returns a copy of the Virtual Machine vmids & permissions of the dmabuf. + * The caller must kfree() when finished. + */ +int mem_buf_dma_buf_copy_vmperm(struct dma_buf *dmabuf, int **vmids, int **perms, + int *nr_acl_entries); + +typedef int (*mem_buf_dma_buf_destructor)(void *dtor_data); +int mem_buf_dma_buf_set_destructor(struct dma_buf *dmabuf, + mem_buf_dma_buf_destructor dtor, + void *dtor_data); + +/** + * struct mem_buf_allocation_data - Data structure that contains information + * about a memory buffer allocation request. + * @size: The size (in bytes) of the memory to be requested from a remote VM + * @nr_acl_entries: The number of ACL entries in @acl_list + * @acl_list: A list of VMID and permission pairs that describe what VMIDs will + * have access to the memory, and with what permissions + * @src_mem_type: The type of memory that the remote VM should allocate + * (e.g. ION memory) + * @src_data: A pointer to memory type specific data that the remote VM may need + * when performing an allocation (e.g. ION memory allocations require a heap ID) + * @dst_mem_type: The type of memory that the native VM wants (e.g. ION memory) + * @dst_data: A pointer to memory type specific data that the native VM may + * need when adding the memory from the remote VM (e.g. ION memory requires a + * heap ID to add the memory to). + */ +struct mem_buf_allocation_data { + size_t size; + unsigned int nr_acl_entries; + int *vmids; + int *perms; + enum mem_buf_mem_type src_mem_type; + void *src_data; + enum mem_buf_mem_type dst_mem_type; + void *dst_data; +}; + +struct mem_buf_lend_kernel_arg { + unsigned int nr_acl_entries; + int *vmids; + int *perms; + gh_memparcel_handle_t memparcel_hdl; + u32 flags; + u64 label; +}; + +int mem_buf_lend(struct dma_buf *dmabuf, + struct mem_buf_lend_kernel_arg *arg); + +/* + * mem_buf_share + * Grant the local VM, as well as one or more remote VMs access + * to the dmabuf. The permissions of the local VM default to RWX + * unless otherwise specified. + */ +int mem_buf_share(struct dma_buf *dmabuf, + struct mem_buf_lend_kernel_arg *arg); + + +struct mem_buf_retrieve_kernel_arg { + int sender_vmid; + unsigned int nr_acl_entries; + int *vmids; + int *perms; + gh_memparcel_handle_t memparcel_hdl; + int fd_flags; +}; +struct dma_buf *mem_buf_retrieve(struct mem_buf_retrieve_kernel_arg *arg); +int mem_buf_reclaim(struct dma_buf *dmabuf); + +#if IS_ENABLED(CONFIG_QCOM_MEM_BUF) + +int mem_buf_get_fd(void *membuf_desc); + +void mem_buf_put(void *membuf_desc); + +void *mem_buf_get(int fd); + +#else + +static inline int mem_buf_get_fd(void *membuf_desc) +{ + return -ENODEV; +} + +static inline void mem_buf_put(void *membuf_desc) +{ +} + +static inline void *mem_buf_get(int fd) +{ + return ERR_PTR(-ENODEV); +} + +#endif /* CONFIG_QCOM_MEM_BUF */ +#endif /* _MEM_BUF_H */ diff --git a/include/uapi/linux/mem-buf.h b/include/uapi/linux/mem-buf.h new file mode 100644 index 000000000000..3bfd4505d757 --- /dev/null +++ b/include/uapi/linux/mem-buf.h @@ -0,0 +1,235 @@ +/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + */ + +#ifndef _UAPI_LINUX_MEM_BUF_H +#define _UAPI_LINUX_MEM_BUF_H + +#include +#include + +#define MEM_BUF_IOC_MAGIC 'M' + +/** + * enum mem_buf_mem_type: Types of memory that can be allocated from and to + * @MEM_BUF_ION_MEM_TYPE: The memory for the source or destination is ION memory + */ +enum mem_buf_mem_type { + MEM_BUF_ION_MEM_TYPE, + MEM_BUF_MAX_MEM_TYPE, +}; +#define MEM_BUF_DMAHEAP_MEM_TYPE (MEM_BUF_ION_MEM_TYPE + 1) + +/* The mem-buf values that represent VMIDs for an ACL. */ +#define MEM_BUF_VMID_PRIMARY_VM 0 +#define MEM_BUF_VMID_TRUSTED_VM 1 + +#define MEM_BUF_PERM_FLAG_READ (1U << 0) +#define MEM_BUF_PERM_FLAG_WRITE (1U << 1) +#define MEM_BUF_PERM_FLAG_EXEC (1U << 2) +#define MEM_BUF_PERM_VALID_FLAGS\ + (MEM_BUF_PERM_FLAG_READ | MEM_BUF_PERM_FLAG_WRITE |\ + MEM_BUF_PERM_FLAG_EXEC) + +#define MEM_BUF_MAX_NR_ACL_ENTS 16 + +/** + * struct acl_entry: Represents the access control permissions for a VMID. + * @vmid: The mem-buf VMID specifier associated with the VMID that will access + * the memory. + * @perms: The access permissions for the VMID in @vmid. This flag is + * interpreted as a bitmap, and thus, should be a combination of one or more + * of the MEM_BUF_PERM_FLAG_* flags. + */ +struct acl_entry { + __u32 vmid; + __u32 perms; +}; + +/** + * struct mem_buf_ion_data: Data that is unique to memory that is of type + * MEM_BUF_ION_MEM_TYPE. + * @heap_id: The heap ID of where memory should be allocated from or added to. + */ +struct mem_buf_ion_data { + __u32 heap_id; +}; + +#define MEM_BUF_MAX_DMAHEAP_NAME_LEN 128 +/** + * struct mem_buf_dmaheap_data: Data that is unique to memory that is of type + * MEM_BUF_DMAHEAP_MEM_TYPE. + * @heap_name: array of characters containing the heap name. + */ +struct mem_buf_dmaheap_data { + __u64 heap_name; +}; + +/** + * struct mem_buf_alloc_ioctl_arg: A request to allocate memory from another + * VM to other VMs. + * @size: The size of the allocation. + * @acl_list: An array of structures, where each structure specifies a VMID + * and the access permissions that the VMID will have to the memory to be + * allocated. + * @nr_acl_entries: The number of ACL entries in @acl_list. + * @src_mem_type: The type of memory that the source VM should allocate from. + * This should be one of the mem_buf_mem_type enum values. + * @src_data: A pointer to data that the source VM should interpret when + * performing the allocation. + * @dst_mem_type: The type of memory that the destination VM should treat the + * incoming allocation from the source VM as. This should be one of the + * mem_buf_mem_type enum values. + * @mem_buf_fd: A file descriptor representing the memory that was allocated + * from the source VM and added to the current VM. Calling close() on this file + * descriptor will deallocate the memory from the current VM, and return it + * to the source VM. + * * @dst_data: A pointer to data that the destination VM should interpret when + * adding the memory to the current VM. + * + * All reserved fields must be zeroed out by the caller prior to invoking the + * allocation IOCTL command with this argument. + */ +struct mem_buf_alloc_ioctl_arg { + __u64 size; + __u64 acl_list; + __u32 nr_acl_entries; + __u32 src_mem_type; + __u64 src_data; + __u32 dst_mem_type; + __u32 mem_buf_fd; + __u64 dst_data; + __u64 reserved0; + __u64 reserved1; + __u64 reserved2; +}; + +#define MEM_BUF_IOC_ALLOC _IOWR(MEM_BUF_IOC_MAGIC, 0,\ + struct mem_buf_alloc_ioctl_arg) + +/** + * struct mem_buf_lend_ioctl_arg: A request to lend memory from the local VM + * VM to one or more remote VMs. + * @dma_buf_fd: The fd of the dma-buf that will be exported to another VM. + * @nr_acl_entries: The number of ACL entries in @acl_list. + * @acl_list: An array of structures, where each structure specifies a VMID + * and the access permissions that the VMID will have to the memory to be + * exported. Must not include the local VMID. + * @memparcel_hdl: The handle associated with the memparcel that was created by + * granting access to the dma-buf for the VMIDs specified in @acl_list. + * + * All reserved fields must be zeroed out by the caller prior to invoking the + * import IOCTL command with this argument. + */ +struct mem_buf_lend_ioctl_arg { + __u32 dma_buf_fd; + __u32 nr_acl_entries; + __u64 acl_list; + __u64 memparcel_hdl; + __u64 reserved0; + __u64 reserved1; + __u64 reserved2; +}; + +#define MEM_BUF_IOC_LEND _IOWR(MEM_BUF_IOC_MAGIC, 3,\ + struct mem_buf_lend_ioctl_arg) + +#define MEM_BUF_VALID_FD_FLAGS (O_CLOEXEC | O_ACCMODE) +/** + * struct mem_buf_retrieve_ioctl_arg: A request to retrieve memory from another + * VM as a dma-buf + * @sender_vm_fd: An open file descriptor identifing the VM who sent the handle. + * @nr_acl_entries: The number of ACL entries in @acl_list. + * @acl_list: An array of structures, where each structure specifies a VMID + * and the access permissions that the VMID should have for the memparcel. + * @memparcel_hdl: The handle that corresponds to the memparcel we are + * importing. + * @dma_buf_import_fd: A dma-buf file descriptor that the client can use to + * access the buffer. This fd must be closed to release the memory. + * @fd_flags: file descriptor flags used when allocating + * + * All reserved fields must be zeroed out by the caller prior to invoking the + * import IOCTL command with this argument. + */ +struct mem_buf_retrieve_ioctl_arg { + __u32 sender_vm_fd; + __u32 nr_acl_entries; + __u64 acl_list; + __u64 memparcel_hdl; + __u32 dma_buf_import_fd; + __u32 fd_flags; + __u64 reserved0; + __u64 reserved1; + __u64 reserved2; +}; + +#define MEM_BUF_IOC_RETRIEVE _IOWR(MEM_BUF_IOC_MAGIC, 4,\ + struct mem_buf_retrieve_ioctl_arg) + +/** + * struct mem_buf_reclaim_ioctl_arg: A request to reclaim memory from another + * VM. The other VM must have relinquished access, and the current VM must be + * the original owner of the memory. The dma-buf file will not be closed by + * this operation. + * @memparcel_hdl: The handle that corresponds to the memparcel we are + * reclaiming. + * @dma_buf_fd: A dma-buf file descriptor that the client can use to + * access the buffer. + * + * All reserved fields must be zeroed out by the caller prior to invoking the + * import IOCTL command with this argument. + */ +struct mem_buf_reclaim_ioctl_arg { + __u64 memparcel_hdl; + __u32 dma_buf_fd; + __u32 reserved0; + __u64 reserved1; + __u64 reserved2; +}; + +#define MEM_BUF_IOC_RECLAIM _IOWR(MEM_BUF_IOC_MAGIC, 3,\ + struct mem_buf_reclaim_ioctl_arg) + +/** + * struct mem_buf_share_ioctl_arg: An request to share memory between the + * local VM and one or more remote VMs. + * @dma_buf_fd: The fd of the dma-buf that will be exported to another VM. + * @nr_acl_entries: The number of ACL entries in @acl_list. + * @acl_list: An array of structures, where each structure specifies a VMID + * and the access permissions that the VMID will have to the memory to be + * exported. Must include the local VMID. + * @memparcel_hdl: The handle associated with the memparcel that was created by + * granting access to the dma-buf for the VMIDs specified in @acl_list. + * + * All reserved fields must be zeroed out by the caller prior to invoking the + * import IOCTL command with this argument. + */ +struct mem_buf_share_ioctl_arg { + __u32 dma_buf_fd; + __u32 nr_acl_entries; + __u64 acl_list; + __u64 memparcel_hdl; + __u64 reserved0; + __u64 reserved1; + __u64 reserved2; +}; + +#define MEM_BUF_IOC_SHARE _IOWR(MEM_BUF_IOC_MAGIC, 6,\ + struct mem_buf_share_ioctl_arg) + +/** + * struct mem_buf_exclusive_owner_ioctl_arg: A request to see if a DMA-BUF + * is owned by and belongs exclusively to this VM. + * @dma_buf_fd: The fd of the dma-buf the user wants to obtain information on + * @is_exclusive_owner: + */ +struct mem_buf_exclusive_owner_ioctl_arg { + __u32 dma_buf_fd; + __u32 is_exclusive_owner; +}; + +#define MEM_BUF_IOC_EXCLUSIVE_OWNER _IOWR(MEM_BUF_IOC_MAGIC, 2,\ + struct mem_buf_exclusive_owner_ioctl_arg) + +#endif /* _UAPI_LINUX_MEM_BUF_H */