aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@codeaurora.org>2015-09-02 18:46:48 -0400
committerAndy Gross <agross@codeaurora.org>2015-10-14 15:51:21 -0400
commit50e1b29b4438bdb0be61ff41e6925cab6f8a9284 (patch)
treed756f80fc02c454bfb8f5dc36e9331c2a9d637eb
parent3b781e55c6cb1afa5da7b2b1b2bb1b0c9ee7bf97 (diff)
soc: qcom: smd: Remove use of VLAIS
Usage of VLAIS prevents clang from compiling this file, and it also opens us to the possibility of allocating a large structure on the stack to the point that we blow past the limit of the kernel stack. Remove the VLAIS and allocate a structure on the heap with kmalloc so that we're safer and more clang friendly. Cc: Bjorn Andersson <bjorn.andersson@sonymobile.com> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Reviewed-by: Bjorn Andersson <bjorn.andersson@sonymobile.com> Signed-off-by: Andy Gross <agross@codeaurora.org>
-rw-r--r--drivers/soc/qcom/smd-rpm.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/drivers/soc/qcom/smd-rpm.c b/drivers/soc/qcom/smd-rpm.c
index 1392ccf14a20..7709579d63d0 100644
--- a/drivers/soc/qcom/smd-rpm.c
+++ b/drivers/soc/qcom/smd-rpm.c
@@ -17,6 +17,7 @@
17#include <linux/of_platform.h> 17#include <linux/of_platform.h>
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/slab.h>
20 21
21#include <linux/soc/qcom/smd.h> 22#include <linux/soc/qcom/smd.h>
22#include <linux/soc/qcom/smd-rpm.h> 23#include <linux/soc/qcom/smd-rpm.h>
@@ -104,30 +105,34 @@ int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
104 static unsigned msg_id = 1; 105 static unsigned msg_id = 1;
105 int left; 106 int left;
106 int ret; 107 int ret;
107
108 struct { 108 struct {
109 struct qcom_rpm_header hdr; 109 struct qcom_rpm_header hdr;
110 struct qcom_rpm_request req; 110 struct qcom_rpm_request req;
111 u8 payload[count]; 111 u8 payload[];
112 } pkt; 112 } *pkt;
113 size_t size = sizeof(*pkt) + count;
113 114
114 /* SMD packets to the RPM may not exceed 256 bytes */ 115 /* SMD packets to the RPM may not exceed 256 bytes */
115 if (WARN_ON(sizeof(pkt) >= 256)) 116 if (WARN_ON(size >= 256))
116 return -EINVAL; 117 return -EINVAL;
117 118
119 pkt = kmalloc(size, GFP_KERNEL);
120 if (!pkt)
121 return -ENOMEM;
122
118 mutex_lock(&rpm->lock); 123 mutex_lock(&rpm->lock);
119 124
120 pkt.hdr.service_type = RPM_SERVICE_TYPE_REQUEST; 125 pkt->hdr.service_type = RPM_SERVICE_TYPE_REQUEST;
121 pkt.hdr.length = sizeof(struct qcom_rpm_request) + count; 126 pkt->hdr.length = sizeof(struct qcom_rpm_request) + count;
122 127
123 pkt.req.msg_id = msg_id++; 128 pkt->req.msg_id = msg_id++;
124 pkt.req.flags = BIT(state); 129 pkt->req.flags = BIT(state);
125 pkt.req.type = type; 130 pkt->req.type = type;
126 pkt.req.id = id; 131 pkt->req.id = id;
127 pkt.req.data_len = count; 132 pkt->req.data_len = count;
128 memcpy(pkt.payload, buf, count); 133 memcpy(pkt->payload, buf, count);
129 134
130 ret = qcom_smd_send(rpm->rpm_channel, &pkt, sizeof(pkt)); 135 ret = qcom_smd_send(rpm->rpm_channel, pkt, sizeof(*pkt));
131 if (ret) 136 if (ret)
132 goto out; 137 goto out;
133 138
@@ -138,6 +143,7 @@ int qcom_rpm_smd_write(struct qcom_smd_rpm *rpm,
138 ret = rpm->ack_status; 143 ret = rpm->ack_status;
139 144
140out: 145out:
146 kfree(pkt);
141 mutex_unlock(&rpm->lock); 147 mutex_unlock(&rpm->lock);
142 return ret; 148 return ret;
143} 149}