Index: /trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp	(revision 105124)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp	(revision 105125)
@@ -819,15 +819,13 @@
                 return rcStrict;
 
-            /** @todo Is the popf VME \#GP(0) delivered after updating RSP+RIP
-             *        or before? */
-            if (    (   (u16Value & X86_EFL_IF)
-                     && (fEflOld  & X86_EFL_VIP))
-                ||  (u16Value & X86_EFL_TF) )
+            if (   (   (u16Value & X86_EFL_IF)
+                    && (fEflOld  & X86_EFL_VIP))
+                || (u16Value & X86_EFL_TF) )
                 return iemRaiseGeneralProtectionFault0(pVCpu);
 
-            fEflNew = u16Value | (fEflOld & UINT32_C(0xffff0000) & ~X86_EFL_VIF);
-            fEflNew |= (fEflNew & X86_EFL_IF) << (19 - 9);
-            fEflNew &=   X86_EFL_POPF_BITS & ~(X86_EFL_IOPL | X86_EFL_IF);
-            fEflNew |= ~(X86_EFL_POPF_BITS & ~(X86_EFL_IOPL | X86_EFL_IF)) & fEflOld;
+            fEflNew = X86_EFL_RA1_MASK
+                    | (u16Value & ~(X86_EFL_IF | X86_EFL_IOPL | X86_EFL_RAZ_MASK))
+                    | (fEflOld & (UINT32_C(0xffff0000) | X86_EFL_IF | X86_EFL_IOPL) & ~(X86_EFL_VIF | X86_EFL_RF))
+                    | ((uint32_t)(u16Value & X86_EFL_IF) << (X86_EFL_VIF_BIT - X86_EFL_IF_BIT));
 
             pVCpu->cpum.GstCtx.rsp = TmpRsp.u;
Index: /trunk/src/VBox/VMM/include/IEMInline.h
===================================================================
--- /trunk/src/VBox/VMM/include/IEMInline.h	(revision 105124)
+++ /trunk/src/VBox/VMM/include/IEMInline.h	(revision 105125)
@@ -2098,4 +2098,5 @@
  *              Stacks}
  */
+template<uint32_t const a_fTF = X86_EFL_TF>
 static VBOXSTRICTRC iemFinishInstructionWithFlagsSet(PVMCPUCC pVCpu, int rcNormal) RT_NOEXCEPT
 {
@@ -2103,5 +2104,5 @@
      * Normally we're just here to clear RF and/or interrupt shadow bits.
      */
-    if (RT_LIKELY((pVCpu->cpum.GstCtx.eflags.uBoth & (X86_EFL_TF | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) == 0))
+    if (RT_LIKELY((pVCpu->cpum.GstCtx.eflags.uBoth & (a_fTF | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) == 0))
         pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW);
     else
@@ -2111,9 +2112,9 @@
          */
         VBOXSTRICTRC rcStrict;
-        if (pVCpu->cpum.GstCtx.eflags.uBoth & (X86_EFL_TF | CPUMCTX_DBG_HIT_DRX_MASK))
+        if (pVCpu->cpum.GstCtx.eflags.uBoth & (a_fTF | CPUMCTX_DBG_HIT_DRX_MASK))
         {
             IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_DR6);
             pVCpu->cpum.GstCtx.dr[6] &= ~X86_DR6_B_MASK;
-            if (pVCpu->cpum.GstCtx.eflags.uBoth & X86_EFL_TF)
+            if (pVCpu->cpum.GstCtx.eflags.uBoth & a_fTF)
                 pVCpu->cpum.GstCtx.dr[6] |= X86_DR6_BS;
             pVCpu->cpum.GstCtx.dr[6] |= (pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_HIT_DRX_MASK_NONSILENT)
@@ -2862,5 +2863,12 @@
     iemRegAddToRip(pVCpu, cbInstr);
     if (!(fEflOld & X86_EFL_TF))
-        return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
+    {
+        /* Specialized iemRegFinishClearingRF edition here that doesn't check X86_EFL_TF. */
+        AssertCompile(CPUMCTX_INHIBIT_SHADOW < UINT32_MAX);
+        if (RT_LIKELY(!(  pVCpu->cpum.GstCtx.eflags.uBoth
+                        & (X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) ))
+            return VINF_SUCCESS;
+        return iemFinishInstructionWithFlagsSet<0 /*a_fTF*/>(pVCpu, VINF_SUCCESS); /* TF=0, so ignore it.  */
+    }
     return iemFinishInstructionWithTfSet(pVCpu);
 }
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1-template.mac
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1-template.mac	(revision 105124)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1-template.mac	(revision 105125)
@@ -348,4 +348,31 @@
  %endif
 
+
+;
+; popf
+;
+BS3_PROC_BEGIN_CMN bs3CpuWeird1_Popf_Nop_Ud2, BS3_PBC_NEAR
+        popf
+        nop
+.ud2_again:
+        ud2
+        jmp     .ud2_again
+AssertCompile(.ud2_again - BS3_CMN_NM(bs3CpuWeird1_Popf_Nop_Ud2) == 2)
+BS3_PROC_END_CMN   bs3CpuWeird1_Popf_Nop_Ud2
+
+;
+; popf
+;
+BS3_PROC_BEGIN_CMN bs3CpuWeird1_Popf_opsize_Nop_Ud2, BS3_PBC_NEAR
+        db      066h
+        popf
+        nop
+.ud2_again:
+        ud2
+        jmp     .ud2_again
+AssertCompile(.ud2_again - BS3_CMN_NM(bs3CpuWeird1_Popf_opsize_Nop_Ud2) == 3)
+BS3_PROC_END_CMN   bs3CpuWeird1_Popf_opsize_Nop_Ud2
+
+
 %endif ; BS3_INSTANTIATING_CMN
 
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1-x0.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1-x0.c	(revision 105124)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1-x0.c	(revision 105125)
@@ -62,4 +62,14 @@
     extern FNBS3FAR a_Name##_c64, a_Name##_##a_Label##_c64
 
+#define PROTO_ALL(a_Template) \
+    extern FNBS3FAR a_Template ## _c16, \
+                    a_Template ## _c32, \
+                    a_Template ## _c64
+
+#define PROTO_ALL_WITH_END(a_Template) \
+    extern FNBS3FAR a_Template ## _c16, a_Template ## _c16_EndProc, \
+                    a_Template ## _c32, a_Template ## _c32_EndProc, \
+                    a_Template ## _c64, a_Template ## _c64_EndProc
+
 
 /*********************************************************************************************************************************
@@ -145,5 +155,5 @@
                       uDr6, pTrapCtx->uHandlerCs, pTrapCtx->uHandlerSs, pTrapCtx->uHandlerRsp,
                       pTrapCtx->fHandlerRfl, pTrapCtx->cbIretFrame);
-#if 1
+#if 0
         Bs3TestPrintf("Halting in CompareIntCtx: bXcpt=%#x\n", bXcpt);
         ASMHalt();
@@ -653,18 +663,13 @@
 *   IP / EIP  Wrapping                                                                                                           *
 *********************************************************************************************************************************/
-#define PROTO_ALL(a_Template) \
-    FNBS3FAR a_Template ## _c16, a_Template ## _c16_EndProc, \
-             a_Template ## _c32, a_Template ## _c32_EndProc, \
-             a_Template ## _c64, a_Template ## _c64_EndProc
-PROTO_ALL(bs3CpuWeird1_PcWrapBenign1);
-PROTO_ALL(bs3CpuWeird1_PcWrapBenign2);
-PROTO_ALL(bs3CpuWeird1_PcWrapCpuId);
-PROTO_ALL(bs3CpuWeird1_PcWrapIn80);
-PROTO_ALL(bs3CpuWeird1_PcWrapOut80);
-PROTO_ALL(bs3CpuWeird1_PcWrapSmsw);
-PROTO_ALL(bs3CpuWeird1_PcWrapRdCr0);
-PROTO_ALL(bs3CpuWeird1_PcWrapRdDr0);
-PROTO_ALL(bs3CpuWeird1_PcWrapWrDr0);
-#undef PROTO_ALL
+PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapBenign1);
+PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapBenign2);
+PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapCpuId);
+PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapIn80);
+PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapOut80);
+PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapSmsw);
+PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapRdCr0);
+PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapRdDr0);
+PROTO_ALL_WITH_END(bs3CpuWeird1_PcWrapWrDr0);
 
 typedef enum { kPcWrapSetup_None, kPcWrapSetup_ZeroRax } PCWRAPSETUP;
@@ -1207,8 +1212,4 @@
 *   PUSH / POP                                                                                                                   *
 *********************************************************************************************************************************/
-#define PROTO_ALL(a_Template) \
-    FNBS3FAR a_Template ## _c16, \
-             a_Template ## _c32, \
-             a_Template ## _c64
 PROTO_ALL(bs3CpuWeird1_Push_xSP_Ud2);
 PROTO_ALL(bs3CpuWeird1_Push_opsize_xSP_Ud2);
@@ -1217,5 +1218,4 @@
 PROTO_ALL(bs3CpuWeird1_Pop_opsize_xSP_Ud2);
 PROTO_ALL(bs3CpuWeird1_Pop_opsize_xBX_Ud2);
-#undef PROTO_ALL
 
 
@@ -1504,8 +1504,4 @@
 *   PUSH SREG / POP SREG                                                                                                         *
 *********************************************************************************************************************************/
-#define PROTO_ALL(a_Template) \
-    FNBS3FAR a_Template ## _c16, \
-             a_Template ## _c32, \
-             a_Template ## _c64
 PROTO_ALL(bs3CpuWeird1_Push_cs_Ud2);
 PROTO_ALL(bs3CpuWeird1_Push_ss_Ud2);
@@ -1530,5 +1526,4 @@
 PROTO_ALL(bs3CpuWeird1_Pop_opsize_fs_Ud2);
 PROTO_ALL(bs3CpuWeird1_Pop_opsize_gs_Ud2);
-#undef PROTO_ALL
 
 
@@ -1836,8 +1831,5 @@
                         Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
                         if (bs3CpuWeird1_ComparePushPop(&TrapCtx, &TrapExpect))
-                        {
-                            ASMHalt();
                             break;
-                        }
 
                         if (*PtrStack2.pu64 != u64ExpectPushed.u)
@@ -1865,8 +1857,5 @@
                         Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
                         if (bs3CpuWeird1_ComparePushPop(&TrapCtx, &TrapExpect))
-                        {
-                            ASMHalt();
                             break;
-                        }
                     }
 #endif
@@ -1890,2 +1879,303 @@
 }
 
+
+
+/*********************************************************************************************************************************
+*   POPF                                                                                                                         *
+*********************************************************************************************************************************/
+
+/**
+ * Compares popf result.
+ */
+static uint8_t bs3CpuWeird1_ComparePopf(PCBS3TRAPFRAME pTrapCtx, PCBS3REGCTX pCtxExpect, uint8_t bXcpt)
+{
+    uint16_t const cErrorsBefore = Bs3TestSubErrorCount();
+    CHECK_MEMBER("bXcpt",       "%#04x",    pTrapCtx->bXcpt,        bXcpt);
+    CHECK_MEMBER("bErrCd",      "%#06RX64", pTrapCtx->uErrCd,       0);
+    Bs3TestCheckRegCtxEx(&pTrapCtx->Ctx, pCtxExpect, 0 /*cbPcAdjust*/, 0 /*cbSpAdjust*/, 0 /*fExtraEfl*/,
+                         g_pszTestMode, g_usBs3TestStep);
+    if (Bs3TestSubErrorCount() != cErrorsBefore)
+    {
+        Bs3TrapPrintFrame(pTrapCtx);
+#if 0
+        Bs3TestPrintf("Halting in ComparePopf: bXcpt=%#x\n", pTrapCtx->bXcpt);
+        ASMHalt();
+#endif
+        return 1;
+    }
+    return 0;
+}
+
+PROTO_ALL(bs3CpuWeird1_Popf_Nop_Ud2);
+PROTO_ALL(bs3CpuWeird1_Popf_opsize_Nop_Ud2);
+
+BS3_DECL_FAR(uint8_t) BS3_CMN_FAR_NM(bs3CpuWeird1_Popf)(uint8_t bTestMode)
+{
+    static struct
+    {
+        FPFNBS3FAR  pfnStart;
+        uint8_t     cBits;
+        int8_t      cbAdjSp;    /**< The SP adjustment value. */
+        uint8_t     offNop;     /**< The NOP offset into the code. */
+        uint8_t     offUd2;     /**< The UD2 offset into the code. */
+    } const s_aTests[] =
+    {
+        { bs3CpuWeird1_Popf_Nop_Ud2_c16,        16, 2, 1, 2 },
+        { bs3CpuWeird1_Popf_opsize_Nop_Ud2_c16, 16, 4, 2, 3 },
+
+        { bs3CpuWeird1_Popf_Nop_Ud2_c32,        32, 4, 1, 2 },
+        { bs3CpuWeird1_Popf_opsize_Nop_Ud2_c32, 32, 2, 2, 3 },
+
+        { bs3CpuWeird1_Popf_Nop_Ud2_c64,        64, 8, 1, 2 },
+        { bs3CpuWeird1_Popf_opsize_Nop_Ud2_c64, 64, 2, 2, 3 },
+    };
+
+    BS3REGCTX               Ctx;
+    BS3REGCTX               CtxExpect;
+    BS3TRAPFRAME            TrapCtx;
+    BS3PTRUNION             PtrStack;
+    uint8_t const           cTestBits = BS3_MODE_IS_16BIT_CODE(bTestMode) ? 16 : BS3_MODE_IS_32BIT_CODE(bTestMode) ? 32 : 64;
+    uint32_t const          fEflCpu   = X86_EFL_1 | X86_EFL_STATUS_BITS | X86_EFL_DF | X86_EFL_IF | X86_EFL_TF
+                                      | ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80286 ? X86_EFL_IOPL | X86_EFL_NT : 0)
+                                      | ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386 ? X86_EFL_RF | X86_EFL_VM : 0)
+                                      | ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80486 ? X86_EFL_AC | X86_EFL_VIP | X86_EFL_VIF : 0)
+                                      | (g_uBs3CpuDetected & BS3CPU_F_CPUID                     ? X86_EFL_ID : 0);
+    uint32_t const          fEflClear = X86_EFL_1;
+    uint32_t const          fEflSet   = X86_EFL_1 | X86_EFL_STATUS_BITS
+                                      | X86_EFL_DF /* safe? */
+                                      | X86_EFL_IF /* safe? */
+                                      | ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386 ? X86_EFL_RF : 0)
+                                      | ((g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80486 ? X86_EFL_AC | X86_EFL_VIP : 0)
+                                      | (g_uBs3CpuDetected & BS3CPU_F_CPUID                     ? X86_EFL_ID : 0);
+    uint32_t const          fEflKeep  = X86_EFL_VM;
+    uint32_t const          fXcptRf   = BS3_MODE_IS_16BIT_SYS(bTestMode) ? 0 : X86_EFL_RF;
+    bool const              fVme      = BS3_MODE_IS_V86(bTestMode)
+                                     && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80486
+                                     && (Bs3RegGetCr4() & X86_CR4_VME); /* Can't use Ctx.cr4 here, it's always zero. */
+    unsigned                uRing;
+
+    //Bs3TestPrintf("g_uBs3CpuDetected=%#RX16 fEflCpu=%#RX32 fEflSet=%#RX32\n", g_uBs3CpuDetected, fEflCpu, fEflSet);
+    /* make sure they're allocated  */
+    Bs3MemZero(&Ctx, sizeof(Ctx));
+    Bs3MemZero(&TrapCtx, sizeof(TrapCtx));
+
+    bs3CpuWeird1_SetGlobals(bTestMode);
+
+    /* Construct a basic context. */
+    Bs3RegCtxSaveEx(&Ctx, bTestMode, 1024);
+    bs3RegCtxScramble(&Ctx, bTestMode);
+    Bs3MemCpy(&CtxExpect, &Ctx, sizeof(CtxExpect));
+
+    /* Make PtrStack == SS:xSP from Ctx. */
+    PtrStack.pv = Bs3RegCtxGetRspSsAsCurPtr(&Ctx);
+
+    /*
+     * The instruction works differently in different rings, so try them all.
+     */
+    for (uRing = BS3_MODE_IS_V86(bTestMode) ? 3 : 0; ;)
+    {
+        /*
+         * We've got a couple of instruction variations with/without the opsize prefix.
+         */
+        unsigned iTest;
+        for (iTest = 0; iTest < RT_ELEMENTS(s_aTests); iTest++)
+        {
+            if (s_aTests[iTest].cBits == cTestBits)
+            {
+                uint8_t const cbAdjSp = s_aTests[iTest].cbAdjSp;
+                unsigned      uIopl;
+
+                /* Setup the test context. */
+                Bs3RegCtxSetRipCsFromLnkPtr(&Ctx, s_aTests[iTest].pfnStart);
+                if (BS3_MODE_IS_16BIT_SYS(bTestMode))
+                    g_uBs3TrapEipHint = Ctx.rip.u32;
+                CtxExpect.cs    = Ctx.cs;
+
+                for (uIopl = 0; uIopl <= X86_EFL_IOPL; uIopl += 1 << X86_EFL_IOPL_SHIFT)
+                {
+                    bool const     fAlwaysUd  = cbAdjSp != 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) <= BS3CPU_80286;
+                    bool const     fAlwaysGp  = uIopl != X86_EFL_IOPL && BS3_MODE_IS_V86(bTestMode) && (cbAdjSp == 4 || !fVme);
+                    uint8_t const  bXcptNorm  = fAlwaysGp ? X86_XCPT_GP : X86_XCPT_UD;
+                    uint8_t const  offUd      = fAlwaysGp || fAlwaysUd ? 0 : s_aTests[iTest].offUd2;
+                    uint32_t const fCleared   = fAlwaysUd ? 0 : fAlwaysGp ? /* 10980xe - go figure: */ X86_EFL_RF
+                                              : bTestMode == BS3_MODE_RM
+                                              ? X86_EFL_RF | X86_EFL_AC | X86_EFL_VIP /** @todo figure this. iret? bs3kit bug? */
+                                              : X86_EFL_RF;
+                    uint32_t       fPoppable  = fAlwaysGp || fAlwaysUd ? 0
+                                              : uRing == 0                              ? X86_EFL_POPF_BITS
+                                              : uRing <= (uIopl >> X86_EFL_IOPL_SHIFT)  ? X86_EFL_POPF_BITS & ~(X86_EFL_IOPL)
+                                              : !fAlwaysGp                              ? X86_EFL_POPF_BITS & ~(X86_EFL_IOPL | X86_EFL_IF)
+                                              : 0;
+                    uint8_t        bXcptExpect;
+                    fPoppable &= fEflCpu;
+                    if (cbAdjSp == 2)
+                        fPoppable &= UINT16_MAX;
+                    if (bTestMode == BS3_MODE_RM && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) == BS3CPU_80286)
+                        fPoppable &= ~(X86_EFL_IOPL | X86_EFL_NT);
+                    //Bs3TestPrintf("uRing=%u iTest=%u uIopl=%#x fPoppable=%#RX32 fVme=%d cbAdjSp=%d\n", uRing, iTest, uIopl, fPoppable, fVme, cbAdjSp);
+
+                    /* The first steps works with as many EFLAGS bits set as possible. */
+                    Ctx.rflags.u32 &= fEflKeep;
+                    Ctx.rflags.u32 |= fEflSet | uIopl;
+                    CtxExpect.rip.u = Ctx.rip.u + offUd;
+                    CtxExpect.rsp.u = fAlwaysGp || fAlwaysUd ? Ctx.rsp.u : Ctx.rsp.u + cbAdjSp;
+
+                    /*
+                     * Step 1 - pop zero.
+                     */
+                    g_usBs3TestStep++;
+                    PtrStack.pu32[1]     = UINT32_MAX;
+                    if (cbAdjSp >= 4)
+                        PtrStack.pu32[0] = 0;
+                    else
+                    {
+                        PtrStack.pu16[1] = UINT16_MAX;
+                        PtrStack.pu16[0] = 0;
+                    }
+                    CtxExpect.rflags.u32 = (Ctx.rflags.u32 & ~fPoppable & ~fCleared) | fXcptRf;
+                    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
+                    if (bs3CpuWeird1_ComparePopf(&TrapCtx, &CtxExpect, bXcptNorm))
+                        break;
+
+                    /*
+                     * Step 2 - pop 0xfffffff sans TF.
+                     */
+                    g_usBs3TestStep++;
+                    PtrStack.pu32[1] = UINT32_MAX;
+                    PtrStack.pu32[0] = UINT32_MAX & ~X86_EFL_TF;
+                    CtxExpect.rflags.u32 = (Ctx.rflags.u32 & ~fPoppable & ~fCleared)
+                                         | (UINT32_MAX & ~X86_EFL_TF & fPoppable & ~fCleared)
+                                         | fXcptRf;
+                    bXcptExpect = bXcptNorm;
+                    if (fVme && cbAdjSp == 2 && uIopl != X86_EFL_IOPL)
+                    {
+                        CtxExpect.rip.u      = Ctx.rip.u;
+                        CtxExpect.rsp.u      = Ctx.rsp.u;
+                        CtxExpect.rflags.u32 = (Ctx.rflags.u32 & ~fCleared) | fXcptRf;
+                        bXcptExpect = X86_XCPT_GP;
+                    }
+                    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
+                    if (bs3CpuWeird1_ComparePopf(&TrapCtx, &CtxExpect, bXcptExpect))
+                        break;
+
+
+                    /* We repeat the steps with max bits cleared before the popf. */
+                    Ctx.rflags.u32 &= fEflKeep;
+                    Ctx.rflags.u32 |= fEflClear | uIopl;
+                    CtxExpect.rip.u = Ctx.rip.u + offUd;
+                    CtxExpect.rsp.u = fAlwaysGp || fAlwaysUd ? Ctx.rsp.u : Ctx.rsp.u + cbAdjSp;
+
+                    /*
+                     * Step 3 - pop zero.
+                     */
+                    g_usBs3TestStep++;
+                    PtrStack.pu32[1]     = UINT32_MAX;
+                    if (cbAdjSp >= 4)
+                        PtrStack.pu32[0] = 0;
+                    else
+                    {
+                        PtrStack.pu16[1] = UINT16_MAX;
+                        PtrStack.pu16[0] = 0;
+                    }
+                    CtxExpect.rflags.u32 = (Ctx.rflags.u32 & ~fPoppable & ~fCleared) | fXcptRf;
+                    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
+                    if (bs3CpuWeird1_ComparePopf(&TrapCtx, &CtxExpect, bXcptNorm))
+                        break;
+
+                    /*
+                     * Step 4 - pop 0xfffffff sans TF.
+                     */
+                    g_usBs3TestStep++;
+                    PtrStack.pu32[1] = UINT32_MAX;
+                    PtrStack.pu32[0] = UINT32_MAX & ~X86_EFL_TF;
+                    CtxExpect.rflags.u32 = (Ctx.rflags.u32 & ~fPoppable & ~fCleared)
+                                         | (UINT32_MAX & ~X86_EFL_TF & fPoppable & ~fCleared)
+                                         | fXcptRf;
+                    if (fVme && cbAdjSp == 2 && uIopl != X86_EFL_IOPL)
+                        CtxExpect.rflags.u32 |= X86_EFL_VIF;
+                    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
+                    if (bs3CpuWeird1_ComparePopf(&TrapCtx, &CtxExpect, bXcptNorm))
+                        break;
+
+                    /*
+                     * Step 5 - Pop TF and get a #DB on the following instruction.
+                     */
+                    g_usBs3TestStep++;
+                    PtrStack.pu32[1] = UINT32_MAX;
+                    PtrStack.pu32[0] = UINT32_MAX;
+                    if (cbAdjSp != 2 || !fVme || uIopl == X86_EFL_IOPL)
+                    {
+                        CtxExpect.rflags.u32 = (Ctx.rflags.u32 & ~fPoppable & ~fCleared)
+                                             | (UINT32_MAX & fPoppable & ~fCleared)
+                                             | fXcptRf;
+                        CtxExpect.rip.u      = Ctx.rip.u + offUd;
+                        if (CtxExpect.rip.u != Ctx.rip.u)
+                        {
+                            bXcptExpect = X86_XCPT_DB;
+                            CtxExpect.rflags.u32 &= ~X86_EFL_RF;
+                        }
+                        else
+                            bXcptExpect = bXcptNorm;
+                    }
+                    else
+                    {
+                        CtxExpect.rflags.u32 = Ctx.rflags.u32 | fXcptRf;
+                        CtxExpect.rip.u      = Ctx.rip.u;
+                        CtxExpect.rsp.u      = Ctx.rsp.u;
+                        PtrStack.pu32[0]     = UINT32_MAX & ~X86_EFL_IF; /* only one trigger */
+                        bXcptExpect     = X86_XCPT_GP;
+                    }
+                    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
+                    if (bs3CpuWeird1_ComparePopf(&TrapCtx, &CtxExpect, bXcptExpect))
+                        break;
+
+                    /*
+                     * Step 6 - Start with TF set and pop zeros.  Should #DB after POPF.
+                     */
+                    g_usBs3TestStep++;
+                    PtrStack.pu32[1]     = UINT32_MAX;
+                    if (cbAdjSp >= 4)
+                        PtrStack.pu32[0] = 0;
+                    else
+                    {
+                        PtrStack.pu16[1] = UINT16_MAX;
+                        PtrStack.pu16[0] = 0;
+                    }
+                    Ctx.rflags.u32      |= X86_EFL_TF;
+                    CtxExpect.rip.u      = Ctx.rip.u + offUd - !!offUd;
+                    CtxExpect.rsp.u      = Ctx.rsp.u + (offUd ? cbAdjSp : 0);
+                    CtxExpect.rflags.u32 = (Ctx.rflags.u32 & ~fPoppable & ~fCleared) | fXcptRf;
+                    if (offUd)
+                        CtxExpect.rflags.u32 &= ~X86_EFL_RF;
+
+                    Bs3TrapSetJmpAndRestore(&Ctx, &TrapCtx);
+                    if (bs3CpuWeird1_ComparePopf(&TrapCtx, &CtxExpect, offUd ? X86_XCPT_DB : bXcptNorm))
+                        break;
+
+                    /** @todo test VIP in VME mode. */
+                    g_usBs3TestStep = (g_usBs3TestStep + 9) / 10 * 10;
+                }
+                g_usBs3TestStep = (g_usBs3TestStep + 99) / 100 * 100;
+            }
+            g_usBs3TestStep = (g_usBs3TestStep + 999) / 1000 * 1000;
+        }
+
+        /*
+         * Next ring.
+         */
+        if (uRing >= 3 || bTestMode == BS3_MODE_RM)
+            break;
+        uRing++;
+        Bs3RegCtxConvertToRingX(&Ctx, uRing);
+        CtxExpect.bCpl = Ctx.bCpl;
+        CtxExpect.ss   = Ctx.ss;
+        CtxExpect.ds   = Ctx.ds;
+        CtxExpect.es   = Ctx.es;
+        CtxExpect.fs   = Ctx.fs;
+        CtxExpect.gs   = Ctx.gs;
+        g_usBs3TestStep = (g_usBs3TestStep + 9999) / 10000 * 10000;
+    }
+
+    return 0;
+}
+
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1.c	(revision 105124)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-weird-1.c	(revision 105125)
@@ -50,4 +50,5 @@
 FNBS3TESTDOMODE BS3_CMN_FAR_NM(bs3CpuWeird1_PushPop);
 FNBS3TESTDOMODE BS3_CMN_FAR_NM(bs3CpuWeird1_PushPopSReg);
+FNBS3TESTDOMODE BS3_CMN_FAR_NM(bs3CpuWeird1_Popf);
 
 
@@ -57,8 +58,11 @@
 static const BS3TESTMODEBYONEENTRY g_aModeByOneTests[] =
 {
+#if 1
     { "dbg+inhibit+ringxfer",   BS3_CMN_FAR_NM(bs3CpuWeird1_DbgInhibitRingXfer),    0 },
     { "pc wrapping",            BS3_CMN_FAR_NM(bs3CpuWeird1_PcWrapping),            0 },
     { "push/pop",               BS3_CMN_FAR_NM(bs3CpuWeird1_PushPop),               0 },
     { "push/pop sreg",          BS3_CMN_FAR_NM(bs3CpuWeird1_PushPopSReg),           0 },
+#endif
+    { "popf",                   BS3_CMN_FAR_NM(bs3CpuWeird1_Popf),                  0 },
 };
 
