123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
- */
- #include "hab.h"
- #include <linux/module.h>
- int32_t habmm_socket_open(int32_t *handle, uint32_t mm_ip_id,
- uint32_t timeout, uint32_t flags)
- {
- while (unlikely(!READ_ONCE(hab_driver.hab_init_success))) {
- pr_info_once("opening on mmid %d when hab has not completed init\n",
- mm_ip_id);
- schedule();
- }
- return hab_vchan_open(hab_driver.kctx, mm_ip_id, handle,
- timeout, flags);
- }
- EXPORT_SYMBOL(habmm_socket_open);
- int32_t habmm_socket_close(int32_t handle)
- {
- /*
- * The ctx_lock read-side path calls frequently, while the
- * write-side path calls less. In order to avoid disabling
- * bh on the read side of ctx_lock, do not support calling
- * this function in interrupt context. Otherwise you may
- * run into serious deadlock issues.
- */
- WARN_ON(in_irq() || in_serving_softirq());
- return hab_vchan_close(hab_driver.kctx, handle);
- }
- EXPORT_SYMBOL(habmm_socket_close);
- int32_t habmm_socket_send(int32_t handle, void *src_buff,
- uint32_t size_bytes, uint32_t flags)
- {
- struct hab_send param = {0};
- param.vcid = handle;
- param.data = (uint64_t)(uintptr_t)src_buff;
- param.sizebytes = size_bytes;
- param.flags = flags;
- return hab_vchan_send(hab_driver.kctx, handle,
- size_bytes, src_buff, flags);
- }
- EXPORT_SYMBOL(habmm_socket_send);
- int32_t habmm_socket_recv(int32_t handle, void *dst_buff, uint32_t *size_bytes,
- uint32_t timeout, uint32_t flags)
- {
- int ret = 0;
- struct hab_message *msg = NULL;
- void **scatter_buf = NULL;
- int i = 0;
- if (!size_bytes || !dst_buff)
- return -EINVAL;
- ret = hab_vchan_recv(hab_driver.kctx, &msg, handle, size_bytes, timeout, flags);
- if (ret == 0 && msg) {
- if (unlikely(msg->scatter)) {
- scatter_buf = (void **)msg->data;
- /* The maximum size of msg is limited in hab_msg_alloc*/
- for (i = 0; i < msg->sizebytes / PAGE_SIZE; i++)
- memcpy((char *)((uint64_t)dst_buff
- + (uint64_t)(i * PAGE_SIZE)), scatter_buf[i], PAGE_SIZE);
- if (msg->sizebytes % PAGE_SIZE)
- memcpy((char *)((uint64_t)dst_buff
- + (uint64_t)(i * PAGE_SIZE)), scatter_buf[i],
- msg->sizebytes % PAGE_SIZE);
- } else
- memcpy(dst_buff, msg->data, msg->sizebytes);
- } else if (ret && msg) {
- pr_warn("vcid %X recv failed %d but msg is still received %zd bytes\n",
- handle, ret, msg->sizebytes);
- }
- if (msg)
- hab_msg_free(msg);
- return ret;
- }
- EXPORT_SYMBOL(habmm_socket_recv);
- int32_t habmm_export(int32_t handle, void *buff_to_share, uint32_t size_bytes,
- uint32_t *export_id, uint32_t flags)
- {
- int ret;
- struct hab_export param = {0};
- if (!export_id)
- return -EINVAL;
- param.vcid = handle;
- param.buffer = (uint64_t)(uintptr_t)buff_to_share;
- param.sizebytes = size_bytes;
- param.flags = flags;
- ret = hab_mem_export(hab_driver.kctx, ¶m, 1);
- *export_id = param.exportid;
- return ret;
- }
- EXPORT_SYMBOL(habmm_export);
- int32_t habmm_unexport(int32_t handle, uint32_t export_id, uint32_t flags)
- {
- struct hab_unexport param = {0};
- param.vcid = handle;
- param.exportid = export_id;
- return hab_mem_unexport(hab_driver.kctx, ¶m, 1);
- }
- EXPORT_SYMBOL(habmm_unexport);
- int32_t habmm_import(int32_t handle, void **buff_shared, uint32_t size_bytes,
- uint32_t export_id, uint32_t flags)
- {
- int ret;
- struct hab_import param = {0};
- if (!buff_shared)
- return -EINVAL;
- param.vcid = handle;
- param.sizebytes = size_bytes;
- param.exportid = export_id;
- param.flags = flags;
- ret = hab_mem_import(hab_driver.kctx, ¶m, 1);
- if (!ret)
- *buff_shared = (void *)(uintptr_t)param.kva;
- return ret;
- }
- EXPORT_SYMBOL(habmm_import);
- int32_t habmm_unimport(int32_t handle,
- uint32_t export_id,
- void *buff_shared,
- uint32_t flags)
- {
- struct hab_unimport param = {0};
- param.vcid = handle;
- param.exportid = export_id;
- param.kva = (uint64_t)(uintptr_t)buff_shared;
- return hab_mem_unimport(hab_driver.kctx, ¶m, 1);
- }
- EXPORT_SYMBOL(habmm_unimport);
- int32_t habmm_socket_query(int32_t handle,
- struct hab_socket_info *info,
- uint32_t flags)
- {
- int ret;
- uint64_t ids;
- char nm[VMNAME_SIZE * 2];
- if (!info)
- return -EINVAL;
- ret = hab_vchan_query(hab_driver.kctx, handle, &ids, nm, sizeof(nm), 1);
- if (!ret) {
- info->vmid_local = ids & 0xFFFFFFFF;
- info->vmid_remote = (ids & 0xFFFFFFFF00000000UL) > 32;
- strscpy(info->vmname_local, nm, sizeof(info->vmname_local));
- strscpy(info->vmname_remote, &nm[sizeof(info->vmname_local)],
- sizeof(info->vmname_remote));
- }
- return ret;
- }
- EXPORT_SYMBOL(habmm_socket_query);
|