Commit 9a78d4fc authored by Sowmini Varadhan's avatar Sowmini Varadhan Committed by David S. Miller

sparc/pci: Refactor dev_archdata initialization into pci_init_dev_archdata

The function pcibios_add_device() added by commit d0c31e02
("sparc/PCI: Fix for panic while enabling SR-IOV") initializes
the dev_archdata by doing a memcpy from the PF. This has the
problem that it erroneously copies the OF device without
explicitly refcounting it.

As David Miller pointed out: "Generally speaking we don't
really support hot-plug for OF probed devices, but if we did
all of the device tree pointers have to be refcounted properly."

To fix this error, and also avoid code duplication, this patch
creates a new helper function, pci_init_dev_archdata(), that
initializes the fields in dev_archdata, and can be invoked
by callers after they have taken the needed refcounts
Signed-off-by: default avatarSowmini Varadhan <sowmini.varadhan@oracle.com>
Tested-by: default avatarBabu Moger <babu.moger@oracle.com>
Reviewed-by: default avatarKhalid Aziz <khalid.aziz@oracle.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a95f94bc
...@@ -245,6 +245,18 @@ static void pci_parse_of_addrs(struct platform_device *op, ...@@ -245,6 +245,18 @@ static void pci_parse_of_addrs(struct platform_device *op,
} }
} }
static void pci_init_dev_archdata(struct dev_archdata *sd, void *iommu,
void *stc, void *host_controller,
struct platform_device *op,
int numa_node)
{
sd->iommu = iommu;
sd->stc = stc;
sd->host_controller = host_controller;
sd->op = op;
sd->numa_node = numa_node;
}
static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
struct device_node *node, struct device_node *node,
struct pci_bus *bus, int devfn) struct pci_bus *bus, int devfn)
...@@ -259,13 +271,10 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, ...@@ -259,13 +271,10 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
if (!dev) if (!dev)
return NULL; return NULL;
op = of_find_device_by_node(node);
sd = &dev->dev.archdata; sd = &dev->dev.archdata;
sd->iommu = pbm->iommu; pci_init_dev_archdata(sd, pbm->iommu, &pbm->stc, pbm, op,
sd->stc = &pbm->stc; pbm->numa_node);
sd->host_controller = pbm;
sd->op = op = of_find_device_by_node(node);
sd->numa_node = pbm->numa_node;
sd = &op->dev.archdata; sd = &op->dev.archdata;
sd->iommu = pbm->iommu; sd->iommu = pbm->iommu;
sd->stc = &pbm->stc; sd->stc = &pbm->stc;
...@@ -1003,9 +1012,13 @@ int pcibios_add_device(struct pci_dev *dev) ...@@ -1003,9 +1012,13 @@ int pcibios_add_device(struct pci_dev *dev)
* Copy dev_archdata from PF to VF * Copy dev_archdata from PF to VF
*/ */
if (dev->is_virtfn) { if (dev->is_virtfn) {
struct dev_archdata *psd;
pdev = dev->physfn; pdev = dev->physfn;
memcpy(&dev->dev.archdata, &pdev->dev.archdata, psd = &pdev->dev.archdata;
sizeof(struct dev_archdata)); pci_init_dev_archdata(&dev->dev.archdata, psd->iommu,
psd->stc, psd->host_controller, NULL,
psd->numa_node);
} }
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment