From: Oliver O'Halloran <oohall@gmail.com> Date: 2019-09-30 02:10:59
A couple of extra patches on top of Shawn's existing re-ordering patch.
This seems to fix the problem Alexey noted with Shawn's change causing
VFs to lose their IOMMU group. I've tried pretty hard to make this a
minimal fix it's still a bit large.
If mpe is happy to take this as a fix for 5.4 then I'll leave it,
otherwise we might want to look at different approaches.
From: Oliver O'Halloran <oohall@gmail.com> Date: 2019-09-30 02:12:29
On PowerNV we use the pcibios_sriov_enable() hook to do two things:
1. Create a pci_dn structure for each of the VFs, and
2. Configure the PHB's internal BARs that map MMIO ranges to PEs
so that each VF has it's own PE. Note that the PE also determines
the IOMMU table the HW uses for the device.
Currently we do not set the pe_number field of the pci_dn immediately after
assigning the PE number for the VF that it represents. Instead, we do that
in a fixup (see pnv_pci_dma_dev_setup) which is run inside the
pcibios_add_device() hook which is run prior to adding the device to the
bus.
On PowerNV we add the device to it's IOMMU group using a bus notifier and
in order for this to work the PE number needs to be known when the bus
notifier is run. This works today since the PE number is set in the fixup
which runs before adding the device to the bus. However, if we want to move
the fixup to a later stage this will break.
We can fix this by setting the pdn->pe_number inside of
pcibios_sriov_enable(). There's no good to avoid this since we already have
all the required information at that point, so... do that. Moving this
earlier does cause two problems:
1. We trip the WARN_ON() in the fixup code, and
2. The EEH core will clear pdn->pe_number while recovering VFs.
The only justification for either of these is a comment in eeh_rmv_device()
suggesting that pdn->pe_number *must* be set to IODA_INVALID_PE in order
for the VF to be scanned. However, this comment appears to have no basis in
reality so just delete it.
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
---
Can't get rid of the fixup entirely since we need it to set the
ioda_pe->pdev back-pointer. I'll look at killing that another time.
---
arch/powerpc/kernel/eeh_driver.c | 6 ------
arch/powerpc/platforms/powernv/pci-ioda.c | 19 +++++++++++++++----
arch/powerpc/platforms/powernv/pci.c | 4 ----
3 files changed, 15 insertions(+), 14 deletions(-)
@@ -1558,6 +1558,10 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)/* Reserve PE for each VF */for(vf_index=0;vf_index<num_vfs;vf_index++){+intvf_devfn=pci_iov_virtfn_devfn(pdev,vf_index);+intvf_bus=pci_iov_virtfn_bus(pdev,vf_index);+structpci_dn*vf_pdn;+if(pdn->m64_single_mode)pe_num=pdn->pe_num_map[vf_index];else
@@ -1570,13 +1574,11 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)pe->pbus=NULL;pe->parent_dev=pdev;pe->mve_number=-1;-pe->rid=(pci_iov_virtfn_bus(pdev,vf_index)<<8)|-pci_iov_virtfn_devfn(pdev,vf_index);+pe->rid=(vf_bus<<8)|vf_devfn;pe_info(pe,"VF %04d:%02d:%02d.%d associated with PE#%x\n",hose->global_number,pdev->bus->number,-PCI_SLOT(pci_iov_virtfn_devfn(pdev,vf_index)),-PCI_FUNC(pci_iov_virtfn_devfn(pdev,vf_index)),pe_num);+PCI_SLOT(vf_devfn),PCI_FUNC(vf_devfn),pe_num);if(pnv_ioda_configure_pe(phb,pe)){/* XXX What do we do here ? */
@@ -1590,6 +1592,15 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)list_add_tail(&pe->list,&phb->ioda.pe_list);mutex_unlock(&phb->ioda.pe_list_mutex);+/* associate this pe to it's pdn */+list_for_each_entry(vf_pdn,&pdn->parent->child_list,list){+if(vf_pdn->busno==vf_bus&&+vf_pdn->devfn==vf_devfn){+vf_pdn->pe_number=pe_num;+break;+}+}+pnv_pci_ioda2_setup_dma_pe(phb,pe);#ifdef CONFIG_IOMMU_APIiommu_register_group(&pe->table_group,
From: Oliver O'Halloran <oohall@gmail.com> Date: 2019-09-30 02:13:47
From: Shawn Anastasio <redacted>
Move PCI device setup from pcibios_add_device() and pcibios_fixup_bus() to
pcibios_bus_add_device(). This ensures that platform-specific DMA and IOMMU
setup occurs after the device has been registered in sysfs, which is a
requirement for IOMMU group assignment to work
This fixes IOMMU group assignment for hotplugged devices on pseries, where
the existing behavior results in IOMMU assignment before registration.
Thanks to Lukas Wunner [off-list ref] for the suggestion.
Signed-off-by: Shawn Anastasio <redacted>
---
arch/powerpc/kernel/pci-common.c | 25 +++++++++----------------
1 file changed, 9 insertions(+), 16 deletions(-)
@@ -1037,9 +1033,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)/* Now fixup the bus bus */pcibios_setup_bus_self(bus);--/* Now fixup devices on that bus */-pcibios_setup_bus_devices(bus);}EXPORT_SYMBOL(pcibios_fixup_bus);
From: Oliver O'Halloran <oohall@gmail.com> Date: 2019-09-30 02:15:12
With the previous patch applied pcibios_setup_device() will always be run
when pcibios_bus_add_device() is called. There are several code paths where
pcibios_setup_bus_device() is still called (the PowerPC specific PCI
hotplug support is one) so with just the previous patch applied the setup
can be run multiple times on a device, once before the device is added
to the bus and once after.
There's no need to run the setup in the early case any more so just
remove it entirely.
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
---
arch/powerpc/include/asm/pci.h | 1 -
arch/powerpc/kernel/pci-common.c | 25 -------------------------
arch/powerpc/kernel/pci-hotplug.c | 1 -
arch/powerpc/kernel/pci_of_scan.c | 1 -
4 files changed, 28 deletions(-)
@@ -1000,24 +1000,6 @@ int pcibios_add_device(struct pci_dev *dev)return0;}-voidpcibios_setup_bus_devices(structpci_bus*bus)-{-structpci_dev*dev;--pr_debug("PCI: Fixup bus devices %d (%s)\n",-bus->number,bus->self?pci_name(bus->self):"PHB");--list_for_each_entry(dev,&bus->devices,bus_list){-/* Cardbus can call us to add new devices to a bus, so ignore-*thosewhoarealreadyfullydiscovered-*/-if(pci_dev_is_added(dev))-continue;--pcibios_setup_device(dev);-}-}-voidpcibios_set_master(structpci_dev*dev){/* No special bus mastering setup handling */
@@ -1036,13 +1018,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)}EXPORT_SYMBOL(pcibios_fixup_bus);-voidpci_fixup_cardbus(structpci_bus*bus)-{-/* Now fixup devices on that bus */-pcibios_setup_bus_devices(bus);-}--staticintskip_isa_ioresource_align(structpci_dev*dev){if(pci_has_flag(PCI_CAN_SKIP_ISA_ALIGN)&&
On Mon, Sep 30, 2019 at 12:08:46PM +1000, Oliver O'Halloran wrote:
This is all powerpc, so I assume Michael will handle this. Just
random things I noticed; ignore if they don't make sense:
On PowerNV we use the pcibios_sriov_enable() hook to do two things:
1. Create a pci_dn structure for each of the VFs, and
2. Configure the PHB's internal BARs that map MMIO ranges to PEs
so that each VF has it's own PE. Note that the PE also determines
s/it's/its/
the IOMMU table the HW uses for the device.
Currently we do not set the pe_number field of the pci_dn immediately after
assigning the PE number for the VF that it represents. Instead, we do that
in a fixup (see pnv_pci_dma_dev_setup) which is run inside the
pcibios_add_device() hook which is run prior to adding the device to the
bus.
On PowerNV we add the device to it's IOMMU group using a bus notifier and
s/it's/its/
in order for this to work the PE number needs to be known when the bus
notifier is run. This works today since the PE number is set in the fixup
which runs before adding the device to the bus. However, if we want to move
the fixup to a later stage this will break.
We can fix this by setting the pdn->pe_number inside of
pcibios_sriov_enable(). There's no good to avoid this since we already have
s/no good/no good reason/ ?
Not quite sure what "this" refers to ... "no good reason to avoid
setting pdn->pe_number in pcibios_sriov_enable()"? The double
negative makes it a little hard to parse.
quoted hunk
all the required information at that point, so... do that. Moving this
earlier does cause two problems:
1. We trip the WARN_ON() in the fixup code, and
2. The EEH core will clear pdn->pe_number while recovering VFs.
The only justification for either of these is a comment in eeh_rmv_device()
suggesting that pdn->pe_number *must* be set to IODA_INVALID_PE in order
for the VF to be scanned. However, this comment appears to have no basis in
reality so just delete it.
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
---
Can't get rid of the fixup entirely since we need it to set the
ioda_pe->pdev back-pointer. I'll look at killing that another time.
---
arch/powerpc/kernel/eeh_driver.c | 6 ------
arch/powerpc/platforms/powernv/pci-ioda.c | 19 +++++++++++++++----
arch/powerpc/platforms/powernv/pci.c | 4 ----
3 files changed, 15 insertions(+), 14 deletions(-)
Not related to *this* patch, but this looks like maybe it's supposed
to match the pci_name(), e.g., "%04x:%02x:%02x.%d" from
pci_setup_device()? If so, the "%04d:%02d:%02d" here will be
confusing since the decimal & hex won't always match.
hose->global_number, pdev->bus->number,
Consider pci_domain_nr(bus) instead of hose->global_number? It would
be nice if you had the pci_dev * for each VF so you could just use
pci_name(vf) instead of all this domain/bus/PCI_SLOT/FUNC.
quoted hunk
- PCI_SLOT(pci_iov_virtfn_devfn(pdev, vf_index)),
- PCI_FUNC(pci_iov_virtfn_devfn(pdev, vf_index)), pe_num);
+ PCI_SLOT(vf_devfn), PCI_FUNC(vf_devfn), pe_num);
if (pnv_ioda_configure_pe(phb, pe)) {
/* XXX What do we do here ? */
On Tue, Oct 1, 2019 at 3:09 AM Bjorn Helgaas [off-list ref] wrote:
On Mon, Sep 30, 2019 at 12:08:46PM +1000, Oliver O'Halloran wrote:
This is all powerpc, so I assume Michael will handle this. Just
random things I noticed; ignore if they don't make sense:
quoted
On PowerNV we use the pcibios_sriov_enable() hook to do two things:
1. Create a pci_dn structure for each of the VFs, and
2. Configure the PHB's internal BARs that map MMIO ranges to PEs
so that each VF has it's own PE. Note that the PE also determines
s/it's/its/
quoted
the IOMMU table the HW uses for the device.
Currently we do not set the pe_number field of the pci_dn immediately after
assigning the PE number for the VF that it represents. Instead, we do that
in a fixup (see pnv_pci_dma_dev_setup) which is run inside the
pcibios_add_device() hook which is run prior to adding the device to the
bus.
On PowerNV we add the device to it's IOMMU group using a bus notifier and
s/it's/its/
quoted
in order for this to work the PE number needs to be known when the bus
notifier is run. This works today since the PE number is set in the fixup
which runs before adding the device to the bus. However, if we want to move
the fixup to a later stage this will break.
We can fix this by setting the pdn->pe_number inside of
pcibios_sriov_enable(). There's no good to avoid this since we already have
s/no good/no good reason/ ?
Not quite sure what "this" refers to ... "no good reason to avoid
setting pdn->pe_number in pcibios_sriov_enable()"? The double
negative makes it a little hard to parse.
I agree it's a bit vague, I'll re-word it.
quoted
all the required information at that point, so... do that. Moving this
earlier does cause two problems:
1. We trip the WARN_ON() in the fixup code, and
2. The EEH core will clear pdn->pe_number while recovering VFs.
The only justification for either of these is a comment in eeh_rmv_device()
suggesting that pdn->pe_number *must* be set to IODA_INVALID_PE in order
for the VF to be scanned. However, this comment appears to have no basis in
reality so just delete it.
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
---
Can't get rid of the fixup entirely since we need it to set the
ioda_pe->pdev back-pointer. I'll look at killing that another time.
---
arch/powerpc/kernel/eeh_driver.c | 6 ------
arch/powerpc/platforms/powernv/pci-ioda.c | 19 +++++++++++++++----
arch/powerpc/platforms/powernv/pci.c | 4 ----
3 files changed, 15 insertions(+), 14 deletions(-)
Not related to *this* patch, but this looks like maybe it's supposed
to match the pci_name(), e.g., "%04x:%02x:%02x.%d" from
pci_setup_device()? If so, the "%04d:%02d:%02d" here will be
confusing since the decimal & hex won't always match.
That looks plain wrong. I'll send a separate patch to fix it.
quoted
hose->global_number, pdev->bus->number,
Consider pci_domain_nr(bus) instead of hose->global_number? It would
be nice if you had the pci_dev * for each VF so you could just use
pci_name(vf) instead of all this domain/bus/PCI_SLOT/FUNC.
Unfortunately, we don't have pci_devs for the VFs when
pcibios_sriov_enable() is called. On powernv (and pseries) we only
permit config accesses to a BDF when a pci_dn exists for that BDF
because the platform code assumes that one will exist. As a result we
can't scan the VFs until after pcibios_sriov_enable() is called since
that's where pci_dn's are created for the VFs. I'm working on removing
the use of pci_dn from powernv entirely though. Once that's done we
should revisit whether any of this infrastructure is necessary...
Oliver
On PowerNV we use the pcibios_sriov_enable() hook to do two things:
1. Create a pci_dn structure for each of the VFs, and
2. Configure the PHB's internal BARs that map MMIO ranges to PEs
so that each VF has it's own PE. Note that the PE also determines
the IOMMU table the HW uses for the device.
Currently we do not set the pe_number field of the pci_dn immediately after
assigning the PE number for the VF that it represents. Instead, we do that
in a fixup (see pnv_pci_dma_dev_setup) which is run inside the
pcibios_add_device() hook which is run prior to adding the device to the
bus.
On PowerNV we add the device to it's IOMMU group using a bus notifier and
in order for this to work the PE number needs to be known when the bus
notifier is run. This works today since the PE number is set in the fixup
which runs before adding the device to the bus. However, if we want to move
the fixup to a later stage this will break.
We can fix this by setting the pdn->pe_number inside of
pcibios_sriov_enable(). There's no good to avoid this since we already have
all the required information at that point, so... do that. Moving this
earlier does cause two problems:
1. We trip the WARN_ON() in the fixup code, and
2. The EEH core will clear pdn->pe_number while recovering VFs.
The only justification for either of these is a comment in eeh_rmv_device()
suggesting that pdn->pe_number *must* be set to IODA_INVALID_PE in order
for the VF to be scanned. However, this comment appears to have no basis in
reality so just delete it.
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
---
Can't get rid of the fixup entirely since we need it to set the
ioda_pe->pdev back-pointer. I'll look at killing that another time.
---
arch/powerpc/kernel/eeh_driver.c | 6 ------
arch/powerpc/platforms/powernv/pci-ioda.c | 19 +++++++++++++++----
arch/powerpc/platforms/powernv/pci.c | 4 ----
3 files changed, 15 insertions(+), 14 deletions(-)
@@ -1558,6 +1558,10 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)/* Reserve PE for each VF */for(vf_index=0;vf_index<num_vfs;vf_index++){+intvf_devfn=pci_iov_virtfn_devfn(pdev,vf_index);+intvf_bus=pci_iov_virtfn_bus(pdev,vf_index);+structpci_dn*vf_pdn;+if(pdn->m64_single_mode)pe_num=pdn->pe_num_map[vf_index];else
@@ -1570,13 +1574,11 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)pe->pbus=NULL;pe->parent_dev=pdev;pe->mve_number=-1;-pe->rid=(pci_iov_virtfn_bus(pdev,vf_index)<<8)|-pci_iov_virtfn_devfn(pdev,vf_index);+pe->rid=(vf_bus<<8)|vf_devfn;pe_info(pe,"VF %04d:%02d:%02d.%d associated with PE#%x\n",hose->global_number,pdev->bus->number,-PCI_SLOT(pci_iov_virtfn_devfn(pdev,vf_index)),-PCI_FUNC(pci_iov_virtfn_devfn(pdev,vf_index)),pe_num);+PCI_SLOT(vf_devfn),PCI_FUNC(vf_devfn),pe_num);if(pnv_ioda_configure_pe(phb,pe)){/* XXX What do we do here ? */
@@ -1590,6 +1592,15 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)list_add_tail(&pe->list,&phb->ioda.pe_list);mutex_unlock(&phb->ioda.pe_list_mutex);+/* associate this pe to it's pdn */+list_for_each_entry(vf_pdn,&pdn->parent->child_list,list){+if(vf_pdn->busno==vf_bus&&+vf_pdn->devfn==vf_devfn){+vf_pdn->pe_number=pe_num;+break;+}+}+pnv_pci_ioda2_setup_dma_pe(phb,pe);#ifdef CONFIG_IOMMU_APIiommu_register_group(&pe->table_group,
From: Shawn Anastasio <redacted>
Move PCI device setup from pcibios_add_device() and pcibios_fixup_bus() to
pcibios_bus_add_device(). This ensures that platform-specific DMA and IOMMU
setup occurs after the device has been registered in sysfs, which is a
requirement for IOMMU group assignment to work
This fixes IOMMU group assignment for hotplugged devices on pseries, where
the existing behavior results in IOMMU assignment before registration.
Thanks to Lukas Wunner [off-list ref] for the suggestion.
Signed-off-by: Shawn Anastasio <redacted>
@@ -1037,9 +1033,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)/* Now fixup the bus bus */pcibios_setup_bus_self(bus);--/* Now fixup devices on that bus */-pcibios_setup_bus_devices(bus);}EXPORT_SYMBOL(pcibios_fixup_bus);
With the previous patch applied pcibios_setup_device() will always be run
when pcibios_bus_add_device() is called. There are several code paths where
pcibios_setup_bus_device() is still called (the PowerPC specific PCI
hotplug support is one) so with just the previous patch applied the setup
can be run multiple times on a device, once before the device is added
to the bus and once after.
There's no need to run the setup in the early case any more so just
remove it entirely.
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
@@ -1000,24 +1000,6 @@ int pcibios_add_device(struct pci_dev *dev)return0;}-voidpcibios_setup_bus_devices(structpci_bus*bus)-{-structpci_dev*dev;--pr_debug("PCI: Fixup bus devices %d (%s)\n",-bus->number,bus->self?pci_name(bus->self):"PHB");--list_for_each_entry(dev,&bus->devices,bus_list){-/* Cardbus can call us to add new devices to a bus, so ignore-*thosewhoarealreadyfullydiscovered-*/-if(pci_dev_is_added(dev))-continue;--pcibios_setup_device(dev);-}-}-voidpcibios_set_master(structpci_dev*dev){/* No special bus mastering setup handling */
@@ -1036,13 +1018,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)}EXPORT_SYMBOL(pcibios_fixup_bus);-voidpci_fixup_cardbus(structpci_bus*bus)-{-/* Now fixup devices on that bus */-pcibios_setup_bus_devices(bus);-}--staticintskip_isa_ioresource_align(structpci_dev*dev){if(pci_has_flag(PCI_CAN_SKIP_ISA_ALIGN)&&
A couple of extra patches on top of Shawn's existing re-ordering patch.
This seems to fix the problem Alexey noted with Shawn's change causing
VFs to lose their IOMMU group. I've tried pretty hard to make this a
minimal fix it's still a bit large.
If mpe is happy to take this as a fix for 5.4 then I'll leave it,
otherwise we might want to look at different approaches.
Thanks for fixing this Oliver!
Reviewed-by: Shawn Anastasio <redacted>
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2019-10-11 08:37:48
"Oliver O'Halloran" [off-list ref] writes:
On Tue, Oct 1, 2019 at 3:09 AM Bjorn Helgaas [off-list ref] wrote:
quoted
On Mon, Sep 30, 2019 at 12:08:46PM +1000, Oliver O'Halloran wrote:
This is all powerpc, so I assume Michael will handle this. Just
random things I noticed; ignore if they don't make sense:
quoted
On PowerNV we use the pcibios_sriov_enable() hook to do two things:
1. Create a pci_dn structure for each of the VFs, and
2. Configure the PHB's internal BARs that map MMIO ranges to PEs
so that each VF has it's own PE. Note that the PE also determines
s/it's/its/
quoted
the IOMMU table the HW uses for the device.
Currently we do not set the pe_number field of the pci_dn immediately after
assigning the PE number for the VF that it represents. Instead, we do that
in a fixup (see pnv_pci_dma_dev_setup) which is run inside the
pcibios_add_device() hook which is run prior to adding the device to the
bus.
On PowerNV we add the device to it's IOMMU group using a bus notifier and
s/it's/its/
quoted
in order for this to work the PE number needs to be known when the bus
notifier is run. This works today since the PE number is set in the fixup
which runs before adding the device to the bus. However, if we want to move
the fixup to a later stage this will break.
We can fix this by setting the pdn->pe_number inside of
pcibios_sriov_enable(). There's no good to avoid this since we already have
s/no good/no good reason/ ?
Not quite sure what "this" refers to ... "no good reason to avoid
setting pdn->pe_number in pcibios_sriov_enable()"? The double
negative makes it a little hard to parse.