Loading arch/arm/configs/mdm9607-perf_defconfig +1 −0 Original line number Original line Diff line number Diff line Loading @@ -348,6 +348,7 @@ CONFIG_MSM_PIL=y CONFIG_MSM_PIL_MSS_QDSP6V5=y CONFIG_MSM_PIL_MSS_QDSP6V5=y CONFIG_TRACER_PKT=y CONFIG_TRACER_PKT=y CONFIG_MSM_BAM_DMUX=y CONFIG_MSM_BAM_DMUX=y CONFIG_QCOM_SMCINVOKE=y CONFIG_IIO=y CONFIG_IIO=y CONFIG_IIO_BUFFER_CB=y CONFIG_IIO_BUFFER_CB=y CONFIG_SENSORS_BMI160_IIO=y CONFIG_SENSORS_BMI160_IIO=y Loading arch/arm/configs/mdm9607_defconfig +1 −0 Original line number Original line Diff line number Diff line Loading @@ -348,6 +348,7 @@ CONFIG_MSM_PIL=y CONFIG_MSM_PIL_MSS_QDSP6V5=y CONFIG_MSM_PIL_MSS_QDSP6V5=y CONFIG_TRACER_PKT=y CONFIG_TRACER_PKT=y CONFIG_MSM_BAM_DMUX=y CONFIG_MSM_BAM_DMUX=y CONFIG_QCOM_SMCINVOKE=y CONFIG_IIO=y CONFIG_IIO=y CONFIG_IIO_BUFFER_CB=y CONFIG_IIO_BUFFER_CB=y CONFIG_SENSORS_BMI160_IIO=y CONFIG_SENSORS_BMI160_IIO=y Loading drivers/soc/qcom/smcinvoke.c +31 −21 Original line number Original line Diff line number Diff line /* Copyright (c) 2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -192,9 +192,9 @@ static int prepare_send_scm_msg(const uint8_t *in_buf, size_t in_buf_len, desc.arginfo = SMCINVOKE_TZ_PARAM_ID; desc.arginfo = SMCINVOKE_TZ_PARAM_ID; desc.args[0] = (uint64_t)virt_to_phys(in_buf); desc.args[0] = (uint64_t)virt_to_phys(in_buf); desc.args[1] = in_buf_len; desc.args[1] = inbuf_flush_size; desc.args[2] = (uint64_t)virt_to_phys(out_buf); desc.args[2] = (uint64_t)virt_to_phys(out_buf); desc.args[3] = out_buf_len; desc.args[3] = outbuf_flush_size; dmac_flush_range(in_buf, in_buf + inbuf_flush_size); dmac_flush_range(in_buf, in_buf + inbuf_flush_size); dmac_flush_range(out_buf, out_buf + outbuf_flush_size); dmac_flush_range(out_buf, out_buf + outbuf_flush_size); Loading @@ -207,12 +207,11 @@ static int prepare_send_scm_msg(const uint8_t *in_buf, size_t in_buf_len, ret = qseecom_process_listener_from_smcinvoke(&desc); ret = qseecom_process_listener_from_smcinvoke(&desc); *smcinvoke_result = (int32_t)desc.ret[1]; *smcinvoke_result = (int32_t)desc.ret[1]; if (ret || desc.ret[1] || desc.ret[2] || desc.ret[0]) { if (ret || desc.ret[1] || desc.ret[2] || desc.ret[0]) pr_err("SCM call failed with ret val = %d %d %d %d\n", pr_err("SCM call failed with ret val = %d %d %d %d\n", ret, (int)desc.ret[0], ret, (int)desc.ret[0], (int)desc.ret[1], (int)desc.ret[2]); (int)desc.ret[1], (int)desc.ret[2]); ret = ret | desc.ret[0] | desc.ret[1] | desc.ret[2]; } dmac_inv_range(in_buf, in_buf + inbuf_flush_size); dmac_inv_range(in_buf, in_buf + inbuf_flush_size); dmac_inv_range(out_buf, out_buf + outbuf_flush_size); dmac_inv_range(out_buf, out_buf + outbuf_flush_size); return ret; return ret; Loading Loading @@ -243,7 +242,7 @@ static int marshal_out(void *buf, uint32_t buf_size, pr_err("%s: buffer overflow detected\n", __func__); pr_err("%s: buffer overflow detected\n", __func__); goto out; goto out; } } if (copy_to_user((void __user *)(args_buf[i].b.addr), if (copy_to_user((void __user *)(uintptr_t)(args_buf[i].b.addr), (uint8_t *)(buf) + tz_args->b.offset, (uint8_t *)(buf) + tz_args->b.offset, tz_args->b.size)) { tz_args->b.size)) { pr_err("Error %d copying ctxt to user\n", ret); pr_err("Error %d copying ctxt to user\n", ret); Loading Loading @@ -328,7 +327,7 @@ static int marshal_in(const struct smcinvoke_cmd_req *req, tz_args++; tz_args++; if (copy_from_user(buf+offset, if (copy_from_user(buf+offset, (void __user *)(args_buf[i].b.addr), (void __user *)(uintptr_t)(args_buf[i].b.addr), args_buf[i].b.size)) args_buf[i].b.size)) goto out; goto out; Loading Loading @@ -383,24 +382,28 @@ long smcinvoke_ioctl(struct file *filp, unsigned cmd, unsigned long arg) nr_args = object_counts_num_buffers(req.counts) + nr_args = object_counts_num_buffers(req.counts) + object_counts_num_objects(req.counts); object_counts_num_objects(req.counts); if (!nr_args || req.argsize != sizeof(union smcinvoke_arg)) { if (req.argsize != sizeof(union smcinvoke_arg)) { ret = -EINVAL; ret = -EINVAL; goto out; goto out; } } if (nr_args) { args_buf = kzalloc(nr_args * req.argsize, GFP_KERNEL); args_buf = kzalloc(nr_args * req.argsize, GFP_KERNEL); if (!args_buf) { if (!args_buf) { ret = -ENOMEM; ret = -ENOMEM; goto out; goto out; } } ret = copy_from_user(args_buf, (void __user *)(req.args), ret = copy_from_user(args_buf, (void __user *)(uintptr_t)(req.args), nr_args * req.argsize); nr_args * req.argsize); if (ret) { if (ret) { ret = -EFAULT; ret = -EFAULT; goto out; goto out; } } } inmsg_size = compute_in_msg_size(&req, args_buf); inmsg_size = compute_in_msg_size(&req, args_buf); in_msg = (void *)__get_free_pages(GFP_KERNEL, in_msg = (void *)__get_free_pages(GFP_KERNEL, Loading @@ -426,10 +429,17 @@ long smcinvoke_ioctl(struct file *filp, unsigned cmd, unsigned long arg) if (ret) if (ret) goto out; goto out; /* * if invoke op results in an err, no need to marshal_out and * copy args buf to user space */ if (!req.result) { ret = marshal_out(in_msg, inmsg_size, &req, args_buf); ret = marshal_out(in_msg, inmsg_size, &req, args_buf); ret |= copy_to_user((void __user *)(req.args), args_buf, ret |= copy_to_user( nr_args * req.argsize); (void __user *)(uintptr_t)(req.args), args_buf, nr_args * req.argsize); } ret |= copy_to_user((void __user *)arg, &req, sizeof(req)); ret |= copy_to_user((void __user *)arg, &req, sizeof(req)); if (ret) if (ret) goto out; goto out; Loading include/uapi/linux/smcinvoke.h +5 −5 Original line number Original line Diff line number Diff line Loading @@ -34,7 +34,7 @@ struct smcinvoke_cmd_req { uint32_t counts; uint32_t counts; int32_t result; int32_t result; uint32_t argsize; uint32_t argsize; uint64_t __user args; uint64_t args; }; }; #define SMCINVOKE_IOC_MAGIC 0x98 #define SMCINVOKE_IOC_MAGIC 0x98 Loading Loading
arch/arm/configs/mdm9607-perf_defconfig +1 −0 Original line number Original line Diff line number Diff line Loading @@ -348,6 +348,7 @@ CONFIG_MSM_PIL=y CONFIG_MSM_PIL_MSS_QDSP6V5=y CONFIG_MSM_PIL_MSS_QDSP6V5=y CONFIG_TRACER_PKT=y CONFIG_TRACER_PKT=y CONFIG_MSM_BAM_DMUX=y CONFIG_MSM_BAM_DMUX=y CONFIG_QCOM_SMCINVOKE=y CONFIG_IIO=y CONFIG_IIO=y CONFIG_IIO_BUFFER_CB=y CONFIG_IIO_BUFFER_CB=y CONFIG_SENSORS_BMI160_IIO=y CONFIG_SENSORS_BMI160_IIO=y Loading
arch/arm/configs/mdm9607_defconfig +1 −0 Original line number Original line Diff line number Diff line Loading @@ -348,6 +348,7 @@ CONFIG_MSM_PIL=y CONFIG_MSM_PIL_MSS_QDSP6V5=y CONFIG_MSM_PIL_MSS_QDSP6V5=y CONFIG_TRACER_PKT=y CONFIG_TRACER_PKT=y CONFIG_MSM_BAM_DMUX=y CONFIG_MSM_BAM_DMUX=y CONFIG_QCOM_SMCINVOKE=y CONFIG_IIO=y CONFIG_IIO=y CONFIG_IIO_BUFFER_CB=y CONFIG_IIO_BUFFER_CB=y CONFIG_SENSORS_BMI160_IIO=y CONFIG_SENSORS_BMI160_IIO=y Loading
drivers/soc/qcom/smcinvoke.c +31 −21 Original line number Original line Diff line number Diff line /* Copyright (c) 2016, The Linux Foundation. All rights reserved. /* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. * * * This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -192,9 +192,9 @@ static int prepare_send_scm_msg(const uint8_t *in_buf, size_t in_buf_len, desc.arginfo = SMCINVOKE_TZ_PARAM_ID; desc.arginfo = SMCINVOKE_TZ_PARAM_ID; desc.args[0] = (uint64_t)virt_to_phys(in_buf); desc.args[0] = (uint64_t)virt_to_phys(in_buf); desc.args[1] = in_buf_len; desc.args[1] = inbuf_flush_size; desc.args[2] = (uint64_t)virt_to_phys(out_buf); desc.args[2] = (uint64_t)virt_to_phys(out_buf); desc.args[3] = out_buf_len; desc.args[3] = outbuf_flush_size; dmac_flush_range(in_buf, in_buf + inbuf_flush_size); dmac_flush_range(in_buf, in_buf + inbuf_flush_size); dmac_flush_range(out_buf, out_buf + outbuf_flush_size); dmac_flush_range(out_buf, out_buf + outbuf_flush_size); Loading @@ -207,12 +207,11 @@ static int prepare_send_scm_msg(const uint8_t *in_buf, size_t in_buf_len, ret = qseecom_process_listener_from_smcinvoke(&desc); ret = qseecom_process_listener_from_smcinvoke(&desc); *smcinvoke_result = (int32_t)desc.ret[1]; *smcinvoke_result = (int32_t)desc.ret[1]; if (ret || desc.ret[1] || desc.ret[2] || desc.ret[0]) { if (ret || desc.ret[1] || desc.ret[2] || desc.ret[0]) pr_err("SCM call failed with ret val = %d %d %d %d\n", pr_err("SCM call failed with ret val = %d %d %d %d\n", ret, (int)desc.ret[0], ret, (int)desc.ret[0], (int)desc.ret[1], (int)desc.ret[2]); (int)desc.ret[1], (int)desc.ret[2]); ret = ret | desc.ret[0] | desc.ret[1] | desc.ret[2]; } dmac_inv_range(in_buf, in_buf + inbuf_flush_size); dmac_inv_range(in_buf, in_buf + inbuf_flush_size); dmac_inv_range(out_buf, out_buf + outbuf_flush_size); dmac_inv_range(out_buf, out_buf + outbuf_flush_size); return ret; return ret; Loading Loading @@ -243,7 +242,7 @@ static int marshal_out(void *buf, uint32_t buf_size, pr_err("%s: buffer overflow detected\n", __func__); pr_err("%s: buffer overflow detected\n", __func__); goto out; goto out; } } if (copy_to_user((void __user *)(args_buf[i].b.addr), if (copy_to_user((void __user *)(uintptr_t)(args_buf[i].b.addr), (uint8_t *)(buf) + tz_args->b.offset, (uint8_t *)(buf) + tz_args->b.offset, tz_args->b.size)) { tz_args->b.size)) { pr_err("Error %d copying ctxt to user\n", ret); pr_err("Error %d copying ctxt to user\n", ret); Loading Loading @@ -328,7 +327,7 @@ static int marshal_in(const struct smcinvoke_cmd_req *req, tz_args++; tz_args++; if (copy_from_user(buf+offset, if (copy_from_user(buf+offset, (void __user *)(args_buf[i].b.addr), (void __user *)(uintptr_t)(args_buf[i].b.addr), args_buf[i].b.size)) args_buf[i].b.size)) goto out; goto out; Loading Loading @@ -383,24 +382,28 @@ long smcinvoke_ioctl(struct file *filp, unsigned cmd, unsigned long arg) nr_args = object_counts_num_buffers(req.counts) + nr_args = object_counts_num_buffers(req.counts) + object_counts_num_objects(req.counts); object_counts_num_objects(req.counts); if (!nr_args || req.argsize != sizeof(union smcinvoke_arg)) { if (req.argsize != sizeof(union smcinvoke_arg)) { ret = -EINVAL; ret = -EINVAL; goto out; goto out; } } if (nr_args) { args_buf = kzalloc(nr_args * req.argsize, GFP_KERNEL); args_buf = kzalloc(nr_args * req.argsize, GFP_KERNEL); if (!args_buf) { if (!args_buf) { ret = -ENOMEM; ret = -ENOMEM; goto out; goto out; } } ret = copy_from_user(args_buf, (void __user *)(req.args), ret = copy_from_user(args_buf, (void __user *)(uintptr_t)(req.args), nr_args * req.argsize); nr_args * req.argsize); if (ret) { if (ret) { ret = -EFAULT; ret = -EFAULT; goto out; goto out; } } } inmsg_size = compute_in_msg_size(&req, args_buf); inmsg_size = compute_in_msg_size(&req, args_buf); in_msg = (void *)__get_free_pages(GFP_KERNEL, in_msg = (void *)__get_free_pages(GFP_KERNEL, Loading @@ -426,10 +429,17 @@ long smcinvoke_ioctl(struct file *filp, unsigned cmd, unsigned long arg) if (ret) if (ret) goto out; goto out; /* * if invoke op results in an err, no need to marshal_out and * copy args buf to user space */ if (!req.result) { ret = marshal_out(in_msg, inmsg_size, &req, args_buf); ret = marshal_out(in_msg, inmsg_size, &req, args_buf); ret |= copy_to_user((void __user *)(req.args), args_buf, ret |= copy_to_user( nr_args * req.argsize); (void __user *)(uintptr_t)(req.args), args_buf, nr_args * req.argsize); } ret |= copy_to_user((void __user *)arg, &req, sizeof(req)); ret |= copy_to_user((void __user *)arg, &req, sizeof(req)); if (ret) if (ret) goto out; goto out; Loading
include/uapi/linux/smcinvoke.h +5 −5 Original line number Original line Diff line number Diff line Loading @@ -34,7 +34,7 @@ struct smcinvoke_cmd_req { uint32_t counts; uint32_t counts; int32_t result; int32_t result; uint32_t argsize; uint32_t argsize; uint64_t __user args; uint64_t args; }; }; #define SMCINVOKE_IOC_MAGIC 0x98 #define SMCINVOKE_IOC_MAGIC 0x98 Loading