Always skip odd bar when skipping 64bit BARs in pci_epf_test_set_bar()
and pci_epf_test_alloc_space().

Otherwise, pci_epf_test_set_bar() will call pci_epc_set_bar() on odd loop
index when skipping reserved 64bit BAR. Moreover, pci_epf_test_alloc_space()
will call pci_epf_alloc_space() on bind for odd loop index when BAR is 64bit
but leaks on subsequent unbind by not calling pci_epf_free_space().

Signed-off-by: Alan Mikhak <alan.mik...@sifive.com>
Reviewed-by: Paul Walmsley <paul.walms...@sifive.com>
---
 drivers/pci/endpoint/functions/pci-epf-test.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c 
b/drivers/pci/endpoint/functions/pci-epf-test.c
index 27806987e93b..96156a537922 100644
--- a/drivers/pci/endpoint/functions/pci-epf-test.c
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -389,7 +389,7 @@ static void pci_epf_test_unbind(struct pci_epf *epf)
 
 static int pci_epf_test_set_bar(struct pci_epf *epf)
 {
-       int bar;
+       int bar, add;
        int ret;
        struct pci_epf_bar *epf_bar;
        struct pci_epc *epc = epf->epc;
@@ -400,8 +400,14 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
 
        epc_features = epf_test->epc_features;
 
-       for (bar = BAR_0; bar <= BAR_5; bar++) {
+       for (bar = BAR_0; bar <= BAR_5; bar += add) {
                epf_bar = &epf->bar[bar];
+               /*
+                * pci_epc_set_bar() sets PCI_BASE_ADDRESS_MEM_TYPE_64
+                * if the specific implementation required a 64-bit BAR,
+                * even if we only requested a 32-bit BAR.
+                */
+               add = (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) ? 2 : 1;
 
                if (!!(epc_features->reserved_bar & (1 << bar)))
                        continue;
@@ -413,13 +419,6 @@ static int pci_epf_test_set_bar(struct pci_epf *epf)
                        if (bar == test_reg_bar)
                                return ret;
                }
-               /*
-                * pci_epc_set_bar() sets PCI_BASE_ADDRESS_MEM_TYPE_64
-                * if the specific implementation required a 64-bit BAR,
-                * even if we only requested a 32-bit BAR.
-                */
-               if (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
-                       bar++;
        }
 
        return 0;
@@ -431,7 +430,7 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
        struct device *dev = &epf->dev;
        struct pci_epf_bar *epf_bar;
        void *base;
-       int bar;
+       int bar, add;
        enum pci_barno test_reg_bar = epf_test->test_reg_bar;
        const struct pci_epc_features *epc_features;
 
@@ -445,8 +444,10 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
        }
        epf_test->reg[test_reg_bar] = base;
 
-       for (bar = BAR_0; bar <= BAR_5; bar++) {
+       for (bar = BAR_0; bar <= BAR_5; bar += add) {
                epf_bar = &epf->bar[bar];
+               add = (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64) ? 2 : 1;
+
                if (bar == test_reg_bar)
                        continue;
 
@@ -459,8 +460,6 @@ static int pci_epf_test_alloc_space(struct pci_epf *epf)
                        dev_err(dev, "Failed to allocate space for BAR%d\n",
                                bar);
                epf_test->reg[bar] = base;
-               if (epf_bar->flags & PCI_BASE_ADDRESS_MEM_TYPE_64)
-                       bar++;
        }
 
        return 0;
-- 
2.7.4

Reply via email to