0

I have problem handling external interrupt for type 1 hypervisor, type 2 is working fine with windows 10 but type 1 is causing windows 10 to hangup in login screen.

This is how I enable external interrupts: When setting up cpus I enable VM-exit control bit 15 "acknowledge external interrupts" and pin-based bit 0 "external interrupts exiting", and I allocate buffer in each cpu context for pending interrupts.

When VM-exit reason 1 "external interrupt exiting" I do VMX-read 0x4404 "VM-exit interruption information" and I check for bit 31 "Valid" and bits 10:8 "interruption type" equal 0 "external interrupt", also I check bit 11 to VMX-read 0x4406 "exit interruption error code", and before injecting interrupt I check if interruptible VMX-read 0x6820 "guest RFLAGS" bit 9 "Interrupt enable flag" and VMX-read 0x4824 "guest interruptibility state" bit 1 "blocking by mov ss", if guest interruptible VMX-write 0x4016 "VM-entry interruption information field" and VMX-write 0x4018 "VM-entry error code" if error code valid, otherwise I save error code and interrupt information to pending interrupt buffer and set interrupt window exiting primary-proc-based bit 2.

When VM-exit reason 7 "Interrupt window exiting" I search for pending interrupts in allocated buffer, if found inject interrupt otherwise clear interrupt window exiting.

GoodDevGuy
  • 13
  • 4
  • 1
    There are a few additional things you have to check for. Off the top of my head: TPR (CR8) and IMR. Obviously they allowed the interrupt at the time you received it, but you have to make sure it is still allowed at the time you deliver it. – prl Jul 29 '21 at 06:30
  • Why do you only check bit 1 of interruptibility state and not bits 0 and 2? – prl Jul 29 '21 at 06:30
  • If more than one interrupt is pending in your queue, you have to deliver the highest priority one. – prl Jul 29 '21 at 06:31
  • The usual way to implement this is to implement a full virtual local APIC. Post the incoming interrupt in the IRR of the virtual APIC and then the APIC logic takes care of the things I mentioned. – prl Jul 29 '21 at 06:33
  • The fact that you mentioned the error code register implies that you aren't fully distinguishing external interrupts and faults. You probably need completely separate handling. Interrupts never have an error code. – prl Jul 29 '21 at 06:35
  • @prl not checking interruptibility state bit 0 and 2 was mistake but somehow didn't cause any problem, I check for bit 0 and 1 and 2 now, I haven't done apic virtualization yet. I've add error code checking as an attempt to solve to problem since intel sdm isn't clear about external interrupts and error codes but I've removed it now. – GoodDevGuy Jul 29 '21 at 07:08
  • I've tested my hypervisor type 1 now in vmware with single core and it works fine, that means the problem occurs only in multi-process system, note that host IDT is different from guest IDT. – GoodDevGuy Jul 29 '21 at 07:10
  • @prl I've found TPR and understood it, but cannot find IMR anywhere in intel SDM, do you mean TMR Trigger Mode Register? – GoodDevGuy Jul 29 '21 at 10:28
  • Sorry, there's no mask register in the APIC. I guess I was thinking of the ISR. You may have to implement a virtual APIC, because the ISR bit will be set by the physical APIC when you receive the interrupt, but the guest shouldn't see the ISR bit set until you deliver the interrupt. (But you may get away with that—the guest OS may not care.) – prl Jul 29 '21 at 17:19

0 Answers0