diff options
author | Stephen Boyd <sboyd@codeaurora.org> | 2015-09-02 18:46:48 -0400 |
---|---|---|
committer | Andy Gross <agross@codeaurora.org> | 2015-10-14 15:51:21 -0400 |
commit | 50e1b29b4438bdb0be61ff41e6925cab6f8a9284 (patch) | |
tree | d756f80fc02c454bfb8f5dc36e9331c2a9d637eb | |
parent | 3b781e55c6cb1afa5da7b2b1b2bb1b0c9ee7bf97 (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.c | 32 |
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 | ||
140 | out: | 145 | out: |
146 | kfree(pkt); | ||
141 | mutex_unlock(&rpm->lock); | 147 | mutex_unlock(&rpm->lock); |
142 | return ret; | 148 | return ret; |
143 | } | 149 | } |