git: 2f176a2b2010 - main - pciconf: Fix up pciconf -lc output
David Bright
david at bright-family.net
Wed Jun 9 17:52:24 UTC 2021
On Jun 1, 2021, at 12:44 PM, John Baldwin <jhb at FreeBSD.org> wrote:
>
> On 6/1/21 8:56 AM, David Bright wrote:
>> The branch main has been updated by dab:
>> URL: https://cgit.FreeBSD.org/src/commit/?id=2f176a2b20107f7a9132242223e9eef657400514
>> commit 2f176a2b20107f7a9132242223e9eef657400514
>>
>> pciconf: Fix up pciconf -lc output
>> The pciconf command fails to emit newlines when particular ecap field
>> values are seen. Fix them up. This has been seen on several systems at
>> $JOB. The documentation for PCI capabilities says that capability
>> type 0 should not be used once the spec for PCI capabilities was
>> published, but that seems more wishful-thinking than reality. pciconf
>> also chooses not to print fields related to field values that are
>> zero, but it seems several of these fields are zero on actual
>> hardware.
>>
>
> Are the ecap registers actually valid for version 1 in this case? That is,
> should we treat version 0 as being version 1? The current checks are just
> defensive coding for not parsing something unless we know it is valid.
> If the only version 0 caps in practice are always compatible with version 1
> we could just treat 0 as if it were 1.
I think the answer is “maybe, but we don’t know for sure”. Robert Herndon did some looking at this; his findings are paraphrased below:
-----
Searching on version fields in PCI caps and ecaps doesn’t produce a lot of information. There are references to particular devices indicating that ‘version’ should be ‘1’, or that it should not be ‘0’, but there’s nothing that says so for any generic case, or in the standards I’ve found. The version field is only four bits, so it seems a little odd that zero wouldn’t be a reasonable-ish value. Internally we have only found two hosts exhibiting this issue and both exhibit the same behavior. When the early return on version 0 is disabled they show multiple instances of:
cap 10[40] = PCI-Express 2 root endpoint max data 128(128)
ecap 000b[100] = Vendor 0 ID 1
none114 at pci0:93:15:0: class=0x110100 card=0x00008086 chip=0x20588086 rev=0x07 hdr=0x00
So they appear to be mainstream vendor (Intel) devices. All instances showed ‘Vendor 0 ID 1’. In this particular instance, the current FreeBSD code would print this much information and a little more before refusing to dump more detailed information, printing
printf("Vendor [%d] ID %04x Rev %d Length %d\n", ver,
PCIR_VSEC_ID(hdr), PCIR_VSEC_REV(hdr), len);
before returning. (After the return, it does read more registers out of the capability, and prints more detailed information for extra registers as found).
It’s conceivable that reading these registers when a particular field is zero could cause it to print erroneous or misleading information, but there is a reasonable probability that it would be helpful in real usage.
-----
--
David Bright
dab at FreeBSD.org
More information about the dev-commits-src-all
mailing list