mirror of https://gitee.com/openkylin/linux.git
powerpc/pseries: fix EEH recovery of some IOV devices
EEH recovery currently fails on pSeries for some IOV capable PCI devices, if CONFIG_PCI_IOV is on and the hypervisor doesn't provide certain device tree properties for the device. (Found on an IOV capable device using the ipr driver.) Recovery fails in pci_enable_resources() at the check on r->parent, because r->flags is set and r->parent is not. This state is due to sriov_init() setting the start, end and flags members of the IOV BARs but the parent not being set later in pseries_pci_fixup_iov_resources(), because the "ibm,open-sriov-vf-bar-info" property is missing. Correct this by zeroing the resource flags for IOV BARs when they can't be configured (this is the same method used by sriov_init() and __pci_read_base()). VFs cleared this way can't be enabled later, because that requires another device tree property, "ibm,number-of-configurable-vfs" as well as support for the RTAS function "ibm_map_pes". These are all part of hypervisor support for IOV and it seems unlikely that a hypervisor would ever partially, but not fully, support it. (None are currently provided by QEMU/KVM.) Signed-off-by: Sam Bobroff <sbobroff@linux.ibm.com> Reviewed-by: Bryant G. Ly <bryantly@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
e0da99123f
commit
b87b9cf493
|
@ -647,6 +647,15 @@ void of_pci_parse_iov_addrs(struct pci_dev *dev, const int *indexes)
|
|||
}
|
||||
}
|
||||
|
||||
static void pseries_disable_sriov_resources(struct pci_dev *pdev)
|
||||
{
|
||||
int i;
|
||||
|
||||
pci_warn(pdev, "No hypervisor support for SR-IOV on this device, IOV BARs disabled.\n");
|
||||
for (i = 0; i < PCI_SRIOV_NUM_BARS; i++)
|
||||
pdev->resource[i + PCI_IOV_RESOURCES].flags = 0;
|
||||
}
|
||||
|
||||
static void pseries_pci_fixup_resources(struct pci_dev *pdev)
|
||||
{
|
||||
const int *indexes;
|
||||
|
@ -654,10 +663,10 @@ static void pseries_pci_fixup_resources(struct pci_dev *pdev)
|
|||
|
||||
/*Firmware must support open sriov otherwise dont configure*/
|
||||
indexes = of_get_property(dn, "ibm,open-sriov-vf-bar-info", NULL);
|
||||
if (!indexes)
|
||||
return;
|
||||
/* Assign the addresses from device tree*/
|
||||
of_pci_set_vf_bar_size(pdev, indexes);
|
||||
if (indexes)
|
||||
of_pci_set_vf_bar_size(pdev, indexes);
|
||||
else
|
||||
pseries_disable_sriov_resources(pdev);
|
||||
}
|
||||
|
||||
static void pseries_pci_fixup_iov_resources(struct pci_dev *pdev)
|
||||
|
@ -669,10 +678,10 @@ static void pseries_pci_fixup_iov_resources(struct pci_dev *pdev)
|
|||
return;
|
||||
/*Firmware must support open sriov otherwise dont configure*/
|
||||
indexes = of_get_property(dn, "ibm,open-sriov-vf-bar-info", NULL);
|
||||
if (!indexes)
|
||||
return;
|
||||
/* Assign the addresses from device tree*/
|
||||
of_pci_parse_iov_addrs(pdev, indexes);
|
||||
if (indexes)
|
||||
of_pci_parse_iov_addrs(pdev, indexes);
|
||||
else
|
||||
pseries_disable_sriov_resources(pdev);
|
||||
}
|
||||
|
||||
static resource_size_t pseries_pci_iov_resource_alignment(struct pci_dev *pdev,
|
||||
|
|
Loading…
Reference in New Issue