On 17/06/26 11:45PM, Junjie Cao wrote:
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

Hi Junjie,

  Yeah, it's a typo. The destination register should be "PCI_EXP_LNKSTA2".
  Thank you for pointing this out. We will rectify it in the next version.

Thanks,



Reply via email to