aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorDenis Kirjanov <kda@linux-powerpc.org>2015-06-12 02:57:11 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2015-10-02 08:57:59 -0400
commit5ada62b1070a57562664713bbf46a78d5dc4cb23 (patch)
treec7a7063880b78558d772a8b0f50d8d519cfa56f9 /drivers/char
parentb6080db4f4e8bf28717b832976efc421de25b86c (diff)
agp/uninorth: fix a memleak in create_gatt_table
Fix the memory leak in create_gatt_table: we've lost a kfree on the exit path for the pages array allocated in uninorth_create_gatt_table Signed-off-by: Denis Kirjanov <kda@linux-powerpc.org> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/uninorth-agp.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index a56ee9bedd11..05755441250c 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -361,6 +361,10 @@ static int agp_uninorth_resume(struct pci_dev *pdev)
361} 361}
362#endif /* CONFIG_PM */ 362#endif /* CONFIG_PM */
363 363
364static struct {
365 struct page **pages_arr;
366} uninorth_priv;
367
364static int uninorth_create_gatt_table(struct agp_bridge_data *bridge) 368static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
365{ 369{
366 char *table; 370 char *table;
@@ -371,7 +375,6 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
371 int i; 375 int i;
372 void *temp; 376 void *temp;
373 struct page *page; 377 struct page *page;
374 struct page **pages;
375 378
376 /* We can't handle 2 level gatt's */ 379 /* We can't handle 2 level gatt's */
377 if (bridge->driver->size_type == LVL2_APER_SIZE) 380 if (bridge->driver->size_type == LVL2_APER_SIZE)
@@ -400,8 +403,8 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
400 if (table == NULL) 403 if (table == NULL)
401 return -ENOMEM; 404 return -ENOMEM;
402 405
403 pages = kmalloc((1 << page_order) * sizeof(struct page*), GFP_KERNEL); 406 uninorth_priv.pages_arr = kmalloc((1 << page_order) * sizeof(struct page*), GFP_KERNEL);
404 if (pages == NULL) 407 if (uninorth_priv.pages_arr == NULL)
405 goto enomem; 408 goto enomem;
406 409
407 table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1); 410 table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
@@ -409,14 +412,14 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
409 for (page = virt_to_page(table), i = 0; page <= virt_to_page(table_end); 412 for (page = virt_to_page(table), i = 0; page <= virt_to_page(table_end);
410 page++, i++) { 413 page++, i++) {
411 SetPageReserved(page); 414 SetPageReserved(page);
412 pages[i] = page; 415 uninorth_priv.pages_arr[i] = page;
413 } 416 }
414 417
415 bridge->gatt_table_real = (u32 *) table; 418 bridge->gatt_table_real = (u32 *) table;
416 /* Need to clear out any dirty data still sitting in caches */ 419 /* Need to clear out any dirty data still sitting in caches */
417 flush_dcache_range((unsigned long)table, 420 flush_dcache_range((unsigned long)table,
418 (unsigned long)table_end + 1); 421 (unsigned long)table_end + 1);
419 bridge->gatt_table = vmap(pages, (1 << page_order), 0, PAGE_KERNEL_NCG); 422 bridge->gatt_table = vmap(uninorth_priv.pages_arr, (1 << page_order), 0, PAGE_KERNEL_NCG);
420 423
421 if (bridge->gatt_table == NULL) 424 if (bridge->gatt_table == NULL)
422 goto enomem; 425 goto enomem;
@@ -434,7 +437,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge)
434 return 0; 437 return 0;
435 438
436enomem: 439enomem:
437 kfree(pages); 440 kfree(uninorth_priv.pages_arr);
438 if (table) 441 if (table)
439 free_pages((unsigned long)table, page_order); 442 free_pages((unsigned long)table, page_order);
440 return -ENOMEM; 443 return -ENOMEM;
@@ -456,6 +459,7 @@ static int uninorth_free_gatt_table(struct agp_bridge_data *bridge)
456 */ 459 */
457 460
458 vunmap(bridge->gatt_table); 461 vunmap(bridge->gatt_table);
462 kfree(uninorth_priv.pages_arr);
459 table = (char *) bridge->gatt_table_real; 463 table = (char *) bridge->gatt_table_real;
460 table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1); 464 table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
461 465