VirtualBox

Ignore:
Timestamp:
Oct 28, 2022 2:05:24 PM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
154329
Message:

ValKit/bs3-cpu-weird-1: More on the PC wraparound testcase.

File:
1 edited

Legend:

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

    r97330 r97332  
    792792
    793793
    794 static uint8_t bs3CpuWeird1_PcWrapping_Worker64(uint8_t bMode, uint8_t BS3_FAR *pbPage1,
    795                                                 uint8_t BS3_FAR *pbPage2, uint32_t uFlatPage1,
     794static uint8_t bs3CpuWeird1_PcWrapping_Worker64(uint8_t bMode, uint8_t BS3_FAR *pbBuf, uint32_t uFlatBuf,
    796795                                                void const BS3_FAR *pvTemplate, size_t cbTemplate, PCWRAPSETUP enmSetup)
    797796{
     797    uint8_t BS3_FAR * const pbPage1 = pbBuf;                 /* mapped at 0, 4G and 8G */
     798    uint8_t BS3_FAR * const pbPage2 = &pbBuf[X86_PAGE_SIZE]; /* mapped at -4K, 4G-4K and 8G-4K. */
    798799    BS3TRAPFRAME            TrapCtx;
    799800    BS3TRAPFRAME            TrapExpect;
    800801    BS3REGCTX               Ctx;
    801     unsigned                cbPage1;
    802     unsigned                cbPage2;
     802    unsigned                cbStart;
     803    unsigned                cbEnd;
    803804
    804805    /* make sure they're allocated  */
     
    811812     * at the start of the buffer and giving it a quick run.
    812813     */
    813     Bs3MemCpy(&pbPage1[X86_PAGE_SIZE - cbTemplate], pvTemplate, cbTemplate);
    814     pbPage2[0] = 0x0f;      /* ud2 */
    815     pbPage2[1] = 0x0b;
     814    Bs3MemCpy(pbPage1, pvTemplate, cbTemplate);
     815    pbPage1[cbTemplate]     = 0x0f; /* ud2 */
     816    pbPage1[cbTemplate + 1] = 0x0b;
    816817
    817818    Bs3RegCtxSaveEx(&Ctx, bMode, 1024);
    818819
    819     Ctx.rip.u = uFlatPage1 + X86_PAGE_SIZE - cbTemplate;
     820    Ctx.rip.u = uFlatBuf;
    820821    switch (enmSetup)
    821822    {
     
    839840     * Unlike 16-bit mode, the instruction may cross the wraparound boundary,
    840841     * so we test by advancing the template across byte-by-byte.
    841      */
    842     for (cbPage1 = cbTemplate, cbPage2 = 0; cbPage1 > 0; cbPage1--, cbPage2++, g_usBs3TestStep++)
    843     {
    844         pbPage1[X86_PAGE_SIZE - cbPage1 - 1] = 0xcc;
    845         Bs3MemCpy(&pbPage1[X86_PAGE_SIZE - cbPage1], pvTemplate, cbPage1);
    846         Bs3MemCpy(pbPage2, &((uint8_t const *)pvTemplate)[cbPage1], cbPage2);
    847         pbPage2[cbPage2]     = 0x0f;    /* ud2 */
    848         pbPage2[cbPage2 + 1] = 0x0b;
    849 
    850         Ctx.rip.u = UINT64_MAX - cbPage1 + 1;
    851         TrapExpect.Ctx.rip.u = cbPage2;
     842     *
     843     * Page #1 is mapped at address zero and Page #2 as the last one.
     844     */
     845    Bs3MemSet(pbBuf, 0xf1, X86_PAGE_SIZE * 2);
     846    for (cbStart = cbTemplate, cbEnd = 0; cbStart > 0; cbStart--, cbEnd++)
     847    {
     848        pbPage2[X86_PAGE_SIZE - cbStart - 1] = 0xf1;
     849        Bs3MemCpy(&pbPage2[X86_PAGE_SIZE - cbStart], pvTemplate, cbStart);
     850        Bs3MemCpy(pbPage1, &((uint8_t const *)pvTemplate)[cbStart], cbEnd);
     851        pbPage1[cbEnd]     = 0x0f;    /* ud2 */
     852        pbPage1[cbEnd + 1] = 0x0b;
     853
     854        Ctx.rip.u            = UINT64_MAX - cbStart + 1;
     855        TrapExpect.Ctx.rip.u = cbEnd;
    852856
    853857        Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
    854858        if (bs3CpuWeird1_ComparePcWrap(&TrapCtx, &TrapExpect))
    855859            return 1;
     860        g_usBs3TestStep++;
     861
     862        /* Also check that crossing 4G isn't buggered up in our code by
     863           32-bit and 16-bit mode support.*/
     864        Ctx.rip.u            = _4G - cbStart;
     865        TrapExpect.Ctx.rip.u = _4G + cbEnd;
     866        Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     867        if (bs3CpuWeird1_ComparePcWrap(&TrapCtx, &TrapExpect))
     868            return 1;
     869        g_usBs3TestStep++;
     870
     871        Ctx.rip.u            = _4G*2 - cbStart;
     872        TrapExpect.Ctx.rip.u = _4G*2 + cbEnd;
     873        Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
     874        if (bs3CpuWeird1_ComparePcWrap(&TrapCtx, &TrapExpect))
     875            return 1;
     876        g_usBs3TestStep += 2;
    856877    }
    857878    return 0;
     
    928949                                                     (uintptr_t)s_aTemplates16[i].pfnEnd - (uintptr_t)s_aTemplates16[i].pfnStart,
    929950                                                     s_aTemplates16[i].enmSetup);
    930                 g_usBs3TestStep = (g_usBs3TestStep + 16) & ~16;
     951                g_usBs3TestStep = i * 256;
    931952            }
    932953
     
    944965    {
    945966        /*
    946          * For both 32-bit and 64-bit mode tests we only need a buffer with
    947          * two pages.
     967         * For 32-bit and 64-bit mode we just need two pages.
    948968         */
    949         uint8_t BS3_FAR *pbBuf = (uint8_t BS3_FAR *)Bs3MemAlloc(BS3MEMKIND_TILED, X86_PAGE_SIZE * 2);
     969        size_t const     cbBuf = X86_PAGE_SIZE * 2;
     970        uint8_t BS3_FAR *pbBuf = (uint8_t BS3_FAR *)Bs3MemAlloc(BS3MEMKIND_TILED, cbBuf);
    950971        if (pbBuf)
    951972        {
    952973            uint32_t const uFlatBuf = Bs3SelPtrToFlat(pbBuf);
    953             Bs3MemSet(pbBuf, 0xf1, X86_PAGE_SIZE * 2);
     974            Bs3MemSet(pbBuf, 0xf1, cbBuf);
    954975
    955976            /*
     
    9831004                                                     (uintptr_t)s_aTemplates32[i].pfnEnd - (uintptr_t)s_aTemplates32[i].pfnStart,
    9841005                                                     s_aTemplates32[i].enmSetup);
    985                     g_usBs3TestStep = (g_usBs3TestStep + 16) & ~16;
     1006                    g_usBs3TestStep = i * 256;
    9861007                }
    9871008
     
    9891010            }
    9901011            /*
    991              * For 64-bit we have to alias the two pages so they straddle address 0.
     1012             * For 64-bit we have to alias the two buffer pages to the first and
     1013             * last page in the address space. To test that the 32-bit 4G rollover
     1014             * isn't incorrectly applied to LM64, we repeat this mappingfor the 4G
     1015             * and 8G boundaries too.
     1016             *
    9921017             * This ASSUMES there is nothing important in page 0 when in LM64.
    9931018             */
    9941019            else
    9951020            {
    996                 int rc = Bs3PagingAlias(UINT64_MAX - X86_PAGE_SIZE + 1, uFlatBuf, X86_PAGE_SIZE,
     1021                static const struct { uint64_t uDst; uint16_t off; } s_aMappings[] =
     1022                {
     1023                    { UINT64_MAX - X86_PAGE_SIZE + 1, X86_PAGE_SIZE * 1 },
     1024                    { UINT64_C(0),                    X86_PAGE_SIZE * 0 },
     1025#if 1 /* technically not required as we just repeat the same 4G address space in long mode: */
     1026                    { _4G - X86_PAGE_SIZE,            X86_PAGE_SIZE * 1 },
     1027                    { _4G,                            X86_PAGE_SIZE * 0 },
     1028                    { _4G*2 - X86_PAGE_SIZE,          X86_PAGE_SIZE * 1 },
     1029                    { _4G*2,                          X86_PAGE_SIZE * 0 },
     1030#endif
     1031                };
     1032                int      rc = VINF_SUCCESS;
     1033                unsigned iMap;
     1034                BS3_ASSERT(bMode == BS3_MODE_LM64);
     1035                for (iMap = 0; iMap < RT_ELEMENTS(s_aMappings) && RT_SUCCESS(rc); iMap++)
     1036                {
     1037                    rc = Bs3PagingAlias(s_aMappings[iMap].uDst, uFlatBuf + s_aMappings[iMap].off, X86_PAGE_SIZE,
    9971038                                        X86_PTE_P | X86_PTE_A | X86_PTE_D | X86_PTE_RW);
    998                 BS3_ASSERT(bMode == BS3_MODE_LM64);
     1039                    if (RT_FAILURE(rc))
     1040                        Bs3TestFailedF("Bs3PagingAlias(%#RX64,...) failed: %d", s_aMappings[iMap].uDst, rc);
     1041                }
     1042
    9991043                if (RT_SUCCESS(rc))
    10001044                {
    1001                     rc = Bs3PagingAlias(UINT64_C(0), uFlatBuf + X86_PAGE_SIZE, X86_PAGE_SIZE,
    1002                                         X86_PTE_P | X86_PTE_A | X86_PTE_D | X86_PTE_RW);
    1003                     if (RT_SUCCESS(rc))
     1045                    static struct { FPFNBS3FAR pfnStart, pfnEnd; PCWRAPSETUP enmSetup; } const s_aTemplates64[] =
    10041046                    {
    1005                         static struct { FPFNBS3FAR pfnStart, pfnEnd; PCWRAPSETUP enmSetup; } const s_aTemplates64[] =
    1006                         {
    1007 #define ENTRY64(a_Template, a_enmSetup)     { a_Template ## _c64, a_Template ## _c64_EndProc, a_enmSetup }
    1008                             ENTRY64(bs3CpuWeird1_PcWrapBenign1, kPcWrapSetup_None),
    1009                             ENTRY64(bs3CpuWeird1_PcWrapBenign2, kPcWrapSetup_None),
    1010                             ENTRY64(bs3CpuWeird1_PcWrapCpuId,   kPcWrapSetup_ZeroRax),
    1011                             ENTRY64(bs3CpuWeird1_PcWrapIn80,    kPcWrapSetup_None),
    1012                             ENTRY64(bs3CpuWeird1_PcWrapOut80,   kPcWrapSetup_None),
    1013                             ENTRY64(bs3CpuWeird1_PcWrapSmsw,    kPcWrapSetup_None),
    1014                             ENTRY64(bs3CpuWeird1_PcWrapRdCr0,   kPcWrapSetup_None),
    1015                             ENTRY64(bs3CpuWeird1_PcWrapRdDr0,   kPcWrapSetup_None),
    1016                             ENTRY64(bs3CpuWeird1_PcWrapWrDr0,   kPcWrapSetup_ZeroRax),
     1047#define ENTRY64(a_Template, a_enmSetup) { a_Template ## _c64, a_Template ## _c64_EndProc, a_enmSetup }
     1048                        ENTRY64(bs3CpuWeird1_PcWrapBenign1, kPcWrapSetup_None),
     1049                        ENTRY64(bs3CpuWeird1_PcWrapBenign2, kPcWrapSetup_None),
     1050                        ENTRY64(bs3CpuWeird1_PcWrapCpuId,   kPcWrapSetup_ZeroRax),
     1051                        ENTRY64(bs3CpuWeird1_PcWrapIn80,    kPcWrapSetup_None),
     1052                        ENTRY64(bs3CpuWeird1_PcWrapOut80,   kPcWrapSetup_None),
     1053                        ENTRY64(bs3CpuWeird1_PcWrapSmsw,    kPcWrapSetup_None),
     1054                        ENTRY64(bs3CpuWeird1_PcWrapRdCr0,   kPcWrapSetup_None),
     1055                        ENTRY64(bs3CpuWeird1_PcWrapRdDr0,   kPcWrapSetup_None),
     1056                        ENTRY64(bs3CpuWeird1_PcWrapWrDr0,   kPcWrapSetup_ZeroRax),
    10171057#undef ENTRY64
    1018                         };
    1019 
    1020                         for (i = 0; i < RT_ELEMENTS(s_aTemplates64); i++)
    1021                         {
    1022                             bs3CpuWeird1_PcWrapping_Worker64(bMode, pbBuf, &pbBuf[X86_PAGE_SIZE], uFlatBuf,
    1023                                                              Bs3SelLnkPtrToCurPtr(s_aTemplates64[i].pfnStart),
    1024                                                                 (uintptr_t)s_aTemplates64[i].pfnEnd
    1025                                                               - (uintptr_t)s_aTemplates64[i].pfnStart,
    1026                                                              s_aTemplates64[i].enmSetup);
    1027                             g_usBs3TestStep = (g_usBs3TestStep + 16) & ~16;
    1028                         }
    1029 
    1030                         bRet = 0;
    1031 
    1032                         Bs3PagingUnalias(UINT64_C(0), X86_PAGE_SIZE);
     1058                    };
     1059
     1060                    for (i = 0; i < RT_ELEMENTS(s_aTemplates64); i++)
     1061                    {
     1062                        bs3CpuWeird1_PcWrapping_Worker64(bMode, pbBuf, uFlatBuf,
     1063                                                         Bs3SelLnkPtrToCurPtr(s_aTemplates64[i].pfnStart),
     1064                                                            (uintptr_t)s_aTemplates64[i].pfnEnd
     1065                                                          - (uintptr_t)s_aTemplates64[i].pfnStart,
     1066                                                         s_aTemplates64[i].enmSetup);
     1067                        g_usBs3TestStep = i * 256;
    10331068                    }
    1034                     else
    1035                         Bs3TestFailedF("Bs3PagingAlias(0...) failed: %d", rc);
    1036                     Bs3PagingUnalias(UINT64_MAX - X86_PAGE_SIZE + 1, X86_PAGE_SIZE);
     1069
     1070                    bRet = 0;
     1071
     1072                    Bs3PagingUnalias(UINT64_C(0), X86_PAGE_SIZE);
    10371073                }
    1038                 else
    1039                     Bs3TestFailedF("Bs3PagingAlias(0xfff...) failed: %d", rc);
     1074
     1075                while (iMap-- > 0)
     1076                    Bs3PagingUnalias(s_aMappings[iMap].uDst, X86_PAGE_SIZE);
    10401077            }
     1078            Bs3MemFree(pbBuf, cbBuf);
    10411079        }
    10421080        else
    1043             Bs3TestFailed("Failed to allocate 2 pages for tests.");
    1044         Bs3MemFree(pbBuf, X86_PAGE_SIZE * 2);
     1081            Bs3TestFailed("Failed to allocate 2-3 pages for tests.");
    10451082    }
    10461083
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