From 8f5870302b3091e194e936b17081d0ca2fd52300 Mon Sep 17 00:00:00 2001 From: Prakruthi Deepak Heragu Date: Tue, 18 Feb 2025 22:05:10 -0800 Subject: [PATCH] ANDROID: gunyah: Add an RM API to authenticate a VM RM supports authentication of VMs with the assistance of the firmware. Add an API for auth_mgr to use if the VM it manages uses the firmare for authentication. Bug: 399219478 Change-Id: Ib550c642146586434d8328bb53de08690e2527ad Signed-off-by: Prakruthi Deepak Heragu --- drivers/virt/gunyah/rsc_mgr.h | 9 +++++ drivers/virt/gunyah/rsc_mgr_rpc.c | 63 +++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/drivers/virt/gunyah/rsc_mgr.h b/drivers/virt/gunyah/rsc_mgr.h index b717b23c8bce..ddc6e67c3e10 100644 --- a/drivers/virt/gunyah/rsc_mgr.h +++ b/drivers/virt/gunyah/rsc_mgr.h @@ -79,6 +79,15 @@ enum gunyah_rm_vm_auth_mechanism { /* clang-format on */ }; +#define GUNYAH_VM_AUTH_PARAM_PAS_ID 0 +struct gunyah_rm_vm_authenticate_param_entry { + u32 param_type; + u32 param; +} __packed; + +int gunyah_rm_vm_authenticate(struct gunyah_rm *rm, u16 vmid, + ssize_t n_entries, + struct gunyah_rm_vm_authenticate_param_entry *entry); int gunyah_rm_vm_configure(struct gunyah_rm *rm, u16 vmid, enum gunyah_rm_vm_auth_mechanism auth_mechanism, u32 mem_handle, u64 image_offset, u64 image_size, diff --git a/drivers/virt/gunyah/rsc_mgr_rpc.c b/drivers/virt/gunyah/rsc_mgr_rpc.c index 187b8824b45e..172796faaa32 100644 --- a/drivers/virt/gunyah/rsc_mgr_rpc.c +++ b/drivers/virt/gunyah/rsc_mgr_rpc.c @@ -21,6 +21,7 @@ #define GUNYAH_RM_RPC_VM_STOP 0x56000005 #define GUNYAH_RM_RPC_VM_RESET 0x56000006 #define GUNYAH_RM_RPC_VM_CONFIG_IMAGE 0x56000009 +#define GUNYAH_RM_RPC_VM_AUTH_IMAGE 0x5600000A #define GUNYAH_RM_RPC_VM_INIT 0x5600000B #define GUNYAH_RM_RPC_VM_GET_HYP_RESOURCES 0x56000020 #define GUNYAH_RM_RPC_VM_GET_VMID 0x56000024 @@ -96,6 +97,12 @@ struct gunyah_rm_vm_stop_req { __le32 stop_reason; } __packed; +/* Call: VM_AUTH_IMAGE */ +struct gunyah_rm_vm_authenticate_req_header { + __le16 vmid; + __le16 n_params; +} __packed; + /* Call: VM_CONFIG_IMAGE */ struct gunyah_rm_vm_config_image_req { __le16 vmid; @@ -419,6 +426,62 @@ int gunyah_rm_vm_stop(struct gunyah_rm *rm, u16 vmid) } ALLOW_ERROR_INJECTION(gunyah_rm_vm_stop, ERRNO); +/** + * gunyah_rm_vm_authenticate() - Send a request to Resource Manager VM to authenticate a VM. + * @rm: Handle to a Gunyah resource manager + * @vmid: VM identifier allocated with gunyah_rm_alloc_vmid + * @n_entries: Number of entries of type gunyah_rm_vm_auth_param_entry + * @entry: Type of authentication parameters + */ +int gunyah_rm_vm_authenticate(struct gunyah_rm *rm, u16 vmid, + ssize_t n_entries, + struct gunyah_rm_vm_authenticate_param_entry *entry) +{ + struct gunyah_rm_vm_authenticate_req_header *req_header; + struct gunyah_rm_vm_authenticate_param_entry *dest_entry; + size_t resp_payload_size; + size_t req_size; + int err; + void *req_buf; + __le32 *resp; + + req_size = sizeof(*req_header) + n_entries * sizeof(*entry); + + req_buf = kzalloc(req_size, GFP_KERNEL); + if (!req_buf) + return -ENOMEM; + + req_header = req_buf; + req_header->vmid = vmid; + req_header->n_params = n_entries; + + dest_entry = req_buf + sizeof(*req_header); + memcpy(dest_entry, entry, sizeof(*entry) * n_entries); + + err = gunyah_rm_call(rm, GUNYAH_RM_RPC_VM_AUTH_IMAGE, + req_buf, req_size, (void **)&resp, + &resp_payload_size); + if (err) { + pr_err("%s: Unable to send VM_AUTH_IMAGE to RM: %d\n", __func__, err); + kfree(req_buf); + return err; + } + + if (resp_payload_size) { + pr_err("%s: Invalid size received for VM_AUTH_IMAGE: %zu\n", + __func__, resp_payload_size); + kfree(resp); + kfree(req_buf); + return -EINVAL; + } + + /* no need to free the resp as no payload is expected */ + kfree(req_buf); + return 0; +} +ALLOW_ERROR_INJECTION(gunyah_rm_vm_authenticate, ERRNO); +EXPORT_SYMBOL_GPL(gunyah_rm_vm_authenticate); + /** * gunyah_rm_vm_configure() - Prepare a VM to start and provide the common * configuration needed by RM to configure a VM