aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/pci-calgary.c
diff options
context:
space:
mode:
authorMuli Ben-Yehuda <muli@il.ibm.com>2006-09-26 04:52:31 -0400
committerAndi Kleen <andi@basil.nowhere.org>2006-09-26 04:52:31 -0400
commitb8f4fe66a560b5ccbb4d4d0d2df356a5d9b98b83 (patch)
tree71b68a0950e4058dd0a4771d093f4e2a58227820 /arch/x86_64/kernel/pci-calgary.c
parent9f2dc46d5ec6fd7787182d2232a1003af11879f1 (diff)
[PATCH] Calgary IOMMU: fix error path memleak in calgary_free_tar
We were freeing the iommu_table and leaking the bitmap pages. Also rename it to calgary_free_bus, which is more accurate. Signed-off-by: Muli Ben-Yehuda <muli@il.ibm.com> Signed-off-by: Jon Mason <jdmason@us.ibm.com> Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/x86_64/kernel/pci-calgary.c')
-rw-r--r--arch/x86_64/kernel/pci-calgary.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c
index b2182c93630..6c5da1d813f 100644
--- a/arch/x86_64/kernel/pci-calgary.c
+++ b/arch/x86_64/kernel/pci-calgary.c
@@ -658,11 +658,12 @@ static int __init calgary_setup_tar(struct pci_dev *dev, void __iomem *bbar)
658 return 0; 658 return 0;
659} 659}
660 660
661static void __init calgary_free_tar(struct pci_dev *dev) 661static void __init calgary_free_bus(struct pci_dev *dev)
662{ 662{
663 u64 val64; 663 u64 val64;
664 struct iommu_table *tbl = dev->sysdata; 664 struct iommu_table *tbl = dev->sysdata;
665 void __iomem *target; 665 void __iomem *target;
666 unsigned int bitmapsz;
666 667
667 target = calgary_reg(tbl->bbar, tar_offset(dev->bus->number)); 668 target = calgary_reg(tbl->bbar, tar_offset(dev->bus->number));
668 val64 = be64_to_cpu(readq(target)); 669 val64 = be64_to_cpu(readq(target));
@@ -670,8 +671,15 @@ static void __init calgary_free_tar(struct pci_dev *dev)
670 writeq(cpu_to_be64(val64), target); 671 writeq(cpu_to_be64(val64), target);
671 readq(target); /* flush */ 672 readq(target); /* flush */
672 673
674 bitmapsz = tbl->it_size / BITS_PER_BYTE;
675 free_pages((unsigned long)tbl->it_map, get_order(bitmapsz));
676 tbl->it_map = NULL;
677
673 kfree(tbl); 678 kfree(tbl);
674 dev->sysdata = NULL; 679 dev->sysdata = NULL;
680
681 /* Can't free bootmem allocated memory after system is up :-( */
682 bus_info[dev->bus->number].tce_space = NULL;
675} 683}
676 684
677static void calgary_watchdog(unsigned long data) 685static void calgary_watchdog(unsigned long data)
@@ -853,7 +861,7 @@ error:
853 if (!bus_info[dev->bus->number].tce_space && !translate_empty_slots) 861 if (!bus_info[dev->bus->number].tce_space && !translate_empty_slots)
854 continue; 862 continue;
855 calgary_disable_translation(dev); 863 calgary_disable_translation(dev);
856 calgary_free_tar(dev); 864 calgary_free_bus(dev);
857 pci_dev_put(dev); 865 pci_dev_put(dev);
858 } 866 }
859 867