Hi Shrihari,
On Tue, 9 Jun 2026 16:28:34 +0530, Shrihari E S wrote:
> if (flitmode) {
> - pci_long_test_and_set_mask(exp_cap + PCI_EXP_LNKSTA2,
> + uint32_t pos = dev->exp.exp_cap;
> +
> + pci_word_test_and_set_mask(exp_cap + PCI_EXP_FLAGS,
> PCI_EXP_LNKSTA2_FLIT);
> + pci_word_test_and_set_mask(exp_cap + PCI_EXP_FLAGS,
> + PCI_EXP_FLAGS_FLIT);
Following up on Jonathan's observation here -- I'd also noticed a
bogus Interrupt Message Number on a plain flit-mode root port, so I
checked what the stray write actually does to the Flags register.
The impact is wider than just UIO:
The first set_mask writes PCI_EXP_LNKSTA2_FLIT (0x0400) into
PCI_EXP_FLAGS (cap offset 0x02) instead of PCI_EXP_LNKSTA2 (0x32).
0x0400 falls in the Interrupt Message Number field (bits 13:9) of the
Flags register, so a flit-mode port ends up reporting a nonzero
Interrupt Message Number (it reads back as 2).
pcie_cap_fill_lnk() runs for every flit-mode port, and x-256b-flit
defaults to on for pcie-root-port, so even a plain
"-device pcie-root-port" comes up with the corrupted field.
The second line (PCI_EXP_FLAGS_FLIT into Flags) looks correct and
should stay. The first one looks like a typo in the destination
register -- it was PCI_EXP_LNKSTA2 before this series (visible in the
hunk above), so I'd restore it there rather than drop it.
pcie_cap_flit_write_config() does maintain the LNKSTA2 flit bit, but
only on guest LNKCTL writes; it doesn't run at realize/reset, so
dropping the line would leave LNKSTA2 flit status reading 0 at reset
instead of its pre-series value.
Many thanks,
Junjie