summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYong Ding <yongding@codeaurora.org>2018-03-19 16:39:28 +0800
committerGerrit - the friendly Code Review server <code-review@localhost>2018-03-20 19:01:52 -0700
commit4fc0ee9d997b4f2ebff497655c024ec4d5b2ea47 (patch)
tree89badda802f35e33fa318228234593e381abffad
parentbb9c0e0ec85aa211716bff72ae378e0c87dae4a2 (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.c41
-rw-r--r--drivers/soc/qcom/hab/hab.h7
-rw-r--r--drivers/soc/qcom/hab/hab_vchan.c18
-rw-r--r--drivers/soc/qcom/hab/khab.c23
-rw-r--r--include/linux/habmm.h13
-rw-r--r--include/uapi/linux/habmm.h11
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, &param, 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 */