Skip to content

Commit 7c67470

Browse files
Lorenzo Pieralisibjorn-helgaas
authored andcommitted
PCI: Move domain assignment from arm64 to generic code
The current logic in arm64 pci_bus_assign_domain_nr() is flawed in that depending on the host controller configuration for a platform and the initialization sequence, core code may end up allocating PCI domain numbers from both DT and the generic domain counter, which would result in PCI domain allocation aliases/errors. Fix the logic behind the PCI domain number assignment and move the resulting code to the PCI core so the same domain allocation logic is used on all platforms that select CONFIG_PCI_DOMAINS_GENERIC. [bhelgaas: tidy changelog] Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: Liviu Dudau <Liviu.Dudau@arm.com> Acked-by: Arnd Bergmann <arnd@arndb.de> CC: Rob Herring <robh+dt@kernel.org> CC: Catalin Marinas <catalin.marinas@arm.com>
1 parent 97bf6af commit 7c67470

File tree

2 files changed

+49
-22
lines changed

2 files changed

+49
-22
lines changed

arch/arm64/kernel/pci.c

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,3 @@ int pcibios_add_device(struct pci_dev *dev)
4646

4747
return 0;
4848
}
49-
50-
51-
#ifdef CONFIG_PCI_DOMAINS_GENERIC
52-
static bool dt_domain_found = false;
53-
54-
void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
55-
{
56-
int domain = of_get_pci_domain_nr(parent->of_node);
57-
58-
if (domain >= 0) {
59-
dt_domain_found = true;
60-
} else if (dt_domain_found == true) {
61-
dev_err(parent, "Node %s is missing \"linux,pci-domain\" property in DT\n",
62-
parent->of_node->full_name);
63-
return;
64-
} else {
65-
domain = pci_get_new_domain_nr();
66-
}
67-
68-
bus->domain_nr = domain;
69-
}
70-
#endif

drivers/pci/pci.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include <linux/kernel.h>
1111
#include <linux/delay.h>
1212
#include <linux/init.h>
13+
#include <linux/of.h>
14+
#include <linux/of_pci.h>
1315
#include <linux/pci.h>
1416
#include <linux/pm.h>
1517
#include <linux/slab.h>
@@ -4439,6 +4441,53 @@ int pci_get_new_domain_nr(void)
44394441
{
44404442
return atomic_inc_return(&__domain_nr);
44414443
}
4444+
4445+
#ifdef CONFIG_PCI_DOMAINS_GENERIC
4446+
void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent)
4447+
{
4448+
static int use_dt_domains = -1;
4449+
int domain = of_get_pci_domain_nr(parent->of_node);
4450+
4451+
/*
4452+
* Check DT domain and use_dt_domains values.
4453+
*
4454+
* If DT domain property is valid (domain >= 0) and
4455+
* use_dt_domains != 0, the DT assignment is valid since this means
4456+
* we have not previously allocated a domain number by using
4457+
* pci_get_new_domain_nr(); we should also update use_dt_domains to
4458+
* 1, to indicate that we have just assigned a domain number from
4459+
* DT.
4460+
*
4461+
* If DT domain property value is not valid (ie domain < 0), and we
4462+
* have not previously assigned a domain number from DT
4463+
* (use_dt_domains != 1) we should assign a domain number by
4464+
* using the:
4465+
*
4466+
* pci_get_new_domain_nr()
4467+
*
4468+
* API and update the use_dt_domains value to keep track of method we
4469+
* are using to assign domain numbers (use_dt_domains = 0).
4470+
*
4471+
* All other combinations imply we have a platform that is trying
4472+
* to mix domain numbers obtained from DT and pci_get_new_domain_nr(),
4473+
* which is a recipe for domain mishandling and it is prevented by
4474+
* invalidating the domain value (domain = -1) and printing a
4475+
* corresponding error.
4476+
*/
4477+
if (domain >= 0 && use_dt_domains) {
4478+
use_dt_domains = 1;
4479+
} else if (domain < 0 && use_dt_domains != 1) {
4480+
use_dt_domains = 0;
4481+
domain = pci_get_new_domain_nr();
4482+
} else {
4483+
dev_err(parent, "Node %s has inconsistent \"linux,pci-domain\" property in DT\n",
4484+
parent->of_node->full_name);
4485+
domain = -1;
4486+
}
4487+
4488+
bus->domain_nr = domain;
4489+
}
4490+
#endif
44424491
#endif
44434492

44444493
/**

0 commit comments

Comments
 (0)