summaryrefslogtreecommitdiff
path: root/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2014-03-26 19:21:20 +0000
committer <>2014-05-08 15:03:54 +0000
commitfb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch)
treec2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac
parent58ed4748338f9466599adfc8a9171280ed99e23f (diff)
downloadVirtualBox-master.tar.gz
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac')
-rw-r--r--src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac174
1 files changed, 142 insertions, 32 deletions
diff --git a/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac b/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac
index 7bd6e42f..70fde1ce 100644
--- a/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac
+++ b/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac
@@ -4,7 +4,7 @@
;
;
-; Copyright (C) 2006-2012 Oracle Corporation
+; Copyright (C) 2006-2013 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
@@ -82,11 +82,15 @@ BEGINPROC vmmR0ToRawMode
call NAME(vmmR0ToRawModeAsm)
%ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
- CPUM_FROM_CPUMCPU(edx)
; Restore blocked Local APIC NMI vectors
; Do this here to ensure the host CS is already restored
- mov ecx, [edx + CPUM.fApicDisVectors]
- mov edx, [edx + CPUM.pvApicBase]
+ mov ecx, [edx + CPUMCPU.fApicDisVectors]
+ test ecx, ecx
+ jz gth_apic_done
+ cmp byte [edx + CPUMCPU.fX2Apic], 1
+ je gth_x2apic
+
+ mov edx, [edx + CPUMCPU.pvApicBase]
shr ecx, 1
jnc gth_nolint0
and dword [edx + APIC_REG_LVT_LINT0], ~APIC_REG_LVT_MASKED
@@ -103,7 +107,47 @@ gth_nopc:
jnc gth_notherm
and dword [edx + APIC_REG_LVT_THMR], ~APIC_REG_LVT_MASKED
gth_notherm:
-%endif
+ jmp gth_apic_done
+
+gth_x2apic:
+ push eax ; save eax
+ push ebx ; save it for fApicDisVectors
+ push edx ; save edx just in case.
+ mov ebx, ecx ; ebx = fApicDisVectors, ecx free for MSR use
+ shr ebx, 1
+ jnc gth_x2_nolint0
+ mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_LINT0 >> 4)
+ rdmsr
+ and eax, ~APIC_REG_LVT_MASKED
+ wrmsr
+gth_x2_nolint0:
+ shr ebx, 1
+ jnc gth_x2_nolint1
+ mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_LINT1 >> 4)
+ rdmsr
+ and eax, ~APIC_REG_LVT_MASKED
+ wrmsr
+gth_x2_nolint1:
+ shr ebx, 1
+ jnc gth_x2_nopc
+ mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_PC >> 4)
+ rdmsr
+ and eax, ~APIC_REG_LVT_MASKED
+ wrmsr
+gth_x2_nopc:
+ shr ebx, 1
+ jnc gth_x2_notherm
+ mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_THMR >> 4)
+ rdmsr
+ and eax, ~APIC_REG_LVT_MASKED
+ wrmsr
+gth_x2_notherm:
+ pop edx
+ pop ebx
+ pop eax
+
+gth_apic_done:
+%endif ; VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
%ifdef VBOX_WITH_STATISTICS
;
@@ -163,14 +207,15 @@ BEGINPROC vmmR0ToRawModeAsm
pop dword [edx + CPUMCPU.Host.eflags]
; Block Local APIC NMI vectors
- xor edi, edi
-
%ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
- mov esi, edx
- CPUM_FROM_CPUMCPU(edx)
- mov ebx, [edx + CPUM.pvApicBase]
+ cmp byte [edx + CPUMCPU.pvApicBase], 1
+ je htg_x2apic
+
+ mov ebx, [edx + CPUMCPU.pvApicBase]
or ebx, ebx
- jz htg_noapic
+ jz htg_apic_done
+ xor edi, edi ; fApicDisVectors
+
mov eax, [ebx + APIC_REG_LVT_LINT0]
mov ecx, eax
and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
@@ -215,10 +260,63 @@ htg_nopc:
mov [ebx + APIC_REG_LVT_THMR], eax
mov eax, [ebx + APIC_REG_LVT_THMR] ; write completion
htg_notherm:
- mov [edx + CPUM.fApicDisVectors], edi
-htg_noapic:
- mov edx, esi
-%endif
+ mov [edx + CPUMCPU.fApicDisVectors], edi
+ jmp htg_apic_done
+
+htg_x2apic:
+ mov esi, edx ; Save edx.
+ xor edi, edi ; fApicDisVectors
+
+ mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_LINT0 >> 4)
+ rdmsr
+ mov ebx, eax
+ and ebx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+ cmp ebx, APIC_REG_LVT_MODE_NMI
+ jne htg_x2_nolint0
+ or edi, 0x01
+ or eax, APIC_REG_LVT_MASKED
+ wrmsr
+htg_x2_nolint0:
+ mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_LINT1 >> 4)
+ rdmsr
+ mov ebx, eax
+ and ebx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+ cmp ebx, APIC_REG_LVT_MODE_NMI
+ jne htg_x2_nolint1
+ or edi, 0x02
+ or eax, APIC_REG_LVT_MASKED
+ wrmsr
+htg_x2_nolint1:
+ mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_PC >> 4)
+ rdmsr
+ mov ebx, eax
+ and ebx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+ cmp ebx, APIC_REG_LVT_MODE_NMI
+ jne htg_x2_nopc
+ or edi, 0x04
+ or eax, APIC_REG_LVT_MASKED
+ wrmsr
+htg_x2_nopc:
+ mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_VERSION >> 4)
+ rdmsr
+ shr eax, 16
+ cmp al, 5
+ jb htg_x2_notherm
+ mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_THMR >> 4)
+ rdmsr
+ mov ebx, eax
+ and ebx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
+ cmp ebx, APIC_REG_LVT_MODE_NMI
+ jne htg_x2_notherm
+ or edi, 0x08
+ or eax, APIC_REG_LVT_MASKED
+ wrmsr
+htg_x2_notherm:
+ mov edx, esi ; Restore edx.
+ mov [edx + CPUMCPU.fApicDisVectors], edi
+
+htg_apic_done:
+%endif ; VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
FIXUP FIX_NO_SYSENTER_JMP, 0, htg_no_sysenter - NAME(Start) ; this will insert a jmp htg_no_sysenter if host doesn't use sysenter.
; save MSR_IA32_SYSENTER_CS register.
@@ -255,7 +353,7 @@ htg_no_syscall:
mov [edx + CPUMCPU.fUseFlags], esi
; debug registers.
- test esi, CPUM_USE_DEBUG_REGS | CPUM_USE_DEBUG_REGS_HOST
+ test esi, CPUM_USE_DEBUG_REGS_HYPER | CPUM_USE_DEBUG_REGS_HOST
jnz htg_debug_regs_save_dr7and6
htg_debug_regs_no:
@@ -406,7 +504,7 @@ GLOBALNAME FarJmpGCTarget
mov esi, [edx + CPUMCPU.fUseFlags]
; debug registers
- test esi, CPUM_USE_DEBUG_REGS
+ test esi, CPUM_USE_DEBUG_REGS_HYPER
jnz htg_debug_regs_guest
htg_debug_regs_guest_done:
DEBUG_CHAR('9')
@@ -514,6 +612,7 @@ htg_debug_regs_guest:
mov [edx + CPUMCPU.Host.dr2], ecx
mov eax, dr3
mov [edx + CPUMCPU.Host.dr3], eax
+ or dword [edx + CPUMCPU.fUseFlags], CPUM_USED_DEBUG_REGS_HOST
; load hyper DR0-7
mov ebx, [edx + CPUMCPU.Hyper.dr]
@@ -524,11 +623,11 @@ htg_debug_regs_guest:
mov dr2, eax
mov ebx, [edx + CPUMCPU.Hyper.dr + 8*3]
mov dr3, ebx
- ;mov eax, [edx + CPUMCPU.Hyper.dr + 8*6]
- mov ecx, 0ffff0ff0h
+ mov ecx, X86_DR6_INIT_VAL
mov dr6, ecx
mov eax, [edx + CPUMCPU.Hyper.dr + 8*7]
mov dr7, eax
+ or dword [edx + CPUMCPU.fUseFlags], CPUM_USED_DEBUG_REGS_HYPER
jmp htg_debug_regs_guest_done
ENDPROC vmmR0ToRawModeAsm
@@ -680,25 +779,31 @@ BEGINPROC vmmRCToHostAsm
; special registers which may change.
vmmRCToHostAsm_SaveNoGeneralRegs:
+ mov edi, eax ; save return code in EDI (careful with COM_DWORD_REG from here on!)
; str [edx + CPUMCPU.Hyper.tr] - double fault only, and it won't be right then either.
sldt [edx + CPUMCPU.Hyper.ldtr.Sel]
; No need to save CRx here. They are set dynamically according to Guest/Host requirements.
; FPU context is saved before restore of host saving (another) branch.
+ ; Disable debug regsiters if active so they cannot trigger while switching.
+ test dword [edx + CPUMCPU.fUseFlags], CPUM_USED_DEBUG_REGS_HYPER
+ jz .gth_disabled_dr7
+ mov eax, X86_DR7_INIT_VAL
+ mov dr7, eax
+.gth_disabled_dr7:
+
%ifdef VBOX_WITH_NMI
;
; Disarm K7 NMI.
;
mov esi, edx
- mov edi, eax
xor edx, edx
xor eax, eax
mov ecx, MSR_K7_EVNTSEL0
wrmsr
- mov eax, edi
mov edx, esi
%endif
@@ -706,7 +811,6 @@ vmmRCToHostAsm_SaveNoGeneralRegs:
;;
;; Load Intermediate memory context.
;;
- mov edi, eax ; save return code in EDI (careful with COM_DWORD_REG from here on!)
mov ecx, [edx + CPUMCPU.Host.cr3]
FIXUP SWITCHER_FIX_INTER_CR3_GC, 1
mov eax, 0ffffffffh
@@ -886,10 +990,9 @@ gth_fpu_no:
; restore debug registers (if modified) (esi must still be fUseFlags!)
; (must be done after cr4 reload because of the debug extension.)
- test esi, CPUM_USE_DEBUG_REGS | CPUM_USE_DEBUG_REGS_HOST
- jz short gth_debug_regs_no
- jmp gth_debug_regs_restore
-gth_debug_regs_no:
+ test esi, CPUM_USE_DEBUG_REGS_HYPER | CPUM_USE_DEBUG_REGS_HOST | CPUM_USED_DEBUG_REGS_HOST
+ jnz gth_debug_regs_restore
+gth_debug_regs_done:
; restore general registers.
mov eax, edi ; restore return code. eax = return code !!
@@ -910,10 +1013,15 @@ gth_debug_regs_no:
; edx and edi must be preserved.
gth_debug_regs_restore:
DEBUG_S_CHAR('d')
- xor eax, eax
- mov dr7, eax ; paranoia or not?
- test esi, CPUM_USE_DEBUG_REGS
- jz short gth_debug_regs_dr7
+ mov eax, dr7 ; Some DR7 paranoia first...
+ mov ecx, X86_DR7_INIT_VAL
+ cmp eax, ecx
+ je .gth_debug_skip_dr7_disabling
+ mov dr7, ecx
+.gth_debug_skip_dr7_disabling:
+ test esi, CPUM_USED_DEBUG_REGS_HOST
+ jz .gth_debug_regs_dr7
+
DEBUG_S_CHAR('r')
mov eax, [edx + CPUMCPU.Host.dr0]
mov dr0, eax
@@ -923,12 +1031,14 @@ gth_debug_regs_restore:
mov dr2, ecx
mov eax, [edx + CPUMCPU.Host.dr3]
mov dr3, eax
-gth_debug_regs_dr7:
+.gth_debug_regs_dr7:
mov ebx, [edx + CPUMCPU.Host.dr6]
mov dr6, ebx
mov ecx, [edx + CPUMCPU.Host.dr7]
mov dr7, ecx
- jmp gth_debug_regs_no
+
+ and dword [edx + CPUMCPU.fUseFlags], ~(CPUM_USED_DEBUG_REGS_HOST | CPUM_USED_DEBUG_REGS_HYPER)
+ jmp gth_debug_regs_done
ENDPROC vmmRCToHostAsm