diff options
| author | Yong Ding <yongding@codeaurora.org> | 2018-03-19 16:39:28 +0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2018-03-20 19:01:52 -0700 |
| commit | 4fc0ee9d997b4f2ebff497655c024ec4d5b2ea47 (patch) | |
| tree | 89badda802f35e33fa318228234593e381abffad | |
| parent | bb9c0e0ec85aa211716bff72ae378e0c87dae4a2 (diff) | |
soc: qcom: hab: add habmm_socket_query support
This query API can be used by hab clients to get
their virtual channels' info if necessary, eg, the
local and remote vmids.
Change-Id: I1293b51a1127997f493f07c0c2181423bf45d79e
Signed-off-by: Yong Ding <yongding@codeaurora.org>
| -rw-r--r-- | drivers/soc/qcom/hab/hab.c | 41 | ||||
| -rw-r--r-- | drivers/soc/qcom/hab/hab.h | 7 | ||||
| -rw-r--r-- | drivers/soc/qcom/hab/hab_vchan.c | 18 | ||||
| -rw-r--r-- | drivers/soc/qcom/hab/khab.c | 23 | ||||
| -rw-r--r-- | include/linux/habmm.h | 13 | ||||
| -rw-r--r-- | include/uapi/linux/habmm.h | 11 |
6 files changed, 105 insertions, 8 deletions
diff --git a/drivers/soc/qcom/hab/hab.c b/drivers/soc/qcom/hab/hab.c index 4136f2995046..1e568c79fcae 100644 --- a/drivers/soc/qcom/hab/hab.c +++ b/drivers/soc/qcom/hab/hab.c @@ -521,14 +521,18 @@ static int hab_initialize_pchan_entry(struct hab_device *mmid_device, ret = habhyp_commdev_alloc((void **)&pchan, is_be, pchan_name, vmid_remote, mmid_device); - if (ret == 0) { - pr_debug("pchan %s added, vmid local %d, remote %d, is_be %d, total %d\n", - pchan_name, vmid_local, vmid_remote, is_be, - mmid_device->pchan_cnt); - } else { + if (ret) { pr_err("failed %d to allocate pchan %s, vmid local %d, remote %d, is_be %d, total %d\n", ret, pchan_name, vmid_local, vmid_remote, is_be, mmid_device->pchan_cnt); + } else { + /* local/remote id setting should be kept in lower level */ + pchan->vmid_local = vmid_local; + pchan->vmid_remote = vmid_remote; + pr_debug("pchan %s mmid %s local %d remote %d role %d\n", + pchan_name, mmid_device->name, + pchan->vmid_local, pchan->vmid_remote, + pchan->dom_id); } return ret; @@ -780,10 +784,12 @@ static long hab_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) struct hab_close *close_param; struct hab_recv *recv_param; struct hab_send *send_param; + struct hab_info *info_param; struct hab_message *msg; void *send_data; unsigned char data[256] = { 0 }; long ret = 0; + char names[30]; if (_IOC_SIZE(cmd) && (cmd & IOC_IN)) { if (_IOC_SIZE(cmd) > sizeof(data)) @@ -873,6 +879,31 @@ static long hab_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) case IOCTL_HAB_VC_UNIMPORT: ret = hab_mem_unimport(ctx, (struct hab_unimport *)data, 0); break; + case IOCTL_HAB_VC_QUERY: + info_param = (struct hab_info *)data; + if (!info_param->names || !info_param->namesize || + info_param->namesize > sizeof(names)) { + pr_err("wrong vm info vcid %X, names %llX, sz %d\n", + info_param->vcid, info_param->names, + info_param->namesize); + ret = -EINVAL; + break; + } + ret = hab_vchan_query(ctx, info_param->vcid, + (uint64_t *)&info_param->ids, + names, info_param->namesize, 0); + if (!ret) { + if (copy_to_user((void __user *)info_param->names, + names, + info_param->namesize)) { + pr_err("copy_to_user failed: vc=%x size=%d\n", + info_param->vcid, + info_param->namesize*2); + info_param->namesize = 0; + ret = -EFAULT; + } + } + break; default: ret = -ENOIOCTLCMD; } diff --git a/drivers/soc/qcom/hab/hab.h b/drivers/soc/qcom/hab/hab.h index f13d6f44b929..dcf2c751df30 100644 --- a/drivers/soc/qcom/hab/hab.h +++ b/drivers/soc/qcom/hab/hab.h @@ -194,6 +194,10 @@ struct physical_channel { void *hyp_data; int dom_id; + int vmid_local; + int vmid_remote; + char vmname_local[12]; + char vmname_remote[12]; int closed; spinlock_t rxbuf_lock; @@ -504,6 +508,9 @@ int fill_default_gvm_settings(struct local_vmid *settings, bool hab_is_loopback(void); +int hab_vchan_query(struct uhab_context *ctx, int32_t vcid, uint64_t *ids, + char *names, size_t name_size, uint32_t flags); + /* Global singleton HAB instance */ extern struct hab_driver hab_driver; diff --git a/drivers/soc/qcom/hab/hab_vchan.c b/drivers/soc/qcom/hab/hab_vchan.c index 91ae173f7e83..e8b8866d570d 100644 --- a/drivers/soc/qcom/hab/hab_vchan.c +++ b/drivers/soc/qcom/hab/hab_vchan.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -211,3 +211,19 @@ void hab_vchan_put(struct virtual_channel *vchan) if (vchan) kref_put(&vchan->refcount, hab_vchan_schedule_free); } + +int hab_vchan_query(struct uhab_context *ctx, int32_t vcid, uint64_t *ids, + char *names, size_t name_size, uint32_t flags) +{ + struct virtual_channel *vchan = hab_get_vchan_fromvcid(vcid, ctx); + + if (!vchan || vchan->otherend_closed) + return -ENODEV; + + *ids = vchan->pchan->vmid_local | + ((uint64_t)vchan->pchan->vmid_remote) << 32; + names[0] = 0; + names[name_size/2] = 0; + + return 0; +} diff --git a/drivers/soc/qcom/hab/khab.c b/drivers/soc/qcom/hab/khab.c index 05e6aa2fa7ca..3fdd11f7daf7 100644 --- a/drivers/soc/qcom/hab/khab.c +++ b/drivers/soc/qcom/hab/khab.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -138,3 +138,24 @@ int32_t habmm_unimport(int32_t handle, 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[sizeof(info->vmname_remote) + sizeof(info->vmname_local)]; + + 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; + + strlcpy(info->vmname_local, nm, sizeof(info->vmname_local)); + strlcpy(info->vmname_remote, &nm[sizeof(info->vmname_local)], + sizeof(info->vmname_remote)); + } + return ret; +} +EXPORT_SYMBOL(habmm_socket_query); diff --git a/include/linux/habmm.h b/include/linux/habmm.h index 4d3a81f536d9..1c27ee4f14f7 100644 --- a/include/linux/habmm.h +++ b/include/linux/habmm.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -35,4 +35,15 @@ int32_t habmm_import(int32_t handle, void **buff_shared, uint32_t size_bytes, int32_t habmm_unimport(int32_t handle, uint32_t export_id, void *buff_shared, uint32_t flags); +struct hab_socket_info { + int32_t vmid_remote; /* habmm's vmid */ + int32_t vmid_local; + /* name from hypervisor framework if available */ + char vmname_remote[12]; + char vmname_local[12]; +}; + +int32_t habmm_socket_query(int32_t handle, struct hab_socket_info *info, + uint32_t flags); + #endif diff --git a/include/uapi/linux/habmm.h b/include/uapi/linux/habmm.h index 8586048e20c0..b1b6561f2552 100644 --- a/include/uapi/linux/habmm.h +++ b/include/uapi/linux/habmm.h @@ -59,6 +59,14 @@ struct hab_unimport { __u32 flags; }; +struct hab_info { + __s32 vcid; + __u64 ids; /* high part remote; low part local */ + __u64 names; + __u32 namesize; /* single name length */ + __u32 flags; +}; + #define HAB_IOC_TYPE 0x0A #define HAB_MAX_MSG_SIZEBYTES 0x1000 #define HAB_MAX_EXPORT_SIZE 0x8000000 @@ -163,4 +171,7 @@ struct hab_unimport { #define IOCTL_HAB_VC_UNIMPORT \ _IOW(HAB_IOC_TYPE, 0x9, struct hab_unimport) +#define IOCTL_HAB_VC_QUERY \ + _IOWR(HAB_IOC_TYPE, 0xA, struct hab_info) + #endif /* HABMM_H */ |
