Re: [kvm-unit-tests PATCH v2] x86: pci: Support unaligned register access in PCI config read/write
Jim Mattson <[email protected]>
| Newsgroups | org.kernel.vger.kvm |
|---|---|
| Message-ID | <CALMp9eQyRbAa-YO06uVmFGp5T8AcG8+U9XmAr4Uoq1yNxwn=Hw@mail.gmail.com> |
On Tue, Aug 4, 2026 at 4:28 PM Irene Wang <[email protected]> wrote: > > Per the PCI Local Bus Specification (Section 3.2.2.3.2, "Configuration > Mechanism #1"), port 0xCF8 (CONFIG_ADDRESS) requires a DWORD-aligned > register offset (bits [1:0] = 00b), while byte and word offsets within > the DWORD must be selected via data port 0xCFC + (reg & 3). > > Previously, PCI_CONF1_ADDRESS did not clear bits [1:0], and 8-bit / > 16-bit helpers always accessed base port 0xCFC directly. This worked > in QEMU because its PCI host bridge emulation preserves unaligned bits > in CONFIG_ADDRESS and uses them during CONFIG_DATA accesses. However, > in strictly spec-compliant VMMs (and potentially real hardware), bits > [1:0] of 0xCF8 are ignored, causing non-aligned reads/writes at port > 0xCFC to erroneously target byte 0 of the DWORD. In practice, this > causes pci_find_dev() to read the vendor ID twice instead of reading > the vendor ID and device ID. > > Fix this by masking `reg` with `~3` in PCI_CONF1_ADDRESS and adding > the `(reg & 3)` offset to the CONFIG_DATA port for 8-bit and 16-bit > accessors, ensuring compatibility across QEMU and other VMMs. Additionally, > assert that 16-bit accesses do not use an offset of 3, as reading/writing a > word across DWORD boundaries (port 0xCFC + 3) is invalid per spec. > > Assisted-by: Gemini:gemini-3.6-flash > Signed-off-by: Irene Wang <[email protected]> Reviewed-by: Jim Mattson <[email protected]>