diff options
author | Jon Mason <jdmason@kudzu.us> | 2006-10-05 12:47:21 -0400 |
---|---|---|
committer | Andi Kleen <andi@basil.nowhere.org> | 2006-10-05 12:47:21 -0400 |
commit | dedc9937e876cb5430bca6a1dccfcc2ff22f8b7c (patch) | |
tree | befdff79af02b30ba42cfdb983343ea7ec7b363f /arch/x86_64/kernel/pci-calgary.c | |
parent | 814eadcefe79a2977a11ba135c4763a402112746 (diff) |
[PATCH] x86-64: Calgary IOMMU: deobfuscate calgary_init
calgary_init's for loop does not correspond to the actual device being
checked, which makes its upperbound check for array overflow useless.
Changing this to a do-while loop is the correct way of doing this.
There should be no possibility of spinning forever in this loop, as
pci_get_device states that it will go through all iterations, then
return NULL (thus breaking the loop).
Signed-off-by: Jon Mason <jdmason@kudzu.us>
Signed-off-by: Muli Ben-Yehuda <muli@il.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.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index f760045d6d35..1100031528dc 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c | |||
@@ -816,6 +816,8 @@ static int __init calgary_init_one(struct pci_dev *dev) | |||
816 | void __iomem *bbar; | 816 | void __iomem *bbar; |
817 | int ret; | 817 | int ret; |
818 | 818 | ||
819 | BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM); | ||
820 | |||
819 | address = locate_register_space(dev); | 821 | address = locate_register_space(dev); |
820 | /* map entire 1MB of Calgary config space */ | 822 | /* map entire 1MB of Calgary config space */ |
821 | bbar = ioremap_nocache(address, 1024 * 1024); | 823 | bbar = ioremap_nocache(address, 1024 * 1024); |
@@ -842,10 +844,10 @@ done: | |||
842 | 844 | ||
843 | static int __init calgary_init(void) | 845 | static int __init calgary_init(void) |
844 | { | 846 | { |
845 | int i, ret = -ENODEV; | 847 | int ret = -ENODEV; |
846 | struct pci_dev *dev = NULL; | 848 | struct pci_dev *dev = NULL; |
847 | 849 | ||
848 | for (i = 0; i < MAX_PHB_BUS_NUM; i++) { | 850 | do { |
849 | dev = pci_get_device(PCI_VENDOR_ID_IBM, | 851 | dev = pci_get_device(PCI_VENDOR_ID_IBM, |
850 | PCI_DEVICE_ID_IBM_CALGARY, | 852 | PCI_DEVICE_ID_IBM_CALGARY, |
851 | dev); | 853 | dev); |
@@ -861,12 +863,12 @@ static int __init calgary_init(void) | |||
861 | ret = calgary_init_one(dev); | 863 | ret = calgary_init_one(dev); |
862 | if (ret) | 864 | if (ret) |
863 | goto error; | 865 | goto error; |
864 | } | 866 | } while (1); |
865 | 867 | ||
866 | return ret; | 868 | return ret; |
867 | 869 | ||
868 | error: | 870 | error: |
869 | for (i--; i >= 0; i--) { | 871 | do { |
870 | dev = pci_find_device_reverse(PCI_VENDOR_ID_IBM, | 872 | dev = pci_find_device_reverse(PCI_VENDOR_ID_IBM, |
871 | PCI_DEVICE_ID_IBM_CALGARY, | 873 | PCI_DEVICE_ID_IBM_CALGARY, |
872 | dev); | 874 | dev); |
@@ -882,7 +884,7 @@ error: | |||
882 | calgary_disable_translation(dev); | 884 | calgary_disable_translation(dev); |
883 | calgary_free_bus(dev); | 885 | calgary_free_bus(dev); |
884 | pci_dev_put(dev); /* Undo calgary_init_one()'s pci_dev_get() */ | 886 | pci_dev_put(dev); /* Undo calgary_init_one()'s pci_dev_get() */ |
885 | } | 887 | } while (1); |
886 | 888 | ||
887 | return ret; | 889 | return ret; |
888 | } | 890 | } |