drm/vmwgfx: Add VMWare host messaging capability
Dan Carpenter
dan.carpenter at oracle.com
Mon May 23 17:34:33 UTC 2016
Hello Sinclair Yeh,
The patch 89da76fde68d: "drm/vmwgfx: Add VMWare host messaging
capability" from Apr 27, 2016, leads to the following static checker
warning:
drivers/gpu/drm/vmwgfx/vmwgfx_msg.c:303 vmw_recv_msg()
warn: 'reply' was already freed.
drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
209 static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
210 size_t *msg_len)
211 {
212 unsigned long eax, ebx, ecx, edx, si, di, bp;
213 char *reply;
214 size_t reply_len;
215 int retries = 0;
216
217
218 *msg_len = 0;
219 *msg = NULL;
220
221 while (retries < RETRIES) {
222 retries++;
223
224 /* Set up additional parameters */
225 si = channel->cookie_high;
226 di = channel->cookie_low;
227
228 VMW_PORT(VMW_PORT_CMD_RECVSIZE,
229 0, si, di,
230 (VMW_HYPERVISOR_PORT | (channel->channel_id << 16)),
231 VMW_HYPERVISOR_MAGIC,
232 eax, ebx, ecx, edx, si, di);
233
234 if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0 ||
235 (HIGH_WORD(ecx) & MESSAGE_STATUS_HB) == 0) {
236 DRM_ERROR("Failed to get reply size\n");
237 return -EINVAL;
238 }
239
240 /* No reply available. This is okay. */
241 if ((HIGH_WORD(ecx) & MESSAGE_STATUS_DORECV) == 0)
242 return 0;
243
244 reply_len = ebx;
245 reply = kzalloc(reply_len + 1, GFP_KERNEL);
246 if (reply == NULL) {
247 DRM_ERROR("Cannot allocate memory for reply\n");
248 return -ENOMEM;
249 }
250
251
252 /* Receive buffer */
253 si = channel->cookie_high;
254 di = (uintptr_t) reply;
255 bp = channel->cookie_low;
256
257 VMW_PORT_HB_IN(
258 (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG,
259 reply_len, si, di,
260 VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16),
261 VMW_HYPERVISOR_MAGIC, bp,
262 eax, ebx, ecx, edx, si, di);
263
264 if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) == 0) {
265 kfree(reply);
266
267 if ((HIGH_WORD(ebx) & MESSAGE_STATUS_CPT) != 0) {
268 /* A checkpoint occurred. Retry. */
269 continue;
270 }
271
272 return -EINVAL;
273 }
274
275 reply[reply_len] = '\0';
276
277
278 /* Ack buffer */
279 si = channel->cookie_high;
280 di = channel->cookie_low;
281
282 VMW_PORT(VMW_PORT_CMD_RECVSTATUS,
283 MESSAGE_STATUS_SUCCESS, si, di,
284 (VMW_HYPERVISOR_PORT | (channel->channel_id << 16)),
285 VMW_HYPERVISOR_MAGIC,
286 eax, ebx, ecx, edx, si, di);
287
288 if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
289 kfree(reply);
^^^^^
Freed here.
290
291 if ((HIGH_WORD(ecx) & MESSAGE_STATUS_CPT) != 0) {
292 /* A checkpoint occurred. Retry. */
293 continue;
294 }
295
296 return -EINVAL;
297 }
298
299 break;
300 }
There should be a test here to see if (retries == RETRIES) then return
an error code instead of setting it to a bogus thing.
301
302 *msg_len = reply_len;
303 *msg = reply;
304
305 return 0;
306 }
regards,
dan carpenter
More information about the dri-devel
mailing list