To inject an interrupt or exception into a guest a hypervisor uses the ENTRY_INTERRUPTION_INFO field in the vmcs. For eg: if there is a need to inject a #GP exception into the guest as part of vmentry, the entry_interruption_info field would look like this: 0x80000B0D.
1 . Bits 7:0 of this field represent the vector (0x0D - which is vector 13)
2. Bits 10:8 indicate the type(in this case type = 0x3 which is a hardware-exception).
3. Bit 11 is the error-code valid bit which is true in the example above.
4. Bit 31 is the valid bit for ENTRY_INTERRUPTION_INFO field.
To inject a software interrupt (say vector 0x8) hypervisor would program entry_interruption_info field as given under: 0x80000408 (type=0x4 and vector=0x8). If the guest is in V86 mode (GUEST_RFLAGS[VM]=1) , the processor behaves according to Table 15.2, Intel SDM, vol 3A .
Given below is a summary of the processor behavior during normal software-interrupt execution in V86 and during an event injection into a V86 guest:
1. EFLAGS.VM = 1 , CR4.VME=1, EFLAGS.IOPL=3
=> In this case the bit in the redirection bitmap of the TSS is consulted.
=> if bit in the redirection bitmap=0, the software interrupt is redirected to x86 style handler.
=> if bit in the redirection bitmap=1, the software interrupt is redirected to protected-mode handler.
2. EFLAGS.VM = 1 , CR4.VME=1, EFLAGS.IOPL<3
=> In this case the bit in the redirection bitmap of the TSS is consulted.
=> if bit in the redirection bitmap=0, the software interrupt is redirected to x86 style handler. Notice that this is the same behavior as with EFLAGS.IOPL=3. The difference is in the value of eflags pushed on the stack. Here the IOPL of the eflags image is forced to 3 and the value of VIF is copied to IF.
Normal behavior: if bit in the redirection bitmap=1, the interrupt is directed to a
#GP handler.
During VMX event injection: if bit in the redirection bitmap = 1, the processor
will *NOT* #GP due to IOPL < CPL.
3. EFLAGS.VM = 1 , CR4.VME=0, EFLAGS.IOPL=3
=>
Normal behavior: Interrupt directed to a protected mode handler (No #GP).
=>
During event injection: Same as above.
4. EFLAGS.VM = 1 , CR4.VME=0, EFLAGS.IOPL<3
=>
Normal behavior: Interrupt directed to a
#GP handler .
=>
During Event Injection: No #GP can occur due to IOPL< CPL. The behavior will be the same as with IOPL=3.
Summary:
From the above discussion is there will be no #GP due to IOPL < CPL during the injection of a software interrupt into a V86 guest. If the hypervisor wants this #GP to occur, it needs to inject a #GP directly into the guest instead of a software-interrupt.This can be achieved by programming the entry_interruption_info field to 0x80000B0D.