Skip to content

Commit

Permalink
x64/vmcs: Temporarily clear CR3[11:0] on promote (#584)
Browse files Browse the repository at this point in the history
As part of the PTI patches, Linux now uses PCIDs to reduce the
cost of context switches. The current PCID is given by CR3[11:0],
and if this is not zero when CR4.PCIDE is set on a write to CR4,
a #GP is raised.

The promotion bug described in #573 was due to Bareflank
restoring the guest CR3 (in which CR3[11:0] was nonzero), and
then restoring the guest CR4, which was setting CR4.PCIDE. The
resulting #GP was raised with nothing to handle it, leading to a
triple fault.

Now Bareflank writes a copy of the guest CR3 with bits 11-0
clear, then writes the guest's CR4. Once the CR4 is
written, the guest's original CR3 is restored.
  • Loading branch information
Connor Davis authored and rianquinn committed Jan 28, 2018
1 parent ee7b537 commit 6c1eefd
Showing 1 changed file with 21 additions and 1 deletion.
22 changes: 21 additions & 1 deletion bfvmm/src/hve/arch/intel_x64/vmcs/vmcs_promote.asm
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,34 @@ vmcs_promote:
vmread rdi, rsi
call _write_cr0 wrt ..plt

;
; Save the guest's cr3
;

mov rsi, VMCS_GUEST_CR3
vmread rdi, rsi
call _write_cr3 wrt ..plt
push rdi

;
; Clear cr3[11:0] and then update cr4. This ensures that
; if cr4.pcide is changing to 1, we avoid a #GP if the
; guest's original cr3[11:0] != 0 (see section 4.10.1).
;

mov rax, 0xFFFFFFFFFFFFF000
and rdi, rax
call _write_cr3 wrt ..plt
mov rsi, VMCS_GUEST_CR4
vmread rdi, rsi
call _write_cr4 wrt ..plt

;
; Restore the guest's actual cr3
;

pop rdi
call _write_cr3 wrt ..plt

mov rsi, VMCS_GUEST_DR7
vmread rdi, rsi
call _write_dr7 wrt ..plt
Expand Down

0 comments on commit 6c1eefd

Please sign in to comment.