Skip to content

Commit 42de19d

Browse files
oohalmpe
authored andcommitted
powerpc/pseries/eeh: Allow zero to be a valid PE configuration address
There's no real reason why zero can't be a valid PE configuration address. Under qemu each sPAPR PHB (i.e. EEH supporting) has the passed-though devices on bus zero, so the PE address of bus <dddd>:00 should be zero. However, all previous versions of Linux will reject that, so Qemu at least goes out of it's way to avoid it. The Qemu implementation of ibm,get-config-addr-info2 RTAS has the following comment: > /* > * We always have PE address of form "00BB0001". "BB" > * represents the bus number of PE's primary bus. > */ So qemu puts a one into the register portion of the PE's config_addr to avoid it being zero. The whole is pretty silly considering that RTAS will return a negative error code if it can't map the device's config_addr to a PE. This patch fixes Linux to treat zero as a valid PE address. This shouldn't have any real effects due to the Qemu hack mentioned above. And the fact that Linux EEH has worked historically on PowerVM means they never pass through devices on bus zero so we would never see the problem there either. Signed-off-by: Oliver O'Halloran <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 98ba956 commit 42de19d

File tree

1 file changed

+22
-16
lines changed

1 file changed

+22
-16
lines changed

arch/powerpc/platforms/pseries/eeh_pseries.c

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -87,21 +87,20 @@ void pseries_pcibios_bus_add_device(struct pci_dev *pdev)
8787
* pseries_eeh_get_pe_config_addr - Find the pe_config_addr for a device
8888
* @pdn: pci_dn of the input device
8989
*
90-
* Retrieve the assocated config address. Actually, there're 2 RTAS
91-
* function calls dedicated for the purpose. We need implement
92-
* it through the new function and then the old one. Besides,
93-
* you should make sure the config address is figured out from
94-
* FDT node before calling the function.
90+
* The EEH RTAS calls use a tuple consisting of: (buid_hi, buid_lo,
91+
* pe_config_addr) as a handle to a given PE. This function finds the
92+
* pe_config_addr based on the device's config addr.
9593
*
96-
* It's notable that zero'ed return value means invalid PE config
97-
* address.
94+
* Keep in mind that the pe_config_addr *might* be numerically identical to the
95+
* device's config addr, but the two are conceptually distinct.
96+
*
97+
* Returns the pe_config_addr, or a negative error code.
9898
*/
9999
static int pseries_eeh_get_pe_config_addr(struct pci_dn *pdn)
100100
{
101101
int config_addr = rtas_config_addr(pdn->busno, pdn->devfn, 0);
102102
struct pci_controller *phb = pdn->phb;
103-
int ret = 0;
104-
int rets[3];
103+
int ret, rets[3];
105104

106105
if (ibm_get_config_addr_info2 != RTAS_UNKNOWN_SERVICE) {
107106
/*
@@ -112,16 +111,16 @@ static int pseries_eeh_get_pe_config_addr(struct pci_dn *pdn)
112111
config_addr, BUID_HI(phb->buid),
113112
BUID_LO(phb->buid), 1);
114113
if (ret || (rets[0] == 0))
115-
return 0;
114+
return -ENOENT;
116115

117-
/* Retrieve the associated PE config address */
116+
/* Retrieve the associated PE config address with function 0 */
118117
ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets,
119118
config_addr, BUID_HI(phb->buid),
120119
BUID_LO(phb->buid), 0);
121120
if (ret) {
122121
pr_warn("%s: Failed to get address for PHB#%x-PE#%x\n",
123122
__func__, phb->global_number, config_addr);
124-
return 0;
123+
return -ENXIO;
125124
}
126125

127126
return rets[0];
@@ -134,13 +133,20 @@ static int pseries_eeh_get_pe_config_addr(struct pci_dn *pdn)
134133
if (ret) {
135134
pr_warn("%s: Failed to get address for PHB#%x-PE#%x\n",
136135
__func__, phb->global_number, config_addr);
137-
return 0;
136+
return -ENXIO;
138137
}
139138

140139
return rets[0];
141140
}
142141

143-
return ret;
142+
/*
143+
* PAPR does describe a process for finding the pe_config_addr that was
144+
* used before the ibm,get-config-addr-info calls were added. However,
145+
* I haven't found *any* systems that don't have that RTAS call
146+
* implemented. If you happen to find one that needs the old DT based
147+
* process, patches are welcome!
148+
*/
149+
return -ENOENT;
144150
}
145151

146152
/**
@@ -417,7 +423,7 @@ void pseries_eeh_init_edev(struct pci_dn *pdn)
417423

418424
/* first up, find the pe_config_addr for the PE containing the device */
419425
addr = pseries_eeh_get_pe_config_addr(pdn);
420-
if (addr == 0) {
426+
if (addr < 0) {
421427
eeh_edev_dbg(edev, "Unable to find pe_config_addr\n");
422428
goto err;
423429
}
@@ -897,7 +903,7 @@ static int __init eeh_pseries_init(void)
897903
config_addr = pseries_eeh_get_pe_config_addr(pdn);
898904

899905
/* invalid PE config addr */
900-
if (config_addr == 0)
906+
if (config_addr < 0)
901907
continue;
902908

903909
pseries_eeh_phb_reset(phb, config_addr, EEH_RESET_FUNDAMENTAL);

0 commit comments

Comments
 (0)