VirtualBox

Changeset 13561

Show
Ignore:
Timestamp:
10/24/08 18:27:26 (3 months ago)
Author:
vboxsync
Message:

Emulate (lock) cmpxchg8b in ring 0 & 3. Added testcase for instruction emulation.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/include/VBox/em.h

    r13375 r13561  
    157157VMMDECL(uint32_t)   EMEmulateCmpXchg(void *pvParam1, uint64_t *pu32Param2, uint64_t u32Param3, size_t cbSize); 
    158158VMMDECL(uint32_t)   EMEmulateLockCmpXchg(void *pvParam1, uint64_t *pu64Param2, uint64_t u64Param3, size_t cbSize); 
    159 VMMDECL(uint32_t)   EMEmulateCmpXchg8b32(RTHCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX); 
    160 VMMDECL(uint32_t)   EMEmulateLockCmpXchg8b(RTHCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX); 
     159VMMDECL(uint32_t)   EMEmulateCmpXchg8b(void *pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX); 
     160VMMDECL(uint32_t)   EMEmulateLockCmpXchg8b(void *pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX); 
    161161/** @} */ 
    162162 
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r13532 r13561  
    14821482 
    14831483    /* Update guest's eflags and finish. */ 
    1484     pRegFrame->eflags.u32 = (pRegFrame->eflags.u32 & ~(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)) 
     1484    pRegFrame->eflags.u32 =   (pRegFrame->eflags.u32 & ~(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)) 
    14851485                            | (eflags                &  (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)); 
    14861486 
    14871487    *pcbSize = param2.size; 
     1488    return VINF_SUCCESS; 
     1489} 
     1490 
     1491/* 
     1492 * [LOCK] CMPXCHG8B emulation. 
     1493 */ 
     1494static int emInterpretCmpXchg8b(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize) 
     1495{ 
     1496    Assert(pCpu->mode != CPUMODE_64BIT);    /** @todo check */ 
     1497    OP_PARAMVAL param1; 
     1498 
     1499    /* Source to make DISQueryParamVal read the register value - ugly hack */ 
     1500    int rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param1, &param1, PARAM_SOURCE); 
     1501    if(VBOX_FAILURE(rc)) 
     1502        return VERR_EM_INTERPRETER; 
     1503 
     1504    RTGCPTR  GCPtrPar1; 
     1505    void    *pvParam1; 
     1506    uint64_t eflags; 
     1507 
     1508    AssertReturn(pCpu->param1.size == 8, VERR_EM_INTERPRETER); 
     1509    switch(param1.type) 
     1510    { 
     1511    case PARMTYPE_ADDRESS: 
     1512        GCPtrPar1 = param1.val.val64; 
     1513        GCPtrPar1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, GCPtrPar1); 
     1514 
     1515        rc = PGMPhysGCPtr2HCPtr(pVM, GCPtrPar1, &pvParam1); 
     1516        if (VBOX_FAILURE(rc)) 
     1517        { 
     1518            AssertRC(rc); 
     1519            return VERR_EM_INTERPRETER; 
     1520        } 
     1521        break; 
     1522 
     1523    default: 
     1524        return VERR_EM_INTERPRETER; 
     1525    } 
     1526 
     1527    LogFlow(("%s %VGv=%08x eax=%08x\n", emGetMnemonic(pCpu), pvParam1, pRegFrame->eax)); 
     1528 
     1529    if (pCpu->prefix & PREFIX_LOCK) 
     1530        eflags = EMEmulateLockCmpXchg8b(pvParam1, &pRegFrame->eax, &pRegFrame->edx, pRegFrame->ebx, pRegFrame->ecx); 
     1531    else 
     1532        eflags = EMEmulateCmpXchg8b(pvParam1, &pRegFrame->eax, &pRegFrame->edx, pRegFrame->ebx, pRegFrame->ecx); 
     1533 
     1534    LogFlow(("%s %VGv=%08x eax=%08x ZF=%d\n", emGetMnemonic(pCpu), pvParam1, pRegFrame->eax, !!(eflags & X86_EFL_ZF))); 
     1535 
     1536    /* Update guest's eflags and finish; note that *only* ZF is affected. */ 
     1537    pRegFrame->eflags.u32 =   (pRegFrame->eflags.u32 & ~(X86_EFL_ZF)) 
     1538                            | (eflags                &  (X86_EFL_ZF)); 
     1539 
     1540    *pcbSize = 8; 
    14881541    return VINF_SUCCESS; 
    14891542} 
     
    28332886             && pCpu->pCurInstr->opcode != OP_OR 
    28342887             && pCpu->pCurInstr->opcode != OP_BTR 
     2888             && pCpu->pCurInstr->opcode != OP_CMPXCHG 
     2889             && pCpu->pCurInstr->opcode != OP_CMPXCHG8B 
    28352890            ) 
    28362891       ) 
     
    29302985#ifdef IN_GC 
    29312986        INTERPRET_CASE(OP_STI,Sti); 
     2987        INTERPRET_CASE(OP_XADD, XAdd); 
     2988#endif 
    29322989        INTERPRET_CASE(OP_CMPXCHG8B, CmpXchg8b); 
    2933         INTERPRET_CASE(OP_XADD, XAdd); 
    2934 #endif 
    29352990        INTERPRET_CASE(OP_HLT,Hlt); 
    29362991        INTERPRET_CASE(OP_IRET,Iret); 
     
    29382993#ifdef VBOX_WITH_STATISTICS 
    29392994#ifndef IN_GC 
    2940         INTERPRET_STAT_CASE(OP_CMPXCHG8B, CmpXchg8b); 
    29412995        INTERPRET_STAT_CASE(OP_XADD, XAdd); 
    29422996#endif 
  • trunk/src/VBox/VMM/VMMAll/EMAllA.asm

    r12989 r13561  
    10261026 
    10271027 
    1028 %if 0 
    1029 ;; not tested!! 
    1030  
    10311028;; 
    10321029; Emulate LOCK CMPXCHG8B instruction, CDECL calling conv. 
    1033 ; VMMDECL(uint32_t) EMEmulateLockCmpXchg8b(RTHCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX); 
    1034 ; 
    1035 ; @returns EFLAGS after the operation, only arithmetic flags are valid. 
    1036 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to first parameter 
    1037 ; @param    [esp + 08h]    Param 2 - Address of the eax register 
    1038 ; @param    [esp + 0ch]    Param 3 - Address of the edx register 
    1039 ; @param    [esp + 10h]    Param 4 - EBX 
    1040 ; @param    [esp + 14h]  Param 5 - ECX 
     1030; VMMDECL(uint32_t) EMEmulateLockCmpXchg8b(void *pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX); 
     1031; 
     1032; @returns EFLAGS after the operation, only the ZF flag is valid. 
     1033; @param    [esp + 04h]  gcc:rdi  msc:rcx       Param 1 - First parameter - pointer to first parameter 
     1034; @param    [esp + 08h]  gcc:rsi  msc:rdx       Param 2 - Address of the eax register 
     1035; @param    [esp + 0ch]  gcc:rdx  msc:r8        Param 3 - Address of the edx register 
     1036; @param    [esp + 10h]  gcc:rcx  msc:r9        Param 4 - EBX 
     1037; @param    [esp + 14h]  gcc:r8   msc:[rsp + 8] Param 5 - ECX 
    10411038; @uses     eax, ecx, edx 
    10421039; 
    10431040align 16 
    10441041BEGINPROC   EMEmulateLockCmpXchg8b 
    1045     push    ebp 
    1046     push    ebx 
     1042    push    xBP 
     1043    push    xBX 
     1044%ifdef RT_ARCH_AMD64 
     1045 %ifdef RT_OS_WINDOWS 
     1046    mov     rbp, rcx 
     1047    mov     r10, rdx 
     1048    mov     eax, dword [rdx] 
     1049    mov     edx, dword [r8] 
     1050    mov     rbx, r9 
     1051    mov     ecx, [rsp + 28h + 16] 
     1052 %else 
     1053    mov     rbp, rdi 
     1054    mov     r10, rdx 
     1055    mov     eax, dword [rsi] 
     1056    mov     edx, dword [rdx] 
     1057    mov     rbx, rcx 
     1058    mov     rcx, r8 
     1059 %endif 
     1060%else 
    10471061    mov     ebp, [esp + 04h + 8]        ; ebp = first parameter 
    10481062    mov     eax, [esp + 08h + 8]        ; &EAX 
     
    10521066    mov     ebx, [esp + 10h + 8]        ; EBX 
    10531067    mov     ecx, [esp + 14h + 8]        ; ECX 
    1054  
    1055     lock cmpxchg8b qword [ebp]          ; do CMPXCHG8B 
     1068%endif 
     1069 
     1070    lock    cmpxchg8b qword [xBP]          ; do CMPXCHG8B 
     1071%ifdef RT_ARCH_AMD64 
     1072 %ifdef RT_OS_WINDOWS 
     1073    mov     dword [r10], eax 
     1074    mov     dword [r8], edx 
     1075 %else 
     1076    mov     dword [rsi], eax 
     1077    mov     dword [r10], edx 
     1078 %endif 
     1079%else 
    10561080    mov     ebx, dword [esp + 08h + 8] 
    10571081    mov     dword [ebx], eax 
    10581082    mov     ebx, dword [esp + 0ch + 8] 
    10591083    mov     dword [ebx], edx 
    1060  
    1061     ; collect flags and return. 
    1062     pushf 
    1063     pop     eax 
    1064  
    1065     pop     ebx 
    1066     pop     ebp 
    1067     retn 
    1068  
     1084%endif 
     1085    ; collect flags and return. 
     1086    pushf 
     1087    pop     MY_RET_REG 
     1088 
     1089    pop     xBX 
     1090    pop     xBP 
     1091    retn 
    10691092ENDPROC     EMEmulateLockCmpXchg8b 
    10701093 
    10711094;; 
    10721095; Emulate CMPXCHG8B instruction, CDECL calling conv. 
    1073 ; VMMDECL(uint32_t) EMEmulateCmpXchg8b(RTHCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX); 
    1074 ; 
    1075 ; @returns EFLAGS after the operation, only arithmetic flags are valid. 
    1076 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to first parameter 
    1077 ; @param    [esp + 08h]    Param 2 - Address of the eax register 
    1078 ; @param    [esp + 0ch]    Param 3 - Address of the edx register 
    1079 ; @param    [esp + 10h]    Param 4 - EBX 
    1080 ; @param    [esp + 14h]  Param 5 - ECX 
     1096; VMMDECL(uint32_t) EMEmulateCmpXchg8b(void *pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX); 
     1097; 
     1098; @returns EFLAGS after the operation, only arithmetic flags are valid. 
     1099; @param    [esp + 04h]  gcc:rdi  msc:rcx       Param 1 - First parameter - pointer to first parameter 
     1100; @param    [esp + 08h]  gcc:rsi  msc:rdx       Param 2 - Address of the eax register 
     1101; @param    [esp + 0ch]  gcc:rdx  msc:r8        Param 3 - Address of the edx register 
     1102; @param    [esp + 10h]  gcc:rcx  msc:r9        Param 4 - EBX 
     1103; @param    [esp + 14h]  gcc:r8   msc:[rsp + 8] Param 5 - ECX 
    10811104; @uses     eax, ecx, edx 
    10821105; 
    10831106align 16 
    10841107BEGINPROC   EMEmulateCmpXchg8b 
    1085     push    ebp 
    1086     push    ebx 
     1108    push    xBP 
     1109    push    xBX 
     1110%ifdef RT_ARCH_AMD64 
     1111 %ifdef RT_OS_WINDOWS 
     1112    mov     rbp, rcx 
     1113    mov     r10, rdx 
     1114    mov     eax, dword [rdx] 
     1115    mov     edx, dword [r8] 
     1116    mov     rbx, r9 
     1117    mov     ecx, [rsp + 28h + 16] 
     1118 %else 
     1119    mov     rbp, rdi 
     1120    mov     r10, rdx 
     1121    mov     eax, dword [rsi] 
     1122    mov     edx, dword [rdx] 
     1123    mov     rbx, rcx 
     1124    mov     rcx, r8 
     1125 %endif 
     1126%else 
    10871127    mov     ebp, [esp + 04h + 8]        ; ebp = first parameter 
    10881128    mov     eax, [esp + 08h + 8]        ; &EAX 
     
    10921132    mov     ebx, [esp + 10h + 8]        ; EBX 
    10931133    mov     ecx, [esp + 14h + 8]        ; ECX 
    1094  
    1095     cmpxchg8b qword [ebp]               ; do CMPXCHG8B 
     1134%endif 
     1135 
     1136    cmpxchg8b qword [xBP]          ; do CMPXCHG8B 
     1137     
     1138%ifdef RT_ARCH_AMD64 
     1139 %ifdef RT_OS_WINDOWS 
     1140    mov     dword [r10], eax 
     1141    mov     dword [r8], edx 
     1142 %else 
     1143    mov     dword [rsi], eax 
     1144    mov     dword [r10], edx 
     1145 %endif 
     1146%else 
    10961147    mov     ebx, dword [esp + 08h + 8] 
    10971148    mov     dword [ebx], eax 
    10981149    mov     ebx, dword [esp + 0ch + 8] 
    10991150    mov     dword [ebx], edx 
    1100  
    1101     ; collect flags and return. 
    1102     pushf 
    1103     pop     eax 
    1104  
    1105     pop     ebx 
    1106     pop     ebp 
     1151%endif 
     1152 
     1153    ; collect flags and return. 
     1154    pushf 
     1155    pop     MY_RET_REG 
     1156 
     1157    pop     xBX 
     1158    pop     xBP 
    11071159    retn 
    11081160ENDPROC     EMEmulateCmpXchg8b 
    11091161 
    1110 %endif 
  • trunk/src/VBox/VMM/testcase/Makefile.kmk

    r13375 r13561  
    2626# Target lists. 
    2727# 
    28 PROGRAMS   += tstVMStructSize tstVMStructGC tstAsmStructs tstAsmStructsGC tstVMM tstVMM-HwAccm tstGlobalConfig 
     28PROGRAMS   += tstVMStructSize tstVMStructGC tstAsmStructs tstAsmStructsGC tstVMM tstVMM-HwAccm tstGlobalConfig tstInstrEmul 
    2929ifneq ($(KBUILD_TARGET),win) 
    3030PROGRAMS   += tstVMMFork 
     
    5454  OTHERS += \ 
    5555        $(VBOX_VMM_TESTCASE_OUT_DIR)/tstAsmStructs.run \ 
    56         $(VBOX_VMM_TESTCASE_OUT_DIR)/tstVMStructSize.run 
     56        $(VBOX_VMM_TESTCASE_OUT_DIR)/tstVMStructSize.run \ 
     57        $(VBOX_VMM_TESTCASE_OUT_DIR)/tstInstrEmul.run 
    5758 endif 
    5859endif 
     
    6162TESTING += \ 
    6263        $(VBOX_VMM_TESTCASE_OUT_DIR)/tstAsmStructs.run \ 
    63         $(VBOX_VMM_TESTCASE_OUT_DIR)/tstVMStructSize.run 
     64        $(VBOX_VMM_TESTCASE_OUT_DIR)/tstVMStructSize.run \ 
     65        $(VBOX_VMM_TESTCASE_OUT_DIR)/tstInstrEmul.run 
    6466 
    6567OTHER_CLEAN += \ 
    6668        $(VBOX_VMM_TESTCASE_OUT_DIR)/tstAsmStructs.run \ 
    6769        $(VBOX_VMM_TESTCASE_OUT_DIR)/tstVMStructSize.run \ 
     70        $(VBOX_VMM_TESTCASE_OUT_DIR)/tstInstrEmul.run \ 
    6871        $(VBOX_VMM_TESTCASE_OUT_DIR)/tstAsmStructs.h \ 
    6972        $(VBOX_VMM_TESTCASE_OUT_DIR)/tstAsmStructsAsm.o \ 
     
    135138tstSSM_SOURCES          = tstSSM.cpp 
    136139tstSSM_LIBS             = $(LIB_VMM) $(LIB_REM) $(LIB_RUNTIME) 
     140 
     141tstInstrEmul_TEMPLATE   = VBOXR3TSTEXE 
     142tstInstrEmul_SOURCES    = tstInstrEmul.cpp \ 
     143                          ../VMMAll/EMAllA.asm 
     144 
     145tstInstrEmul_LIBS       = $(LIB_VMM) $(LIB_REM) $(LIB_RUNTIME) 
    137146 
    138147tstCFGM_TEMPLATE        = VBOXR3TSTEXE 
     
    321330run-struct-tests: $(VBOX_VMM_TESTCASE_OUT_DIR)/tstAsmStructs.run $(VBOX_VMM_TESTCASE_OUT_DIR)/tstVMStructSize.run 
    322331 
     332 
     333# 
     334# Run rule for tstInstrEmul. 
     335# 
     336$(VBOX_VMM_TESTCASE_OUT_DIR)/tstInstrEmul.run: $$(INSTARGET_tstInstrEmul) 
     337        $(QUIET)$(RM) -f $@ 
     338        $(INSTARGET_tstInstrEmul) 
     339        $(QUIET)$(APPEND) "$@" "done" 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy