aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Morse <james.morse@arm.com>2015-10-29 12:50:43 -0400
committerAlex Williamson <alex.williamson@redhat.com>2015-11-03 14:54:00 -0500
commit1b4bb2eaa9b2583521611b4aa978f9f499c92cd4 (patch)
tree30ce8bb09a0c5d957a12499fc8608d39c2eac008
parent4644321fd3c119a819ab24fd2bc2d1f9bca4a695 (diff)
vfio/platform: store mapped memory in region, instead of an on-stack copy
vfio_platform_{read,write}_mmio() call ioremap_nocache() to map a region of io memory, which they store in struct vfio_platform_region to be eventually re-used, or unmapped by vfio_platform_regions_cleanup(). These functions receive a copy of their struct vfio_platform_region argument on the stack - so these mapped areas are always allocated, and always leaked. Pass this argument as a pointer instead. Fixes: 6e3f26456009 "vfio/platform: read and write support for the device fd" Signed-off-by: James Morse <james.morse@arm.com> Acked-by: Baptiste Reynal <b.reynal@virtualopensystems.com> Tested-by: Baptiste Reynal <b.reynal@virtualopensystems.com> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
-rw-r--r--drivers/vfio/platform/vfio_platform_common.c36
1 files changed, 18 insertions, 18 deletions
diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c
index e43efb5e92bf..8c216de883e3 100644
--- a/drivers/vfio/platform/vfio_platform_common.c
+++ b/drivers/vfio/platform/vfio_platform_common.c
@@ -307,17 +307,17 @@ static long vfio_platform_ioctl(void *device_data,
307 return -ENOTTY; 307 return -ENOTTY;
308} 308}
309 309
310static ssize_t vfio_platform_read_mmio(struct vfio_platform_region reg, 310static ssize_t vfio_platform_read_mmio(struct vfio_platform_region *reg,
311 char __user *buf, size_t count, 311 char __user *buf, size_t count,
312 loff_t off) 312 loff_t off)
313{ 313{
314 unsigned int done = 0; 314 unsigned int done = 0;
315 315
316 if (!reg.ioaddr) { 316 if (!reg->ioaddr) {
317 reg.ioaddr = 317 reg->ioaddr =
318 ioremap_nocache(reg.addr, reg.size); 318 ioremap_nocache(reg->addr, reg->size);
319 319
320 if (!reg.ioaddr) 320 if (!reg->ioaddr)
321 return -ENOMEM; 321 return -ENOMEM;
322 } 322 }
323 323
@@ -327,7 +327,7 @@ static ssize_t vfio_platform_read_mmio(struct vfio_platform_region reg,
327 if (count >= 4 && !(off % 4)) { 327 if (count >= 4 && !(off % 4)) {
328 u32 val; 328 u32 val;
329 329
330 val = ioread32(reg.ioaddr + off); 330 val = ioread32(reg->ioaddr + off);
331 if (copy_to_user(buf, &val, 4)) 331 if (copy_to_user(buf, &val, 4))
332 goto err; 332 goto err;
333 333
@@ -335,7 +335,7 @@ static ssize_t vfio_platform_read_mmio(struct vfio_platform_region reg,
335 } else if (count >= 2 && !(off % 2)) { 335 } else if (count >= 2 && !(off % 2)) {
336 u16 val; 336 u16 val;
337 337
338 val = ioread16(reg.ioaddr + off); 338 val = ioread16(reg->ioaddr + off);
339 if (copy_to_user(buf, &val, 2)) 339 if (copy_to_user(buf, &val, 2))
340 goto err; 340 goto err;
341 341
@@ -343,7 +343,7 @@ static ssize_t vfio_platform_read_mmio(struct vfio_platform_region reg,
343 } else { 343 } else {
344 u8 val; 344 u8 val;
345 345
346 val = ioread8(reg.ioaddr + off); 346 val = ioread8(reg->ioaddr + off);
347 if (copy_to_user(buf, &val, 1)) 347 if (copy_to_user(buf, &val, 1))
348 goto err; 348 goto err;
349 349
@@ -376,7 +376,7 @@ static ssize_t vfio_platform_read(void *device_data, char __user *buf,
376 return -EINVAL; 376 return -EINVAL;
377 377
378 if (vdev->regions[index].type & VFIO_PLATFORM_REGION_TYPE_MMIO) 378 if (vdev->regions[index].type & VFIO_PLATFORM_REGION_TYPE_MMIO)
379 return vfio_platform_read_mmio(vdev->regions[index], 379 return vfio_platform_read_mmio(&vdev->regions[index],
380 buf, count, off); 380 buf, count, off);
381 else if (vdev->regions[index].type & VFIO_PLATFORM_REGION_TYPE_PIO) 381 else if (vdev->regions[index].type & VFIO_PLATFORM_REGION_TYPE_PIO)
382 return -EINVAL; /* not implemented */ 382 return -EINVAL; /* not implemented */
@@ -384,17 +384,17 @@ static ssize_t vfio_platform_read(void *device_data, char __user *buf,
384 return -EINVAL; 384 return -EINVAL;
385} 385}
386 386
387static ssize_t vfio_platform_write_mmio(struct vfio_platform_region reg, 387static ssize_t vfio_platform_write_mmio(struct vfio_platform_region *reg,
388 const char __user *buf, size_t count, 388 const char __user *buf, size_t count,
389 loff_t off) 389 loff_t off)
390{ 390{
391 unsigned int done = 0; 391 unsigned int done = 0;
392 392
393 if (!reg.ioaddr) { 393 if (!reg->ioaddr) {
394 reg.ioaddr = 394 reg->ioaddr =
395 ioremap_nocache(reg.addr, reg.size); 395 ioremap_nocache(reg->addr, reg->size);
396 396
397 if (!reg.ioaddr) 397 if (!reg->ioaddr)
398 return -ENOMEM; 398 return -ENOMEM;
399 } 399 }
400 400
@@ -406,7 +406,7 @@ static ssize_t vfio_platform_write_mmio(struct vfio_platform_region reg,
406 406
407 if (copy_from_user(&val, buf, 4)) 407 if (copy_from_user(&val, buf, 4))
408 goto err; 408 goto err;
409 iowrite32(val, reg.ioaddr + off); 409 iowrite32(val, reg->ioaddr + off);
410 410
411 filled = 4; 411 filled = 4;
412 } else if (count >= 2 && !(off % 2)) { 412 } else if (count >= 2 && !(off % 2)) {
@@ -414,7 +414,7 @@ static ssize_t vfio_platform_write_mmio(struct vfio_platform_region reg,
414 414
415 if (copy_from_user(&val, buf, 2)) 415 if (copy_from_user(&val, buf, 2))
416 goto err; 416 goto err;
417 iowrite16(val, reg.ioaddr + off); 417 iowrite16(val, reg->ioaddr + off);
418 418
419 filled = 2; 419 filled = 2;
420 } else { 420 } else {
@@ -422,7 +422,7 @@ static ssize_t vfio_platform_write_mmio(struct vfio_platform_region reg,
422 422
423 if (copy_from_user(&val, buf, 1)) 423 if (copy_from_user(&val, buf, 1))
424 goto err; 424 goto err;
425 iowrite8(val, reg.ioaddr + off); 425 iowrite8(val, reg->ioaddr + off);
426 426
427 filled = 1; 427 filled = 1;
428 } 428 }
@@ -452,7 +452,7 @@ static ssize_t vfio_platform_write(void *device_data, const char __user *buf,
452 return -EINVAL; 452 return -EINVAL;
453 453
454 if (vdev->regions[index].type & VFIO_PLATFORM_REGION_TYPE_MMIO) 454 if (vdev->regions[index].type & VFIO_PLATFORM_REGION_TYPE_MMIO)
455 return vfio_platform_write_mmio(vdev->regions[index], 455 return vfio_platform_write_mmio(&vdev->regions[index],
456 buf, count, off); 456 buf, count, off);
457 else if (vdev->regions[index].type & VFIO_PLATFORM_REGION_TYPE_PIO) 457 else if (vdev->regions[index].type & VFIO_PLATFORM_REGION_TYPE_PIO)
458 return -EINVAL; /* not implemented */ 458 return -EINVAL; /* not implemented */