Two command encodings checked against the specification:
- COMPLETION_WAIT set bit 1 (I, interrupt) instead of bit 0 (S, store), so the
IOMMU was never asked to write the sentinel, the poll always exhausted its
spins, and completeAndWait returned without any guarantee the preceding
invalidation had executed — no invalidation barrier has ever existed, on QEMU
or on silicon. The in-code claim that "QEMU's amd-iommu does not implement
the store form" was a misdiagnosis of this bug: with S set, QEMU stores the
sentinel fine, and the amd-iommu cases now run without the warn line. On real
hardware, which fetches commands asynchronously, the missing barrier was an
IOTLB use-after-free window: unmap returned before the invalidation was
confirmed and the caller freed the frames.
- INVALIDATE_IOMMU_PAGES "invalidate everything" used address bits 51:12
all-ones; the architected encoding is bits 62:12 all-ones (the spec's literal
0x7FFF_FFFF_FFFF_F000). Real silicon is free to misread the non-architected
form as a bounded range.