Xen Test Framework
|
The invlpg
instruction was introduced in the 486 processor.
Its purpose is to invalidate a specific TLB entry without being a general TLB flush. It takes a single memory operand, but doesn't behave like other instructions referencing memory.
It is not documented to suffer the usual memory-based faults (#GP/#SS) for a bad segment, or segment limit violation. It is documented to be a NOP when given a non-canonical address, as opposed to raising a fault.
Experimentally, it does take into account segment bases when calculating which mapping to invalidate, but will also invalidate mappings beyond the segment limit.
This test is divided into two parts.
This code was originally built to confirm whether segment bases were taken into account by the invlpg
instruction. It is kept because it is useful to compare the behaviour of the HAP and shadow paging modes, as well as the emulated invlpg path in each mode.
The algorithm relies on the fact that a hardware pagetable walk which loads a mapping into the TLB for writing will perform an atomic set of the Accessed and Dirty bits in the pagetable entry. Subsequent writes via a mapping present in the TLB do not alter the pagetable entries.
Two mappings are chosen (in this example, the mapping for 4k and 8k physical addresses, but any two will do). Writes are performed to force a TLB fill, then the A/D bits are cleared in the PTEs. An invlpg
instruction is issued to invalidate one of mappings, and further writes are performed.
By inspecting the A/D bits in the PTEs after the second write, it can be determined which mappings where invalidated. A mapping which wasn't invalidated will not require a refill, so the A/D bits will be left clear. A mapping which was invalidated will necessarily require a refill, which will set the A/D bits.
There is a race condition with vcpu scheduling; if a reschedule occurs between the two sets of writes, the TLB might be flushed for reasons not related to this test. As a result, if both mappings are seen to refill, the test is repeated (up to a maximum number of tries).
The interaction of segment bases can be identified by issuing an invlpg
against the first mapping, with a segment base with would shift the linear address to the second mapping, by observing which mapping was refilled into the TLB.
This part of the test checks that the invlpg
instruction doesn't fault under conditions which a normal instruction with a memory operand would.
Additionally, for 64bit environments:
This part of the test is applicable to non-paged environments.