VirtualBox

Changeset 97321 in vbox


Ignore:
Timestamp:
Oct 27, 2022 12:46:16 PM (2 years ago)
Author:
vboxsync
Message:

ValKit/bs3-cpu-weird-1: Adding a PC wraparound testcase.

Location:
trunk/src/VBox/ValidationKit/bootsectors
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1-template.mac

    r96407 r97321  
    116116
    117117
     118;
     119; PC (IP/EIP) wrapper templates.
     120; These will potentially trigger VM exits, except for the benign one.
     121;
     122
     123BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapBenign1, BS3_PBC_NEAR
     124        nop
     125BS3_PROC_END_CMN   bs3CpuWeird1_PcWrapBenign1
     126
     127BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapBenign2, BS3_PBC_NEAR
     128        xor     xDX, xAX
     129BS3_PROC_END_CMN   bs3CpuWeird1_PcWrapBenign2
     130
     131BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapCpuId, BS3_PBC_NEAR
     132        xor     eax, eax
     133        cpuid
     134BS3_PROC_END_CMN   bs3CpuWeird1_PcWrapCpuId
     135
     136BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapIn80, BS3_PBC_NEAR
     137        in      al, 80h
     138BS3_PROC_END_CMN   bs3CpuWeird1_PcWrapIn80
     139
     140BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapOut80, BS3_PBC_NEAR
     141        out     80h, al
     142BS3_PROC_END_CMN   bs3CpuWeird1_PcWrapOut80
     143
     144BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapSmsw, BS3_PBC_NEAR
     145        smsw       si
     146BS3_PROC_END_CMN   bs3CpuWeird1_PcWrapSmsw
     147
     148BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapRdCr0, BS3_PBC_NEAR
     149        mov     sAX, cr0
     150BS3_PROC_END_CMN   bs3CpuWeird1_PcWrapRdCr0
     151
     152BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapRdDr0, BS3_PBC_NEAR
     153        mov     sAX, dr0
     154BS3_PROC_END_CMN   bs3CpuWeird1_PcWrapRdDr0
     155
     156BS3_PROC_BEGIN_CMN bs3CpuWeird1_PcWrapWrDr0, BS3_PBC_NEAR
     157        xor     sAX, sAX
     158        mov     dr0, sAX
     159BS3_PROC_END_CMN   bs3CpuWeird1_PcWrapWrDr0
     160
     161
    118162%endif ; BS3_INSTANTIATING_CMN
    119163
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1-x0.c

    r96407 r97321  
    4141#define BS3_USE_X0_TEXT_SEG
    4242#include <bs3kit.h>
     43#include <bs3-cmn-memory.h>
    4344#include <iprt/asm.h>
    4445#include <iprt/asm-amd64-x86.h>
     
    530531}
    531532
     533
     534/*********************************************************************************************************************************
     535*   IP / EIP  Wrapping                                                                                                           *
     536*********************************************************************************************************************************/
     537#define PROTO1632(a_Template) FNBS3FAR a_Template ## _c16, a_Template ## _c16_EndProc, a_Template ## _c32, a_Template ## _c32_EndProc
     538PROTO1632(bs3CpuWeird1_PcWrapBenign1);
     539PROTO1632(bs3CpuWeird1_PcWrapBenign2);
     540PROTO1632(bs3CpuWeird1_PcWrapCpuId);
     541PROTO1632(bs3CpuWeird1_PcWrapIn80);
     542PROTO1632(bs3CpuWeird1_PcWrapOut80);
     543PROTO1632(bs3CpuWeird1_PcWrapSmsw);
     544PROTO1632(bs3CpuWeird1_PcWrapRdCr0);
     545PROTO1632(bs3CpuWeird1_PcWrapRdDr0);
     546PROTO1632(bs3CpuWeird1_PcWrapWrDr0);
     547#undef PROTO1632
     548
     549
     550/**
     551 * Compares pc wraparound result.
     552 */
     553static uint8_t bs3CpuWeird1_ComparePcWrap(PCBS3TRAPFRAME pTrapCtx, PCBS3TRAPFRAME pTrapExpect)
     554{
     555    uint16_t const cErrorsBefore = Bs3TestSubErrorCount();
     556    CHECK_MEMBER("bXcpt",       "%#04x",    pTrapCtx->bXcpt,        pTrapExpect->bXcpt);
     557    CHECK_MEMBER("bErrCd",      "%#06RX64", pTrapCtx->uErrCd,       pTrapExpect->uErrCd);
     558    Bs3TestCheckRegCtxEx(&pTrapCtx->Ctx, &pTrapExpect->Ctx, 0 /*cbPcAdjust*/, 0 /*cbSpAdjust*/, 0 /*fExtraEfl*/,
     559                         g_pszTestMode, g_usBs3TestStep);
     560    if (Bs3TestSubErrorCount() != cErrorsBefore)
     561    {
     562        Bs3TrapPrintFrame(pTrapCtx);
     563        Bs3TestPrintf("CS=%04RX16 SS:ESP=%04RX16:%08RX64 EFL=%RX64 cbIret=%#x\n",
     564                      pTrapCtx->uHandlerCs, pTrapCtx->uHandlerSs, pTrapCtx->uHandlerRsp,
     565                      pTrapCtx->fHandlerRfl, pTrapCtx->cbIretFrame);
     566#if 0
     567        Bs3TestPrintf("Halting in ComparePcWrap: bXcpt=%#x\n", pTrapCtx->bXcpt);
     568        ASMHalt();
     569#endif
     570        return 1;
     571    }
     572    return 0;
     573}
     574
     575
     576static uint8_t bs3CpuWeird1_PcWrapping_Worker16(uint8_t bMode, uint8_t BS3_FAR *pbCode, uint8_t BS3_FAR *pbHead,
     577                                                uint8_t BS3_FAR *pbTail, uint8_t BS3_FAR *pbAfter,
     578                                                void const BS3_FAR *pvTemplate, size_t cbTemplate)
     579{
     580    BS3TRAPFRAME            TrapCtx;
     581    BS3TRAPFRAME            TrapExpect;
     582    BS3REGCTX               Ctx;
     583    uint8_t                 bXcpt;
     584
     585    /* make sure they're allocated  */
     586    Bs3MemZero(&Ctx, sizeof(Ctx));
     587    Bs3MemZero(&TrapCtx, sizeof(TrapCtx));
     588    Bs3MemZero(&TrapExpect, sizeof(TrapExpect));
     589
     590    /*
     591     * Create the expected result by first placing the code template
     592     * at the start of the buffer and giving it a quick run.
     593     *
     594     * I cannot think of any instruction always causing #GP(0) right now, so
     595     * we generate a ud2 and modify it instead.
     596     */
     597    Bs3MemCpy(pbHead, pvTemplate, cbTemplate);
     598    if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) <= BS3CPU_80286)
     599    {
     600        pbHead[cbTemplate] = 0xcc;      /* int3 */
     601        bXcpt = X86_XCPT_BP;
     602    }
     603    else
     604    {
     605        pbHead[cbTemplate]     = 0x0f;  /* ud2 */
     606        pbHead[cbTemplate + 1] = 0x0b;
     607        bXcpt = X86_XCPT_UD;
     608    }
     609
     610    Bs3RegCtxSaveEx(&Ctx, bMode, 1024);
     611
     612    Ctx.cs    = BS3_FP_SEG(pbCode);
     613    Ctx.rip.u = 0;
     614
     615    /* V8086: Set IOPL to 3. */
     616    if (BS3_MODE_IS_V86(bMode))
     617        Ctx.rflags.u32 |= X86_EFL_IOPL;
     618
     619    Bs3TrapSetJmpAndRestore(&Ctx, &TrapExpect);
     620    if (TrapExpect.bXcpt != bXcpt)
     621    {
     622
     623        Bs3TestFailedF("%u: Setup: bXcpt is %#x, expected %#x!\n", g_usBs3TestStep, TrapExpect.bXcpt, bXcpt);
     624        Bs3TrapPrintFrame(&TrapExpect);
     625        return 1;
     626    }
     627
     628    /*
     629     * Adjust the contexts for the real test.
     630     */
     631    Ctx.cs    = BS3_FP_SEG(pbCode);
     632    Ctx.rip.u = (uint32_t)_64K - cbTemplate;
     633
     634    if ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) <= BS3CPU_80286)
     635        TrapExpect.Ctx.rip.u = 1;
     636    else
     637    {
     638        if (BS3_MODE_IS_16BIT_SYS(bMode))
     639            TrapExpect.Ctx.rip.u = 0;
     640        else
     641            TrapExpect.Ctx.rip.u = UINT32_C(0x10000);
     642        TrapExpect.bXcpt  = X86_XCPT_GP;
     643        TrapExpect.uErrCd = 0;
     644    }
     645
     646    /*
     647     * Prepare the buffer for 16-bit wrap around.
     648     */
     649    Bs3MemSet(pbHead, 0xcc, 64);        /* int3 */
     650    if (bXcpt == X86_XCPT_UD)
     651    {
     652        pbHead[0] = 0x0f;               /* ud2 */
     653        pbHead[1] = 0x0b;
     654    }
     655    Bs3MemCpy(&pbTail[_4K - cbTemplate], pvTemplate, cbTemplate);
     656    Bs3MemSet(pbAfter, 0xf1, 64);       /* icebp / int1 */
     657
     658    /*
     659     * Do a test run.
     660     */
     661    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     662    return bs3CpuWeird1_ComparePcWrap(&TrapCtx, &TrapExpect);
     663}
     664
     665
     666static uint8_t bs3CpuWeird1_PcWrapping_Worker32(uint8_t bMode, RTSEL SelCode, uint8_t BS3_FAR *pbPage1,
     667                                                uint8_t BS3_FAR *pbPage2, uint32_t uFlatPage2,
     668                                                void const BS3_FAR *pvTemplate, size_t cbTemplate)
     669{
     670    BS3TRAPFRAME            TrapCtx;
     671    BS3TRAPFRAME            TrapExpect;
     672    BS3REGCTX               Ctx;
     673
     674    /* make sure they're allocated  */
     675    Bs3MemZero(&Ctx, sizeof(Ctx));
     676    Bs3MemZero(&TrapCtx, sizeof(TrapCtx));
     677    Bs3MemZero(&TrapExpect, sizeof(TrapExpect));
     678
     679    //Bs3TestPrintf("SelCode=%#x pbPage1=%p pbPage2=%p uFlatPage2=%RX32 pvTemplate=%p cbTemplate\n",
     680    //              SelCode, pbPage1, pbPage2, uFlatPage2, pvTemplate, cbTemplate);
     681
     682    /*
     683     * Create the expected result by first placing the code template
     684     * at the start of the buffer and giving it a quick run.
     685     */
     686    Bs3MemSet(pbPage1, 0xcc, _4K);
     687    Bs3MemSet(pbPage2, 0xcc, _4K);
     688    Bs3MemCpy(&pbPage1[_4K - cbTemplate], pvTemplate, cbTemplate);
     689    pbPage2[0] = 0x0f;      /* ud2 */
     690    pbPage2[1] = 0x0b;
     691
     692    Bs3RegCtxSaveEx(&Ctx, bMode, 1024);
     693
     694    Ctx.cs    = BS3_SEL_R0_CS32;
     695    Ctx.rip.u = uFlatPage2 - cbTemplate;
     696
     697    Bs3TrapSetJmpAndRestore(&Ctx, &TrapExpect);
     698    if (TrapExpect.bXcpt != X86_XCPT_UD)
     699    {
     700
     701        Bs3TestFailedF("%u: Setup: bXcpt is %#x, expected %#x!\n", g_usBs3TestStep, TrapExpect.bXcpt, X86_XCPT_UD);
     702        Bs3TrapPrintFrame(&TrapExpect);
     703        return 1;
     704    }
     705
     706    /*
     707     * Adjust the contexts for the real test.
     708     */
     709    Ctx.cs    = SelCode;
     710    Ctx.rip.u = UINT32_MAX - cbTemplate + 1;
     711
     712    TrapExpect.Ctx.cs    = SelCode;
     713    TrapExpect.Ctx.rip.u = 0;
     714
     715    /*
     716     * Do a test run.
     717     */
     718    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     719    if (bs3CpuWeird1_ComparePcWrap(&TrapCtx, &TrapExpect))
     720        ASMHalt();
     721    return 0;
     722}
     723
     724
     725
     726BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuWeird1_PcWrapping)(uint8_t bMode)
     727{
     728    /*
     729     * Allocate a 68KB buffer for testing.
     730     *
     731     * This is a little annoying to work with from 16-bit bit, so we use
     732     * separate pointers to each interesting bit of it.
     733     */
     734    uint8_t bRet = 1;
     735    /** @todo add api for doing this, so we don't need to include bs3-cmn-memory.h. */
     736    uint8_t BS3_FAR *pbBuf = (uint8_t BS3_FAR *)Bs3SlabAllocEx(&g_Bs3Mem4KLow.Core, 17 /*cPages*/, 0 /*fFlags*/);
     737    if (pbBuf != NULL)
     738    {
     739        uint32_t const   uFlatBuf = Bs3SelPtrToFlat(pbBuf);
     740        uint8_t BS3_FAR *pbTail   = Bs3XptrFlatToCurrent(uFlatBuf + 0x0f000);
     741        uint8_t BS3_FAR *pbAfter  = Bs3XptrFlatToCurrent(uFlatBuf + UINT32_C(0x10000));
     742        uint32_t         off;
     743        size_t           i;
     744
     745        /* Fill the buffer with int1 instructions: */
     746        for (off = 0; off < UINT32_C(0x11000); off += _4K)
     747        {
     748            uint8_t BS3_FAR *pbPage = Bs3XptrFlatToCurrent(uFlatBuf + off);
     749            Bs3MemSet(pbPage, 0xf1, _4K);
     750        }
     751
     752        /*
     753         * Now for the testing.
     754         */
     755        bs3CpuWeird1_SetGlobals(bMode);
     756#define WITH_LEN(a_Template)     a_Template, (uintptr_t)a_Template##_EndProc - (uintptr_t)a_Template
     757
     758        if (BS3_MODE_IS_16BIT_CODE(bMode))
     759        {
     760            static struct { FPFNBS3FAR pfnStart, pfnEnd; unsigned fNoV86 : 1; } const s_aTemplates16[] =
     761            {
     762#define ENTRY16(a_Template, a_fNoV86)     { a_Template ## _c16, a_Template##_c16_EndProc, a_fNoV86 }
     763                ENTRY16(bs3CpuWeird1_PcWrapBenign1, 0),
     764                ENTRY16(bs3CpuWeird1_PcWrapBenign2, 0),
     765                ENTRY16(bs3CpuWeird1_PcWrapCpuId,   0),
     766                ENTRY16(bs3CpuWeird1_PcWrapIn80,    0),
     767                ENTRY16(bs3CpuWeird1_PcWrapOut80,   0),
     768                ENTRY16(bs3CpuWeird1_PcWrapSmsw,    0),
     769                ENTRY16(bs3CpuWeird1_PcWrapRdCr0,   1),
     770                ENTRY16(bs3CpuWeird1_PcWrapRdDr0,   1),
     771                ENTRY16(bs3CpuWeird1_PcWrapWrDr0,   1),
     772#undef ENTRY16
     773            };
     774            uint8_t BS3_FAR *pbCode = BS3_FP_MAKE((uint16_t)(uFlatBuf >> 4), 0);
     775            if (!BS3_MODE_IS_RM_OR_V86(bMode))
     776            {
     777                Bs3SelSetup16BitCode(&Bs3GdteSpare00, uFlatBuf, 0);
     778                pbCode = BS3_FP_MAKE(BS3_SEL_SPARE_00, 0);
     779            }
     780
     781            /* Allow IN and OUT to port 80h from V8086 mode. */
     782            if (BS3_MODE_IS_V86(bMode))
     783            {
     784                Bs3RegSetTr(BS3_SEL_TSS32_IOBP_IRB);
     785                ASMBitClear(Bs3SharedIobp, 0x80);
     786            }
     787
     788            for (i = 0; i < RT_ELEMENTS(s_aTemplates16); i++, g_usBs3TestStep++)
     789            {
     790                if (s_aTemplates16[i].fNoV86 && BS3_MODE_IS_V86(bMode))
     791                    continue;
     792                bs3CpuWeird1_PcWrapping_Worker16(bMode, pbCode, pbBuf, pbTail, pbAfter, s_aTemplates16[i].pfnStart,
     793                                                 (uintptr_t)s_aTemplates16[i].pfnEnd - (uintptr_t)s_aTemplates16[i].pfnStart);
     794            }
     795
     796            if (BS3_MODE_IS_V86(bMode))
     797                ASMBitSet(Bs3SharedIobp, 0x80);
     798            bRet = 0;
     799        }
     800        else if (BS3_MODE_IS_32BIT_CODE(bMode))
     801        {
     802            static struct { FPFNBS3FAR pfnStart, pfnEnd; } const s_aTemplates32[] =
     803            {
     804#define ENTRY32(a_Template)     { a_Template ## _c32, a_Template##_c32_EndProc }
     805                ENTRY32(bs3CpuWeird1_PcWrapBenign1),
     806                ENTRY32(bs3CpuWeird1_PcWrapBenign2),
     807                ENTRY32(bs3CpuWeird1_PcWrapCpuId),
     808                //ENTRY32(bs3CpuWeird1_PcWrapIn80),   - causes GURU because of vmxHCAdvanceGuestRipBy.
     809                //ENTRY32(bs3CpuWeird1_PcWrapOut80),  - ditto.
     810                ENTRY32(bs3CpuWeird1_PcWrapSmsw),
     811                ENTRY32(bs3CpuWeird1_PcWrapRdCr0),
     812                ENTRY32(bs3CpuWeird1_PcWrapRdDr0),
     813                ENTRY32(bs3CpuWeird1_PcWrapWrDr0),
     814#undef ENTRY32
     815            };
     816
     817            Bs3SelSetup32BitCode(&Bs3GdteSpare00, uFlatBuf + UINT32_C(0x10000), UINT32_MAX, 0);
     818
     819            for (i = 0; i < RT_ELEMENTS(s_aTemplates32); i++, g_usBs3TestStep++)
     820            {
     821                //Bs3TestPrintf("pfnStart=%p pfnEnd=%p\n", s_aTemplates32[i].pfnStart, s_aTemplates32[i].pfnEnd);
     822                bs3CpuWeird1_PcWrapping_Worker32(bMode, BS3_SEL_SPARE_00, pbTail, pbAfter, uFlatBuf + UINT32_C(0x10000),
     823                                                 Bs3SelLnkPtrToCurPtr(s_aTemplates32[i].pfnStart),
     824                                                 (uintptr_t)s_aTemplates32[i].pfnEnd - (uintptr_t)s_aTemplates32[i].pfnStart);
     825            }
     826            bRet = 0;
     827        }
     828        else
     829        {
     830            BS3_ASSERT(bMode == BS3_MODE_LM64);
     831            /** @todo test LM64 wraparound too (doing some page table aliasing perhaps). */
     832            bRet = BS3TESTDOMODE_SKIPPED;
     833        }
     834
     835        Bs3SlabFree(&g_Bs3Mem4KLow.Core, uFlatBuf, 17);
     836    }
     837    else
     838        Bs3TestFailed("Failed to allocate 17 pages (68KB)");
     839
     840    return bRet;
     841}
     842
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1.c

    r96407 r97321  
    4747*********************************************************************************************************************************/
    4848FNBS3TESTDOMODE bs3CpuWeird1_DbgInhibitRingXfer_f16;
     49FNBS3TESTDOMODE bs3CpuWeird1_PcWrapping_f16;
    4950
    5051
     
    5556{
    5657    { "dbg+inhibit+ringxfer", bs3CpuWeird1_DbgInhibitRingXfer_f16, 0 },
     58    { "pc wrapping", bs3CpuWeird1_PcWrapping_f16, 0 },
    5759};
    5860
     
    7072
    7173    Bs3TestTerm();
    72 for (;;) { ASMHalt(); }
     74    Bs3Shutdown();
    7375}
    7476
Note: See TracChangeset for help on using the changeset viewer.

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