THE SHORT ANSWER
lspci -vvv prints everything pciutils can parse from one function’s configuration space. Read it in four blocks: the device line, the Control, Status and Region lines, the Capabilities list with the PCIe link lines, and the kernel driver lines. A “+” after a flag means the bit is set, “-” means clear. Run it as root.
Which lspci command do you need?
| Command | Shows |
|---|---|
lspci | One line per PCI function |
lspci -nn | Names plus numeric [vendor:device] and class IDs |
lspci -k | The kernel driver in use and the modules that could bind |
lspci -tv | A tree of buses, bridges and devices |
lspci -PP | Each device by its path through the bridges above it |
lspci -D | Domain numbers, even on single-domain machines |
lspci -s 01:00.0 / -d 10de: | Only the function at that address / only that vendor ID |
lspci -v, -vv, -vvv | Increasing detail; -vvv shows everything lspci can parse |
lspci -x, -xxx, -xxxx | Hex dump: 64-byte header, 256 bytes (root only), 4096-byte extended space |
lspci -vmm | Machine-readable output for scripts |
The manual warns that formats other than the machine-readable ones (-m, -vm, -vmm) can change between lspci versions, so don’t parse -vvv in scripts. Run verbose commands as root: many systems restrict part of configuration space to root, and lspci prints <access denied> for what it could not read. lspci(8) manual: options, root access and output formats.
Every lspci line is a capability, a setting or a snapshot
Most of lspci -vvv follows one naming pattern. Once you see it, the wall of flags sorts itself out:
| Name | What it is | Examples |
|---|---|---|
…Cap | Capability: what the device says it can do. Fixed by the hardware. | DevCap, LnkCap |
…Ctl / Control | Setting: what software has told it to do. The kernel or a driver wrote it. | Control, DevCtl, LnkCtl |
…Sta / Status | Snapshot: what is true now, or what has happened since a bit was last cleared. | Status, DevSta, LnkSta, CESta |
That one rule answers a lot. A link problem is a gap between LnkCap and LnkSta. A feature a driver never switched on shows up in a Ctl line. An error that happened at some point shows up as a sticky + in a Sta line, which may be older than the problem you are chasing. lspci measures nothing itself: it reads registers at one instant and prints them. Linux UAPI: PCI and PCIe register definitions (pci_regs.h).
Annotated example: lspci -vvv for one GPU
# Synthetic example: assembled to show the format, not captured from hardware.
# "…" marks trimmed output. Your device will show different values.
$ sudo lspci -vvv -s 01:00.0
01:00.0 VGA compatible controller: Synthetic demo GPU (rev a1) (prog-if 00 [VGA controller])
Subsystem: Synthetic demo board vendor Device 0001
Physical Slot: 1
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin A routed to IRQ 150
IOMMU group: 14
Region 0: Memory at f6000000 (32-bit, non-prefetchable) [size=16M]
Region 1: Memory at e0000000 (64-bit, prefetchable) [size=256M]
Region 3: Memory at f0000000 (64-bit, prefetchable) [size=32M]
Region 5: I/O ports at e000 [size=128]
Expansion ROM at f7000000 [disabled] [size=512K]
Capabilities: [60] Power Management version 3
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [68] MSI: Enable+ Count=1/1 Maskable- 64bit+
Address: 00000000fee00000 Data: 0000
Capabilities: [78] Express (v2) Endpoint, IntMsgNum 0
DevCap: MaxPayload 256 bytes, PhantFunc 0, Latency L0s unlimited, L1 <64us
ExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset- …
DevCtl: CorrErr+ NonFatalErr+ FatalErr+ UnsupReq+
RlxdOrd+ ExtTag+ PhantFunc- AuxPwr- NoSnoop+
MaxPayload 256 bytes, MaxReadReq 512 bytes
DevSta: CorrErr+ NonFatalErr- FatalErr- UnsupReq- AuxPwr- TransPend-
LnkCap: Port #0, Speed 16GT/s, Width x16, ASPM L0s L1, Exit Latency L0s <1us, L1 <4us
ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp+
LnkCtl: ASPM Disabled; RCB 64 bytes, LnkDisable- CommClk+
ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt- …
LnkSta: Speed 8GT/s (downgraded), Width x8 (downgraded)
TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
…
Capabilities: [100 v2] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- …
…
CESta: RxErr+ BadTLP- BadDLLP- Rollover- Timeout- AdvNonFatalErr- …
…
Kernel driver in use: nvidia
Kernel modules: nouveau, nvidia| Line | What it means | What to check |
|---|---|---|
01:00.0 VGA compatible controller … (rev a1) | Bus 01, device 00, function 0; the class; the name from pci.ids; the revision. | rev ff means configuration reads returned all ones. Start with unknown header type 7f. |
Subsystem: | The IDs of the board maker that built this card around the chip. | Needed to match vendor ROMs, quirks and support documents. |
Control: … Mem+ BusMaster+ … DisINTx+ | The Command register: memory decoding and DMA (bus mastering) are on; legacy INTx is off because MSI is in use. | Mem- or BusMaster- on a device whose driver is loaded deserves a closer look. |
Status: Cap+ … <MAbort- | A capability list exists; the latched error bits are clear. | <MAbort+, >SERR+ or <PERR+ are latched events. Compare with a baseline capture. |
IOMMU group: 14 | The IOMMU group the kernel placed this function in (shown with -vv). | For passthrough, read IOMMU groups explained. |
Region 1: Memory at e0000000 (64-bit, prefetchable) [size=256M] | A BAR: its assigned address, type and size as the kernel knows them. | <unassigned> or [disabled] on a BAR the driver needs points to resource allocation; check the kernel log’s BAR messages. |
Capabilities: [68] MSI: Enable+ | The bracketed number is the capability’s offset in configuration space. MSI is enabled. | With a driver loaded, both MSI and MSI-X disabled means legacy interrupts. |
Express (v2) Endpoint | The PCI Express capability, version 2, for an endpoint. The device type decides which lines follow. | Root ports and switch ports print slot and root lines instead. |
DevCtl: … MaxPayload 256 bytes, MaxReadReq 512 bytes | The payload and read-request sizes the device is set to use. | Compare with DevCap and the upstream port when tuning or debugging throughput. |
DevSta: CorrErr+ | A correctable error was detected since the bit was last cleared. | Not proof of failure. Read the AER block and the kernel log. |
LnkCap: … Speed 16GT/s, Width x16 | What this function supports. | This is one end of the link only. |
LnkSta: Speed 8GT/s (downgraded), Width x8 (downgraded) | What the link negotiated, below this function’s capability. | See the next section before calling it a fault. |
CESta: RxErr+ | A receiver error is logged in the AER correctable status. | Correlate with journalctl -k and a baseline. |
Kernel driver in use: / Kernel modules: | The driver bound now / the modules that could bind. | Modules listed but no driver in use means nothing has claimed the device. |
How do I read lspci -vvv output?
Flags. pciutils prints each flag as its name followed by + when the bit is set and - when it is clear, so BusMaster+ means bus mastering is enabled. Values that are not single bits are printed as text, for example DEVSEL=fast or MaxPayload 256 bytes. pciutils source: Control, Status, Region and IOMMU group lines.
The device block is the first line, Subsystem, Physical Slot, Control, Status, the interrupt line, the IOMMU group and the Region lines. Control and Status are the Command and Status registers at offsets 0x04 and 0x06. Linux UAPI: PCI and PCIe register definitions (pci_regs.h).
The capabilities block follows the standard list starting at offset 0x34: Capabilities: [60] means a capability at offset 0x60. Entries with three-digit offsets such as [100 v2] are extended capabilities in the 4 KiB PCIe space, such as AER, ACS or SR-IOV. lspci shows them only when it can read the extended space, which needs root.
The driver block comes last: Kernel driver in use and Kernel modules. The manual notes that -k is on by default with -v in the normal output mode. lspci(8) manual: options, root access and output formats.
What does “downgraded” mean in lspci?
pciutils prints (downgraded) when the negotiated speed or width in LnkSta is lower than the same function’s LnkCap, and (overdriven) if it is higher. It never prints the suffix for root ports, downstream switch ports or PCI/PCI-X-to-PCIe bridges, so the upstream end of a slow link shows no warning. pciutils source: PCIe capability lines and the “downgraded” rule.
LnkCap describes one end only. A link runs at what both ends support and the slot wiring allows: an x16 card in a slot wired for x8 lanes, or behind a root port limited to 8 GT/s, reports “downgraded” and is working as designed. Some devices, GPUs in particular, can also lower link speed when idle to save power, so capture under load before calling it a fault.
# Find the upstream port: the path shows it before the slash.
lspci -PP -s 01:00.0
# Compare both ends (00:01.1 is the example upstream port).
sudo lspci -vv -s 00:01.1 | grep -e LnkCap: -e LnkSta:
sudo lspci -vv -s 01:00.0 | grep -e LnkCap: -e LnkSta:
# The kernel exposes the same values in sysfs:
cat /sys/bus/pci/devices/0000:01:00.0/current_link_speed
cat /sys/bus/pci/devices/0000:01:00.0/max_link_speedThe sysfs link attributes are documented in Linux ABI: PCI sysfs attributes, link speed and reset_method. For a full width and speed investigation, follow PCIe link stuck at x1. The PCI config space decoder shows LnkCap and LnkSta side by side from a hex dump.
Reading the AER block
The Advanced Error Reporting capability lives in extended configuration space, so it appears only when lspci can read the full 4 KiB. UESta holds uncorrectable error status and CESta correctable status. UEMsk and CEMsk show which errors are masked, and UESvrt which uncorrectable errors are treated as fatal.
A + in a status line means that error was logged since the bit was last cleared. AER status bits are sticky, so a set bit can predate your test. Read it together with the kernel log and a baseline capture, not on its own. The kernel’s AER documentation explains how corrected and uncorrectable errors are reported and handled. Linux kernel: PCIe Advanced Error Reporting.
One register deeper with setpci
setpci, from the same pciutils package, reads and writes individual configuration registers. Values and offsets are hexadecimal, and .b, .w and .l select 1, 2 or 4 bytes. Reading is the useful part for debugging:
# Read the Command register of one function.
sudo setpci -s 01:00.0 COMMAND
# Read Link Status: offset 0x12 inside the PCI Express capability, 16 bits.
sudo setpci -s 01:00.0 CAP_EXP+12.w
# List the register and capability names setpci knows.
setpci --dumpregsIn the synthetic example above, a Link Status value of 1083 decodes as speed code 3 (8 GT/s) in bits 3:0, width 8 in bits 9:4 and Slot Clock set in bit 12, the same thing lspci printed as Speed 8GT/s, Width x8 and SlotClk+. Linux UAPI: PCI and PCIe register definitions (pci_regs.h).
Writes are a different matter. setpci writes any register you name, and a wrong value can turn off a device’s memory decoding or cut off the disk or network card you depend on. Its -D demo mode writes nothing, which lets you check a command first. Don’t write registers to “fix” an error you have not diagnosed. setpci(8) manual: register names, widths and demo mode.
Using lspci on a real problem
- Find the function. Run
lspci -nnandlspci -tv; note the address and the[vendor:device]IDs. - Save a full capture.
sudo lspci -vvv -s 01:00.0 > device.txt, plussudo lspci -xxxx -s 01:00.0 > device-hex.txtwhere the vendor’s guidance allows extended reads. The manual notes that some devices react badly to reading parts of their configuration space; read one device, not the whole machine. - Check the device line.
rev ffor an unknown header type means configuration reads are failing; follow unknown header type 7f. If the device is not listed at all, follow device missing from lspci. - Check the driver lines. Modules listed without a driver in use means nothing is bound.
- Check Control and the Regions. An active driver normally needs
Mem+and, for DMA,BusMaster+. Note any unassigned or disabled region. - Compare LnkSta with LnkCap at both ends of the link, under the same workload.
- Read DevSta and the AER block. Note every
+and match it tojournalctl -ktimestamps. - Decode and compare. Paste the hex into the PCI config space decoder, then compare it with a known-good capture in the Header7F Console.
Questions
- How do I read lspci -vvv output?
Read it in four blocks: the device line (address, class, name, revision), the Control, Status and Region lines, the Capabilities list with DevCtl, LnkCap and LnkSta, and the kernel driver lines. A + after a flag name means the bit is set and - means clear. Run it with sudo.
- What is the difference between lspci -v, -vv and -vvv?
Each adds detail.
-vis verbose,-vvadds the details the pciutils authors consider useful, and-vvvshows everything lspci can parse, including less interesting data. None of them changes the device; they only read.- How do I check PCIe link speed and width with lspci?
Run
sudo lspci -vv -s 01:00.0 | grep -e LnkCap -e LnkStawith your address. LnkCap is what the function supports and LnkSta is what it negotiated. Check the upstream port too, because one end cannot tell you the whole link.- Why does lspci show “access denied”?
Part of configuration space is readable only by root on many systems. Without sudo, lspci prints
<access denied>where it could not read, and capabilities such as the PCIe link lines and AER are missing.- Is it safe to run lspci -xxx?
The lspci manual makes
-xxxroot-only because some PCI devices crash when parts of their configuration space are read. Dump one known device with-srather than the whole machine, and follow vendor guidance for fragile hardware.- What does setpci do, and is it safe?
setpci reads and writes individual configuration registers by name or offset. Reading is useful for checking one register. Writing can disable a device or hang access to it, so use the
-Ddemo mode to check a command and don’t write registers you have not diagnosed.
Sources and scope
Source-based guide published by Header7F on 19 October 2026. Commands use placeholder addresses. Header7F has not reproduced every scenario on physical hardware, and no outcome is guaranteed.
- lspci(8) manual: options, root access and output formats
- setpci(8) manual: register names, widths and demo mode
- pciutils source: Control, Status, Region and IOMMU group lines
- pciutils source: PCIe capability lines and the “downgraded” rule
- Linux UAPI: PCI and PCIe register definitions (pci_regs.h)
- Linux kernel: PCIe Advanced Error Reporting
- Linux ABI: PCI sysfs attributes, link speed and reset_method