diff options
| author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2014-03-26 19:21:20 +0000 |
|---|---|---|
| committer | <> | 2014-05-08 15:03:54 +0000 |
| commit | fb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch) | |
| tree | c2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac | |
| parent | 58ed4748338f9466599adfc8a9171280ed99e23f (diff) | |
| download | VirtualBox-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.mac | 174 |
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 |
