Interrupts in the guest VM A look at the steps needed to “reflect” hardware interrupts back into the ROM-BIOS for servicing The VME-bit in CR4 • Our VMX demo-program set the VME-bit (bit #0) in Guest’s Control Register CR4 31 13 V M X E 5 4 0 P P A S E E V M E Legend: VME (Virtual-8086 Extensions): 1=on, 0=off PSE (Page-Size Extensions): 1=on, 0=off PAE (Page-Address Extensions): 1=on, 0=off VMXE (Virtual Machine eXtensions Enabled): 1=yes, 0=no Virtual-8086 Mode Extensions • Software interrupt instructions (int $nn) will selectively be directed either to IDT-gates or to IVT-vectors, depending on a ‘bitmap’ located within the Task-State Descriptor • This ‘interrupt redirection bitmap’ has 256 bits (one for each 8-bit interrupt-number) • Its location within the TSS is immediately ahead of the I/O Permission Bitmap Interrupt-redirection Bitmap TSS base 25 longwords Legend: 1 = interrupt is directed to IDT 0 = interrupt is directed to IVT 256 bits Interrupt-redirection Bitmap 256-bits ( = 32 longwords) = ‘IOMAP’ field (at offset 0x66) 65536 bits = interrupt-redirection bitmap I/O-Permission Bitmap 65536-bits ( = 8192 bytes) = I/O-permission bitmap Task-State Segment Software INTs Only! • The interrupt-redirection bitmap does NOT affect any ‘hardware’ interrupts – they are serviced by the interrupt-handlers whose entry-points are specified within the gatedescriptors that comprise the IDT • How can the Guest VM in our VMX demoprogram handle the ‘hardware’ interrupts generated by the peripheral devices? We’ll modify our VMX demo • One change to ‘vmxstep3.s’: guest_RFLAGS: 0x00023202 # IF=1, IOPL=3 • One change to ‘vmxdemo.s’: in $0x21, %al or $0x10, %al out %al, $0x21 # get master-PIC’s mask # mask UART interrupt # set master-PIC’s mask Modify ‘guest_isrGPF’ • We introduce a major modification into the guest’s General Protection Fault-handler, to “reflect” external device-interrupts back to ‘real-mode’ code in the ROM-BIOS that will be executed in ‘Virtual-8086 mode’ • The steps needed to do this are based on ‘emulating’ the CPU’s usual response to an external interrupt in 8086 real-mode CPU’s interrupt-response • • • • • • • • Push FLAGS register onto the stack Clear IF and TF bits in FLAGS register Push CS and IP registers onto the stack Acquire the device’s interrupt-ID number Lookup that ID-number’s interrupt-vector Put that vector’s ‘loword’ into IP register Put that vector’s ‘hiword’ into CS register Then resume CPU’s fetch-execute cycle EFLAGS 31 21 20 19 18 17 16 14 13 12 11 10 9 8 7 6 4 2 0 V V I A V R N I/O O D I T S Z A P C I I 0 0 0 1 D C M F T PL F F F F F F F F F P F VM (Virtual-8086 Mode): 1=on, 0=off IF (Interrupt-Flag): 1=on, 0=off IOPL (Input/Output Permission-Level): =00 (only ring0 can execute ‘in’ and ’out’) =01 (ring0 and ring1 can execute ‘in’ and ‘out’) =10 (ring0, ring1, ring2 can execute ‘in’ and ‘out’) =11 (ring0, ring1, ring2, ring3 can execute ‘in’ and ‘out’) NOTE: Virtual-8086 mode operates at the ‘ring3’ privilege-level PIC masks • Each Programmable Interrupt Controller has a ‘mask register’ that allows blocking of the interrupts from specific devices Master-PIC mask-register I R Q 7 I R Q 6 I R Q 5 I R Q 4 I R Q 3 I R Q 2 I R Q 1 I R Q 0 Slave-PIC mask-register I R Q F I R Q E I R Q D I R Q C I R Q B I R Q A I R Q 9 I R Q 8 I/O Port 0x21 I/O Port 0xA1 GPF stack-frame GS ? FS ? DS ? ES ? SS SP EFLAGS CS IP SS0:ESP0 error ring0 stack SS:SP (before) ? FLAGS CS IP ring3 stack SS:SP (after) GPF error-code 15 \3 selector-index Legend: EXT (External-event): 1=yes, 0=no INT (Interrupt-table): 1=yes, 0=no TI (Table-Indicator): 1=LDT, 0=GDT Index = Table’s element-number 2 1 0 I E T N X I T T GPF stack-frame Interrupt Vector Table GS FS DS ES SS SP EFLAGS CS IP SS0:ESP0 error ring0 stack hiword hiword hiword hiword hiword hiword hiword hiword hiword hiword hiword hiword hiword hiword hiword loword loword loword loword loword loword loword loword loword loword loword loword loword loword loword