Xen Test Framework
PV IOPL Emulation

Tests for the behaviour of Xen's virtual IOPL handling for PV guests.

Xen cannot actually run PV guests with an IOPL other than 0, or PV guests would be able to play with the real interrupt flag behind Xen's back. Therefore, the guests desired IOPL is shadowed, and consulted when a IO related fault occurs. Xen either completes the IO on behalf of the guest, or bounces the #GP fault back to the guest kernel.

The instructions:

  • cli
  • outb al, $0x80

are tested in both user and kernel context, while varying IOPL, and verifying that a #GP fault was correctly (or not) delivered.

Methods of varying IOPL:

  1. PHYSDEVOP_set_iopl

    The PHYSDEVOP_set_iopl has existed in the Xen ABI for a very long time. Kernel context is considered to have a cpl of 1, even for 64bit PV guests executing in ring3. A side effect of this is that a PV guest kernel will suffer faults from IO accesses until it sets an IOPL of 1. A guest may set the current IOPL, but cannot query the value.

  2. VMASST_TYPE_architectural_iopl

    This is a change to the ABI, introduced in Xen 4.7 (following XSA-171) to make IOPL handling easier for the guest kernel. A guest must opt in to the new ABI by enabling the VMASSIT. This ABI considers a guest kernel to have an cpl of 0, and the shadowed IOPL will be updated from the contents of IRET frame during an IRET hypercall.

See also
tests/pv-iopl/main.c