Special Topics In Computer Engineering Computer Science Essay

Published: Last Edited:

This essay has been submitted by a student. This is not an example of the work written by our professional essay writers.

There are 17 instructions in x86 architecture that, prior to the advent of hardware assisted virtualization, are not virtualizable in certain circumstances. Research this list of instructions, and list each one. Next, for each instruction, explain (briefly) why failing to virtualize the instruction could lead to problems (instability, security, etc.).

There are several Intel instructions that violate the hardware virtualization, these instructions are categorized into: Sensitive register instructions and Protection system instructions. Sensitive register instructions: SGDT, SIDT, SLDT, SMSW, POPF, PUSHF. Protection system instructions: LAR, LSL, VERR, VERW, POP, PUSH, CALL, JMP, INT, RET, STR, MOVE.

Sensitive register instructions

Store Global Descriptor Table (SGDT), Store Interrupt Descriptor Table (SIDT), and Store Local Descriptor Table (SLDT): These instructions violate the requirement 3B of hardware virtualization which states that instructions are sensitive if they read or change sensitive registers and/or memory locations such as a clock register and interrupt registers. SGDT and SLDT store global descriptor table and local descriptor table into the operand respectively. SGDT stores the contents of GDTR in 6-byte memory location. SLDT stores segment selector from LDTR in a 16 or 32-bit general-purpose register or memory location. SIDT on the other hand stores the contents of the IDTR in a 6-byte memory location. The Intel processor has only one of LDTR, GDTR and IDTR registers, so when the operating system tries to access two of the registers at the same time then the problem arises. Although these instructions do not protect the sensitive registers from reading by unprivileged software, the processor allows partial protection for these registers by only allowing tasks at CPL 0 to load the registers. This means that if a VM tries to write to one of these registers, a trap will be generated. The trap allows a VMM to produce the expected result for the VM. However, if an OS in a VM uses SGDT, SLDT, or SIDT to reference the contents of the IDTR, LDTR, or GDTR, the register contents that are applicable to the host OS or Type I VMM will be given. This could cause a problem if an operating system of a virtual machine (VMOS) tries to use these values for its own operations: it might see the state of a different VMOS executing within a VM running on the same VMM. Therefore, a Type I VMM or Type II VMM must provide each VM with its own virtual set of IDTR, LDTR, and GDTR registers.

Store Machine Status Word (SMSW): SMSW instruction stores the machine status word (bits 0 through 15 of control register 0) into a general purpose register or memory location. Bits 6 through 15 of CR0 are reserved bits and therefore cannot be modified. While bits 0 through 5, contain flags that control the operating mode of the processor. The following scenario better explains this instruction: A VMOS is running in real mode within the virtual environment created by a VMM running in protected mode. If the VMOS checked the MSW to see if it was in real mode, it would incorrectly see that the PE bit is set. This means that the machine is in protected mode. If the VMOS halts or shuts down if in protected mode, it will not be able to run successfully. This instruction is only provided for backwards compatibility with the Intel 286 processor. Programs written for the Intel 386 processor and later are supposed to use the MOV instruction to load and store control registers, which are privileged instructions. Therefore, SMSW could be removed and only systems requiring backward compatibility with the Intel 286 processor would be affected. Application software written for the Intel 286 and 8086 processors should be unaffected because the SMSW instruction is a system instruction that should not be used by application software.

Pop Flags off Stack (POPF) and Push Flags onto Stack (PUSHF): The PUSHF instruction pushes the lower 16 bits of the EFLAGS register onto the stack and decrements the stack pointer by 2. The POPF instruction pops a word from the top of the stack, increments the stack pointer by 2, and stores the value in the lower 16 bits of the EFLAGS register. Whilst POPF and PUSHF are associated with 16-bit operands PUSHFD and POPFD instructions are associated with 32-bit operands. Once the EFLAGS register is pushed on to the stack, contents of the EFLAGS register can be examined. Similar to the lower 16 bits of the CR0 register, the EFLAGS register contains flags that control the operating mode of the processor. Therefore, the PUSHF/PUSHFD instructions prevent the Intel processor from being virtualizable in the same way that the SMSW instruction prevents virtualization. In virtual- 8086 mode, the IOPL value must equal 3 in order to use the PUSHF instructions. Of the total 32 flags present in the EFLAGS register; fourteen of them are reserved while six of them are arithmetic flags. The POPF instruction allows values in the EFLAGS register to be modified. It varies based on the processor's current operating mode. When operating at CPL 0, all un-reserved flags in the EFLAGS register can be modified except the VM, VIP, and VIF flags. Similarly to use the POPF instructions in virtual-8086 mode, the value of IOPL must be equal to 3. The IOPL allows an OS to set the privilege level needed to perform I/O. In virtual- 8086 mode, some of the instructions: VM, RF, IOPL, VIP, and VIF flags are unaffected by the POPF instruction. In protected mode, there are several conditions based on privilege levels. First, if the CPL is greater than 0 and less than or equal to the IOPL, all flags can be modified except IOPL, VIP, VIF, and VM. The interrupt flag is altered when the CPL is at least as privileged as the IOPL. Finally, when a POPF/POPFD instruction is executed without enough privilege, an exception is not generated. However, the bits of the EFLAGS register are not changed. The POPF/POPFD instructions also prevent processor virtualization because they allow modification of certain bits in the EFLAGS register that control the operating mode and state of the processor.

Protection system instructions

Load Access Rights (LAR), Load Segment Limit (LSL), Verify Read (VERR) and Verify Write (VERW): Four instructions violate the rule in a similar manner. The LAR instruction loads access rights from a segment descriptor into a general purpose register. The LSL instruction loads the unscrambled segment from the segment descriptor into a general-purpose register. The VERR and VERW instructions verify whether a code or data segment is readable or writable from the current privilege level. The problem with all four of these instructions is that they all perform the check (CPL! DPL) OR (RPL! DPL) during their execution. These conditional checks are performed to ensure that the current privilege level and the requested privilege level are both greater than the descriptor privilege level. Normally VM does not execute at its highest privilege. VM executes at user or application level so that the traps caused by the privileged level can be handled by the VMM. However, most operating systems assume that they are operating at the highest privilege level and that they can access any segment descriptor. Therefore, if a VMOS running at CPL = 3 uses any of the four instructions listed above to examine a segment descriptor with a DPL <3, it is likely that the instruction will not execute properly.

Pop Word off Stack (POP): The reason that the POP instruction prevents virtualization is very similar to that mentioned in the preceding paragraph. The POP instruction loads a value from the top of the stack to a general-purpose register, memory location, or segment register. However, the POP instruction cannot be used to load the CS register since it contains the CPL. A value that is loaded into a segment register must be a valid segment selector. The reason that POP prevents virtualization is because it depends on the value of the CPL. If the SS register is being loaded and the segment selector's RPL and the segment descriptor's DPL are not equal to the CPL, a general protection exception is raised. Additionally, if the DS, ES, FS, or GS register is being loaded, the segment being pointed to, a general protection exception is raised due to a nonconforming code segment or data, and the RPL and CPL are greater than the DPL,. As in the previous case, if a VM's CPL is 3, these privilege level checks could cause unexpected results for a VMOS that assumes it is in CPL 0.

Push Word onto Stack (PUSH): The PUSH instruction also prevents virtualization because it references the protection system. The PUSH instruction allows a general-purpose register, memory location, or a segment register to be pushed onto the stack. This cannot be allowed because bits 0 and 1 of the CS and SS register contain the CPL of the current executing task. The following scenario demonstrates why these instructions could cause problems for virtualization. A process that thinks it is running in CPL 0 pushes the CS register to the stack. It then looks the contents of the CS register on the stack to check its CPL. Upon finding that its CPL is not 0, the process halts.

Procedure Call (CALL), Unconditional Jump (JMP), Interrupt (INT) and Return from Procedure (RET): The CALL instruction saves procedure linking information to the stack and branches to the procedure given in its destination operand. The different types of procedure calls: near calls, far calls to the same privilege level, far calls to a different privilege level, and task switches. Near calls and far calls to the same privilege-level don't cause any problems for virtualization. Task switches and far calls to different privilege levels which involve the CPL, DPL, and RPL are the ones which are a problem for virtualization. If a far call is executed to a different privilege level, the code segment for the procedure being accessed has to be accessed through a call gate. A task uses a different stack for every privilege level. So, when a far call is made to another privilege level, the processor switches to a stack corresponding to the new privilege level of the called procedure. A task switch operates in a manner similar to a call gate. The main difference is that the target operand of the call instruction specifies the segment selector of a task gate instead of a call gate. Both call gates and task gates have many privilege level checks that compare the CPL and RPL to DPLs. Since the VM normally operates at user level (CPL 3), these checks will not work correctly when a VMOS tries to access call gates or task gates at CPL 0. The discussion above on LAR, LSL, VERR, and VERW provides a specific example of how running a CPL 0 operating system as a CPL 3 task could cause a problem. The JMP instruction is similar to the CALL instruction in both the way that it executes and the reasons it prevents virtualization. The main difference between the CALL and the JMP instruction is that the JMP instruction transfers program control to another location in the instruction stream and does not record return information. The INT instruction is also similar to the CALL instruction. The INT n instruction performs a call to the interrupt or exception handler specified by n. INT n does the same thing as a far call made using the CALL instruction except that it pushes the EFLAGS register onto the stack before pushing the return address. The INT instruction references the protection system many times during its execution. The RET instruction has the opposite effect of the CALL instruction. It transfers program control to a return address that is placed on the stack (normally by a CALL instruction). The RET instruction can be used for three different types of returns: near, far, and inter privilege-level returns. Much like the CALL instruction, the inter-privilege-level far return examines the privilege levels and access rights of the code and stacks segments that are being returned to determine if the operation should be allowed. The DS, ES, FS, and GS segment registers are cleared by the RET instruction if they refer to segments that cannot be accessed by the new privilege level. Therefore, RET prevents virtualization because having a CPL of 3 (the VM's privilege level) could cause the DS, ES, FS, and GS registers to not be cleared when they should be. The IRET/IRETD instruction is similar to the RET instruction. The main difference is it returns control from an exception, interrupt handler, or nested task. It prevents virtualization in the same way that the RET instruction does.

Store Task Register (STR): The STR instruction stores the segment selector from the task register into a general purpose register or memory location. The segment selector that is stored with this instruction points to the task state segment of the currently executing task. This instruction prevents virtualization because it allows a task to examine its requested privilege level (RPL). Every segment selector contains an index into the GDT or LDT, a table indicator, and an RPL. The RPL is represented by bits 0 and 1 of the segment selector. The RPL is an override privilege level that is checked (along with the CPL) to determine if a task can access a segment. The RPL is used to ensure that privileged code cannot access a segment on behalf of an application unless the application also has the privilege to access the segment. This is a problem because a VM does not execute at the highest CPL or RPL (RPL = 0), but at RPL= 3. However, most operating systems assume that they are operating at the highest privilege level and that they can access any segment descriptor. Therefore, if a VM running at a CPL and RPL of 3 uses STR to store the contents of task register and then examine the information, it will find that it is not running at the privilege level at which it expects to run.

Move Byte or Word (MOV): Two variants of the MOVE instruction prevent Intel processor virtualization. These are the two MOV instructions that load and store control registers. The MOV opcode that stores segment registers allows all six of the segment registers to be stored to either a general purpose register or to a memory location. This is a problem because the CS and SS registers both contain the CPL in bits 0 and 1. Thus, a task that's stores CS or SS in general purpose register examines the contents of the register to find out that it is not operating at the expected privilege level. The MOV opcode that loads segment registers does offer some protection because it does not allow the CS register to be loaded at all. However, if the task tries to load the SS register, several privilege checks occur that become a problem when the VM is not operating at the privilege level at which a VMOS is expecting-typically 0.

References: Robin, John Scott, and Cynthia E. Irvine. "Analysis of the Intel Pentium's Ability to Support a Secure Virtual Machine Monitor."