VirtualBox

Changeset 105125 in vbox


Ignore:
Timestamp:
Jul 3, 2024 8:07:48 PM (8 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
163755
Message:

VMM/IEM,ValKit/bs3-cpu-weird-1: Fixed popf mistreatment of the new TF bit generally and the calculation of the VIF flags in VME+v86 mode; extended bs3-cpu-weird-1 with popf testcase. bugref:10715

Location:
trunk/src/VBox
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp

    r105098 r105125  
    819819                return rcStrict;
    820820
    821             /** @todo Is the popf VME \#GP(0) delivered after updating RSP+RIP
    822              *        or before? */
    823             if (    (   (u16Value & X86_EFL_IF)
    824                      && (fEflOld  & X86_EFL_VIP))
    825                 ||  (u16Value & X86_EFL_TF) )
     821            if (   (   (u16Value & X86_EFL_IF)
     822                    && (fEflOld  & X86_EFL_VIP))
     823                || (u16Value & X86_EFL_TF) )
    826824                return iemRaiseGeneralProtectionFault0(pVCpu);
    827825
    828             fEflNew = u16Value | (fEflOld & UINT32_C(0xffff0000) & ~X86_EFL_VIF);
    829             fEflNew |= (fEflNew & X86_EFL_IF) << (19 - 9);
    830             fEflNew &=   X86_EFL_POPF_BITS & ~(X86_EFL_IOPL | X86_EFL_IF);
    831             fEflNew |= ~(X86_EFL_POPF_BITS & ~(X86_EFL_IOPL | X86_EFL_IF)) & fEflOld;
     826            fEflNew = X86_EFL_RA1_MASK
     827                    | (u16Value & ~(X86_EFL_IF | X86_EFL_IOPL | X86_EFL_RAZ_MASK))
     828                    | (fEflOld & (UINT32_C(0xffff0000) | X86_EFL_IF | X86_EFL_IOPL) & ~(X86_EFL_VIF | X86_EFL_RF))
     829                    | ((uint32_t)(u16Value & X86_EFL_IF) << (X86_EFL_VIF_BIT - X86_EFL_IF_BIT));
    832830
    833831            pVCpu->cpum.GstCtx.rsp = TmpRsp.u;
  • trunk/src/VBox/VMM/include/IEMInline.h

    r105072 r105125  
    20982098 *              Stacks}
    20992099 */
     2100template<uint32_t const a_fTF = X86_EFL_TF>
    21002101static VBOXSTRICTRC iemFinishInstructionWithFlagsSet(PVMCPUCC pVCpu, int rcNormal) RT_NOEXCEPT
    21012102{
     
    21032104     * Normally we're just here to clear RF and/or interrupt shadow bits.
    21042105     */
    2105     if (RT_LIKELY((pVCpu->cpum.GstCtx.eflags.uBoth & (X86_EFL_TF | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) == 0))
     2106    if (RT_LIKELY((pVCpu->cpum.GstCtx.eflags.uBoth & (a_fTF | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) == 0))
    21062107        pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW);
    21072108    else
     
    21112112         */
    21122113        VBOXSTRICTRC rcStrict;
    2113         if (pVCpu->cpum.GstCtx.eflags.uBoth & (X86_EFL_TF | CPUMCTX_DBG_HIT_DRX_MASK))
     2114        if (pVCpu->cpum.GstCtx.eflags.uBoth & (a_fTF | CPUMCTX_DBG_HIT_DRX_MASK))
    21142115        {
    21152116            IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_DR6);
    21162117            pVCpu->cpum.GstCtx.dr[6] &= ~X86_DR6_B_MASK;
    2117             if (pVCpu->cpum.GstCtx.eflags.uBoth & X86_EFL_TF)
     2118            if (pVCpu->cpum.GstCtx.eflags.uBoth & a_fTF)
    21182119                pVCpu->cpum.GstCtx.dr[6] |= X86_DR6_BS;
    21192120            pVCpu->cpum.GstCtx.dr[6] |= (pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_HIT_DRX_MASK_NONSILENT)
     
    28622863    iemRegAddToRip(pVCpu, cbInstr);
    28632864    if (!(fEflOld & X86_EFL_TF))
    2864         return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
     2865    {
     2866        /* Specialized iemRegFinishClearingRF edition here that doesn't check X86_EFL_TF. */
     2867        AssertCompile(CPUMCTX_INHIBIT_SHADOW < UINT32_MAX);
     2868        if (RT_LIKELY(!(  pVCpu->cpum.GstCtx.eflags.uBoth
     2869                        & (X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) ))
     2870            return VINF_SUCCESS;
     2871        return iemFinishInstructionWithFlagsSet<0 /*a_fTF*/>(pVCpu, VINF_SUCCESS); /* TF=0, so ignore it.  */
     2872    }
    28652873    return iemFinishInstructionWithTfSet(pVCpu);
    28662874}
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1-template.mac

    r105094 r105125  
    348348 %endif
    349349
     350
     351;
     352; popf
     353;
     354BS3_PROC_BEGIN_CMN bs3CpuWeird1_Popf_Nop_Ud2, BS3_PBC_NEAR
     355        popf
     356        nop
     357.ud2_again:
     358        ud2
     359        jmp     .ud2_again
     360AssertCompile(.ud2_again - BS3_CMN_NM(bs3CpuWeird1_Popf_Nop_Ud2) == 2)
     361BS3_PROC_END_CMN   bs3CpuWeird1_Popf_Nop_Ud2
     362
     363;
     364; popf
     365;
     366BS3_PROC_BEGIN_CMN bs3CpuWeird1_Popf_opsize_Nop_Ud2, BS3_PBC_NEAR
     367        db      066h
     368        popf
     369        nop
     370.ud2_again:
     371        ud2
     372        jmp     .ud2_again
     373AssertCompile(.ud2_again - BS3_CMN_NM(bs3CpuWeird1_Popf_opsize_Nop_Ud2) == 3)
     374BS3_PROC_END_CMN   bs3CpuWeird1_Popf_opsize_Nop_Ud2
     375
     376
    350377%endif ; BS3_INSTANTIATING_CMN
    351378
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1-x0.c

    r105094 r105125  
    6262    extern FNBS3FAR a_Name##_c64, a_Name##_##a_Label##_c64
    6363
     64#define PROTO_ALL(a_Template) \
     65    extern FNBS3FAR a_Template ## _c16, \
     66                    a_Template ## _c32, \
     67                    a_Template ## _c64
     68
     69#define PROTO_ALL_WITH_END(a_Template) \
     70    extern FNBS3FAR a_Template ## _c16, a_Template ## _c16_EndProc, \
     71                    a_Template ## _c32, a_Template ## _c32_EndProc, \
     72                    a_Template ## _c64, a_Template ## _c64_EndProc
     73
    6474
    6575/*********************************************************************************************************************************
     
    145155                      uDr6, pTrapCtx->uHandlerCs, pTrapCtx->uHandlerSs, pTrapCtx->uHandlerRsp,
    146156                      pTrapCtx->fHandlerRfl, pTrapCtx->cbIretFrame);
    147 #if 1
     157#if 0
    148158        Bs3TestPrintf("Halting in CompareIntCtx: bXcpt=%#x\n", bXcpt);
    149159        ASMHalt();
     
    653663*   IP / EIP  Wrapping                                                                                                           *
    654664*********************************************************************************************************************************/
    655 #define PROTO_ALL(a_Template) \
    656     FNBS3FAR a_Template ## _c16, a_Template ## _c16_EndProc, \
    657              a_Template ## _c32, a_Template ## _c32_EndProc, \
    658              a_Template ## _c64, a_Template ## _c64_EndProc
    659 PROTO_ALL(bs3CpuWeird1_PcWrapBenign1);
    660 PROTO_ALL(bs3CpuWeird1_PcWrapBenign2);
    661 PROTO_ALL(bs3CpuWeird1_PcWrapCpuId);
    662 PROTO_ALL(bs3CpuWeird1_PcWrapIn80);
    663 PROTO_ALL(bs3CpuWeird1_PcWrapOut80);
    664 PROTO_ALL(bs3CpuWeird1_PcWrapSmsw);
    665 PROTO_ALL(bs3CpuWeird1_PcWrapRdCr0);
    666 PROTO_ALL(bs3CpuWeird1_PcWrapRdDr0);
    667 PROTO_ALL(bs3CpuWeird1_PcWrapWrDr0);
    668 #undef PROTO_ALL
     665PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapBenign1);
     666PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapBenign2);
     667PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapCpuId);
     668PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapIn80);
     669PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapOut80);
     670PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapSmsw);
     671PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapRdCr0);
     672PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapRdDr0);
     673PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapWrDr0);
    669674
    670675typedef enum { kPcWrapSetup_None, kPcWrapSetup_ZeroRax } PCWRAPSETUP;
     
    12071212*   PUSH / POP                                                                                                                   *
    12081213*********************************************************************************************************************************/
    1209 #define PROTO_ALL(a_Template) \
    1210     FNBS3FAR a_Template ## _c16, \
    1211              a_Template ## _c32, \
    1212              a_Template ## _c64
    12131214PROTO_ALL(bs3CpuWeird1_Push_xSP_Ud2);
    12141215PROTO_ALL(bs3CpuWeird1_Push_opsize_xSP_Ud2);
     
    12171218PROTO_ALL(bs3CpuWeird1_Pop_opsize_xSP_Ud2);
    12181219PROTO_ALL(bs3CpuWeird1_Pop_opsize_xBX_Ud2);
    1219 #undef PROTO_ALL
    12201220
    12211221
     
    15041504*   PUSH SREG / POP SREG                                                                                                         *
    15051505*********************************************************************************************************************************/
    1506 #define PROTO_ALL(a_Template) \
    1507     FNBS3FAR a_Template ## _c16, \
    1508              a_Template ## _c32, \
    1509              a_Template ## _c64
    15101506PROTO_ALL(bs3CpuWeird1_Push_cs_Ud2);
    15111507PROTO_ALL(bs3CpuWeird1_Push_ss_Ud2);
     
    15301526PROTO_ALL(bs3CpuWeird1_Pop_opsize_fs_Ud2);
    15311527PROTO_ALL(bs3CpuWeird1_Pop_opsize_gs_Ud2);
    1532 #undef PROTO_ALL
    15331528
    15341529
     
    18361831                        Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    18371832                        if (bs3CpuWeird1_ComparePushPop(&TrapCtx, &TrapExpect))
    1838                         {
    1839                             ASMHalt();
    18401833                            break;
    1841                         }
    18421834
    18431835                        if (*PtrStack2.pu64 != u64ExpectPushed.u)
     
    18651857                        Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    18661858                        if (bs3CpuWeird1_ComparePushPop(&TrapCtx, &TrapExpect))
    1867                         {
    1868                             ASMHalt();
    18691859                            break;
    1870                         }
    18711860                    }
    18721861#endif
     
    18901879}
    18911880
     1881
     1882
     1883/*********************************************************************************************************************************
     1884*   POPF                                                                                                                         *
     1885*********************************************************************************************************************************/
     1886
     1887/**
     1888 * Compares popf result.
     1889 */
     1890static uint8_t bs3CpuWeird1_ComparePopf(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pCtxExpect, uint8_t bXcpt)
     1891{
     1892    uint16_t const cErrorsBefore = Bs3TestSubErrorCount();
     1893    CHECK_MEMBER("bXcpt",       "%#04x",    pTrapCtx->bXcpt,        bXcpt);
     1894    CHECK_MEMBER("bErrCd",      "%#06RX64", pTrapCtx->uErrCd,       0);
     1895    Bs3TestCheckRegCtxEx(&pTrapCtx->Ctx, pCtxExpect, 0 /*cbPcAdjust*/, 0 /*cbSpAdjust*/, 0 /*fExtraEfl*/,
     1896                         g_pszTestMode, g_usBs3TestStep);
     1897    if (Bs3TestSubErrorCount() != cErrorsBefore)
     1898    {
     1899        Bs3TrapPrintFrame(pTrapCtx);
     1900#if 0
     1901        Bs3TestPrintf("Halting in ComparePopf: bXcpt=%#x\n", pTrapCtx->bXcpt);
     1902        ASMHalt();
     1903#endif
     1904        return 1;
     1905    }
     1906    return 0;
     1907}
     1908
     1909PROTO_ALL(bs3CpuWeird1_Popf_Nop_Ud2);
     1910PROTO_ALL(bs3CpuWeird1_Popf_opsize_Nop_Ud2);
     1911
     1912BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuWeird1_Popf)(uint8_t bTestMode)
     1913{
     1914    static struct
     1915    {
     1916        FPFNBS3FAR  pfnStart;
     1917        uint8_t     cBits;
     1918        int8_t      cbAdjSp;    /**< The SP adjustment value. */
     1919        uint8_t     offNop;     /**< The NOP offset into the code. */
     1920        uint8_t     offUd2;     /**< The UD2 offset into the code. */
     1921    } const s_aTests[] =
     1922    {
     1923        { bs3CpuWeird1_Popf_Nop_Ud2_c16,        16, 2, 1, 2 },
     1924        { bs3CpuWeird1_Popf_opsize_Nop_Ud2_c16, 16, 4, 2, 3 },
     1925
     1926        { bs3CpuWeird1_Popf_Nop_Ud2_c32,        32, 4, 1, 2 },
     1927        { bs3CpuWeird1_Popf_opsize_Nop_Ud2_c32, 32, 2, 2, 3 },
     1928
     1929        { bs3CpuWeird1_Popf_Nop_Ud2_c64,        64, 8, 1, 2 },
     1930        { bs3CpuWeird1_Popf_opsize_Nop_Ud2_c64, 64, 2, 2, 3 },
     1931    };
     1932
     1933    BS3REGCTX               Ctx;
     1934    BS3REGCTX               CtxExpect;
     1935    BS3TRAPFRAME            TrapCtx;
     1936    BS3PTRUNION             PtrStack;
     1937    uint8_t const           cTestBits = BS3_MODE_IS_16BIT_CODE(bTestMode) ? 16 : BS3_MODE_IS_32BIT_CODE(bTestMode) ? 32 : 64;
     1938    uint32_t const          fEflCpu   = X86_EFL_1 | X86_EFL_STATUS_BITS | X86_EFL_DF | X86_EFL_IF | X86_EFL_TF
     1939                                      | ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80286 ? X86_EFL_IOPL | X86_EFL_NT : 0)
     1940                                      | ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386 ? X86_EFL_RF | X86_EFL_VM : 0)
     1941                                      | ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80486 ? X86_EFL_AC | X86_EFL_VIP | X86_EFL_VIF : 0)
     1942                                      | (g_uBs3CpuDetected & BS3CPU_F_CPUID                     ? X86_EFL_ID : 0);
     1943    uint32_t const          fEflClear = X86_EFL_1;
     1944    uint32_t const          fEflSet   = X86_EFL_1 | X86_EFL_STATUS_BITS
     1945                                      | X86_EFL_DF /* safe? */
     1946                                      | X86_EFL_IF /* safe? */
     1947                                      | ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386 ? X86_EFL_RF : 0)
     1948                                      | ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80486 ? X86_EFL_AC | X86_EFL_VIP : 0)
     1949                                      | (g_uBs3CpuDetected & BS3CPU_F_CPUID                     ? X86_EFL_ID : 0);
     1950    uint32_t const          fEflKeep  = X86_EFL_VM;
     1951    uint32_t const          fXcptRf   = BS3_MODE_IS_16BIT_SYS(bTestMode) ? 0 : X86_EFL_RF;
     1952    bool const              fVme      = BS3_MODE_IS_V86(bTestMode)
     1953                                     && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80486
     1954                                     && (Bs3RegGetCr4() & X86_CR4_VME); /* Can't use Ctx.cr4 here, it's always zero. */
     1955    unsigned                uRing;
     1956
     1957    //Bs3TestPrintf("g_uBs3CpuDetected=%#RX16 fEflCpu=%#RX32 fEflSet=%#RX32\n", g_uBs3CpuDetected, fEflCpu, fEflSet);
     1958    /* make sure they're allocated  */
     1959    Bs3MemZero(&Ctx, sizeof(Ctx));
     1960    Bs3MemZero(&TrapCtx, sizeof(TrapCtx));
     1961
     1962    bs3CpuWeird1_SetGlobals(bTestMode);
     1963
     1964    /* Construct a basic context. */
     1965    Bs3RegCtxSaveEx(&Ctx, bTestMode, 1024);
     1966    bs3RegCtxScramble(&Ctx, bTestMode);
     1967    Bs3MemCpy(&CtxExpect, &Ctx, sizeof(CtxExpect));
     1968
     1969    /* Make PtrStack == SS:xSP from Ctx. */
     1970    PtrStack.pv = Bs3RegCtxGetRspSsAsCurPtr(&Ctx);
     1971
     1972    /*
     1973     * The instruction works differently in different rings, so try them all.
     1974     */
     1975    for (uRing = BS3_MODE_IS_V86(bTestMode) ? 3 : 0; ;)
     1976    {
     1977        /*
     1978         * We've got a couple of instruction variations with/without the opsize prefix.
     1979         */
     1980        unsigned iTest;
     1981        for (iTest = 0; iTest < RT_ELEMENTS(s_aTests); iTest++)
     1982        {
     1983            if (s_aTests[iTest].cBits == cTestBits)
     1984            {
     1985                uint8_t const cbAdjSp = s_aTests[iTest].cbAdjSp;
     1986                unsigned      uIopl;
     1987
     1988                /* Setup the test context. */
     1989                Bs3RegCtxSetRipCsFromLnkPtr(&Ctx, s_aTests[iTest].pfnStart);
     1990                if (BS3_MODE_IS_16BIT_SYS(bTestMode))
     1991                    g_uBs3TrapEipHint = Ctx.rip.u32;
     1992                CtxExpect.cs    = Ctx.cs;
     1993
     1994                for (uIopl = 0; uIopl <= X86_EFL_IOPL; uIopl += 1 << X86_EFL_IOPL_SHIFT)
     1995                {
     1996                    bool const     fAlwaysUd  = cbAdjSp != 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) <= BS3CPU_80286;
     1997                    bool const     fAlwaysGp  = uIopl != X86_EFL_IOPL && BS3_MODE_IS_V86(bTestMode) && (cbAdjSp == 4 || !fVme);
     1998                    uint8_t const  bXcptNorm  = fAlwaysGp ? X86_XCPT_GP : X86_XCPT_UD;
     1999                    uint8_t const  offUd      = fAlwaysGp || fAlwaysUd ? 0 : s_aTests[iTest].offUd2;
     2000                    uint32_t const fCleared   = fAlwaysUd ? 0 : fAlwaysGp ? /* 10980xe - go figure: */ X86_EFL_RF
     2001                                              : bTestMode == BS3_MODE_RM
     2002                                              ? X86_EFL_RF | X86_EFL_AC | X86_EFL_VIP /** @todo figure this. iret? bs3kit bug? */
     2003                                              : X86_EFL_RF;
     2004                    uint32_t       fPoppable  = fAlwaysGp || fAlwaysUd ? 0
     2005                                              : uRing == 0                              ? X86_EFL_POPF_BITS
     2006                                              : uRing <= (uIopl >> X86_EFL_IOPL_SHIFT)  ? X86_EFL_POPF_BITS & ~(X86_EFL_IOPL)
     2007                                              : !fAlwaysGp                              ? X86_EFL_POPF_BITS & ~(X86_EFL_IOPL | X86_EFL_IF)
     2008                                              : 0;
     2009                    uint8_t        bXcptExpect;
     2010                    fPoppable &= fEflCpu;
     2011                    if (cbAdjSp == 2)
     2012                        fPoppable &= UINT16_MAX;
     2013                    if (bTestMode == BS3_MODE_RM && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) == BS3CPU_80286)
     2014                        fPoppable &= ~(X86_EFL_IOPL | X86_EFL_NT);
     2015                    //Bs3TestPrintf("uRing=%u iTest=%u uIopl=%#x fPoppable=%#RX32 fVme=%d cbAdjSp=%d\n", uRing, iTest, uIopl, fPoppable, fVme, cbAdjSp);
     2016
     2017                    /* The first steps works with as many EFLAGS bits set as possible. */
     2018                    Ctx.rflags.u32 &= fEflKeep;
     2019                    Ctx.rflags.u32 |= fEflSet | uIopl;
     2020                    CtxExpect.rip.u = Ctx.rip.u + offUd;
     2021                    CtxExpect.rsp.u = fAlwaysGp || fAlwaysUd ? Ctx.rsp.u : Ctx.rsp.u + cbAdjSp;
     2022
     2023                    /*
     2024                     * Step 1 - pop zero.
     2025                     */
     2026                    g_usBs3TestStep++;
     2027                    PtrStack.pu32[1]     = UINT32_MAX;
     2028                    if (cbAdjSp >= 4)
     2029                        PtrStack.pu32[0] = 0;
     2030                    else
     2031                    {
     2032                        PtrStack.pu16[1] = UINT16_MAX;
     2033                        PtrStack.pu16[0] = 0;
     2034                    }
     2035                    CtxExpect.rflags.u32 = (Ctx.rflags.u32 & ~fPoppable & ~fCleared) | fXcptRf;
     2036                    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2037                    if (bs3CpuWeird1_ComparePopf(&TrapCtx, &CtxExpect, bXcptNorm))
     2038                        break;
     2039
     2040                    /*
     2041                     * Step 2 - pop 0xfffffff sans TF.
     2042                     */
     2043                    g_usBs3TestStep++;
     2044                    PtrStack.pu32[1] = UINT32_MAX;
     2045                    PtrStack.pu32[0] = UINT32_MAX & ~X86_EFL_TF;
     2046                    CtxExpect.rflags.u32 = (Ctx.rflags.u32 & ~fPoppable & ~fCleared)
     2047                                         | (UINT32_MAX & ~X86_EFL_TF & fPoppable & ~fCleared)
     2048                                         | fXcptRf;
     2049                    bXcptExpect = bXcptNorm;
     2050                    if (fVme && cbAdjSp == 2 && uIopl != X86_EFL_IOPL)
     2051                    {
     2052                        CtxExpect.rip.u      = Ctx.rip.u;
     2053                        CtxExpect.rsp.u      = Ctx.rsp.u;
     2054                        CtxExpect.rflags.u32 = (Ctx.rflags.u32 & ~fCleared) | fXcptRf;
     2055                        bXcptExpect = X86_XCPT_GP;
     2056                    }
     2057                    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2058                    if (bs3CpuWeird1_ComparePopf(&TrapCtx, &CtxExpect, bXcptExpect))
     2059                        break;
     2060
     2061
     2062                    /* We repeat the steps with max bits cleared before the popf. */
     2063                    Ctx.rflags.u32 &= fEflKeep;
     2064                    Ctx.rflags.u32 |= fEflClear | uIopl;
     2065                    CtxExpect.rip.u = Ctx.rip.u + offUd;
     2066                    CtxExpect.rsp.u = fAlwaysGp || fAlwaysUd ? Ctx.rsp.u : Ctx.rsp.u + cbAdjSp;
     2067
     2068                    /*
     2069                     * Step 3 - pop zero.
     2070                     */
     2071                    g_usBs3TestStep++;
     2072                    PtrStack.pu32[1]     = UINT32_MAX;
     2073                    if (cbAdjSp >= 4)
     2074                        PtrStack.pu32[0] = 0;
     2075                    else
     2076                    {
     2077                        PtrStack.pu16[1] = UINT16_MAX;
     2078                        PtrStack.pu16[0] = 0;
     2079                    }
     2080                    CtxExpect.rflags.u32 = (Ctx.rflags.u32 & ~fPoppable & ~fCleared) | fXcptRf;
     2081                    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2082                    if (bs3CpuWeird1_ComparePopf(&TrapCtx, &CtxExpect, bXcptNorm))
     2083                        break;
     2084
     2085                    /*
     2086                     * Step 4 - pop 0xfffffff sans TF.
     2087                     */
     2088                    g_usBs3TestStep++;
     2089                    PtrStack.pu32[1] = UINT32_MAX;
     2090                    PtrStack.pu32[0] = UINT32_MAX & ~X86_EFL_TF;
     2091                    CtxExpect.rflags.u32 = (Ctx.rflags.u32 & ~fPoppable & ~fCleared)
     2092                                         | (UINT32_MAX & ~X86_EFL_TF & fPoppable & ~fCleared)
     2093                                         | fXcptRf;
     2094                    if (fVme && cbAdjSp == 2 && uIopl != X86_EFL_IOPL)
     2095                        CtxExpect.rflags.u32 |= X86_EFL_VIF;
     2096                    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2097                    if (bs3CpuWeird1_ComparePopf(&TrapCtx, &CtxExpect, bXcptNorm))
     2098                        break;
     2099
     2100                    /*
     2101                     * Step 5 - Pop TF and get a #DB on the following instruction.
     2102                     */
     2103                    g_usBs3TestStep++;
     2104                    PtrStack.pu32[1] = UINT32_MAX;
     2105                    PtrStack.pu32[0] = UINT32_MAX;
     2106                    if (cbAdjSp != 2 || !fVme || uIopl == X86_EFL_IOPL)
     2107                    {
     2108                        CtxExpect.rflags.u32 = (Ctx.rflags.u32 & ~fPoppable & ~fCleared)
     2109                                             | (UINT32_MAX & fPoppable & ~fCleared)
     2110                                             | fXcptRf;
     2111                        CtxExpect.rip.u      = Ctx.rip.u + offUd;
     2112                        if (CtxExpect.rip.u != Ctx.rip.u)
     2113                        {
     2114                            bXcptExpect = X86_XCPT_DB;
     2115                            CtxExpect.rflags.u32 &= ~X86_EFL_RF;
     2116                        }
     2117                        else
     2118                            bXcptExpect = bXcptNorm;
     2119                    }
     2120                    else
     2121                    {
     2122                        CtxExpect.rflags.u32 = Ctx.rflags.u32 | fXcptRf;
     2123                        CtxExpect.rip.u      = Ctx.rip.u;
     2124                        CtxExpect.rsp.u      = Ctx.rsp.u;
     2125                        PtrStack.pu32[0]     = UINT32_MAX & ~X86_EFL_IF; /* only one trigger */
     2126                        bXcptExpect     = X86_XCPT_GP;
     2127                    }
     2128                    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2129                    if (bs3CpuWeird1_ComparePopf(&TrapCtx, &CtxExpect, bXcptExpect))
     2130                        break;
     2131
     2132                    /*
     2133                     * Step 6 - Start with TF set and pop zeros.  Should #DB after POPF.
     2134                     */
     2135                    g_usBs3TestStep++;
     2136                    PtrStack.pu32[1]     = UINT32_MAX;
     2137                    if (cbAdjSp >= 4)
     2138                        PtrStack.pu32[0] = 0;
     2139                    else
     2140                    {
     2141                        PtrStack.pu16[1] = UINT16_MAX;
     2142                        PtrStack.pu16[0] = 0;
     2143                    }
     2144                    Ctx.rflags.u32      |= X86_EFL_TF;
     2145                    CtxExpect.rip.u      = Ctx.rip.u + offUd - !!offUd;
     2146                    CtxExpect.rsp.u      = Ctx.rsp.u + (offUd ? cbAdjSp : 0);
     2147                    CtxExpect.rflags.u32 = (Ctx.rflags.u32 & ~fPoppable & ~fCleared) | fXcptRf;
     2148                    if (offUd)
     2149                        CtxExpect.rflags.u32 &= ~X86_EFL_RF;
     2150
     2151                    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     2152                    if (bs3CpuWeird1_ComparePopf(&TrapCtx, &CtxExpect, offUd ? X86_XCPT_DB : bXcptNorm))
     2153                        break;
     2154
     2155                    /** @todo test VIP in VME mode. */
     2156                    g_usBs3TestStep = (g_usBs3TestStep + 9) / 10 * 10;
     2157                }
     2158                g_usBs3TestStep = (g_usBs3TestStep + 99) / 100 * 100;
     2159            }
     2160            g_usBs3TestStep = (g_usBs3TestStep + 999) / 1000 * 1000;
     2161        }
     2162
     2163        /*
     2164         * Next ring.
     2165         */
     2166        if (uRing >= 3 || bTestMode == BS3_MODE_RM)
     2167            break;
     2168        uRing++;
     2169        Bs3RegCtxConvertToRingX(&Ctx, uRing);
     2170        CtxExpect.bCpl = Ctx.bCpl;
     2171        CtxExpect.ss   = Ctx.ss;
     2172        CtxExpect.ds   = Ctx.ds;
     2173        CtxExpect.es   = Ctx.es;
     2174        CtxExpect.fs   = Ctx.fs;
     2175        CtxExpect.gs   = Ctx.gs;
     2176        g_usBs3TestStep = (g_usBs3TestStep + 9999) / 10000 * 10000;
     2177    }
     2178
     2179    return 0;
     2180}
     2181
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1.c

    r105099 r105125  
    5050FNBS3TESTDOMODE BS3_CMN_FAR_NM(bs3CpuWeird1_PushPop);
    5151FNBS3TESTDOMODE BS3_CMN_FAR_NM(bs3CpuWeird1_PushPopSReg);
     52FNBS3TESTDOMODE BS3_CMN_FAR_NM(bs3CpuWeird1_Popf);
    5253
    5354
     
    5758static const BS3TESTMODEBYONEENTRY g_aModeByOneTests[] =
    5859{
     60#if 1
    5961    { "dbg+inhibit+ringxfer",   BS3_CMN_FAR_NM(bs3CpuWeird1_DbgInhibitRingXfer),    0 },
    6062    { "pc wrapping",            BS3_CMN_FAR_NM(bs3CpuWeird1_PcWrapping),            0 },
    6163    { "push/pop",               BS3_CMN_FAR_NM(bs3CpuWeird1_PushPop),               0 },
    6264    { "push/pop sreg",          BS3_CMN_FAR_NM(bs3CpuWeird1_PushPopSReg),           0 },
     65#endif
     66    { "popf",                   BS3_CMN_FAR_NM(bs3CpuWeird1_Popf),                  0 },
    6367};
    6468
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette