From 1451a11662a9181172791888d4f62f6b558d96a2 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Wed, 10 Jun 2020 00:07:07 -0700 Subject: [PATCH] haven: Add support for the MEM_ACCEPTED notification It's useful for other virtual machines (VMs) to know if another VM has successfully received a resource that was shared with it (e.g. state tracking can be controlled better with this sort of information). Add support for the MEM_ACCEPTED notification, which clients can use to notify the VM that owns the resource that was shared with it that it has accepted the resource and is using it. Also, add support in the mem-notifier driver to forward the MEM_ACCEPTED notification to clients. Change-Id: I05b9f1d37906d7c2aa729b97df2f8ceb78b560bd Signed-off-by: Isaac J. Manjarres --- .../focaltech_touch/focaltech_core.c | 4 ++-- drivers/input/touchscreen/st/fts.c | 4 ++-- drivers/virt/haven/hh_mem_notifier.c | 12 ++++++++--- drivers/virt/haven/hh_rm_core.c | 9 ++++++++ drivers/virt/haven/hh_rm_iface.c | 21 +++++++++++-------- include/linux/haven/hh_rm_drv.h | 15 +++++++++++-- 6 files changed, 47 insertions(+), 18 deletions(-) diff --git a/drivers/input/touchscreen/focaltech_touch/focaltech_core.c b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c index 2fb409092368..cf38fd5a7766 100644 --- a/drivers/input/touchscreen/focaltech_touch/focaltech_core.c +++ b/drivers/input/touchscreen/focaltech_touch/focaltech_core.c @@ -438,7 +438,7 @@ static int fts_ts_vm_mem_release(struct fts_ts_data *fts_data) pr_err("VM mem release failed: rc=%d\n", rc); rc = hh_rm_mem_notify(fts_data->vm_info->vm_mem_handle, - HH_RM_MEM_NOTIFY_OWNER, + HH_RM_MEM_NOTIFY_OWNER_RELEASED, HH_MEM_NOTIFIER_TAG_TOUCH, 0); if (rc) pr_err("Failed to notify mem release to PVM: rc=%d\n"); @@ -689,7 +689,7 @@ static int fts_ts_vm_mem_lend(struct fts_ts_data *fts_data) vmid_desc = fts_ts_vm_get_vmid(trusted_vmid); - rc = hh_rm_mem_notify(mem_handle, HH_RM_MEM_NOTIFY_RECIPIENT, + rc = hh_rm_mem_notify(mem_handle, HH_RM_MEM_NOTIFY_RECIPIENT_SHARED, HH_MEM_NOTIFIER_TAG_TOUCH, vmid_desc); if (rc) { pr_err("Failed to notify mem lend to hypervisor rc:%d\n", rc); diff --git a/drivers/input/touchscreen/st/fts.c b/drivers/input/touchscreen/st/fts.c index cce1ee2fd85a..3832d89422bf 100644 --- a/drivers/input/touchscreen/st/fts.c +++ b/drivers/input/touchscreen/st/fts.c @@ -462,7 +462,7 @@ static int fts_vm_mem_release(struct fts_ts_info *info) pr_err("VM mem release failed: rc=%d\n", rc); rc = hh_rm_mem_notify(info->vm_info->vm_mem_handle, - HH_RM_MEM_NOTIFY_OWNER, + HH_RM_MEM_NOTIFY_OWNER_RELEASED, HH_MEM_NOTIFIER_TAG_TOUCH, 0); if (rc) pr_err("Failed to notify mem release to PVM: rc=%d\n"); @@ -713,7 +713,7 @@ static int fts_vm_mem_lend(struct fts_ts_info *info) vmid_desc = fts_vm_get_vmid(trusted_vmid); - rc = hh_rm_mem_notify(mem_handle, HH_RM_MEM_NOTIFY_RECIPIENT, + rc = hh_rm_mem_notify(mem_handle, HH_RM_MEM_NOTIFY_RECIPIENT_SHARED, HH_MEM_NOTIFIER_TAG_TOUCH, vmid_desc); if (rc) { pr_err("Failed to notify mem lend to hypervisor rc:%d\n", rc); diff --git a/drivers/virt/haven/hh_mem_notifier.c b/drivers/virt/haven/hh_mem_notifier.c index 4157240882e9..dfd0099bd065 100644 --- a/drivers/virt/haven/hh_mem_notifier.c +++ b/drivers/virt/haven/hh_mem_notifier.c @@ -93,9 +93,14 @@ EXPORT_SYMBOL(hh_mem_notifier_unregister); static enum hh_mem_notifier_tag hh_mem_notifier_get_tag(unsigned long action, void *msg) { - return action == HH_RM_NOTIF_MEM_SHARED ? - ((struct hh_rm_notif_mem_shared_payload *)msg)->mem_info_tag : + if (action == HH_RM_NOTIF_MEM_SHARED) + return + ((struct hh_rm_notif_mem_shared_payload *)msg)->mem_info_tag; + else if (action == HH_RM_NOTIF_MEM_RELEASED) + return ((struct hh_rm_notif_mem_released_payload *)msg)->mem_info_tag; + + return ((struct hh_rm_notif_mem_accepted_payload *)msg)->mem_info_tag; } static int hh_mem_notifier_call(struct notifier_block *nb, unsigned long action, @@ -107,7 +112,8 @@ static int hh_mem_notifier_call(struct notifier_block *nb, unsigned long action, void *data; if ((action != HH_RM_NOTIF_MEM_SHARED) && - (action != HH_RM_NOTIF_MEM_RELEASED)) + (action != HH_RM_NOTIF_MEM_RELEASED) && + (action != HH_RM_NOTIF_MEM_ACCEPTED)) return NOTIFY_DONE; tag = hh_mem_notifier_get_tag(action, msg); diff --git a/drivers/virt/haven/hh_rm_core.c b/drivers/virt/haven/hh_rm_core.c index f1c0ae48dd0c..152f9d78dbb8 100644 --- a/drivers/virt/haven/hh_rm_core.c +++ b/drivers/virt/haven/hh_rm_core.c @@ -236,6 +236,15 @@ static int hh_rm_process_notif(void *recv_buff, size_t recv_buff_size) goto err; } break; + case HH_RM_NOTIF_MEM_ACCEPTED: + if (recv_buff_size != sizeof(*hdr) + + sizeof(struct hh_rm_notif_mem_accepted_payload)) { + pr_err("%s: Invalid size for MEM_ACCEPTED notif: %u\n", + __func__, recv_buff_size - sizeof(*hdr)); + ret = -EINVAL; + goto err; + } + break; case HH_RM_NOTIF_VM_CONSOLE_CHARS: if (recv_buff_size < sizeof(*hdr) + sizeof(struct hh_rm_notif_vm_console_chars)) { diff --git a/drivers/virt/haven/hh_rm_iface.c b/drivers/virt/haven/hh_rm_iface.c index 8d7446836cd9..520f5768ed32 100644 --- a/drivers/virt/haven/hh_rm_iface.c +++ b/drivers/virt/haven/hh_rm_iface.c @@ -22,7 +22,8 @@ #define HH_RM_MEM_SHARE_VALID_FLAGS HH_RM_MEM_SHARE_SANITIZE #define HH_RM_MEM_LEND_VALID_FLAGS HH_RM_MEM_LEND_SANITIZE #define HH_RM_MEM_NOTIFY_VALID_FLAGS\ - (HH_RM_MEM_NOTIFY_RECIPIENT | HH_RM_MEM_NOTIFY_OWNER) + (HH_RM_MEM_NOTIFY_RECIPIENT_SHARED |\ + HH_RM_MEM_NOTIFY_OWNER_RELEASED | HH_RM_MEM_NOTIFY_OWNER_ACCEPTED) static struct hh_vm_property hh_vm_table[HH_VM_MAX]; @@ -1214,9 +1215,9 @@ EXPORT_SYMBOL(hh_rm_mem_lend); * out * @flags: Flags to determine if the notification is for notifying that memory * has been shared to another VM, or that a VM has released memory - * @mem_info_tag: A 32-bit value that is attached to the MEM_SHARED/MEM_RELEASED - * notifications to aid in distinguishing different resources - * from one another. + * @mem_info_tag: A 32-bit value that is attached to the + * MEM_SHARED/MEM_RELEASED/MEM_ACCEPTED notifications to aid in + * distinguishing different resources from one another. * @vmid_desc: A list of VMIDs to notify that memory has been shared with them. * This parameter should only be non-NULL if other VMs are being * notified (i.e. it is invalid to specify this parameter when the @@ -1238,13 +1239,15 @@ int hh_rm_mem_notify(hh_memparcel_handle_t handle, u8 flags, int ret = 0, hh_ret; if ((flags & ~HH_RM_MEM_NOTIFY_VALID_FLAGS) || - ((flags & HH_RM_MEM_NOTIFY_RECIPIENT) && (!vmid_desc || - (vmid_desc && + ((flags & HH_RM_MEM_NOTIFY_RECIPIENT_SHARED) && (!vmid_desc || + (vmid_desc && !vmid_desc->n_vmid_entries))) || - ((flags & HH_RM_MEM_NOTIFY_OWNER) && vmid_desc)) + ((flags & (HH_RM_MEM_NOTIFY_OWNER_RELEASED | + HH_RM_MEM_NOTIFY_OWNER_ACCEPTED)) && vmid_desc) || + (hweight8(flags) != 1)) return -EINVAL; - if (flags & HH_RM_MEM_NOTIFY_RECIPIENT) { + if (flags & HH_RM_MEM_NOTIFY_RECIPIENT_SHARED) { n_vmid_entries = vmid_desc->n_vmid_entries; req_vmid_desc_size = offsetof(struct hh_notify_vmid_desc, vmid_entries[n_vmid_entries]); @@ -1260,7 +1263,7 @@ int hh_rm_mem_notify(hh_memparcel_handle_t handle, u8 flags, req_payload_hdr->flags = flags; req_payload_hdr->mem_info_tag = mem_info_tag; - if (flags & HH_RM_MEM_NOTIFY_RECIPIENT) { + if (flags & HH_RM_MEM_NOTIFY_RECIPIENT_SHARED) { dst_vmid_desc = req_buf + sizeof(*req_payload_hdr); dst_vmid_desc->n_vmid_entries = n_vmid_entries; for (i = 0; i < n_vmid_entries; i++) diff --git a/include/linux/haven/hh_rm_drv.h b/include/linux/haven/hh_rm_drv.h index dc11541af543..b9beedc4f60c 100644 --- a/include/linux/haven/hh_rm_drv.h +++ b/include/linux/haven/hh_rm_drv.h @@ -16,6 +16,7 @@ /* Memory APIs */ #define HH_RM_NOTIF_MEM_SHARED 0x51100011 #define HH_RM_NOTIF_MEM_RELEASED 0x51100012 +#define HH_RM_NOTIF_MEM_ACCEPTED 0x51100013 #define HH_RM_MEM_TYPE_NORMAL 0 #define HH_RM_MEM_TYPE_IO 1 @@ -39,8 +40,11 @@ #define HH_RM_MEM_SHARE_SANITIZE BIT(0) #define HH_RM_MEM_LEND_SANITIZE BIT(0) -#define HH_RM_MEM_NOTIFY_RECIPIENT BIT(0) -#define HH_RM_MEM_NOTIFY_OWNER BIT(1) +#define HH_RM_MEM_NOTIFY_RECIPIENT_SHARED BIT(0) +#define HH_RM_MEM_NOTIFY_RECIPIENT HH_RM_MEM_NOTIFY_RECIPIENT_SHARED +#define HH_RM_MEM_NOTIFY_OWNER_RELEASED BIT(1) +#define HH_RM_MEM_NOTIFY_OWNER HH_RM_MEM_NOTIFY_OWNER_RELEASED +#define HH_RM_MEM_NOTIFY_OWNER_ACCEPTED BIT(2) struct hh_rm_mem_shared_acl_entry; struct hh_rm_mem_shared_sgl_entry; @@ -82,6 +86,13 @@ struct hh_rm_notif_mem_released_payload { hh_label_t mem_info_tag; } __packed; +struct hh_rm_notif_mem_accepted_payload { + u32 mem_handle; + u16 participant_vmid; + u16 reserved; + hh_label_t mem_info_tag; +} __packed; + struct hh_acl_entry { u16 vmid; u8 perms;