* [PATCH] x86, pci: Fix all early PCI scans to check the vendor ID first @ 2012-08-08 22:17 Andi Kleen 2012-08-09 22:34 ` Betty Dall 0 siblings, 1 reply; 10+ messages in thread From: Andi Kleen @ 2012-08-08 22:17 UTC (permalink / raw) To: x86; +Cc: linux-kernel, Andi Kleen From: Andi Kleen <ak@linux.intel.com> According to the Intel PCI experts it's not safe to check any other field than vendor ID for 0xffff when doing PCI scans to see if the device exists. Several of the early PCI scans violated this. I changed them all to always check the vendor ID first. Signed-off-by: Andi Kleen <ak@linux.intel.com> --- arch/x86/kernel/aperture_64.c | 5 +++++ arch/x86/kernel/early-quirks.c | 3 +++ arch/x86/kernel/pci-calgary_64.c | 8 ++++++-- arch/x86/pci/early.c | 3 +++ drivers/firewire/init_ohci1394_dma.c | 3 +++ 5 files changed, 20 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c index d5fd66f..e1ca7cd 100644 --- a/arch/x86/kernel/aperture_64.c +++ b/arch/x86/kernel/aperture_64.c @@ -206,6 +206,11 @@ static u32 __init search_agp_bridge(u32 *order, int *valid_agp) for (func = 0; func < 8; func++) { u32 class, cap; u8 type; + + if (read_pci_config_16(bus, slot, func, PCI_VENDOR_ID) + == 0xffff) + continue; + class = read_pci_config(bus, slot, func, PCI_CLASS_REVISION); if (class == 0xffffffff) diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index 3755ef4..f76b930 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c @@ -250,6 +250,9 @@ static int __init check_dev_quirk(int num, int slot, int func) vendor = read_pci_config_16(num, slot, func, PCI_VENDOR_ID); + if (vendor == 0xffff) + return -1; + device = read_pci_config_16(num, slot, func, PCI_DEVICE_ID); for (i = 0; early_qrk[i].f != NULL; i++) { diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 299d493..05798a0 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c @@ -1324,8 +1324,9 @@ static void __init get_tce_space_from_tar(void) unsigned short pci_device; u32 val; - val = read_pci_config(bus, 0, 0, 0); - pci_device = (val & 0xFFFF0000) >> 16; + if (read_pci_config_16(bus, 0, 0, PCI_VENDOR_ID) == 0xffff) + continue; + pci_device = read_pci_config_16(bus, 0, 0, PCI_DEVICE_ID); if (!is_cal_pci_dev(pci_device)) continue; @@ -1426,6 +1427,9 @@ int __init detect_calgary(void) unsigned short pci_device; u32 val; + if (read_pci_config_16(bus, 0, 0, PCI_VENDOR_ID) == 0xffff) + continue; + val = read_pci_config(bus, 0, 0, 0); pci_device = (val & 0xFFFF0000) >> 16; diff --git a/arch/x86/pci/early.c b/arch/x86/pci/early.c index d1067d5..4fb6847 100644 --- a/arch/x86/pci/early.c +++ b/arch/x86/pci/early.c @@ -91,6 +91,9 @@ void early_dump_pci_devices(void) u32 class; u8 type; + if (read_pci_config_16(bus, slot, func, PCI_VENDOR_ID) == 0xffff) + continue; + class = read_pci_config(bus, slot, func, PCI_CLASS_REVISION); if (class == 0xffffffff) diff --git a/drivers/firewire/init_ohci1394_dma.c b/drivers/firewire/init_ohci1394_dma.c index a9a347a..dd3bd84 100644 --- a/drivers/firewire/init_ohci1394_dma.c +++ b/drivers/firewire/init_ohci1394_dma.c @@ -279,6 +279,9 @@ void __init init_ohci1394_dma_on_all_controllers(void) for (num = 0; num < 32; num++) { for (slot = 0; slot < 32; slot++) { for (func = 0; func < 8; func++) { + if (read_pci_config_16(num, slot, func, PCI_VENDOR_ID) == 0xffff) + continue; + class = read_pci_config(num, slot, func, PCI_CLASS_REVISION); if (class == 0xffffffff) -- 1.7.7.6 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] x86, pci: Fix all early PCI scans to check the vendor ID first 2012-08-08 22:17 [PATCH] x86, pci: Fix all early PCI scans to check the vendor ID first Andi Kleen @ 2012-08-09 22:34 ` Betty Dall 2012-08-09 23:41 ` Andi Kleen 2012-08-10 23:57 ` H. Peter Anvin 0 siblings, 2 replies; 10+ messages in thread From: Betty Dall @ 2012-08-09 22:34 UTC (permalink / raw) To: Andi Kleen; +Cc: x86, linux-kernel, Andi Kleen Hi Andi, On Wed, 2012-08-08 at 15:17 -0700, Andi Kleen wrote: > From: Andi Kleen <ak@linux.intel.com> > > According to the Intel PCI experts it's not safe to check any > other field than vendor ID for 0xffff when doing PCI scans > to see if the device exists. > > Several of the early PCI scans violated this. I changed > them all to always check the vendor ID first. > > Signed-off-by: Andi Kleen <ak@linux.intel.com> > --- > arch/x86/kernel/aperture_64.c | 5 +++++ > arch/x86/kernel/early-quirks.c | 3 +++ > arch/x86/kernel/pci-calgary_64.c | 8 ++++++-- > arch/x86/pci/early.c | 3 +++ > drivers/firewire/init_ohci1394_dma.c | 3 +++ > 5 files changed, 20 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c > index d5fd66f..e1ca7cd 100644 > --- a/arch/x86/kernel/aperture_64.c > +++ b/arch/x86/kernel/aperture_64.c > @@ -206,6 +206,11 @@ static u32 __init search_agp_bridge(u32 *order, int *valid_agp) > for (func = 0; func < 8; func++) { > u32 class, cap; > u8 type; > + > + if (read_pci_config_16(bus, slot, func, PCI_VENDOR_ID) > + == 0xffff) > + continue; I thought this should be a break instead of a continue since the code does a break if the class is 0xffffffff. If the function does not have a valid VENDOR_ID, then the remaining function numbers do not have to be scanned because functions are required to be implemented in order (no skipping a function number.) > + > class = read_pci_config(bus, slot, func, > PCI_CLASS_REVISION); > if (class == 0xffffffff) > diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c > index 3755ef4..f76b930 100644 > --- a/arch/x86/kernel/early-quirks.c > +++ b/arch/x86/kernel/early-quirks.c > @@ -250,6 +250,9 @@ static int __init check_dev_quirk(int num, int slot, int func) > > vendor = read_pci_config_16(num, slot, func, PCI_VENDOR_ID); > > + if (vendor == 0xffff) > + return -1; > + > device = read_pci_config_16(num, slot, func, PCI_DEVICE_ID); > > for (i = 0; early_qrk[i].f != NULL; i++) { > diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c > index 299d493..05798a0 100644 > --- a/arch/x86/kernel/pci-calgary_64.c > +++ b/arch/x86/kernel/pci-calgary_64.c > @@ -1324,8 +1324,9 @@ static void __init get_tce_space_from_tar(void) > unsigned short pci_device; > u32 val; > > - val = read_pci_config(bus, 0, 0, 0); > - pci_device = (val & 0xFFFF0000) >> 16; > + if (read_pci_config_16(bus, 0, 0, PCI_VENDOR_ID) == 0xffff) > + continue; > + pci_device = read_pci_config_16(bus, 0, 0, PCI_DEVICE_ID); > > if (!is_cal_pci_dev(pci_device)) > continue; > @@ -1426,6 +1427,9 @@ int __init detect_calgary(void) > unsigned short pci_device; > u32 val; > > + if (read_pci_config_16(bus, 0, 0, PCI_VENDOR_ID) == 0xffff) > + continue; > + > val = read_pci_config(bus, 0, 0, 0); > pci_device = (val & 0xFFFF0000) >> 16; I liked how you replaced the read_pci_config(bus, 0, 0, 0) with read_pci_config_16(bus, 0, 0, PCI_DEVICE_ID) in the previous diff for the function get_tce_space_from_tar(). Could you do that in this detect_calgary() function too? > > diff --git a/arch/x86/pci/early.c b/arch/x86/pci/early.c > index d1067d5..4fb6847 100644 > --- a/arch/x86/pci/early.c > +++ b/arch/x86/pci/early.c > @@ -91,6 +91,9 @@ void early_dump_pci_devices(void) > u32 class; > u8 type; > > + if (read_pci_config_16(bus, slot, func, PCI_VENDOR_ID) == 0xffff) > + continue; > + > class = read_pci_config(bus, slot, func, > PCI_CLASS_REVISION); > if (class == 0xffffffff) > diff --git a/drivers/firewire/init_ohci1394_dma.c b/drivers/firewire/init_ohci1394_dma.c > index a9a347a..dd3bd84 100644 > --- a/drivers/firewire/init_ohci1394_dma.c > +++ b/drivers/firewire/init_ohci1394_dma.c > @@ -279,6 +279,9 @@ void __init init_ohci1394_dma_on_all_controllers(void) > for (num = 0; num < 32; num++) { > for (slot = 0; slot < 32; slot++) { > for (func = 0; func < 8; func++) { > + if (read_pci_config_16(num, slot, func, PCI_VENDOR_ID) == 0xffff) > + continue; > + > class = read_pci_config(num, slot, func, > PCI_CLASS_REVISION); > if (class == 0xffffffff) It is interesting that these last two functions are doing basically the same pci discovery as the code in search_agp_bridge(), except that they uses continue instead of break. It might be beyond the scope of what you are trying to fix, but those continues could be changed to breaks for the same reason it is a break in search_agp_bridge(). -Betty ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] x86, pci: Fix all early PCI scans to check the vendor ID first 2012-08-09 22:34 ` Betty Dall @ 2012-08-09 23:41 ` Andi Kleen 2012-08-10 23:57 ` H. Peter Anvin 1 sibling, 0 replies; 10+ messages in thread From: Andi Kleen @ 2012-08-09 23:41 UTC (permalink / raw) To: Betty Dall; +Cc: Andi Kleen, x86, linux-kernel, Andi Kleen Thanks Betty. All fixed. I'll post a v2. -Andi -- ak@linux.intel.com -- Speaking for myself only. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] x86, pci: Fix all early PCI scans to check the vendor ID first 2012-08-09 22:34 ` Betty Dall 2012-08-09 23:41 ` Andi Kleen @ 2012-08-10 23:57 ` H. Peter Anvin 2012-08-11 10:43 ` Andi Kleen 2012-08-13 3:23 ` Khalid Aziz 1 sibling, 2 replies; 10+ messages in thread From: H. Peter Anvin @ 2012-08-10 23:57 UTC (permalink / raw) To: Betty Dall; +Cc: Andi Kleen, x86, linux-kernel, Andi Kleen On 08/09/2012 03:34 PM, Betty Dall wrote: > > I thought this should be a break instead of a continue since the code > does a break if the class is 0xffffffff. If the function does not have a > valid VENDOR_ID, then the remaining function numbers do not have to be > scanned because functions are required to be implemented in order (no > skipping a function number.) > Is that true? This is certainly not true in PCI in general: there is required to be a function 0, but there is no guarantee that functions 1-7 don't have gaps. -hpa ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] x86, pci: Fix all early PCI scans to check the vendor ID first 2012-08-10 23:57 ` H. Peter Anvin @ 2012-08-11 10:43 ` Andi Kleen 2012-08-13 21:58 ` Betty Dall 2012-08-13 3:23 ` Khalid Aziz 1 sibling, 1 reply; 10+ messages in thread From: Andi Kleen @ 2012-08-11 10:43 UTC (permalink / raw) To: H. Peter Anvin; +Cc: Betty Dall, Andi Kleen, x86, linux-kernel On Fri, Aug 10, 2012 at 04:57:02PM -0700, H. Peter Anvin wrote: > On 08/09/2012 03:34 PM, Betty Dall wrote: > > > > I thought this should be a break instead of a continue since the code > > does a break if the class is 0xffffffff. If the function does not have a > > valid VENDOR_ID, then the remaining function numbers do not have to be > > scanned because functions are required to be implemented in order (no > > skipping a function number.) > > > > Is that true? This is certainly not true in PCI in general: there is > required to be a function 0, but there is no guarantee that functions > 1-7 don't have gaps. These scans are for special known devices, presumably true for them. Anwyays if you don't like it please use v1 of the patch. -Andi -- ak@linux.intel.com -- Speaking for myself only ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] x86, pci: Fix all early PCI scans to check the vendor ID first 2012-08-11 10:43 ` Andi Kleen @ 2012-08-13 21:58 ` Betty Dall 2012-08-13 22:01 ` H. Peter Anvin 0 siblings, 1 reply; 10+ messages in thread From: Betty Dall @ 2012-08-13 21:58 UTC (permalink / raw) To: Andi Kleen; +Cc: H. Peter Anvin, Andi Kleen, x86, linux-kernel On Sat, 2012-08-11 at 03:43 -0700, Andi Kleen wrote: > On Fri, Aug 10, 2012 at 04:57:02PM -0700, H. Peter Anvin wrote: > > On 08/09/2012 03:34 PM, Betty Dall wrote: > > > > > > I thought this should be a break instead of a continue since the code > > > does a break if the class is 0xffffffff. If the function does not have a > > > valid VENDOR_ID, then the remaining function numbers do not have to be > > > scanned because functions are required to be implemented in order (no > > > skipping a function number.) > > > > > > > Is that true? This is certainly not true in PCI in general: there is > > required to be a function 0, but there is no guarantee that functions > > 1-7 don't have gaps. > > These scans are for special known devices, presumably true for them. > > Anwyays if you don't like it please use v1 of the patch. > > -Andi I checked the PCI specification, and Peter is right that function numbers can be sparse. Please go with version 1 of the patch, as Andi suggested. I will follow up by looking at why the three scans are not consistent and send a patch, if appropriate. The scans could be improved by stopping the function scan if function 0 does not exist because function 0 is required, and if it is not there then none of the other functions will be implemented. -Betty ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] x86, pci: Fix all early PCI scans to check the vendor ID first 2012-08-13 21:58 ` Betty Dall @ 2012-08-13 22:01 ` H. Peter Anvin 0 siblings, 0 replies; 10+ messages in thread From: H. Peter Anvin @ 2012-08-13 22:01 UTC (permalink / raw) To: Betty Dall; +Cc: Andi Kleen, Andi Kleen, x86, linux-kernel On 08/13/2012 02:58 PM, Betty Dall wrote: > > I checked the PCI specification, and Peter is right that function > numbers can be sparse. Please go with version 1 of the patch, as Andi > suggested. I will follow up by looking at why the three scans are not > consistent and send a patch, if appropriate. The scans could be improved > by stopping the function scan if function 0 does not exist because > function 0 is required, and if it is not there then none of the other > functions will be implemented. > Yes, if function 0 doesn't exist we could, and *should* skip functions 1-7; in fact, we should not process functions 1-7 unless the multifunction bit is set in function 0. This matters on real devices in the field. -hpa ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] x86, pci: Fix all early PCI scans to check the vendor ID first 2012-08-10 23:57 ` H. Peter Anvin 2012-08-11 10:43 ` Andi Kleen @ 2012-08-13 3:23 ` Khalid Aziz 2012-08-13 3:24 ` H. Peter Anvin 2012-08-13 4:15 ` Andi Kleen 1 sibling, 2 replies; 10+ messages in thread From: Khalid Aziz @ 2012-08-13 3:23 UTC (permalink / raw) To: H. Peter Anvin; +Cc: Betty Dall, Andi Kleen, x86, linux-kernel, Andi Kleen On 08/10/2012 05:57 PM, H. Peter Anvin wrote: > On 08/09/2012 03:34 PM, Betty Dall wrote: >> I thought this should be a break instead of a continue since the code >> does a break if the class is 0xffffffff. If the function does not have a >> valid VENDOR_ID, then the remaining function numbers do not have to be >> scanned because functions are required to be implemented in order (no >> skipping a function number.) >> > Is that true? This is certainly not true in PCI in general: there is > required to be a function 0, but there is no guarantee that functions > 1-7 don't have gaps. If that is the case, there is a problem in the original code in arch/x86/kernel/aperture_64.c.The original code already stops scanning functions the first time it finds an invalid PCI class: 206 for (func = 0; func < 8; func++) { 207 u32 class, cap; 208 u8 type; 209 class = read_pci_config(bus, slot, func, 210 PCI_CLASS_REVISION); 211 if (class == 0xffffffff) 212 break; -- ==================================================================== Khalid Aziz khalid.aziz@hp.com ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] x86, pci: Fix all early PCI scans to check the vendor ID first 2012-08-13 3:23 ` Khalid Aziz @ 2012-08-13 3:24 ` H. Peter Anvin 2012-08-13 4:15 ` Andi Kleen 1 sibling, 0 replies; 10+ messages in thread From: H. Peter Anvin @ 2012-08-13 3:24 UTC (permalink / raw) To: Khalid Aziz; +Cc: Betty Dall, Andi Kleen, x86, linux-kernel, Andi Kleen On 08/12/2012 08:23 PM, Khalid Aziz wrote: > > If that is the case, there is a problem in the original code in > arch/x86/kernel/aperture_64.c.The original code already stops scanning > functions the first time it finds an invalid PCI class: > Unless we can prove that that is invalid *for that specific case*, then it is definitely wrong, and yes, I have seen devices in the field with multiple, discontiguous functions. -hpa -- H. Peter Anvin, Intel Open Source Technology Center I work for Intel. I don't speak on their behalf. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] x86, pci: Fix all early PCI scans to check the vendor ID first 2012-08-13 3:23 ` Khalid Aziz 2012-08-13 3:24 ` H. Peter Anvin @ 2012-08-13 4:15 ` Andi Kleen 1 sibling, 0 replies; 10+ messages in thread From: Andi Kleen @ 2012-08-13 4:15 UTC (permalink / raw) To: Khalid Aziz; +Cc: H. Peter Anvin, Betty Dall, Andi Kleen, x86, linux-kernel > If that is the case, there is a problem in the original code in > arch/x86/kernel/aperture_64.c.The original code already stops scanning > functions the first time it finds an invalid PCI class: This was only for some AMD northbridges, since it worked there it should be ok. The code is obsolete now for modern systems I believe. -Andi ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2012-08-13 22:02 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-08-08 22:17 [PATCH] x86, pci: Fix all early PCI scans to check the vendor ID first Andi Kleen 2012-08-09 22:34 ` Betty Dall 2012-08-09 23:41 ` Andi Kleen 2012-08-10 23:57 ` H. Peter Anvin 2012-08-11 10:43 ` Andi Kleen 2012-08-13 21:58 ` Betty Dall 2012-08-13 22:01 ` H. Peter Anvin 2012-08-13 3:23 ` Khalid Aziz 2012-08-13 3:24 ` H. Peter Anvin 2012-08-13 4:15 ` Andi Kleen
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).