Interrupts in the guest VM “reflect” hardware interrupts back

advertisement
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
Download