diff options
author | Jean Delvare <jdelvare@suse.de> | 2014-02-24 09:45:34 -0500 |
---|---|---|
committer | Borislav Petkov <bp@suse.de> | 2014-02-25 04:09:09 -0500 |
commit | 5576fb8696bf8d8ae60278c2aa4dc23eae9eb86e (patch) | |
tree | 0f33e5b6fca077299ff6a8f5bfccc5522bc85702 /drivers/edac | |
parent | 0e089c182889e1551dcaaea8ee1639bfa81896a3 (diff) |
amd8111_edac: Fix leaks in probe error paths
Both probe error paths are incomplete and leak memory and device
references. Add the missing cleanups.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Link: http://lkml.kernel.org/r/20140224154534.5a3b797a@endymion.delvare
Cc: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Diffstat (limited to 'drivers/edac')
-rw-r--r-- | drivers/edac/amd8111_edac.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/drivers/edac/amd8111_edac.c b/drivers/edac/amd8111_edac.c index ddd890052ce2..2b63f7c2d6d2 100644 --- a/drivers/edac/amd8111_edac.c +++ b/drivers/edac/amd8111_edac.c | |||
@@ -350,6 +350,7 @@ static int amd8111_dev_probe(struct pci_dev *dev, | |||
350 | const struct pci_device_id *id) | 350 | const struct pci_device_id *id) |
351 | { | 351 | { |
352 | struct amd8111_dev_info *dev_info = &amd8111_devices[id->driver_data]; | 352 | struct amd8111_dev_info *dev_info = &amd8111_devices[id->driver_data]; |
353 | int ret = -ENODEV; | ||
353 | 354 | ||
354 | dev_info->dev = pci_get_device(PCI_VENDOR_ID_AMD, | 355 | dev_info->dev = pci_get_device(PCI_VENDOR_ID_AMD, |
355 | dev_info->err_dev, NULL); | 356 | dev_info->err_dev, NULL); |
@@ -359,16 +360,15 @@ static int amd8111_dev_probe(struct pci_dev *dev, | |||
359 | "vendor %x, device %x, name %s\n", | 360 | "vendor %x, device %x, name %s\n", |
360 | PCI_VENDOR_ID_AMD, dev_info->err_dev, | 361 | PCI_VENDOR_ID_AMD, dev_info->err_dev, |
361 | dev_info->ctl_name); | 362 | dev_info->ctl_name); |
362 | return -ENODEV; | 363 | goto err; |
363 | } | 364 | } |
364 | 365 | ||
365 | if (pci_enable_device(dev_info->dev)) { | 366 | if (pci_enable_device(dev_info->dev)) { |
366 | pci_dev_put(dev_info->dev); | ||
367 | printk(KERN_ERR "failed to enable:" | 367 | printk(KERN_ERR "failed to enable:" |
368 | "vendor %x, device %x, name %s\n", | 368 | "vendor %x, device %x, name %s\n", |
369 | PCI_VENDOR_ID_AMD, dev_info->err_dev, | 369 | PCI_VENDOR_ID_AMD, dev_info->err_dev, |
370 | dev_info->ctl_name); | 370 | dev_info->ctl_name); |
371 | return -ENODEV; | 371 | goto err_dev_put; |
372 | } | 372 | } |
373 | 373 | ||
374 | /* | 374 | /* |
@@ -381,8 +381,10 @@ static int amd8111_dev_probe(struct pci_dev *dev, | |||
381 | edac_device_alloc_ctl_info(0, dev_info->ctl_name, 1, | 381 | edac_device_alloc_ctl_info(0, dev_info->ctl_name, 1, |
382 | NULL, 0, 0, | 382 | NULL, 0, 0, |
383 | NULL, 0, dev_info->edac_idx); | 383 | NULL, 0, dev_info->edac_idx); |
384 | if (!dev_info->edac_dev) | 384 | if (!dev_info->edac_dev) { |
385 | return -ENOMEM; | 385 | ret = -ENOMEM; |
386 | goto err_dev_put; | ||
387 | } | ||
386 | 388 | ||
387 | dev_info->edac_dev->pvt_info = dev_info; | 389 | dev_info->edac_dev->pvt_info = dev_info; |
388 | dev_info->edac_dev->dev = &dev_info->dev->dev; | 390 | dev_info->edac_dev->dev = &dev_info->dev->dev; |
@@ -399,8 +401,7 @@ static int amd8111_dev_probe(struct pci_dev *dev, | |||
399 | if (edac_device_add_device(dev_info->edac_dev) > 0) { | 401 | if (edac_device_add_device(dev_info->edac_dev) > 0) { |
400 | printk(KERN_ERR "failed to add edac_dev for %s\n", | 402 | printk(KERN_ERR "failed to add edac_dev for %s\n", |
401 | dev_info->ctl_name); | 403 | dev_info->ctl_name); |
402 | edac_device_free_ctl_info(dev_info->edac_dev); | 404 | goto err_edac_free_ctl; |
403 | return -ENODEV; | ||
404 | } | 405 | } |
405 | 406 | ||
406 | printk(KERN_INFO "added one edac_dev on AMD8111 " | 407 | printk(KERN_INFO "added one edac_dev on AMD8111 " |
@@ -409,6 +410,13 @@ static int amd8111_dev_probe(struct pci_dev *dev, | |||
409 | dev_info->ctl_name); | 410 | dev_info->ctl_name); |
410 | 411 | ||
411 | return 0; | 412 | return 0; |
413 | |||
414 | err_edac_free_ctl: | ||
415 | edac_device_free_ctl_info(dev_info->edac_dev); | ||
416 | err_dev_put: | ||
417 | pci_dev_put(dev_info->dev); | ||
418 | err: | ||
419 | return ret; | ||
412 | } | 420 | } |
413 | 421 | ||
414 | static void amd8111_dev_remove(struct pci_dev *dev) | 422 | static void amd8111_dev_remove(struct pci_dev *dev) |
@@ -437,6 +445,7 @@ static int amd8111_pci_probe(struct pci_dev *dev, | |||
437 | const struct pci_device_id *id) | 445 | const struct pci_device_id *id) |
438 | { | 446 | { |
439 | struct amd8111_pci_info *pci_info = &amd8111_pcis[id->driver_data]; | 447 | struct amd8111_pci_info *pci_info = &amd8111_pcis[id->driver_data]; |
448 | int ret = -ENODEV; | ||
440 | 449 | ||
441 | pci_info->dev = pci_get_device(PCI_VENDOR_ID_AMD, | 450 | pci_info->dev = pci_get_device(PCI_VENDOR_ID_AMD, |
442 | pci_info->err_dev, NULL); | 451 | pci_info->err_dev, NULL); |
@@ -446,16 +455,15 @@ static int amd8111_pci_probe(struct pci_dev *dev, | |||
446 | "vendor %x, device %x, name %s\n", | 455 | "vendor %x, device %x, name %s\n", |
447 | PCI_VENDOR_ID_AMD, pci_info->err_dev, | 456 | PCI_VENDOR_ID_AMD, pci_info->err_dev, |
448 | pci_info->ctl_name); | 457 | pci_info->ctl_name); |
449 | return -ENODEV; | 458 | goto err; |
450 | } | 459 | } |
451 | 460 | ||
452 | if (pci_enable_device(pci_info->dev)) { | 461 | if (pci_enable_device(pci_info->dev)) { |
453 | pci_dev_put(pci_info->dev); | ||
454 | printk(KERN_ERR "failed to enable:" | 462 | printk(KERN_ERR "failed to enable:" |
455 | "vendor %x, device %x, name %s\n", | 463 | "vendor %x, device %x, name %s\n", |
456 | PCI_VENDOR_ID_AMD, pci_info->err_dev, | 464 | PCI_VENDOR_ID_AMD, pci_info->err_dev, |
457 | pci_info->ctl_name); | 465 | pci_info->ctl_name); |
458 | return -ENODEV; | 466 | goto err_dev_put; |
459 | } | 467 | } |
460 | 468 | ||
461 | /* | 469 | /* |
@@ -465,8 +473,10 @@ static int amd8111_pci_probe(struct pci_dev *dev, | |||
465 | */ | 473 | */ |
466 | pci_info->edac_idx = edac_pci_alloc_index(); | 474 | pci_info->edac_idx = edac_pci_alloc_index(); |
467 | pci_info->edac_dev = edac_pci_alloc_ctl_info(0, pci_info->ctl_name); | 475 | pci_info->edac_dev = edac_pci_alloc_ctl_info(0, pci_info->ctl_name); |
468 | if (!pci_info->edac_dev) | 476 | if (!pci_info->edac_dev) { |
469 | return -ENOMEM; | 477 | ret = -ENOMEM; |
478 | goto err_dev_put; | ||
479 | } | ||
470 | 480 | ||
471 | pci_info->edac_dev->pvt_info = pci_info; | 481 | pci_info->edac_dev->pvt_info = pci_info; |
472 | pci_info->edac_dev->dev = &pci_info->dev->dev; | 482 | pci_info->edac_dev->dev = &pci_info->dev->dev; |
@@ -483,8 +493,7 @@ static int amd8111_pci_probe(struct pci_dev *dev, | |||
483 | if (edac_pci_add_device(pci_info->edac_dev, pci_info->edac_idx) > 0) { | 493 | if (edac_pci_add_device(pci_info->edac_dev, pci_info->edac_idx) > 0) { |
484 | printk(KERN_ERR "failed to add edac_pci for %s\n", | 494 | printk(KERN_ERR "failed to add edac_pci for %s\n", |
485 | pci_info->ctl_name); | 495 | pci_info->ctl_name); |
486 | edac_pci_free_ctl_info(pci_info->edac_dev); | 496 | goto err_edac_free_ctl; |
487 | return -ENODEV; | ||
488 | } | 497 | } |
489 | 498 | ||
490 | printk(KERN_INFO "added one edac_pci on AMD8111 " | 499 | printk(KERN_INFO "added one edac_pci on AMD8111 " |
@@ -493,6 +502,13 @@ static int amd8111_pci_probe(struct pci_dev *dev, | |||
493 | pci_info->ctl_name); | 502 | pci_info->ctl_name); |
494 | 503 | ||
495 | return 0; | 504 | return 0; |
505 | |||
506 | err_edac_free_ctl: | ||
507 | edac_pci_free_ctl_info(pci_info->edac_dev); | ||
508 | err_dev_put: | ||
509 | pci_dev_put(pci_info->dev); | ||
510 | err: | ||
511 | return ret; | ||
496 | } | 512 | } |
497 | 513 | ||
498 | static void amd8111_pci_remove(struct pci_dev *dev) | 514 | static void amd8111_pci_remove(struct pci_dev *dev) |