summaryrefslogtreecommitdiffstats
path: root/drivers/hv
diff options
context:
space:
mode:
authorDexuan Cui <decui@microsoft.com>2018-12-17 15:16:09 -0500
committerSasha Levin <sashal@kernel.org>2019-01-09 14:20:47 -0500
commitba50bf1ce9a51fc97db58b96d01306aa70bc3979 (patch)
treee43d0dce0b0db7d34d931254351210ab1a4e2fc1 /drivers/hv
parentbfeffd155283772bbe78c6a05dec7c0128ee500c (diff)
Drivers: hv: vmbus: Check for ring when getting debug info
fc96df16a1ce is good and can already fix the "return stack garbage" issue, but let's also improve hv_ringbuffer_get_debuginfo(), which would silently return stack garbage, if people forget to check channel->state or ring_info->ring_buffer, when using the function in the future. Having an error check in the function would eliminate the potential risk. Add a Fixes tag to indicate the patch depdendency. Fixes: fc96df16a1ce ("Drivers: hv: vmbus: Return -EINVAL for the sys files for unopened channels") Cc: stable@vger.kernel.org Cc: K. Y. Srinivasan <kys@microsoft.com> Cc: Haiyang Zhang <haiyangz@microsoft.com> Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com> Signed-off-by: Dexuan Cui <decui@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/hv')
-rw-r--r--drivers/hv/ring_buffer.c31
-rw-r--r--drivers/hv/vmbus_drv.c91
2 files changed, 76 insertions, 46 deletions
diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 64d0c85d5161..1f1a55e07733 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -164,26 +164,25 @@ hv_get_ringbuffer_availbytes(const struct hv_ring_buffer_info *rbi,
164} 164}
165 165
166/* Get various debug metrics for the specified ring buffer. */ 166/* Get various debug metrics for the specified ring buffer. */
167void hv_ringbuffer_get_debuginfo(const struct hv_ring_buffer_info *ring_info, 167int hv_ringbuffer_get_debuginfo(const struct hv_ring_buffer_info *ring_info,
168 struct hv_ring_buffer_debug_info *debug_info) 168 struct hv_ring_buffer_debug_info *debug_info)
169{ 169{
170 u32 bytes_avail_towrite; 170 u32 bytes_avail_towrite;
171 u32 bytes_avail_toread; 171 u32 bytes_avail_toread;
172 172
173 if (ring_info->ring_buffer) { 173 if (!ring_info->ring_buffer)
174 hv_get_ringbuffer_availbytes(ring_info, 174 return -EINVAL;
175 &bytes_avail_toread, 175
176 &bytes_avail_towrite); 176 hv_get_ringbuffer_availbytes(ring_info,
177 177 &bytes_avail_toread,
178 debug_info->bytes_avail_toread = bytes_avail_toread; 178 &bytes_avail_towrite);
179 debug_info->bytes_avail_towrite = bytes_avail_towrite; 179 debug_info->bytes_avail_toread = bytes_avail_toread;
180 debug_info->current_read_index = 180 debug_info->bytes_avail_towrite = bytes_avail_towrite;
181 ring_info->ring_buffer->read_index; 181 debug_info->current_read_index = ring_info->ring_buffer->read_index;
182 debug_info->current_write_index = 182 debug_info->current_write_index = ring_info->ring_buffer->write_index;
183 ring_info->ring_buffer->write_index; 183 debug_info->current_interrupt_mask
184 debug_info->current_interrupt_mask = 184 = ring_info->ring_buffer->interrupt_mask;
185 ring_info->ring_buffer->interrupt_mask; 185 return 0;
186 }
187} 186}
188EXPORT_SYMBOL_GPL(hv_ringbuffer_get_debuginfo); 187EXPORT_SYMBOL_GPL(hv_ringbuffer_get_debuginfo);
189 188
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index d0ff65675292..403fee01572c 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -313,12 +313,16 @@ static ssize_t out_intr_mask_show(struct device *dev,
313{ 313{
314 struct hv_device *hv_dev = device_to_hv_device(dev); 314 struct hv_device *hv_dev = device_to_hv_device(dev);
315 struct hv_ring_buffer_debug_info outbound; 315 struct hv_ring_buffer_debug_info outbound;
316 int ret;
316 317
317 if (!hv_dev->channel) 318 if (!hv_dev->channel)
318 return -ENODEV; 319 return -ENODEV;
319 if (hv_dev->channel->state != CHANNEL_OPENED_STATE) 320
320 return -EINVAL; 321 ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound,
321 hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound); 322 &outbound);
323 if (ret < 0)
324 return ret;
325
322 return sprintf(buf, "%d\n", outbound.current_interrupt_mask); 326 return sprintf(buf, "%d\n", outbound.current_interrupt_mask);
323} 327}
324static DEVICE_ATTR_RO(out_intr_mask); 328static DEVICE_ATTR_RO(out_intr_mask);
@@ -328,12 +332,15 @@ static ssize_t out_read_index_show(struct device *dev,
328{ 332{
329 struct hv_device *hv_dev = device_to_hv_device(dev); 333 struct hv_device *hv_dev = device_to_hv_device(dev);
330 struct hv_ring_buffer_debug_info outbound; 334 struct hv_ring_buffer_debug_info outbound;
335 int ret;
331 336
332 if (!hv_dev->channel) 337 if (!hv_dev->channel)
333 return -ENODEV; 338 return -ENODEV;
334 if (hv_dev->channel->state != CHANNEL_OPENED_STATE) 339
335 return -EINVAL; 340 ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound,
336 hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound); 341 &outbound);
342 if (ret < 0)
343 return ret;
337 return sprintf(buf, "%d\n", outbound.current_read_index); 344 return sprintf(buf, "%d\n", outbound.current_read_index);
338} 345}
339static DEVICE_ATTR_RO(out_read_index); 346static DEVICE_ATTR_RO(out_read_index);
@@ -344,12 +351,15 @@ static ssize_t out_write_index_show(struct device *dev,
344{ 351{
345 struct hv_device *hv_dev = device_to_hv_device(dev); 352 struct hv_device *hv_dev = device_to_hv_device(dev);
346 struct hv_ring_buffer_debug_info outbound; 353 struct hv_ring_buffer_debug_info outbound;
354 int ret;
347 355
348 if (!hv_dev->channel) 356 if (!hv_dev->channel)
349 return -ENODEV; 357 return -ENODEV;
350 if (hv_dev->channel->state != CHANNEL_OPENED_STATE) 358
351 return -EINVAL; 359 ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound,
352 hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound); 360 &outbound);
361 if (ret < 0)
362 return ret;
353 return sprintf(buf, "%d\n", outbound.current_write_index); 363 return sprintf(buf, "%d\n", outbound.current_write_index);
354} 364}
355static DEVICE_ATTR_RO(out_write_index); 365static DEVICE_ATTR_RO(out_write_index);
@@ -360,12 +370,15 @@ static ssize_t out_read_bytes_avail_show(struct device *dev,
360{ 370{
361 struct hv_device *hv_dev = device_to_hv_device(dev); 371 struct hv_device *hv_dev = device_to_hv_device(dev);
362 struct hv_ring_buffer_debug_info outbound; 372 struct hv_ring_buffer_debug_info outbound;
373 int ret;
363 374
364 if (!hv_dev->channel) 375 if (!hv_dev->channel)
365 return -ENODEV; 376 return -ENODEV;
366 if (hv_dev->channel->state != CHANNEL_OPENED_STATE) 377
367 return -EINVAL; 378 ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound,
368 hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound); 379 &outbound);
380 if (ret < 0)
381 return ret;
369 return sprintf(buf, "%d\n", outbound.bytes_avail_toread); 382 return sprintf(buf, "%d\n", outbound.bytes_avail_toread);
370} 383}
371static DEVICE_ATTR_RO(out_read_bytes_avail); 384static DEVICE_ATTR_RO(out_read_bytes_avail);
@@ -376,12 +389,15 @@ static ssize_t out_write_bytes_avail_show(struct device *dev,
376{ 389{
377 struct hv_device *hv_dev = device_to_hv_device(dev); 390 struct hv_device *hv_dev = device_to_hv_device(dev);
378 struct hv_ring_buffer_debug_info outbound; 391 struct hv_ring_buffer_debug_info outbound;
392 int ret;
379 393
380 if (!hv_dev->channel) 394 if (!hv_dev->channel)
381 return -ENODEV; 395 return -ENODEV;
382 if (hv_dev->channel->state != CHANNEL_OPENED_STATE) 396
383 return -EINVAL; 397 ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound,
384 hv_ringbuffer_get_debuginfo(&hv_dev->channel->outbound, &outbound); 398 &outbound);
399 if (ret < 0)
400 return ret;
385 return sprintf(buf, "%d\n", outbound.bytes_avail_towrite); 401 return sprintf(buf, "%d\n", outbound.bytes_avail_towrite);
386} 402}
387static DEVICE_ATTR_RO(out_write_bytes_avail); 403static DEVICE_ATTR_RO(out_write_bytes_avail);
@@ -391,12 +407,15 @@ static ssize_t in_intr_mask_show(struct device *dev,
391{ 407{
392 struct hv_device *hv_dev = device_to_hv_device(dev); 408 struct hv_device *hv_dev = device_to_hv_device(dev);
393 struct hv_ring_buffer_debug_info inbound; 409 struct hv_ring_buffer_debug_info inbound;
410 int ret;
394 411
395 if (!hv_dev->channel) 412 if (!hv_dev->channel)
396 return -ENODEV; 413 return -ENODEV;
397 if (hv_dev->channel->state != CHANNEL_OPENED_STATE) 414
398 return -EINVAL; 415 ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
399 hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound); 416 if (ret < 0)
417 return ret;
418
400 return sprintf(buf, "%d\n", inbound.current_interrupt_mask); 419 return sprintf(buf, "%d\n", inbound.current_interrupt_mask);
401} 420}
402static DEVICE_ATTR_RO(in_intr_mask); 421static DEVICE_ATTR_RO(in_intr_mask);
@@ -406,12 +425,15 @@ static ssize_t in_read_index_show(struct device *dev,
406{ 425{
407 struct hv_device *hv_dev = device_to_hv_device(dev); 426 struct hv_device *hv_dev = device_to_hv_device(dev);
408 struct hv_ring_buffer_debug_info inbound; 427 struct hv_ring_buffer_debug_info inbound;
428 int ret;
409 429
410 if (!hv_dev->channel) 430 if (!hv_dev->channel)
411 return -ENODEV; 431 return -ENODEV;
412 if (hv_dev->channel->state != CHANNEL_OPENED_STATE) 432
413 return -EINVAL; 433 ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
414 hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound); 434 if (ret < 0)
435 return ret;
436
415 return sprintf(buf, "%d\n", inbound.current_read_index); 437 return sprintf(buf, "%d\n", inbound.current_read_index);
416} 438}
417static DEVICE_ATTR_RO(in_read_index); 439static DEVICE_ATTR_RO(in_read_index);
@@ -421,12 +443,15 @@ static ssize_t in_write_index_show(struct device *dev,
421{ 443{
422 struct hv_device *hv_dev = device_to_hv_device(dev); 444 struct hv_device *hv_dev = device_to_hv_device(dev);
423 struct hv_ring_buffer_debug_info inbound; 445 struct hv_ring_buffer_debug_info inbound;
446 int ret;
424 447
425 if (!hv_dev->channel) 448 if (!hv_dev->channel)
426 return -ENODEV; 449 return -ENODEV;
427 if (hv_dev->channel->state != CHANNEL_OPENED_STATE) 450
428 return -EINVAL; 451 ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
429 hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound); 452 if (ret < 0)
453 return ret;
454
430 return sprintf(buf, "%d\n", inbound.current_write_index); 455 return sprintf(buf, "%d\n", inbound.current_write_index);
431} 456}
432static DEVICE_ATTR_RO(in_write_index); 457static DEVICE_ATTR_RO(in_write_index);
@@ -437,12 +462,15 @@ static ssize_t in_read_bytes_avail_show(struct device *dev,
437{ 462{
438 struct hv_device *hv_dev = device_to_hv_device(dev); 463 struct hv_device *hv_dev = device_to_hv_device(dev);
439 struct hv_ring_buffer_debug_info inbound; 464 struct hv_ring_buffer_debug_info inbound;
465 int ret;
440 466
441 if (!hv_dev->channel) 467 if (!hv_dev->channel)
442 return -ENODEV; 468 return -ENODEV;
443 if (hv_dev->channel->state != CHANNEL_OPENED_STATE) 469
444 return -EINVAL; 470 ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
445 hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound); 471 if (ret < 0)
472 return ret;
473
446 return sprintf(buf, "%d\n", inbound.bytes_avail_toread); 474 return sprintf(buf, "%d\n", inbound.bytes_avail_toread);
447} 475}
448static DEVICE_ATTR_RO(in_read_bytes_avail); 476static DEVICE_ATTR_RO(in_read_bytes_avail);
@@ -453,12 +481,15 @@ static ssize_t in_write_bytes_avail_show(struct device *dev,
453{ 481{
454 struct hv_device *hv_dev = device_to_hv_device(dev); 482 struct hv_device *hv_dev = device_to_hv_device(dev);
455 struct hv_ring_buffer_debug_info inbound; 483 struct hv_ring_buffer_debug_info inbound;
484 int ret;
456 485
457 if (!hv_dev->channel) 486 if (!hv_dev->channel)
458 return -ENODEV; 487 return -ENODEV;
459 if (hv_dev->channel->state != CHANNEL_OPENED_STATE) 488
460 return -EINVAL; 489 ret = hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound);
461 hv_ringbuffer_get_debuginfo(&hv_dev->channel->inbound, &inbound); 490 if (ret < 0)
491 return ret;
492
462 return sprintf(buf, "%d\n", inbound.bytes_avail_towrite); 493 return sprintf(buf, "%d\n", inbound.bytes_avail_towrite);
463} 494}
464static DEVICE_ATTR_RO(in_write_bytes_avail); 495static DEVICE_ATTR_RO(in_write_bytes_avail);