VirtualBox

Ignore:
Timestamp:
Feb 6, 2024 10:59:03 AM (12 months ago)
Author:
vboxsync
Message:

ValidationKit/bootsectors/bs3-cpu-instr-2: Extend cmpxchg16b and cmpxchg8b with checking for how #AC is handled, bugref:9898

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-instr-2-template.c

    r103208 r103223  
    29752975{
    29762976
    2977     BS3REGCTX       Ctx;
    2978     BS3REGCTX       ExpectCtx;
    2979     BS3TRAPFRAME    TrapFrame;
    2980     RTUINT64U       au64[3];
    2981     PRTUINT64U      pau64       = RT_ALIGN_PT(&au64[0], sizeof(RTUINT64U), PRTUINT64U);
    2982     bool const      fSupportCX8 = RT_BOOL(ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_CX8);
    2983     unsigned        iFlags;
    2984     unsigned        offBuf;
    2985     unsigned        iMatch;
    2986     unsigned        iWorker;
     2977    BS3REGCTX                   Ctx;
     2978    BS3REGCTX                   ExpectCtx;
     2979    BS3TRAPFRAME                TrapFrame;
     2980    RTUINT64U                   au64[3];
     2981    PRTUINT64U                  pau64       = RT_ALIGN_PT(&au64[0], sizeof(RTUINT64U), PRTUINT64U);
     2982    bool const                  fSupportCX8 = RT_BOOL(ASMCpuId_EDX(1) & X86_CPUID_FEATURE_EDX_CX8);
     2983    const char BS3_FAR * const  pszMode     = Bs3GetModeName(bMode);
     2984    uint8_t                     bRing       = BS3_MODE_IS_V86(bMode) ? 3 : 0;
     2985    unsigned                    iFlags;
     2986    unsigned                    offBuf;
     2987    unsigned                    iMatch;
     2988    unsigned                    iWorker;
    29872989    static struct
    29882990    {
     
    30203022
    30213023    /*
    3022      * One loop with the normal variant and one with the locked one
     3024     * Run the tests in all rings since alignment issues may behave
     3025     * differently in ring-3 compared to ring-0.
    30233026     */
    3024     g_usBs3TestStep = 0;
    3025     for (iWorker = 0; iWorker < RT_ELEMENTS(s_aWorkers); iWorker++)
    3026     {
    3027         Bs3RegCtxSetRipCsFromCurPtr(&Ctx, s_aWorkers[iWorker].pfnWorker);
    3028 
     3027    for (;;)
     3028    {
    30293029        /*
    3030          * One loop with all status flags set, and one with them clear.
     3030         * One loop with alignment checks disabled and one with enabled.
    30313031         */
    3032         Ctx.rflags.u16 |= X86_EFL_STATUS_BITS;
    3033         for (iFlags = 0; iFlags < 2; iFlags++)
     3032        unsigned iCfg;
     3033        for (iCfg = 0; iCfg < 2; iCfg++)
    30343034        {
    3035             Bs3MemCpy(&ExpectCtx, &Ctx, sizeof(ExpectCtx));
    3036 
    3037             for (offBuf = 0; offBuf < sizeof(RTUINT64U); offBuf++)
     3035            if (iCfg)
    30383036            {
     3037                Ctx.rflags.u32 |= X86_EFL_AC;
     3038                Ctx.cr0.u32    |= X86_CR0_AM;
     3039            }
     3040            else
     3041            {
     3042                Ctx.rflags.u32 &= ~X86_EFL_AC;
     3043                Ctx.cr0.u32    &= ~X86_CR0_AM;
     3044            }
     3045
     3046            /*
     3047             * One loop with the normal variant and one with the locked one
     3048             */
     3049            g_usBs3TestStep = 0;
     3050            for (iWorker = 0; iWorker < RT_ELEMENTS(s_aWorkers); iWorker++)
     3051            {
     3052                Bs3RegCtxSetRipCsFromCurPtr(&Ctx, s_aWorkers[iWorker].pfnWorker);
     3053
     3054                /*
     3055                 * One loop with all status flags set, and one with them clear.
     3056                 */
     3057                Ctx.rflags.u16 |= X86_EFL_STATUS_BITS;
     3058                for (iFlags = 0; iFlags < 2; iFlags++)
     3059                {
     3060                    Bs3MemCpy(&ExpectCtx, &Ctx, sizeof(ExpectCtx));
     3061
     3062                    for (offBuf = 0; offBuf < sizeof(RTUINT64U); offBuf++)
     3063                    {
    30393064#  define CX8_OLD_LO       UINT32_C(0xcc9c4bbd)
    30403065#  define CX8_OLD_HI       UINT32_C(0x749549ab)
     
    30443069#  define CX8_STORE_HI     UINT32_C(0xd1b54963)
    30453070
    3046                 PRTUINT64U pBuf = (PRTUINT64U)&pau64->au8[offBuf];
    3047 
    3048                 ExpectCtx.rax.u = Ctx.rax.u = CX8_MISMATCH_LO;
    3049                 ExpectCtx.rdx.u = Ctx.rdx.u = CX8_MISMATCH_HI;
    3050 
    3051                 Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rdi, &Ctx.fs, pBuf);
    3052                 Bs3RegCtxSetGrpSegFromCurPtr(&ExpectCtx, &ExpectCtx.rdi, &ExpectCtx.fs, pBuf);
    3053 
    3054                 for (iMatch = 0; iMatch < 2; iMatch++)
    3055                 {
    3056                     uint8_t bExpectXcpt;
    3057                     pBuf->s.Lo = CX8_OLD_LO;
    3058                     pBuf->s.Hi = CX8_OLD_HI;
    3059 
    3060                     Bs3TrapSetJmpAndRestore(&Ctx, &TrapFrame);
    3061                     g_usBs3TestStep++;
    3062                     //Bs3TestPrintf("Test: iFlags=%d offBuf=%d iMatch=%u iWorker=%u\n", iFlags, offBuf, iMatch, iWorker);
    3063                     bExpectXcpt = X86_XCPT_DB;
    3064                     if (fSupportCX8)
    3065                     {
    3066                         ExpectCtx.rax.u = CX8_OLD_LO;
    3067                         ExpectCtx.rdx.u = CX8_OLD_HI;
    3068                         if (iMatch & 1)
    3069                             ExpectCtx.rflags.u32 = Ctx.rflags.u32 | X86_EFL_ZF;
    3070                         else
    3071                             ExpectCtx.rflags.u32 = Ctx.rflags.u32 & ~X86_EFL_ZF;
    3072                         ExpectCtx.rip.u = Ctx.rip.u + s_aWorkers[iWorker].offIcebp;
    3073 
    3074                         /** @todo r=aeichner RF (Resume Flag) gets always cleared on my i7-6700K. */
    3075                         ExpectCtx.rflags.u32 &= ~X86_EFL_RF;
     3071                        PRTUINT64U pBuf = (PRTUINT64U)&pau64->au8[offBuf];
     3072
     3073                        ExpectCtx.rax.u = Ctx.rax.u = CX8_MISMATCH_LO;
     3074                        ExpectCtx.rdx.u = Ctx.rdx.u = CX8_MISMATCH_HI;
     3075
     3076                        Bs3RegCtxSetGrpSegFromCurPtr(&Ctx, &Ctx.rdi, &Ctx.fs, pBuf);
     3077                        Bs3RegCtxSetGrpSegFromCurPtr(&ExpectCtx, &ExpectCtx.rdi, &ExpectCtx.fs, pBuf);
     3078
     3079                        for (iMatch = 0; iMatch < 2; iMatch++)
     3080                        {
     3081                            uint8_t bExpectXcpt;
     3082                            pBuf->s.Lo = CX8_OLD_LO;
     3083                            pBuf->s.Hi = CX8_OLD_HI;
     3084
     3085                            Bs3TrapSetJmpAndRestore(&Ctx, &TrapFrame);
     3086                            g_usBs3TestStep++;
     3087                            //Bs3TestPrintf("Test: iFlags=%d offBuf=%d iMatch=%u iWorker=%u\n", iFlags, offBuf, iMatch, iWorker);
     3088                            bExpectXcpt = X86_XCPT_UD;
     3089                            if (fSupportCX8)
     3090                            {
     3091                                if (   offBuf
     3092                                    && bRing == 3
     3093                                    && bMode != BS3_MODE_RM
     3094                                    && !BS3_MODE_IS_V86(bMode)
     3095                                    && iCfg)
     3096                                {
     3097                                    bExpectXcpt = X86_XCPT_AC;
     3098                                    ExpectCtx.rflags.u32 = Ctx.rflags.u32;
     3099                                }
     3100                                else
     3101                                {
     3102                                    bExpectXcpt = X86_XCPT_DB;
     3103
     3104                                    ExpectCtx.rax.u = CX8_OLD_LO;
     3105                                    ExpectCtx.rdx.u = CX8_OLD_HI;
     3106
     3107                                    if (iMatch & 1)
     3108                                        ExpectCtx.rflags.u32 = Ctx.rflags.u32 | X86_EFL_ZF;
     3109                                    else
     3110                                        ExpectCtx.rflags.u32 = Ctx.rflags.u32 & ~X86_EFL_ZF;
     3111                                }
     3112
     3113                                /* Kludge! Looks like EFLAGS.AC is cleared when raising #GP in real mode on an i7-6700K. WEIRD! */
     3114                                if (bMode == BS3_MODE_RM && (Ctx.rflags.u32 & X86_EFL_AC))
     3115                                {
     3116                                    if (TrapFrame.Ctx.rflags.u32 & X86_EFL_AC)
     3117                                        Bs3TestFailedF("Expected EFLAGS.AC to be cleared (bXcpt=%d)", TrapFrame.bXcpt);
     3118                                    TrapFrame.Ctx.rflags.u32 |= X86_EFL_AC;
     3119                                }
     3120                            }
     3121
     3122                            if (   !Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &ExpectCtx, bExpectXcpt == X86_XCPT_DB ? s_aWorkers[iWorker].offIcebp : 0, 0 /*cbSpAdjust*/,
     3123                                                         bExpectXcpt == X86_XCPT_DB || BS3_MODE_IS_16BIT_SYS(bMode) ? 0 : X86_EFL_RF, pszMode, g_usBs3TestStep)
     3124                                || TrapFrame.bXcpt != bExpectXcpt)
     3125                            {
     3126                                if (TrapFrame.bXcpt != bExpectXcpt)
     3127                                    Bs3TestFailedF("Expected bXcpt=#%x, got %#x (%#x)", bExpectXcpt, TrapFrame.bXcpt, TrapFrame.uErrCd);
     3128                                Bs3TestFailedF("^^^ bRing=%u iCfg=%d iWorker=%d iFlags=%d offBuf=%d iMatch=%u\n",
     3129                                               bRing, iCfg, iWorker, iFlags, offBuf, iMatch);
     3130                                ASMHalt();
     3131                            }
     3132
     3133                            ExpectCtx.rax.u = Ctx.rax.u = CX8_OLD_LO;
     3134                            ExpectCtx.rdx.u = Ctx.rdx.u = CX8_OLD_HI;
     3135                        }
    30763136                    }
    3077                     if (   !Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &ExpectCtx, 0 /*cbPcAdjust*/, 0 /*cbSpAdjust*/,
    3078                                                  0 /*fExtraEfl*/, "mode", 0 /*idTestStep*/)
    3079                         || TrapFrame.bXcpt != bExpectXcpt)
    3080                     {
    3081                         if (TrapFrame.bXcpt != bExpectXcpt)
    3082                             Bs3TestFailedF("Expected bXcpt=#%x, got %#x (%#x)", bExpectXcpt, TrapFrame.bXcpt, TrapFrame.uErrCd);
    3083                         Bs3TestFailedF("^^^ iWorker=%d iFlags=%d offBuf=%d iMatch=%u\n", iWorker, iFlags, offBuf, iMatch);
    3084                         ASMHalt();
    3085                     }
    3086 
    3087                     ExpectCtx.rax.u = Ctx.rax.u = CX8_OLD_LO;
    3088                     ExpectCtx.rdx.u = Ctx.rdx.u = CX8_OLD_HI;
     3137                    Ctx.rflags.u16 &= ~X86_EFL_STATUS_BITS;
    30893138                }
    30903139            }
    3091             Ctx.rflags.u16 &= ~X86_EFL_STATUS_BITS;
    3092         }
     3140        } /* for each test config. */
     3141
     3142        /*
     3143         * Next ring.
     3144         */
     3145        bRing++;
     3146        if (bRing > 3 || bMode == BS3_MODE_RM)
     3147            break;
     3148        Bs3RegCtxConvertToRingX(&Ctx, bRing);
    30933149    }
    30943150
     
    31053161BS3_DECL_FAR(uint8_t) BS3_CMN_NM(bs3CpuInstr2_cmpxchg16b)(uint8_t bMode)
    31063162{
    3107     BS3REGCTX       Ctx;
    3108     BS3REGCTX       ExpectCtx;
    3109     BS3TRAPFRAME    TrapFrame;
    3110     RTUINT128U      au128[3];
    3111     PRTUINT128U     pau128       = RT_ALIGN_PT(&au128[0], sizeof(RTUINT128U), PRTUINT128U);
    3112     bool const      fSupportCX16 = RT_BOOL(ASMCpuId_ECX(1) & X86_CPUID_FEATURE_ECX_CX16);
    3113     unsigned        iFlags;
    3114     unsigned        offBuf;
    3115     unsigned        iMatch;
    3116     unsigned        iWorker;
     3163    BS3REGCTX                   Ctx;
     3164    BS3REGCTX                   ExpectCtx;
     3165    BS3TRAPFRAME                TrapFrame;
     3166    RTUINT128U                  au128[3];
     3167    PRTUINT128U                 pau128       = RT_ALIGN_PT(&au128[0], sizeof(RTUINT128U), PRTUINT128U);
     3168    bool const                  fSupportCX16 = RT_BOOL(ASMCpuId_ECX(1) & X86_CPUID_FEATURE_ECX_CX16);
     3169    const char BS3_FAR * const  pszMode      = Bs3GetModeName(bMode);
     3170    uint8_t                     bRing        = BS3_MODE_IS_V86(bMode) ? 3 : 0;
     3171    unsigned                    iFlags;
     3172    unsigned                    offBuf;
     3173    unsigned                    iMatch;
     3174    unsigned                    iWorker;
    31173175    static struct
    31183176    {
     
    31453203        Bs3TestPrintf("Note! CMPXCHG16B is not supported by the CPU!\n");
    31463204
     3205
    31473206    /*
    3148      * One loop with the normal variant and one with the locked one
     3207     * Run the tests in all rings since alignment issues may behave
     3208     * differently in ring-3 compared to ring-0.
    31493209     */
    3150     g_usBs3TestStep = 0;
    3151     for (iWorker = 0; iWorker < RT_ELEMENTS(s_aWorkers); iWorker++)
    3152     {
    3153         Bs3RegCtxSetRipCsFromCurPtr(&Ctx, s_aWorkers[iWorker].pfnWorker);
    3154 
     3210    for (;;)
     3211    {
    31553212        /*
    3156          * One loop with all status flags set, and one with them clear.
     3213         * One loop with alignment checks disabled and one with enabled.
    31573214         */
    3158         Ctx.rflags.u16 |= X86_EFL_STATUS_BITS;
    3159         for (iFlags = 0; iFlags < 2; iFlags++)
     3215        unsigned iCfg;
     3216        for (iCfg = 0; iCfg < 2; iCfg++)
    31603217        {
    3161             Bs3MemCpy(&ExpectCtx, &Ctx, sizeof(ExpectCtx));
    3162 
    3163             for (offBuf = 0; offBuf < sizeof(RTUINT128U); offBuf++)
     3218            if (iCfg)
    31643219            {
     3220                Ctx.rflags.u32 |= X86_EFL_AC;
     3221                Ctx.cr0.u32    |= X86_CR0_AM;
     3222            }
     3223            else
     3224            {
     3225                Ctx.rflags.u32 &= ~X86_EFL_AC;
     3226                Ctx.cr0.u32    &= ~X86_CR0_AM;
     3227            }
     3228
     3229            /*
     3230             * One loop with the normal variant and one with the locked one
     3231             */
     3232            g_usBs3TestStep = 0;
     3233            for (iWorker = 0; iWorker < RT_ELEMENTS(s_aWorkers); iWorker++)
     3234            {
     3235                Bs3RegCtxSetRipCsFromCurPtr(&Ctx, s_aWorkers[iWorker].pfnWorker);
     3236
     3237                /*
     3238                 * One loop with all status flags set, and one with them clear.
     3239                 */
     3240                Ctx.rflags.u16 |= X86_EFL_STATUS_BITS;
     3241                for (iFlags = 0; iFlags < 2; iFlags++)
     3242                {
     3243                    Bs3MemCpy(&ExpectCtx, &Ctx, sizeof(ExpectCtx));
     3244
     3245                    for (offBuf = 0; offBuf < sizeof(RTUINT128U); offBuf++)
     3246                    {
    31653247#  define CX16_OLD_LO       UINT64_C(0xabb6345dcc9c4bbd)
    31663248#  define CX16_OLD_HI       UINT64_C(0x7b06ea35749549ab)
     
    31703252#  define CX16_STORE_HI     UINT64_C(0x17ff434ed1b54963)
    31713253
    3172                 PRTUINT128U pBuf = (PRTUINT128U)&pau128->au8[offBuf];
    3173 
    3174                 ExpectCtx.rax.u = Ctx.rax.u = CX16_MISMATCH_LO;
    3175                 ExpectCtx.rdx.u = Ctx.rdx.u = CX16_MISMATCH_HI;
    3176                 for (iMatch = 0; iMatch < 2; iMatch++)
    3177                 {
    3178                     uint8_t bExpectXcpt;
    3179                     pBuf->s.Lo = CX16_OLD_LO;
    3180                     pBuf->s.Hi = CX16_OLD_HI;
    3181                     ExpectCtx.rdi.u = Ctx.rdi.u = (uintptr_t)pBuf;
    3182                     Bs3TrapSetJmpAndRestore(&Ctx, &TrapFrame);
    3183                     g_usBs3TestStep++;
    3184                     //Bs3TestPrintf("Test: iFlags=%d offBuf=%d iMatch=%u iWorker=%u\n", iFlags, offBuf, iMatch, iWorker);
    3185                     bExpectXcpt = X86_XCPT_UD;
    3186                     if (fSupportCX16)
    3187                     {
    3188                         if (offBuf & 15)
     3254                        PRTUINT128U pBuf = (PRTUINT128U)&pau128->au8[offBuf];
     3255
     3256                        ExpectCtx.rax.u = Ctx.rax.u = CX16_MISMATCH_LO;
     3257                        ExpectCtx.rdx.u = Ctx.rdx.u = CX16_MISMATCH_HI;
     3258                        for (iMatch = 0; iMatch < 2; iMatch++)
    31893259                        {
    3190                             bExpectXcpt = X86_XCPT_GP;
    3191                             ExpectCtx.rip.u = Ctx.rip.u;
    3192                             ExpectCtx.rflags.u32 = Ctx.rflags.u32;
     3260                            uint8_t bExpectXcpt;
     3261                            pBuf->s.Lo = CX16_OLD_LO;
     3262                            pBuf->s.Hi = CX16_OLD_HI;
     3263                            ExpectCtx.rdi.u = Ctx.rdi.u = (uintptr_t)pBuf;
     3264                            Bs3TrapSetJmpAndRestore(&Ctx, &TrapFrame);
     3265                            g_usBs3TestStep++;
     3266                            //Bs3TestPrintf("Test: iFlags=%d offBuf=%d iMatch=%u iWorker=%u\n", iFlags, offBuf, iMatch, iWorker);
     3267                            bExpectXcpt = X86_XCPT_UD;
     3268                            if (fSupportCX16)
     3269                            {
     3270                                if (offBuf & 15)
     3271                                {
     3272                                    bExpectXcpt = X86_XCPT_GP;
     3273                                    ExpectCtx.rip.u = Ctx.rip.u;
     3274                                    ExpectCtx.rflags.u32 = Ctx.rflags.u32;
     3275                                }
     3276                                else
     3277                                {
     3278                                    ExpectCtx.rax.u = CX16_OLD_LO;
     3279                                    ExpectCtx.rdx.u = CX16_OLD_HI;
     3280                                    if (iMatch & 1)
     3281                                        ExpectCtx.rflags.u32 = Ctx.rflags.u32 | X86_EFL_ZF;
     3282                                    else
     3283                                        ExpectCtx.rflags.u32 = Ctx.rflags.u32 & ~X86_EFL_ZF;
     3284                                    ExpectCtx.rip.u = Ctx.rip.u + s_aWorkers[iWorker].offUd2;
     3285                                }
     3286                                ExpectCtx.rflags.u32 |= X86_EFL_RF;
     3287                            }
     3288                            if (   !Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &ExpectCtx, 0 /*cbPcAdjust*/, 0 /*cbSpAdjust*/,
     3289                                                         0 /*fExtraEfl*/, pszMode, 0 /*idTestStep*/)
     3290                                || TrapFrame.bXcpt != bExpectXcpt)
     3291                            {
     3292                                if (TrapFrame.bXcpt != bExpectXcpt)
     3293                                    Bs3TestFailedF("Expected bXcpt=#%x, got %#x (%#x)", bExpectXcpt, TrapFrame.bXcpt, TrapFrame.uErrCd);
     3294                                Bs3TestFailedF("^^^bRing=%d iWorker=%d iFlags=%d offBuf=%d iMatch=%u\n", bRing, iWorker, iFlags, offBuf, iMatch);
     3295                                ASMHalt();
     3296                            }
     3297
     3298                            ExpectCtx.rax.u = Ctx.rax.u = CX16_OLD_LO;
     3299                            ExpectCtx.rdx.u = Ctx.rdx.u = CX16_OLD_HI;
    31933300                        }
    3194                         else
    3195                         {
    3196                             ExpectCtx.rax.u = CX16_OLD_LO;
    3197                             ExpectCtx.rdx.u = CX16_OLD_HI;
    3198                             if (iMatch & 1)
    3199                                 ExpectCtx.rflags.u32 = Ctx.rflags.u32 | X86_EFL_ZF;
    3200                             else
    3201                                 ExpectCtx.rflags.u32 = Ctx.rflags.u32 & ~X86_EFL_ZF;
    3202                             ExpectCtx.rip.u = Ctx.rip.u + s_aWorkers[iWorker].offUd2;
    3203                         }
    3204                         ExpectCtx.rflags.u32 |= X86_EFL_RF;
    32053301                    }
    3206                     if (   !Bs3TestCheckRegCtxEx(&TrapFrame.Ctx, &ExpectCtx, 0 /*cbPcAdjust*/, 0 /*cbSpAdjust*/,
    3207                                                  0 /*fExtraEfl*/, "lm64", 0 /*idTestStep*/)
    3208                         || TrapFrame.bXcpt != bExpectXcpt)
    3209                     {
    3210                         if (TrapFrame.bXcpt != bExpectXcpt)
    3211                             Bs3TestFailedF("Expected bXcpt=#%x, got %#x (%#x)", bExpectXcpt, TrapFrame.bXcpt, TrapFrame.uErrCd);
    3212                         Bs3TestFailedF("^^^ iWorker=%d iFlags=%d offBuf=%d iMatch=%u\n", iWorker, iFlags, offBuf, iMatch);
    3213                         ASMHalt();
    3214                     }
    3215 
    3216                     ExpectCtx.rax.u = Ctx.rax.u = CX16_OLD_LO;
    3217                     ExpectCtx.rdx.u = Ctx.rdx.u = CX16_OLD_HI;
     3302                    Ctx.rflags.u16 &= ~X86_EFL_STATUS_BITS;
    32183303                }
    32193304            }
    3220             Ctx.rflags.u16 &= ~X86_EFL_STATUS_BITS;
    3221         }
     3305        } /* for each test config. */
     3306
     3307        /*
     3308         * Next ring.
     3309         */
     3310        bRing++;
     3311        if (bRing > 3 || bMode == BS3_MODE_RM)
     3312            break;
     3313        Bs3RegCtxConvertToRingX(&Ctx, bRing);
    32223314    }
    32233315
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