Nothing in tree exercises IOTLB invalidation for any emulated vIOMMU:
the existing iommu-testdev tests only check one-shot translation, so a
regression that failed to flush a stale IOTLB entry would go unnoticed.
Add a test that drives the queued-invalidation path end to end
(vtd_process_inv_desc -> vtd_process_iotlb_desc ->
vtd_iotlb_{global,domain,page}_invalidate). For each
{legacy, scalable-slt, scalable-flt} x {global, domain, page}
combination it:
1. maps IOVA -> PA_A and DMAs, populating the IOTLB;
2. rewrites the leaf PTE to PA_B *without* invalidating and DMAs
again, asserting the stale entry is still served (MISMATCH);
3. submits the IOTLB invalidation plus a wait descriptor, then DMAs
and asserts the fresh page walk now reaches PA_B.
Step 2 makes the flush observable: it fails loudly if the IOTLB
is not actually caching the first translation.
For scalable first-level (flt), QEMU keeps first- and second-level
mappings in a single IOTLB that the legacy VTD_INV_DESC_IOTLB descriptor
flushes for every level, so the test uses that descriptor across all
modes. PASID-selective invalidation (VTD_INV_DESC_PIOTLB, vtd_piotlb_*)
is a separate path and is left for a follow-up.
It also adds three page-selective cases that cache a second page and check
its fate after invalidating the first: for second-level (legacy, scalable-slt)
the second page survives, while for first-level (scalable-flt) QEMU flushes all
first-stage entries of the domain, so it does not. This distinguishes a
page-selective flush from a domain-wide or global one.
Signed-off-by: Junjie Cao <junjie.cao@intel.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260703072200.463082-4-junjie.cao@intel.com>