VirtualBox

Changeset 45276 in vbox


Ignore:
Timestamp:
Apr 2, 2013 8:17:11 AM (11 years ago)
Author:
vboxsync
Message:

Ring-1 compression patches, courtesy of trivirt AG:

  • main: diff to remove the hwvirt requirement for QNX
  • rem: diff for dealing with raw ring 0/1 selectors and general changes to allowed guest execution states
  • vmm: changes for using the guest's TSS selector index as our hypervisor TSS selector (makes str safe) (VBOX_WITH_SAFE_STR )
  • vmm: changes for dealing with guest ring 1 code (VBOX_WITH_RAW_RING1)
  • vmm: change to emulate smsw in RC/R0 (QNX uses this old style instruction a lot so going to qemu for emulation is very expensive)
  • vmm: change (hack) to kick out patm virtual handlers in case they conflict with guest GDT/TSS write monitors; we should allow multiple handlers per page, but that change would be rather invasive
Location:
trunk
Files:
39 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/cpum.h

    r44793 r45276  
    485485DECLASM(void)           CPUMGCCallV86Code(PCPUMCTXCORE pRegFrame);
    486486
     487
     488/**
     489 * Get the current privilege level of the guest.
     490 *
     491 * @returns CPL
     492 * @param   pVCpu       The current virtual CPU.
     493 * @param   pRegFrame   Pointer to the register frame.
     494 */
     495VMMDECL(uint32_t)       CPUMRCGetGuestCPL(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
     496
     497#ifdef VBOX_WITH_RAW_RING1
     498/**
     499 * Transforms the guest CPU state to raw-ring mode.
     500 *
     501 * This function will change the any of the cs and ss register with DPL=0 to DPL=1.
     502 *
     503 * @returns VBox status. (recompiler failure)
     504 * @param   pVCpu       Pointer to the VMCPU.
     505 * @param   pCtxCore    The context core (for trap usage).
     506 * @see     @ref pg_raw
     507 */
     508VMMDECL(void)         CPUMRCRecheckRawState(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore);
     509#endif
     510
    487511/** @} */
    488512#endif /* IN_RC */
  • trunk/include/VBox/vmm/em.h

    r44528 r45276  
    133133#define EMIsRawRing0Enabled(pVM) (!(pVM)->fRecompileSupervisor)
    134134
     135#ifdef VBOX_WITH_RAW_RING1
     136/**
     137 * Checks if raw ring-1 execute mode is enabled.
     138 *
     139 * @returns true if enabled.
     140 * @returns false if disabled.
     141 * @param   pVM         The VM to operate on.
     142 */
     143#define EMIsRawRing1Enabled(pVM) ((pVM)->fRawRing1Enabled)
     144#else
     145#define EMIsRawRing1Enabled(pVM) false
     146#endif
     147
    135148/**
    136149 * Checks if execution with hardware assisted virtualization is enabled.
  • trunk/include/VBox/vmm/selm.h

    r42427 r45276  
    107107VMMR3DECL(bool)         SELMR3CheckTSS(PVM pVM);
    108108VMMR3DECL(int)          SELMR3DebugCheck(PVM pVM);
     109#ifdef VBOX_WITH_SAFE_STR
     110VMMR3DECL(bool)         SELMR3CheckShadowTR(PVM pVM);
     111#endif
     112
    109113/** @def SELMR3_DEBUG_CHECK
    110114 * Invokes SELMR3DebugCheck in stricts builds. */
  • trunk/include/VBox/vmm/vm.h

    r45152 r45276  
    843843    /** Whether to recompile supervisor mode code or run it raw/hm. */
    844844    bool                        fRecompileSupervisor;
     845    /** Whether raw mode supports ring-1 code or not. */
     846    bool                        fRawRing1Enabled;
    845847    /** PATM enabled flag.
    846848     * This is placed here for performance reasons. */
     
    862864
    863865    /** Alignment padding.. */
    864     uint32_t                    uPadding1;
     866    uint8_t                     uPadding1[3];
    865867
    866868    /** @name Debugging
  • trunk/include/VBox/vmm/vm.mac

    r45152 r45276  
    5959    .fRecompileUser         resb 1
    6060    .fRecompileSupervisor   resb 1
     61    .fRawRing1Enabled       resb 1
    6162    .fPATMEnabled           resb 1
    6263    .fCSAMEnabled           resb 1
     
    6667    .fUseLargePages         resb 1
    6768
    68     .uPadding1              resd 1
     69    .uPadding1              resb 3
    6970
    7071    .hTraceBufRC            RTRCPTR_RES 1
  • trunk/src/VBox/Main/Makefile.kmk

    r45138 r45276  
    5656VBOX_MAIN_DEFS += \
    5757        $(if $(VBOX_WITH_RAW_MODE),VBOX_WITH_RAW_MODE,) \
     58        $(if $(VBOX_WITH_RAW_RING1),VBOX_WITH_RAW_RING1,) \
    5859        $(if $(VBOX_WITH_NETFLT),VBOX_WITH_NETFLT,) \
    5960        $(if $(VBOX_WITH_COPYTOGUEST),VBOX_WITH_COPYTOGUEST,) \
  • trunk/src/VBox/Main/src-all/Global.cpp

    r44413 r45276  
    313313        StorageControllerType_PIIX4, StorageBus_IDE, ChipsetType_PIIX3, AudioControllerType_AC97  },
    314314    { "Other",   "Other",             "QNX",                "QNX",
     315#ifdef VBOX_WITH_RAW_RING1
     316      VBOXOSTYPE_QNX,             VBOXOSHINT_NONE,
     317#else
    315318      VBOXOSTYPE_QNX,             VBOXOSHINT_HWVIRTEX,
     319#endif
    316320       512,   4,  4 * _1G64, NetworkAdapterType_Am79C973, 0, StorageControllerType_PIIX4, StorageBus_IDE,
    317321      StorageControllerType_PIIX4, StorageBus_IDE, ChipsetType_PIIX3, AudioControllerType_AC97  },
  • trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp

    r44829 r45276  
    810810        InsertConfigInteger(pRoot, "CSAMEnabled",          1);     /* boolean */
    811811#endif
     812
     813#ifdef VBOX_WITH_RAW_RING1
     814        if (osTypeId == "QNX")
     815        {
     816            /* QNX needs special treatment in raw mode due to its use of ring-1. */
     817            InsertConfigInteger(pRoot, "RawR1Enabled",     1);     /* boolean */
     818        }
     819#endif
     820
    812821        /* Not necessary, but to make sure these two settings end up in the release log. */
    813822        BOOL fPageFusion = FALSE;
  • trunk/src/VBox/VMM/Makefile.kmk

    r45152 r45276  
    5757 VMM_COMMON_DEFS += VBOX_WITH_OLD_VTX_CODE
    5858endif
     59ifdef VBOX_WITH_SAFE_STR
     60 VMM_COMMON_DEFS += VBOX_WITH_SAFE_STR
     61endif
     62ifdef VBOX_WITH_RAW_RING1
     63 VMM_COMMON_DEFS += VBOX_WITH_RAW_RING1
     64endif
     65
    5966# VMM_COMMON_DEFS += VBOX_WITH_NS_ACCOUNTING_STATS
    6067
  • trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp

    r45142 r45276  
    2727#include <VBox/vmm/pgm.h>
    2828#include <VBox/vmm/mm.h>
     29#include <VBox/vmm/em.h>
    2930#if defined(VBOX_WITH_RAW_MODE) && !defined(IN_RING0)
    3031# include <VBox/vmm/selm.h>
     
    26562657                uCpl = (pVCpu->cpum.s.Guest.ss.Sel & X86_SEL_RPL);
    26572658#ifdef VBOX_WITH_RAW_MODE_NOT_R0
     2659# ifdef VBOX_WITH_RAW_RING1
     2660                if (pVCpu->cpum.s.fRawEntered)
     2661                {
     2662                    if (    EMIsRawRing1Enabled(pVCpu->CTX_SUFF(pVM))
     2663                        &&  uCpl == 2)
     2664                        uCpl = 1;
     2665                    else
     2666                    if (uCpl == 1)
     2667                        uCpl = 0;
     2668                }
     2669                Assert(uCpl != 2);  /* ring 2 support not allowed anymore. */
     2670# else
    26582671                if (uCpl == 1)
    26592672                    uCpl = 0;
     2673# endif
    26602674#endif
    26612675            }
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r44528 r45276  
    5454//# define VBOX_SAME_AS_EM
    5555//# define VBOX_COMPARE_IEM_LAST
     56#endif
     57
     58#ifdef VBOX_WITH_RAW_RING1
     59#define EM_EMULATE_SMSW
    5660#endif
    5761
     
    10291033}
    10301034
    1031 #if defined(IN_RC) /*&& defined(VBOX_WITH_PATM)*/
     1035#ifdef IN_RC
    10321036
    10331037DECLINLINE(int) emRCStackRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCPTR GCPtrSrc, uint32_t cb)
     
    10951099}
    10961100
    1097 #endif /* IN_RC && VBOX_WITH_PATM */
     1101/**
     1102 * IRET Emulation.
     1103 */
     1104static int emInterpretIret(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize)
     1105{
     1106#ifdef VBOX_WITH_RAW_RING1
     1107    NOREF(pvFault); NOREF(pcbSize);
     1108    if (EMIsRawRing1Enabled(pVM))
     1109    {
     1110        RTGCUINTPTR pIretStack = (RTGCUINTPTR)pRegFrame->esp;
     1111        RTGCUINTPTR eip, cs, esp, ss, eflags, uMask;
     1112        int         rc;
     1113        uint32_t    cpl, rpl;
     1114
     1115        /* We only execute 32-bits protected mode code in raw mode, so no need to bother to check for 16-bits code here. */
     1116        /* @todo: we don't verify all the edge cases that generate #GP faults */
     1117
     1118        Assert(pRegFrame == CPUMGetGuestCtxCore(pVCpu));
     1119        Assert(!CPUMIsGuestIn64BitCode(pVCpu));
     1120        /** @todo Rainy day: Test what happens when VERR_EM_INTERPRETER is returned by
     1121         *        this function.  Fear that it may guru on us, thus not converted to
     1122         *        IEM. */
     1123
     1124        rc  = emRCStackRead(pVM, pVCpu, pRegFrame, &eip,      (RTGCPTR)pIretStack      , 4);
     1125        rc |= emRCStackRead(pVM, pVCpu, pRegFrame, &cs,       (RTGCPTR)(pIretStack + 4), 4);
     1126        rc |= emRCStackRead(pVM, pVCpu, pRegFrame, &eflags,   (RTGCPTR)(pIretStack + 8), 4);
     1127        AssertRCReturn(rc, VERR_EM_INTERPRETER);
     1128        AssertReturn(eflags & X86_EFL_VM, VERR_EM_INTERPRETER);
     1129
     1130        /* Deal with V86 above. */
     1131        if (eflags & X86_EFL_VM)
     1132            return EMInterpretIretV86ForPatm(pVM, pVCpu, pRegFrame);
     1133
     1134        cpl = CPUMRCGetGuestCPL(pVCpu, pRegFrame);
     1135        rpl = cs & X86_SEL_RPL;
     1136
     1137        Log(("emInterpretIret: iret to CS:EIP=%04X:%08X eflags=%x\n", cs, eip, eflags));
     1138        if (rpl != cpl)
     1139        {
     1140            rc |= emRCStackRead(pVM, pVCpu, pRegFrame, &esp,      (RTGCPTR)(pIretStack + 12), 4);
     1141            rc |= emRCStackRead(pVM, pVCpu, pRegFrame, &ss,       (RTGCPTR)(pIretStack + 16), 4);
     1142            AssertRCReturn(rc, VERR_EM_INTERPRETER);
     1143            Log(("emInterpretIret: return to different privilege level (rpl=%d cpl=%d)\n", rpl, cpl));
     1144            Log(("emInterpretIret: SS:ESP=%04X:08X\n", ss, esp));
     1145            pRegFrame->ss.Sel = ss;
     1146            pRegFrame->esp    = esp;
     1147        }
     1148        pRegFrame->cs.Sel = cs;
     1149        pRegFrame->eip    = eip;
     1150
     1151        /* Adjust CS & SS as required. */
     1152        CPUMRCRecheckRawState(pVCpu, pRegFrame);
     1153
     1154        /* Mask away all reserved bits */
     1155        uMask = X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_TF | X86_EFL_IF | X86_EFL_DF | X86_EFL_OF | X86_EFL_IOPL | X86_EFL_NT | X86_EFL_RF | X86_EFL_VM | X86_EFL_AC | X86_EFL_VIF | X86_EFL_VIP | X86_EFL_ID;
     1156        eflags &= uMask;
     1157
     1158        CPUMRawSetEFlags(pVCpu, eflags);
     1159        Assert((pRegFrame->eflags.u32 & (X86_EFL_IF|X86_EFL_IOPL)) == X86_EFL_IF);
     1160        return VINF_SUCCESS;
     1161    }
     1162#else
     1163    NOREF(pVM); NOREF(pVCpu); NOREF(pDis); NOREF(pRegFrame); NOREF(pvFault); NOREF(pcbSize);
     1164#endif
     1165    return VERR_EM_INTERPRETER;
     1166}
     1167
     1168#endif /* IN_RC */
    10981169
    10991170
     
    25082579        return VERR_EM_INTERPRETER;
    25092580
    2510 #ifdef IN_RC
    2511     if (TRPMHasTrap(pVCpu))
    2512     {
    2513         if (TRPMGetErrorCode(pVCpu) & X86_TRAP_PF_RW)
     2581    if (param1.type == DISQPV_TYPE_ADDRESS)
     2582    {
     2583        RTGCPTR pDest;
     2584        uint64_t val64;
     2585
     2586        switch(param1.type)
    25142587        {
    2515 #else
    2516         /** @todo Make this the default and don't rely on TRPM information. */
    2517         if (param1.type == DISQPV_TYPE_ADDRESS)
     2588        case DISQPV_TYPE_IMMEDIATE:
     2589            if(!(param1.flags  & (DISQPV_FLAG_32|DISQPV_FLAG_64)))
     2590                return VERR_EM_INTERPRETER;
     2591            /* fallthru */
     2592
     2593        case DISQPV_TYPE_ADDRESS:
     2594            pDest = (RTGCPTR)param1.val.val64;
     2595            pDest = emConvertToFlatAddr(pVM, pRegFrame, pDis, &pDis->Param1, pDest);
     2596            break;
     2597
     2598        default:
     2599            AssertFailed();
     2600            return VERR_EM_INTERPRETER;
     2601        }
     2602
     2603        switch(param2.type)
    25182604        {
    2519 #endif
    2520             RTGCPTR pDest;
    2521             uint64_t val64;
    2522 
    2523             switch(param1.type)
     2605        case DISQPV_TYPE_IMMEDIATE: /* register type is translated to this one too */
     2606            val64 = param2.val.val64;
     2607            break;
     2608
     2609        default:
     2610            Log(("emInterpretMov: unexpected type=%d rip=%RGv\n", param2.type, (RTGCPTR)pRegFrame->rip));
     2611            return VERR_EM_INTERPRETER;
     2612        }
     2613#ifdef LOG_ENABLED
     2614        if (pDis->uCpuMode == DISCPUMODE_64BIT)
     2615            LogFlow(("EMInterpretInstruction at %RGv: OP_MOV %RGv <- %RX64 (%d) &val64=%RHv\n", (RTGCPTR)pRegFrame->rip, pDest, val64, param2.size, &val64));
     2616        else
     2617            LogFlow(("EMInterpretInstruction at %08RX64: OP_MOV %RGv <- %08X  (%d) &val64=%RHv\n", pRegFrame->rip, pDest, (uint32_t)val64, param2.size, &val64));
     2618#endif
     2619
     2620        Assert(param2.size <= 8 && param2.size > 0);
     2621        EM_ASSERT_FAULT_RETURN(pDest == pvFault, VERR_EM_INTERPRETER);
     2622        rc = emRamWrite(pVM, pVCpu, pRegFrame, pDest, &val64, param2.size);
     2623        if (RT_FAILURE(rc))
     2624            return VERR_EM_INTERPRETER;
     2625
     2626        *pcbSize = param2.size;
     2627    }
     2628#if defined(IN_RC) && defined(VBOX_WITH_RAW_RING1)
     2629    /* mov xx, cs instruction is dangerous in raw mode and replaced by an 'int3' by csam/patm. */
     2630    else if (   param1.type == DISQPV_TYPE_REGISTER
     2631             && param2.type == DISQPV_TYPE_REGISTER)
     2632    {
     2633        AssertReturn((pDis->Param1.fUse & (DISUSE_REG_GEN8|DISUSE_REG_GEN16|DISUSE_REG_GEN32)), VERR_EM_INTERPRETER);
     2634        AssertReturn(pDis->Param2.fUse == DISUSE_REG_SEG, VERR_EM_INTERPRETER);
     2635        AssertReturn(pDis->Param2.Base.idxSegReg == DISSELREG_CS, VERR_EM_INTERPRETER);
     2636
     2637        uint32_t u32Cpl = CPUMRCGetGuestCPL(pVCpu, pRegFrame);
     2638        uint32_t uValCS = (pRegFrame->cs.Sel & ~X86_SEL_RPL) | u32Cpl;
     2639
     2640        Log(("EMInterpretInstruction: OP_MOV cs=%x->%x\n", pRegFrame->cs.Sel, uValCS));
     2641        switch (param1.size)
     2642        {
     2643        case 1: rc = DISWriteReg8(pRegFrame, pDis->Param1.Base.idxGenReg,  (uint8_t) uValCS); break;
     2644        case 2: rc = DISWriteReg16(pRegFrame, pDis->Param1.Base.idxGenReg, (uint16_t)uValCS); break;
     2645        case 4: rc = DISWriteReg32(pRegFrame, pDis->Param1.Base.idxGenReg, (uint32_t)uValCS); break;
     2646        default:
     2647            AssertFailed();
     2648            return VERR_EM_INTERPRETER;
     2649        }
     2650        AssertRCReturn(rc, rc);
     2651    }   
     2652#endif
     2653    else
     2654    { /* read fault */
     2655        RTGCPTR pSrc;
     2656        uint64_t val64;
     2657
     2658        /* Source */
     2659        switch(param2.type)
     2660        {
     2661        case DISQPV_TYPE_IMMEDIATE:
     2662            if(!(param2.flags & (DISQPV_FLAG_32|DISQPV_FLAG_64)))
     2663                return VERR_EM_INTERPRETER;
     2664            /* fallthru */
     2665
     2666        case DISQPV_TYPE_ADDRESS:
     2667            pSrc = (RTGCPTR)param2.val.val64;
     2668            pSrc = emConvertToFlatAddr(pVM, pRegFrame, pDis, &pDis->Param2, pSrc);
     2669            break;
     2670
     2671        default:
     2672            return VERR_EM_INTERPRETER;
     2673        }
     2674
     2675        Assert(param1.size <= 8 && param1.size > 0);
     2676        EM_ASSERT_FAULT_RETURN(pSrc == pvFault, VERR_EM_INTERPRETER);
     2677        rc = emRamRead(pVM, pVCpu, pRegFrame, &val64, pSrc, param1.size);
     2678        if (RT_FAILURE(rc))
     2679            return VERR_EM_INTERPRETER;
     2680
     2681        /* Destination */
     2682        switch(param1.type)
     2683        {
     2684        case DISQPV_TYPE_REGISTER:
     2685            switch(param1.size)
    25242686            {
    2525             case DISQPV_TYPE_IMMEDIATE:
    2526                 if(!(param1.flags  & (DISQPV_FLAG_32|DISQPV_FLAG_64)))
    2527                     return VERR_EM_INTERPRETER;
    2528                 /* fallthru */
    2529 
    2530             case DISQPV_TYPE_ADDRESS:
    2531                 pDest = (RTGCPTR)param1.val.val64;
    2532                 pDest = emConvertToFlatAddr(pVM, pRegFrame, pDis, &pDis->Param1, pDest);
    2533                 break;
    2534 
    2535             default:
    2536                 AssertFailed();
    2537                 return VERR_EM_INTERPRETER;
    2538             }
    2539 
    2540             switch(param2.type)
    2541             {
    2542             case DISQPV_TYPE_IMMEDIATE: /* register type is translated to this one too */
    2543                 val64 = param2.val.val64;
    2544                 break;
    2545 
    2546             default:
    2547                 Log(("emInterpretMov: unexpected type=%d rip=%RGv\n", param2.type, (RTGCPTR)pRegFrame->rip));
    2548                 return VERR_EM_INTERPRETER;
    2549             }
    2550 #ifdef LOG_ENABLED
    2551             if (pDis->uCpuMode == DISCPUMODE_64BIT)
    2552                 LogFlow(("EMInterpretInstruction at %RGv: OP_MOV %RGv <- %RX64 (%d) &val64=%RHv\n", (RTGCPTR)pRegFrame->rip, pDest, val64, param2.size, &val64));
    2553             else
    2554                 LogFlow(("EMInterpretInstruction at %08RX64: OP_MOV %RGv <- %08X  (%d) &val64=%RHv\n", pRegFrame->rip, pDest, (uint32_t)val64, param2.size, &val64));
    2555 #endif
    2556 
    2557             Assert(param2.size <= 8 && param2.size > 0);
    2558             EM_ASSERT_FAULT_RETURN(pDest == pvFault, VERR_EM_INTERPRETER);
    2559             rc = emRamWrite(pVM, pVCpu, pRegFrame, pDest, &val64, param2.size);
    2560             if (RT_FAILURE(rc))
    2561                 return VERR_EM_INTERPRETER;
    2562 
    2563             *pcbSize = param2.size;
    2564         }
    2565         else
    2566         { /* read fault */
    2567             RTGCPTR pSrc;
    2568             uint64_t val64;
    2569 
    2570             /* Source */
    2571             switch(param2.type)
    2572             {
    2573             case DISQPV_TYPE_IMMEDIATE:
    2574                 if(!(param2.flags & (DISQPV_FLAG_32|DISQPV_FLAG_64)))
    2575                     return VERR_EM_INTERPRETER;
    2576                 /* fallthru */
    2577 
    2578             case DISQPV_TYPE_ADDRESS:
    2579                 pSrc = (RTGCPTR)param2.val.val64;
    2580                 pSrc = emConvertToFlatAddr(pVM, pRegFrame, pDis, &pDis->Param2, pSrc);
    2581                 break;
    2582 
     2687            case 1: rc = DISWriteReg8(pRegFrame, pDis->Param1.Base.idxGenReg,  (uint8_t) val64); break;
     2688            case 2: rc = DISWriteReg16(pRegFrame, pDis->Param1.Base.idxGenReg, (uint16_t)val64); break;
     2689            case 4: rc = DISWriteReg32(pRegFrame, pDis->Param1.Base.idxGenReg, (uint32_t)val64); break;
     2690            case 8: rc = DISWriteReg64(pRegFrame, pDis->Param1.Base.idxGenReg, val64); break;
    25832691            default:
    25842692                return VERR_EM_INTERPRETER;
    25852693            }
    2586 
    2587             Assert(param1.size <= 8 && param1.size > 0);
    2588             EM_ASSERT_FAULT_RETURN(pSrc == pvFault, VERR_EM_INTERPRETER);
    2589             rc = emRamRead(pVM, pVCpu, pRegFrame, &val64, pSrc, param1.size);
    25902694            if (RT_FAILURE(rc))
    2591                 return VERR_EM_INTERPRETER;
    2592 
    2593             /* Destination */
    2594             switch(param1.type)
    2595             {
    2596             case DISQPV_TYPE_REGISTER:
    2597                 switch(param1.size)
    2598                 {
    2599                 case 1: rc = DISWriteReg8(pRegFrame, pDis->Param1.Base.idxGenReg,  (uint8_t) val64); break;
    2600                 case 2: rc = DISWriteReg16(pRegFrame, pDis->Param1.Base.idxGenReg, (uint16_t)val64); break;
    2601                 case 4: rc = DISWriteReg32(pRegFrame, pDis->Param1.Base.idxGenReg, (uint32_t)val64); break;
    2602                 case 8: rc = DISWriteReg64(pRegFrame, pDis->Param1.Base.idxGenReg, val64); break;
    2603                 default:
    2604                     return VERR_EM_INTERPRETER;
    2605                 }
    2606                 if (RT_FAILURE(rc))
    2607                     return rc;
    2608                 break;
    2609 
    2610             default:
    2611                 return VERR_EM_INTERPRETER;
    2612             }
     2695                return rc;
     2696            break;
     2697
     2698        default:
     2699            return VERR_EM_INTERPRETER;
     2700        }
    26132701#ifdef LOG_ENABLED
    2614             if (pDis->uCpuMode == DISCPUMODE_64BIT)
    2615                 LogFlow(("EMInterpretInstruction: OP_MOV %RGv -> %RX64 (%d)\n", pSrc, val64, param1.size));
    2616             else
    2617                 LogFlow(("EMInterpretInstruction: OP_MOV %RGv -> %08X (%d)\n", pSrc, (uint32_t)val64, param1.size));
    2618 #endif
    2619         }
    2620         return VINF_SUCCESS;
    2621 #ifdef IN_RC
    2622     }
    2623     return VERR_EM_INTERPRETER;
    2624 #endif
     2702        if (pDis->uCpuMode == DISCPUMODE_64BIT)
     2703            LogFlow(("EMInterpretInstruction: OP_MOV %RGv -> %RX64 (%d)\n", pSrc, val64, param1.size));
     2704        else
     2705            LogFlow(("EMInterpretInstruction: OP_MOV %RGv -> %08X (%d)\n", pSrc, (uint32_t)val64, param1.size));
     2706#endif
     2707    }
     2708    return VINF_SUCCESS;
    26252709}
    26262710
     
    30153099#endif /* IN_RC */
    30163100
    3017 
    3018 /**
    3019  * IRET Emulation.
    3020  */
    3021 static int emInterpretIret(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize)
    3022 {
    3023     /* only allow direct calls to EMInterpretIret for now */
    3024     NOREF(pVM); NOREF(pVCpu); NOREF(pDis); NOREF(pRegFrame); NOREF(pvFault); NOREF(pcbSize);
    3025     return VERR_EM_INTERPRETER;
    3026 }
    30273101
    30283102/**
     
    35973671        /* Get the current privilege level. */
    35983672        uint32_t cpl = CPUMGetGuestCPL(pVCpu);
    3599         if (    cpl != 0
    3600             &&  pDis->pCurInstr->uOpcode != OP_RDTSC)    /* rdtsc requires emulation in ring 3 as well */
     3673#ifdef VBOX_WITH_RAW_RING1
     3674        if (   !EMIsRawRing1Enabled(pVM)
     3675            || cpl > 1
     3676            || pRegFrame->eflags.Bits.u2IOPL > cpl
     3677           )
    36013678        {
    3602             Log(("WARNING: refusing instruction emulation for user-mode code!!\n"));
    3603             STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,FailedUserMode));
    3604             return VERR_EM_INTERPRETER;
     3679#endif
     3680            if (    cpl != 0
     3681                &&  pDis->pCurInstr->uOpcode != OP_RDTSC)    /* rdtsc requires emulation in ring 3 as well */
     3682            {
     3683                Log(("WARNING: refusing instruction emulation for user-mode code!!\n"));
     3684                STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,FailedUserMode));
     3685                return VERR_EM_INTERPRETER;
     3686            }
     3687#ifdef VBOX_WITH_RAW_RING1
    36053688        }
     3689#endif
    36063690    }
    36073691    else
     
    38353919        INTERPRET_CASE(OP_STI,Sti);
    38363920        INTERPRET_CASE(OP_XADD, XAdd);
     3921        INTERPRET_CASE(OP_IRET,Iret);
    38373922#endif
    38383923        INTERPRET_CASE(OP_CMPXCHG8B, CmpXchg8b);
    38393924        INTERPRET_CASE(OP_HLT,Hlt);
    3840         INTERPRET_CASE(OP_IRET,Iret);
    38413925        INTERPRET_CASE(OP_WBINVD,WbInvd);
    38423926#ifdef VBOX_WITH_STATISTICS
  • trunk/src/VBox/VMM/VMMAll/PATMAll.cpp

    r44362 r45276  
    627627    case OP_MOV:
    628628        if (fPatchFlags & PATMFL_IDTHANDLER)
    629         {
    630629            pszInstr = "mov (Int/Trap Handler)";
    631         }
     630        else
     631            pszInstr = "mov (cs)";
    632632        break;
    633633    case OP_SYSENTER:
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r45103 r45276  
    352352            }
    353353            /* Unhandled part of a monitored page */
     354            Log(("Unhandled part of monitored page %RGv\n", pvFault));
    354355        }
    355356        else
  • trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp

    r45103 r45276  
    756756
    757757    /* Non-supervisor mode write means it's used for something else. */
    758     if (CPUMGetGuestCPL(pVCpu) != 0)
     758    if (CPUMGetGuestCPL(pVCpu) == 3)
    759759        return true;
    760760
  • trunk/src/VBox/VMM/VMMAll/SELMAll.cpp

    r43387 r45276  
    838838}
    839839
     840#ifdef VBOX_WITH_RAW_RING1
     841/**
     842 * Sets ss:esp for ring1 in main Hypervisor's TSS.
     843 *
     844 * @param   pVM     Pointer to the VM.
     845 * @param   ss      Ring2 SS register value. Pass 0 if invalid.
     846 * @param   esp     Ring2 ESP register value.
     847 */
     848void selmSetRing2Stack(PVM pVM, uint32_t ss, RTGCPTR32 esp)
     849{
     850    Assert((ss & 3) == 2 || esp == 0);
     851    pVM->selm.s.Tss.ss2  = ss;
     852    pVM->selm.s.Tss.esp2 = (uint32_t)esp;
     853}
     854#endif
    840855
    841856#ifdef VBOX_WITH_RAW_MODE_NOT_R0
     
    855870    PVMCPU pVCpu = &pVM->aCpus[0];
    856871
     872#ifdef SELM_TRACK_GUEST_TSS_CHANGES
    857873    if (pVM->selm.s.fSyncTSSRing0Stack)
    858874    {
     875#endif
    859876        RTGCPTR GCPtrTss = pVM->selm.s.GCPtrGuestTss;
    860877        int     rc;
     
    913930        selmSetRing1Stack(pVM, tss.ss0 | 1, (RTGCPTR32)tss.esp0);
    914931        pVM->selm.s.fSyncTSSRing0Stack = false;
    915     }
     932#ifdef SELM_TRACK_GUEST_TSS_CHANGES
     933    }
     934#endif
    916935
    917936    *pSS  = pVM->selm.s.Tss.ss1;
  • trunk/src/VBox/VMM/VMMAll/TRPMAll.cpp

    r44362 r45276  
    2727#include <VBox/vmm/selm.h>
    2828#include <VBox/vmm/stam.h>
     29#include <VBox/vmm/dbgf.h>
    2930#include "TRPMInternal.h"
    3031#include <VBox/vmm/vm.h>
     
    593594                pTrapStack = (uint32_t *)(uintptr_t)pTrapStackGC;
    594595#else
    595                 Assert(eflags.Bits.u1VM || (pRegFrame->ss.Sel & X86_SEL_RPL) == 0 || (pRegFrame->ss.Sel & X86_SEL_RPL) == 3);
     596                Assert(eflags.Bits.u1VM || (pRegFrame->ss.Sel & X86_SEL_RPL) == 0 || (pRegFrame->ss.Sel & X86_SEL_RPL) == 3 || (EMIsRawRing1Enabled(pVM) && (pRegFrame->ss.Sel & X86_SEL_RPL) == 1));
    596597                /* Check maximum amount we need (10 when executing in V86 mode) */
    597598                if ((pTrapStackGC >> PAGE_SHIFT) != ((pTrapStackGC - 10*sizeof(uint32_t)) >> PAGE_SHIFT)) /* fail if we cross a page boundary */
     
    624625                    if (!fConforming && dpl < cpl)
    625626                    {
    626                         if ((pRegFrame->ss.Sel & X86_SEL_RPL) == 1 && !eflags.Bits.u1VM)
    627                             pTrapStack[--idx] = pRegFrame->ss.Sel & ~1;    /* Mask away traces of raw ring execution (ring 1). */
     627#ifdef IN_RC /* Only in GC mode we still see tracing of our ring modifications */
     628                        if (    (pRegFrame->ss.Sel & X86_SEL_RPL) == 1
     629                            &&  !eflags.Bits.u1VM)
     630                            pTrapStack[--idx] = pRegFrame->ss.Sel & ~1;         /* Mask away traces of raw ring 0 execution (ring 1). */
     631# ifdef VBOX_WITH_RAW_RING1
    628632                        else
     633                        if (    EMIsRawRing1Enabled(pVM)
     634                            &&  (pRegFrame->ss.Sel & X86_SEL_RPL) == 2)
     635                            pTrapStack[--idx] = (pRegFrame->ss.Sel & ~2) | 1;   /* Mask away traces of raw ring 1 execution (ring 2). */
     636# endif
     637                        else
     638#endif  /* IN_RC */
    629639                            pTrapStack[--idx] = pRegFrame->ss.Sel;
    630640
     
    635645                    /* Note: Not really necessary as we grab include those bits in the trap/irq handler trampoline */
    636646                    pTrapStack[--idx] = eflags.u32;
    637 
    638                     if ((pRegFrame->cs.Sel & X86_SEL_RPL) == 1 && !eflags.Bits.u1VM)
    639                         pTrapStack[--idx] = pRegFrame->cs.Sel & ~1;    /* Mask away traces of raw ring execution (ring 1). */
     647#ifdef IN_RC /* Only in GC mode we still see tracing of our ring modifications */
     648                    if (    (pRegFrame->cs.Sel & X86_SEL_RPL) == 1
     649                        &&  !eflags.Bits.u1VM)
     650                        pTrapStack[--idx] = pRegFrame->cs.Sel & ~1;         /* Mask away traces of raw ring execution (ring 1). */
     651# ifdef VBOX_WITH_RAW_RING1
    640652                    else
     653                    if (    EMIsRawRing1Enabled(pVM)
     654                        &&  (pRegFrame->cs.Sel & X86_SEL_RPL) == 2)
     655                        pTrapStack[--idx] = (pRegFrame->cs.Sel & ~2) | 1;   /* Mask away traces of raw ring 1 execution (ring 2). */
     656# endif
     657                    else
     658#endif  /* IN_RC */
    641659                        pTrapStack[--idx] = pRegFrame->cs.Sel;
    642660
     
    660678                    /* Mask away dangerous flags for the trap/interrupt handler. */
    661679                    eflags.u32 &= ~(X86_EFL_TF | X86_EFL_VM | X86_EFL_RF | X86_EFL_NT);
     680#ifdef DEBUG
     681                    if (DBGFIsStepping(pVCpu))
     682                        eflags.u32 |= X86_EFL_TF;
     683#endif
    662684
    663685                    /* Turn off interrupts for interrupt gates. */
     
    669691#ifdef DEBUG
    670692                    for (int j = idx; j < 0; j++)
    671                         Log4(("Stack %RRv pos %02d: %08x\n", &pTrapStack[j], j, pTrapStack[j]));
     693                        LogFlow(("Stack %RRv pos %02d: %08x\n", &pTrapStack[j], j, pTrapStack[j]));
    672694
    673695                    Log4(("eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n"
  • trunk/src/VBox/VMM/VMMR3/CPUM.cpp

    r44399 r45276  
    4242#include <VBox/vmm/pdmapi.h>
    4343#include <VBox/vmm/mm.h>
     44#include <VBox/vmm/em.h>
    4445#include <VBox/vmm/selm.h>
    4546#include <VBox/vmm/dbgf.h>
     
    41924193     * Are we in Ring-0?
    41934194     */
    4194     if (    pCtxCore->ss.Sel && (pCtxCore->ss.Sel & X86_SEL_RPL) == 0
     4195    if (    pCtxCore->ss.Sel
     4196        &&  (pCtxCore->ss.Sel & X86_SEL_RPL) == 0
    41954197        &&  !pCtxCore->eflags.Bits.u1VM)
    41964198    {
     
    42044206         */
    42054207        pCtxCore->ss.Sel |= 1;
    4206         if (pCtxCore->cs.Sel && (pCtxCore->cs.Sel & X86_SEL_RPL) == 0)
     4208        if (    pCtxCore->cs.Sel
     4209            &&  (pCtxCore->cs.Sel & X86_SEL_RPL) == 0)
    42074210            pCtxCore->cs.Sel |= 1;
    42084211    }
    42094212    else
    42104213    {
     4214#ifdef VBOX_WITH_RAW_RING1
     4215        if (    EMIsRawRing1Enabled(pVM)
     4216            &&  !pCtxCore->eflags.Bits.u1VM
     4217            &&  (pCtxCore->ss.Sel & X86_SEL_RPL) == 1)
     4218        {
     4219            /* Set CPL to Ring-2. */
     4220            pCtxCore->ss.Sel = (pCtxCore->ss.Sel & ~X86_SEL_RPL) | 2;
     4221            if (pCtxCore->cs.Sel && (pCtxCore->cs.Sel & X86_SEL_RPL) == 1)
     4222                pCtxCore->cs.Sel = (pCtxCore->cs.Sel & ~X86_SEL_RPL) | 2;
     4223        }
     4224#else
    42114225        AssertMsg((pCtxCore->ss.Sel & X86_SEL_RPL) >= 2 || pCtxCore->eflags.Bits.u1VM,
    42124226                  ("ring-1 code not supported\n"));
     4227#endif
    42134228        /*
    42144229         * PATM takes care of IOPL and IF flags for Ring-3 and Ring-2 code as well.
     
    42214236     */
    42224237    AssertMsg((pCtxCore->eflags.u32 & X86_EFL_IF), ("X86_EFL_IF is clear\n"));
    4223     AssertReleaseMsg(   pCtxCore->eflags.Bits.u2IOPL < (unsigned)(pCtxCore->ss.Sel & X86_SEL_RPL)
    4224                      || pCtxCore->eflags.Bits.u1VM,
     4238    AssertReleaseMsg(pCtxCore->eflags.Bits.u2IOPL == 0,
    42254239                     ("X86_EFL_IOPL=%d CPL=%d\n", pCtxCore->eflags.Bits.u2IOPL, pCtxCore->ss.Sel & X86_SEL_RPL));
    42264240    Assert((pVCpu->cpum.s.Guest.cr0 & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE)) == (X86_CR0_PG | X86_CR0_PE | X86_CR0_WP));
     
    42314245    return VINF_SUCCESS;
    42324246}
     4247
    42334248
    42344249
     
    43004315        if (!pCtxCore->eflags.Bits.u1VM)
    43014316        {
    4302             /** @todo See what happens if we remove this. */
    4303             if ((pCtxCore->ds.Sel & X86_SEL_RPL) == 1)
    4304                 pCtxCore->ds.Sel &= ~X86_SEL_RPL;
    4305             if ((pCtxCore->es.Sel & X86_SEL_RPL) == 1)
    4306                 pCtxCore->es.Sel &= ~X86_SEL_RPL;
    4307             if ((pCtxCore->fs.Sel & X86_SEL_RPL) == 1)
    4308                 pCtxCore->fs.Sel &= ~X86_SEL_RPL;
    4309             if ((pCtxCore->gs.Sel & X86_SEL_RPL) == 1)
    4310                 pCtxCore->gs.Sel &= ~X86_SEL_RPL;
     4317#ifdef VBOX_WITH_RAW_RING1
     4318            if (    EMIsRawRing1Enabled(pVM)
     4319                &&  (pCtxCore->ss.Sel & X86_SEL_RPL) == 2)
     4320            {
     4321                /* Not quite sure if this is really required, but shouldn't harm (too much anyways). */
     4322                /** @todo See what happens if we remove this. */
     4323                if ((pCtxCore->ds.Sel & X86_SEL_RPL) == 2)
     4324                    pCtxCore->ds.Sel = (pCtxCore->ds.Sel & ~X86_SEL_RPL) | 1;
     4325                if ((pCtxCore->es.Sel & X86_SEL_RPL) == 2)
     4326                    pCtxCore->es.Sel = (pCtxCore->es.Sel & ~X86_SEL_RPL) | 1;
     4327                if ((pCtxCore->fs.Sel & X86_SEL_RPL) == 2)
     4328                    pCtxCore->fs.Sel = (pCtxCore->fs.Sel & ~X86_SEL_RPL) | 1;
     4329                if ((pCtxCore->gs.Sel & X86_SEL_RPL) == 2)
     4330                    pCtxCore->gs.Sel = (pCtxCore->gs.Sel & ~X86_SEL_RPL) | 1;
     4331
     4332                /*
     4333                 * Ring-2 selector => Ring-1.
     4334                 */
     4335                pCtxCore->ss.Sel = (pCtxCore->ss.Sel & ~X86_SEL_RPL) | 1;
     4336                if ((pCtxCore->cs.Sel & X86_SEL_RPL) == 2)
     4337                    pCtxCore->cs.Sel = (pCtxCore->cs.Sel & ~X86_SEL_RPL) | 1;
     4338            }
     4339            else
     4340            {
     4341#endif
     4342                /** @todo See what happens if we remove this. */
     4343                if ((pCtxCore->ds.Sel & X86_SEL_RPL) == 1)
     4344                    pCtxCore->ds.Sel &= ~X86_SEL_RPL;
     4345                if ((pCtxCore->es.Sel & X86_SEL_RPL) == 1)
     4346                    pCtxCore->es.Sel &= ~X86_SEL_RPL;
     4347                if ((pCtxCore->fs.Sel & X86_SEL_RPL) == 1)
     4348                    pCtxCore->fs.Sel &= ~X86_SEL_RPL;
     4349                if ((pCtxCore->gs.Sel & X86_SEL_RPL) == 1)
     4350                    pCtxCore->gs.Sel &= ~X86_SEL_RPL;
     4351#ifdef VBOX_WITH_RAW_RING1
     4352            }
     4353#endif
    43114354        }
    43124355    }
  • trunk/src/VBox/VMM/VMMR3/CSAM.cpp

    r44399 r45276  
    847847        break;
    848848
     849    /* removing breaks win2k guests? */
     850    case OP_IRET:
     851#ifdef VBOX_WITH_RAW_RING1
     852        if (EMIsRawRing1Enabled(pVM))
     853            break;
     854#endif
     855        /* no break */
     856
    849857    case OP_ILLUD2:
    850858        /* This appears to be some kind of kernel panic in Linux 2.4; no point to continue. */
     
    852860    case OP_INT3:
    853861    case OP_INVALID:
    854 #if 1
    855     /* removing breaks win2k guests? */
    856     case OP_IRET:
    857 #endif
    858862        return VINF_SUCCESS;
    859863    }
     
    919923    }
    920924
     925#ifdef VBOX_WITH_RAW_RING1
     926    case OP_MOV:
     927        /* mov xx, CS is a dangerous instruction as our raw ring usage leaks through. */
     928        if (    EMIsRawRing1Enabled(pVM)
     929            &&  (pCpu->Param2.fUse & DISUSE_REG_SEG)
     930            &&  (pCpu->Param2.Base.idxSegReg == DISSELREG_CS))
     931        {
     932            Log(("CSAM: Patching dangerous 'mov xx, cs' instruction at %RGv with an int3\n", pCurInstrGC));
     933            if (PATMR3HasBeenPatched(pVM, pCurInstrGC) == false)
     934            {
     935                rc = PATMR3InstallPatch(pVM, pCurInstrGC, (pPage->fCode32) ? PATMFL_CODE32 : 0);
     936                if (RT_FAILURE(rc))
     937                {
     938                    Log(("PATMR3InstallPatch failed with %d\n", rc));
     939                    return VWRN_CONTINUE_ANALYSIS;
     940                }
     941            }
     942            return VWRN_CONTINUE_ANALYSIS;
     943        }
     944        break;
     945#endif
     946
    921947    case OP_PUSH:
     948        /** @todo broken comparison!! should be if ((pCpu->Param1.fUse & DISUSE_REG_SEG) &&  (pCpu->Param1.Base.idxSegReg == DISSELREG_SS)) */
    922949        if (pCpu->pCurInstr->fParam1 != OP_PARM_REG_CS)
    923950            break;
    924951
    925952        /* no break */
     953#ifndef VBOX_WITH_SAFE_STR
    926954    case OP_STR:
     955#endif
    927956    case OP_LSL:
    928957    case OP_LAR:
     
    26422671
    26432672            rc = PATMR3InstallPatch(pVM, pHandler, fPatchFlags);
    2644             if (RT_SUCCESS(rc) || rc == VERR_PATM_ALREADY_PATCHED)
     2673            if (    RT_SUCCESS(rc)
     2674                ||  rc == VERR_PATM_ALREADY_PATCHED)
    26452675            {
    26462676                Log(("Gate handler 0x%X is SAFE!\n", iGate));
  • trunk/src/VBox/VMM/VMMR3/DBGFDisas.cpp

    r44528 r45276  
    661661        RTStrPrintf(szBuf, sizeof(szBuf), "DBGFR3DisasInstrCurrentLog failed with rc=%Rrc\n", rc);
    662662    if (pszPrefix && *pszPrefix)
    663         RTLogPrintf("%s-CPU%u: %s\n", pszPrefix, pVCpu->idCpu, szBuf);
     663    {
     664        if (pVCpu->CTX_SUFF(pVM)->cCpus > 1)
     665            RTLogPrintf("%s-CPU%u: %s\n", pszPrefix, pVCpu->idCpu, szBuf);
     666        else
     667            RTLogPrintf("%s: %s\n", pszPrefix, szBuf);
     668    }
    664669    else
    665670        RTLogPrintf("%s\n", szBuf);
     
    692697        RTStrPrintf(szBuf, sizeof(szBuf), "DBGFR3DisasInstrLog(, %RTsel, %RGv) failed with rc=%Rrc\n", Sel, GCPtr, rc);
    693698    if (pszPrefix && *pszPrefix)
    694         RTLogPrintf("%s-CPU%u: %s\n", pszPrefix, pVCpu->idCpu, szBuf);
     699    {
     700        if (pVCpu->CTX_SUFF(pVM)->cCpus > 1)
     701            RTLogPrintf("%s-CPU%u: %s\n", pszPrefix, pVCpu->idCpu, szBuf);
     702        else
     703            RTLogPrintf("%s: %s\n", pszPrefix, szBuf);
     704    }
    695705    else
    696706        RTLogPrintf("%s\n", szBuf);
  • trunk/src/VBox/VMM/VMMR3/EM.cpp

    r45152 r45276  
    124124    pVM->fRecompileSupervisor = RT_SUCCESS(rc) ? !fEnabled : false;
    125125    Log(("EMR3Init: fRecompileUser=%RTbool fRecompileSupervisor=%RTbool\n", pVM->fRecompileUser, pVM->fRecompileSupervisor));
     126
     127#ifdef VBOX_WITH_RAW_RING1
     128    rc = CFGMR3QueryBool(CFGMR3GetRoot(pVM), "RawR1Enabled", &fEnabled);
     129    pVM->fRawRing1Enabled = RT_SUCCESS(rc) ? fEnabled : false;
     130    Log(("EMR3Init: fRawRing1Enabled=%RTbool\n", pVM->fRawRing1Enabled));
     131#else
     132    pVM->fRawRing1Enabled = false;      /* disabled by default. */
     133#endif
    126134
    127135#ifdef VBOX_WITH_REM
     
    268276        EM_REG_COUNTER_USED(&pStats->StatRZLmsw,                 "/EM/CPU%d/RZ/Interpret/Success/Lmsw",       "The number of times LMSW was successfully interpreted.");
    269277        EM_REG_COUNTER_USED(&pStats->StatR3Lmsw,                 "/EM/CPU%d/R3/Interpret/Success/Lmsw",       "The number of times LMSW was successfully interpreted.");
     278        EM_REG_COUNTER_USED(&pStats->StatRZSmsw,                 "/EM/CPU%d/RZ/Interpret/Success/Smsw",       "The number of times SMSW was successfully interpreted.");
     279        EM_REG_COUNTER_USED(&pStats->StatR3Smsw,                 "/EM/CPU%d/R3/Interpret/Success/Smsw",       "The number of times SMSW was successfully interpreted.");
    270280
    271281        EM_REG_COUNTER(&pStats->StatRZInterpretFailed,           "/EM/CPU%d/RZ/Interpret/Failed",            "The number of times an instruction was not interpreted.");
     
    322332        EM_REG_COUNTER_USED(&pStats->StatRZFailedLmsw,           "/EM/CPU%d/RZ/Interpret/Failed/Lmsw",       "The number of times LMSW was not interpreted.");
    323333        EM_REG_COUNTER_USED(&pStats->StatR3FailedLmsw,           "/EM/CPU%d/R3/Interpret/Failed/Lmsw",       "The number of times LMSW was not interpreted.");
     334        EM_REG_COUNTER_USED(&pStats->StatRZFailedSmsw,           "/EM/CPU%d/RZ/Interpret/Failed/Smsw",       "The number of times SMSW was not interpreted.");
     335        EM_REG_COUNTER_USED(&pStats->StatR3FailedSmsw,           "/EM/CPU%d/R3/Interpret/Failed/Smsw",       "The number of times SMSW was not interpreted.");
    324336
    325337        EM_REG_COUNTER_USED(&pStats->StatRZFailedMisc,           "/EM/CPU%d/RZ/Interpret/Failed/Misc",       "The number of times some misc instruction was encountered.");
     
    938950static int emR3RemStep(PVM pVM, PVMCPU pVCpu)
    939951{
    940     LogFlow(("emR3RemStep: cs:eip=%04x:%08x\n", CPUMGetGuestCS(pVCpu),  CPUMGetGuestEIP(pVCpu)));
     952    Log3(("emR3RemStep: cs:eip=%04x:%08x\n", CPUMGetGuestCS(pVCpu),  CPUMGetGuestEIP(pVCpu)));
    941953
    942954#ifdef VBOX_WITH_REM
     
    958970#endif
    959971
    960     LogFlow(("emR3RemStep: returns %Rrc cs:eip=%04x:%08x\n", rc, CPUMGetGuestCS(pVCpu),  CPUMGetGuestEIP(pVCpu)));
     972    Log3(("emR3RemStep: returns %Rrc cs:eip=%04x:%08x\n", rc, CPUMGetGuestCS(pVCpu),  CPUMGetGuestEIP(pVCpu)));
    961973    return rc;
    962974}
     
    11821194    {
    11831195        DBGFR3PrgStep(pVCpu);
    1184         DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "RSS: ");
     1196        DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "RSS");
    11851197        emR3RemStep(pVM, pVCpu);
    11861198        if (emR3Reschedule(pVM, pVCpu, pVCpu->em.s.pCtx) != EMSTATE_REM)
     
    13081320            return EMSTATE_REM;
    13091321
     1322# ifdef VBOX_WITH_RAW_RING1
     1323        /* Only ring 0 and 1 supervisor code. */
     1324        if (EMIsRawRing1Enabled(pVM))
     1325        {
     1326            if ((uSS & X86_SEL_RPL) == 2)   /* ring 1 code is moved into ring 2, so we can't support ring-2 in that case. */
     1327            {
     1328                Log2(("raw r0 mode refused: CPL %d\n", uSS & X86_SEL_RPL));
     1329                return EMSTATE_REM;
     1330            }
     1331        }
     1332        else
     1333# endif
    13101334        /* Only ring 0 supervisor code. */
    13111335        if ((uSS & X86_SEL_RPL) != 0)
     
    13341358        {
    13351359            Log2(("raw r0 mode forced: patch code\n"));
     1360# ifdef VBOX_WITH_SAFE_STR
     1361            Assert(pCtx->tr.Sel);
     1362# endif
    13361363            return EMSTATE_RAW;
    13371364        }
     
    13461373# endif
    13471374
     1375# ifndef VBOX_WITH_RAW_RING1
    13481376        /** @todo still necessary??? */
    13491377        if (EFlags.Bits.u2IOPL != 0)
     
    13521380            return EMSTATE_REM;
    13531381        }
     1382# endif
    13541383    }
    13551384
     
    13871416        return EMSTATE_REM;
    13881417    }
     1418
     1419# ifdef VBOX_WITH_SAFE_STR
     1420    if (pCtx->tr.Sel == 0)
     1421    {
     1422        Log(("Raw mode refused -> TR=0\n"));
     1423        return EMSTATE_REM;
     1424    }
     1425# endif
    13891426
    13901427    /*Assert(PGMPhysIsA20Enabled(pVCpu));*/
  • trunk/src/VBox/VMM/VMMR3/EMHM.cpp

    r44528 r45276  
    137137    {
    138138        DBGFR3PrgStep(pVCpu);
    139         DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "RSS: ");
     139        DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "RSS");
    140140        rc = emR3HmStep(pVM, pVCpu);
    141141        if (    rc != VINF_SUCCESS
  • trunk/src/VBox/VMM/VMMR3/EMRaw.cpp

    r44399 r45276  
    159159    PCPUMCTX    pCtx   = pVCpu->em.s.pCtx;
    160160    bool        fGuest = pVCpu->em.s.enmState != EMSTATE_DEBUG_HYPER;
    161 #ifndef DEBUG_sandervl
     161#ifndef DEBUG_sander
    162162    Log(("emR3RawStep: cs:eip=%RTsel:%RGr efl=%RGr\n", fGuest ? CPUMGetGuestCS(pVCpu) : CPUMGetHyperCS(pVCpu),
    163163         fGuest ? CPUMGetGuestEIP(pVCpu) : CPUMGetHyperEIP(pVCpu), fGuest ? CPUMGetGuestEFlags(pVCpu) : CPUMGetHyperEFlags(pVCpu)));
     
    196196        else
    197197            rc = VMMR3RawRunGC(pVM, pVCpu);
    198 #ifndef DEBUG_sandervl
     198#ifndef DEBUG_sander
    199199        Log(("emR3RawStep: cs:eip=%RTsel:%RGr efl=%RGr - GC rc %Rrc\n", fGuest ? CPUMGetGuestCS(pVCpu) : CPUMGetHyperCS(pVCpu),
    200200             fGuest ? CPUMGetGuestEIP(pVCpu) : CPUMGetHyperEIP(pVCpu), fGuest ? CPUMGetGuestEFlags(pVCpu) : CPUMGetHyperEFlags(pVCpu), rc));
     
    237237    {
    238238        DBGFR3PrgStep(pVCpu);
    239         DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "RSS: ");
     239        DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "RSS");
    240240        rc = emR3RawStep(pVM, pVCpu);
    241         if (rc != VINF_SUCCESS)
     241        if (   rc != VINF_SUCCESS
     242            && rc != VINF_EM_DBG_STEPPED)
    242243            break;
    243244    }
     
    950951    {
    951952        DBGFR3_INFO_LOG(pVM, "cpumguest", "PRIV");
    952         DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "Privileged instr: ");
     953        DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "Privileged instr");
    953954    }
    954955#endif
     
    10901091                    {
    10911092                        DBGFR3_INFO_LOG(pVM, "cpumguest", "PRIV");
    1092                         DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "Privileged instr: ");
     1093                        DBGFR3_DISAS_INSTR_CUR_LOG(pVCpu, "Privileged instr");
    10931094                    }
    10941095#endif
     
    13611362        Assert(REMR3QueryPendingInterrupt(pVM, pVCpu) == REM_NO_PENDING_IRQ);
    13621363# endif
     1364# ifdef VBOX_WITH_RAW_RING1
     1365        Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss.Sel & X86_SEL_RPL) == 3 || (pCtx->ss.Sel & X86_SEL_RPL) == 0 || (EMIsRawRing1Enabled(pVM) && (pCtx->ss.Sel & X86_SEL_RPL) == 1));
     1366# else
    13631367        Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss.Sel & X86_SEL_RPL) == 3 || (pCtx->ss.Sel & X86_SEL_RPL) == 0);
     1368# endif
    13641369        AssertMsg(   (pCtx->eflags.u32 & X86_EFL_IF)
    13651370                  || PATMShouldUseRawMode(pVM, (RTGCPTR)pCtx->eip),
     
    14291434            Log(("RV86: %04x:%08x IF=%d VMFlags=%x\n", pCtx->cs.Sel, pCtx->eip, pCtx->eflags.Bits.u1IF, pGCState->uVMFlags));
    14301435        else if ((pCtx->ss.Sel & X86_SEL_RPL) == 1)
    1431             Log(("RR0: %08x ESP=%08x EFL=%x IF=%d/%d VMFlags=%x PIF=%d CPL=%d (Scanned=%d)\n",
    1432                  pCtx->eip, pCtx->esp, CPUMRawGetEFlags(pVCpu), !!(pGCState->uVMFlags & X86_EFL_IF), pCtx->eflags.Bits.u1IF,
     1436            Log(("RR0: %x:%08x ESP=%x:%08x EFL=%x IF=%d/%d VMFlags=%x PIF=%d CPL=%d (Scanned=%d)\n",
     1437                 pCtx->cs.Sel, pCtx->eip, pCtx->ss.Sel, pCtx->esp, CPUMRawGetEFlags(pVCpu), !!(pGCState->uVMFlags & X86_EFL_IF), pCtx->eflags.Bits.u1IF,
    14331438                 pGCState->uVMFlags, pGCState->fPIF, (pCtx->ss.Sel & X86_SEL_RPL), CSAMIsPageScanned(pVM, (RTGCPTR)pCtx->eip)));
     1439# ifdef VBOX_WITH_RAW_RING1
     1440        else if ((pCtx->ss.Sel & X86_SEL_RPL) == 2)
     1441            Log(("RR1: %x:%08x ESP=%x:%08x IF=%d VMFlags=%x CPL=%x\n", pCtx->cs.Sel, pCtx->eip, pCtx->ss.Sel, pCtx->esp, pCtx->eflags.Bits.u1IF, pGCState->uVMFlags, (pCtx->ss.Sel & X86_SEL_RPL)));
     1442# endif
    14341443        else if ((pCtx->ss.Sel & X86_SEL_RPL) == 3)
    1435             Log(("RR3: %08x ESP=%08x IF=%d VMFlags=%x\n", pCtx->eip, pCtx->esp, pCtx->eflags.Bits.u1IF, pGCState->uVMFlags));
     1444            Log(("RR3: %x:%08x ESP=%x:%08x IF=%d VMFlags=%x\n", pCtx->cs.Sel, pCtx->eip, pCtx->ss.Sel, pCtx->esp, pCtx->eflags.Bits.u1IF, pGCState->uVMFlags));
    14361445#endif /* LOG_ENABLED */
    1437 
    14381446
    14391447
     
    15431551            ||  VMCPU_FF_ISPENDING(pVCpu, ~VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK))
    15441552        {
    1545             Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss.Sel & X86_SEL_RPL) != 1);
     1553            Assert(pCtx->eflags.Bits.u1VM || (EMIsRawRing1Enabled(pVM) ? ((pCtx->ss.Sel & X86_SEL_RPL) != 2) : ((pCtx->ss.Sel & X86_SEL_RPL) != 1)));
    15461554
    15471555            STAM_REL_PROFILE_ADV_SUSPEND(&pVCpu->em.s.StatRAWTotal, a);
  • trunk/src/VBox/VMM/VMMR3/PATM.cpp

    r44399 r45276  
    15351535        break;
    15361536
     1537#ifdef VBOX_WITH_SAFE_STR   /* @todo remove DISOPTYPE_PRIVILEGED_NOTRAP from disasm table */
     1538    case OP_STR:
     1539        break;
     1540#endif
     1541
    15371542    default:
    15381543        if (pCpu->pCurInstr->fOpType & (DISOPTYPE_PRIVILEGED_NOTRAP))
     
    16451650    case OP_RETN:
    16461651        return VINF_SUCCESS;
     1652
     1653#ifdef VBOX_WITH_SAFE_STR   /* @todo remove DISOPTYPE_PRIVILEGED_NOTRAP from disasm table */
     1654    case OP_STR:
     1655        break;
     1656#endif
    16471657
    16481658    case OP_POPF:
     
    18061816
    18071817    case OP_POP:
     1818        /** @todo broken comparison!! should be if ((pCpu->Param1.fUse & DISUSE_REG_SEG) &&  (pCpu->Param1.Base.idxSegReg == DISSELREG_SS)) */
    18081819        if (pCpu->pCurInstr->fParam1 == OP_PARM_REG_SS)
    18091820        {
     
    19131924
    19141925    case OP_PUSH:
     1926        /** @todo broken comparison!! should be if ((pCpu->Param1.fUse & DISUSE_REG_SEG) &&  (pCpu->Param1.Base.idxSegReg == DISSELREG_SS)) */
    19151927        if (pCpu->pCurInstr->fParam1 == OP_PARM_REG_CS)
    19161928        {
     
    19471959
    19481960    case OP_STR:
     1961#ifdef VBOX_WITH_SAFE_STR   /* @todo remove DISOPTYPE_PRIVILEGED_NOTRAP from disasm table and move OP_STR into #ifndef */
     1962        /* Now safe because our shadow TR entry is identical to the guest's. */
     1963        goto duplicate_instr;
     1964#endif
    19491965    case OP_SLDT:
    19501966        rc = patmPatchGenSldtStr(pVM, pPatch, pCpu, pCurInstrGC);
     
    44424458            break;
    44434459
     4460#ifndef VBOX_WITH_SAFE_STR
    44444461        case OP_STR:
     4462#endif
    44454463        case OP_SGDT:
    44464464        case OP_SLDT:
     
    44534471        case OP_VERR:
    44544472        case OP_IRET:
     4473#ifdef VBOX_WITH_RAW_RING1
     4474        case OP_MOV:
     4475#endif
    44554476            rc = patmR3PatchInstrInt3(pVM, pInstrGC, pInstrHC, &cpu, &pPatchRec->patch);
    44564477            break;
  • trunk/src/VBox/VMM/VMMR3/PATMA.asm

    r44528 r45276  
    12621262
    12631263    ; force ring 1 CS RPL
    1264     or      dword [esp+8], 1
     1264    or      dword [esp+8], 1        ;-> @todo we leave traces or raw mode if we jump back to the host context to handle pending interrupts! (below)
    12651265iret_notring0:
    12661266
     
    14431443    DD      PATM_FIXUP
    14441444    DD      PATMIretTable - PATMIretStart
     1445    DD      PATM_IRET_FUNCTION
     1446    DD      0
     1447    DD      PATM_VMFLAGS
     1448    DD      0
     1449    DD      PATM_VMFLAGS
     1450    DD      0
     1451    DD      PATM_VMFLAGS
     1452    DD      0
     1453    DD      PATM_TEMP_EAX
     1454    DD      0
     1455    DD      PATM_TEMP_ECX
     1456    DD      0
     1457    DD      PATM_TEMP_RESTORE_FLAGS
     1458    DD      0
     1459    DD      PATM_PENDINGACTION
     1460    DD      0
     1461    DD      0ffffffffh
     1462SECTION .text
     1463
     1464;;****************************************************
     1465;; Abstract:
     1466;;
     1467;; if eflags.NT==0 && iretstack.eflags.VM==0 && iretstack.eflags.IOPL==0
     1468;; then
     1469;;     if return to ring 0 (iretstack.new_cs & 3 == 0)
     1470;;     then
     1471;;          if iretstack.new_eflags.IF == 1 && iretstack.new_eflags.IOPL == 0
     1472;;          then
     1473;;              iretstack.new_cs |= 1
     1474;;          else
     1475;;              int 3
     1476;;     endif
     1477;;     uVMFlags &= ~X86_EFL_IF
     1478;;     iret
     1479;; else
     1480;;     int 3
     1481;;****************************************************
     1482;;
     1483; Stack:
     1484;
     1485; esp + 32 - GS         (V86 only)
     1486; esp + 28 - FS         (V86 only)
     1487; esp + 24 - DS         (V86 only)
     1488; esp + 20 - ES         (V86 only)
     1489; esp + 16 - SS         (if transfer to outer ring)
     1490; esp + 12 - ESP        (if transfer to outer ring)
     1491; esp + 8  - EFLAGS
     1492; esp + 4  - CS
     1493; esp      - EIP
     1494;;
     1495BEGINPROC   PATMIretRing1Replacement
     1496PATMIretRing1Start:
     1497    mov     dword [ss:PATM_INTERRUPTFLAG], 0
     1498    pushfd
     1499
     1500%ifdef PATM_LOG_PATCHIRET
     1501    push    eax
     1502    push    ecx
     1503    push    edx
     1504    lea     edx, dword [ss:esp+12+4]        ;3 dwords + pushed flags -> iret eip
     1505    mov     eax, PATM_ACTION_LOG_IRET
     1506    lock    or dword [ss:PATM_PENDINGACTION], eax
     1507    mov     ecx, PATM_ACTION_MAGIC
     1508    db      0fh, 0bh        ; illegal instr (hardcoded assumption in PATMHandleIllegalInstrTrap)
     1509    pop     edx
     1510    pop     ecx
     1511    pop     eax
     1512%endif
     1513
     1514    test    dword [esp], X86_EFL_NT
     1515    jnz     near iretring1_fault1
     1516
     1517    ; we can't do an iret to v86 code, as we run with CPL=1. The iret would attempt a protected mode iret and (most likely) fault.
     1518    test    dword [esp+12], X86_EFL_VM
     1519    jnz     near iretring1_return_to_v86
     1520
     1521    ;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     1522    ;;@todo: not correct for iret back to ring 2!!!!!
     1523    ;;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
     1524
     1525    test    dword [esp+8], 2
     1526    jnz     iretring1_checkpendingirq
     1527
     1528    test    dword [esp+12], X86_EFL_IF
     1529    jz      near iretring1_clearIF
     1530
     1531iretring1_checkpendingirq:
     1532
     1533; if interrupts are pending, then we must go back to the host context to handle them!
     1534; Note: This is very important as pending pic interrupts can be overridden by apic interrupts if we don't check early enough (Fedora 5 boot)
     1535; @@todo fix this properly, so we can dispatch pending interrupts in GC
     1536    test    dword [ss:PATM_VM_FORCEDACTIONS], VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC
     1537    jz      iretring1_continue
     1538
     1539; Go to our hypervisor trap handler to dispatch the pending irq
     1540    mov     dword [ss:PATM_TEMP_EAX], eax
     1541    mov     dword [ss:PATM_TEMP_ECX], ecx
     1542    mov     dword [ss:PATM_TEMP_EDI], edi
     1543    mov     dword [ss:PATM_TEMP_RESTORE_FLAGS], PATM_RESTORE_EAX | PATM_RESTORE_ECX | PATM_RESTORE_EDI
     1544    mov     eax, PATM_ACTION_PENDING_IRQ_AFTER_IRET
     1545    lock    or dword [ss:PATM_PENDINGACTION], eax
     1546    mov     ecx, PATM_ACTION_MAGIC
     1547    mov     edi, PATM_CURINSTRADDR
     1548
     1549    popfd
     1550    db      0fh, 0bh        ; illegal instr (hardcoded assumption in PATMHandleIllegalInstrTrap)
     1551    ; does not return
     1552
     1553iretring1_continue:
     1554
     1555    test    dword [esp+8], 2
     1556    jnz     iretring1_notring01
     1557
     1558    test    dword [esp+8], 1
     1559    jz      iretring1_ring0
     1560
     1561    ; ring 1 return change CS & SS RPL to 2 from 1
     1562    and     dword [esp+8], ~1       ; CS
     1563    or      dword [esp+8], 2
     1564
     1565    and     dword [esp+20], ~1      ; SS
     1566    or      dword [esp+20], 2
     1567
     1568    jmp     short iretring1_notring01
     1569iretring1_ring0:
     1570    ; force ring 1 CS RPL
     1571    or      dword [esp+8], 1
     1572
     1573iretring1_notring01:
     1574    ; This section must *always* be executed (!!)
     1575    ; Extract the IOPL from the return flags, save them to our virtual flags and
     1576    ; put them back to zero
     1577    ; @note we assume iretd doesn't fault!!!
     1578    push    eax
     1579    mov     eax, dword [esp+16]
     1580    and     eax, X86_EFL_IOPL
     1581    and     dword [ss:PATM_VMFLAGS], ~X86_EFL_IOPL
     1582    or      dword [ss:PATM_VMFLAGS], eax
     1583    pop     eax
     1584    and     dword [esp+12], ~X86_EFL_IOPL
     1585
     1586    ; Set IF again; below we make sure this won't cause problems.
     1587    or      dword [ss:PATM_VMFLAGS], X86_EFL_IF
     1588
     1589    ; make sure iret is executed fully (including the iret below; cli ... iret can otherwise be interrupted)
     1590    mov     dword [ss:PATM_INHIBITIRQADDR], PATM_CURINSTRADDR
     1591
     1592    popfd
     1593    mov     dword [ss:PATM_INTERRUPTFLAG], 1
     1594    iretd
     1595    PATM_INT3
     1596
     1597iretring1_fault:
     1598    popfd
     1599    mov     dword [ss:PATM_INTERRUPTFLAG], 1
     1600    PATM_INT3
     1601
     1602iretring1_fault1:
     1603    nop
     1604    popfd
     1605    mov     dword [ss:PATM_INTERRUPTFLAG], 1
     1606    PATM_INT3
     1607
     1608iretring1_clearIF:
     1609    push    dword [esp+4]           ; eip to return to
     1610    pushfd
     1611    push    eax
     1612    push    PATM_FIXUP
     1613    DB      0E8h                    ; call
     1614    DD      PATM_IRET_FUNCTION
     1615    add     esp, 4                  ; pushed address of jump table
     1616
     1617    cmp     eax, 0
     1618    je      near iretring1_fault3
     1619
     1620    mov     dword [esp+12+4], eax   ; stored eip in iret frame
     1621    pop     eax
     1622    popfd
     1623    add     esp, 4                  ; pushed eip
     1624
     1625    ; This section must *always* be executed (!!)
     1626    ; Extract the IOPL from the return flags, save them to our virtual flags and
     1627    ; put them back to zero
     1628    push    eax
     1629    mov     eax, dword [esp+16]
     1630    and     eax, X86_EFL_IOPL
     1631    and     dword [ss:PATM_VMFLAGS], ~X86_EFL_IOPL
     1632    or      dword [ss:PATM_VMFLAGS], eax
     1633    pop     eax
     1634    and     dword [esp+12], ~X86_EFL_IOPL
     1635
     1636    ; Clear IF
     1637    and     dword [ss:PATM_VMFLAGS], ~X86_EFL_IF
     1638    popfd
     1639
     1640    test    dword [esp+8], 1
     1641    jz      iretring1_clearIF_ring0
     1642
     1643    ; ring 1 return change CS & SS RPL to 2 from 1
     1644    and     dword [esp+8], ~1       ; CS
     1645    or      dword [esp+8], 2
     1646
     1647    and     dword [esp+20], ~1      ; SS
     1648    or      dword [esp+20], 2
     1649                                                ; the patched destination code will set PATM_INTERRUPTFLAG after the return!
     1650    iretd
     1651
     1652iretring1_clearIF_ring0:
     1653    ; force ring 1 CS RPL
     1654    or      dword [esp+8], 1
     1655                                                ; the patched destination code will set PATM_INTERRUPTFLAG after the return!
     1656    iretd
     1657
     1658iretring1_return_to_v86:
     1659    test    dword [esp+12], X86_EFL_IF
     1660    jz      iretring1_fault
     1661
     1662    ; Go to our hypervisor trap handler to perform the iret to v86 code
     1663    mov     dword [ss:PATM_TEMP_EAX], eax
     1664    mov     dword [ss:PATM_TEMP_ECX], ecx
     1665    mov     dword [ss:PATM_TEMP_RESTORE_FLAGS], PATM_RESTORE_EAX | PATM_RESTORE_ECX
     1666    mov     eax, PATM_ACTION_DO_V86_IRET
     1667    lock    or dword [ss:PATM_PENDINGACTION], eax
     1668    mov     ecx, PATM_ACTION_MAGIC
     1669
     1670    popfd
     1671
     1672    db      0fh, 0bh        ; illegal instr (hardcoded assumption in PATMHandleIllegalInstrTrap)
     1673    ; does not return
     1674
     1675
     1676iretring1_fault3:
     1677    pop     eax
     1678    popfd
     1679    add     esp, 4                  ; pushed eip
     1680    jmp     iretring1_fault
     1681
     1682align   4
     1683PATMIretRing1Table:
     1684    DW      PATM_MAX_JUMPTABLE_ENTRIES          ; nrSlots
     1685    DW      0                                   ; ulInsertPos
     1686    DD      0                                   ; cAddresses
     1687    TIMES PATCHJUMPTABLE_SIZE DB 0              ; lookup slots
     1688
     1689PATMIretRing1End:
     1690ENDPROC     PATMIretRing1Replacement
     1691
     1692SECTION .data
     1693; Patch record for 'iretd'
     1694GLOBALNAME PATMIretRing1Record
     1695    RTCCPTR_DEF PATMIretRing1Start
     1696    DD      0
     1697    DD      0
     1698    DD      0
     1699    DD      PATMIretRing1End- PATMIretRing1Start
     1700%ifdef PATM_LOG_PATCHIRET
     1701    DD      26
     1702%else
     1703    DD      25
     1704%endif
     1705    DD      PATM_INTERRUPTFLAG
     1706    DD      0
     1707%ifdef PATM_LOG_PATCHIRET
     1708    DD      PATM_PENDINGACTION
     1709    DD      0
     1710%endif
     1711    DD      PATM_VM_FORCEDACTIONS
     1712    DD      0
     1713    DD      PATM_TEMP_EAX
     1714    DD      0
     1715    DD      PATM_TEMP_ECX
     1716    DD      0
     1717    DD      PATM_TEMP_EDI
     1718    DD      0
     1719    DD      PATM_TEMP_RESTORE_FLAGS
     1720    DD      0
     1721    DD      PATM_PENDINGACTION
     1722    DD      0
     1723    DD      PATM_CURINSTRADDR
     1724    DD      0
     1725    DD      PATM_VMFLAGS
     1726    DD      0
     1727    DD      PATM_VMFLAGS
     1728    DD      0
     1729    DD      PATM_VMFLAGS
     1730    DD      0
     1731    DD      PATM_INHIBITIRQADDR
     1732    DD      0
     1733    DD      PATM_CURINSTRADDR
     1734    DD      0
     1735    DD      PATM_INTERRUPTFLAG
     1736    DD      0
     1737    DD      PATM_INTERRUPTFLAG
     1738    DD      0
     1739    DD      PATM_INTERRUPTFLAG
     1740    DD      0
     1741    DD      PATM_FIXUP
     1742    DD      PATMIretRing1Table - PATMIretRing1Start
    14451743    DD      PATM_IRET_FUNCTION
    14461744    DD      0
  • trunk/src/VBox/VMM/VMMR3/PATMPatch.cpp

    r44528 r45276  
    2727#include <VBox/vmm/cpum.h>
    2828#include <VBox/vmm/mm.h>
     29#include <VBox/vmm/em.h>
    2930#include <VBox/vmm/trpm.h>
    3031#include <VBox/param.h>
     
    436437
    437438    AssertMsg(fSizeOverride == false, ("operand size override!!\n"));
    438 
    439439    callInfo.pCurInstrGC = pCurInstrGC;
    440440
    441     size = patmPatchGenCode(pVM, pPatch, pPB, &PATMIretRecord, 0, false, &callInfo);
     441#ifdef VBOX_WITH_RAW_RING1
     442    if (EMIsRawRing1Enabled(pVM))
     443    {
     444        size = patmPatchGenCode(pVM, pPatch, pPB, &PATMIretRing1Record, 0, false, &callInfo);
     445    }
     446    else
     447#endif
     448        size = patmPatchGenCode(pVM, pPatch, pPB, &PATMIretRecord, 0, false, &callInfo);
    442449
    443450    PATCHGEN_EPILOG(pPatch, size);
     
    10741081int patmPatchGenIntEntry(PVM pVM, PPATCHINFO pPatch, RTRCPTR pIntHandlerGC)
    10751082{
    1076     uint32_t size;
    10771083    int rc = VINF_SUCCESS;
    10781084
    1079     PATCHGEN_PROLOG(pVM, pPatch);
    1080 
    1081     /* Add lookup record for patch to guest address translation */
    1082     patmR3AddP2GLookupRecord(pVM, pPatch, pPB, pIntHandlerGC, PATM_LOOKUP_PATCH2GUEST);
    1083 
    1084     /* Generate entrypoint for the interrupt handler (correcting CS in the interrupt stack frame) */
    1085     size = patmPatchGenCode(pVM, pPatch, pPB,
    1086                             (pPatch->flags & PATMFL_INTHANDLER_WITH_ERRORCODE) ? &PATMIntEntryRecordErrorCode : &PATMIntEntryRecord,
    1087                             0, false);
    1088 
    1089     PATCHGEN_EPILOG(pPatch, size);
     1085#ifdef VBOX_WITH_RAW_RING1
     1086    if (!EMIsRawRing1Enabled(pVM))    /* direct passthru of interrupts is not allowed in the ring-1 support case as we can't deal with the ring-1/2 ambiguity in the patm asm code and we don't need it either as TRPMForwardTrap takes care of the details. */
     1087    {
     1088#endif
     1089        uint32_t size;
     1090        PATCHGEN_PROLOG(pVM, pPatch);
     1091
     1092        /* Add lookup record for patch to guest address translation */
     1093        patmR3AddP2GLookupRecord(pVM, pPatch, pPB, pIntHandlerGC, PATM_LOOKUP_PATCH2GUEST);
     1094
     1095        /* Generate entrypoint for the interrupt handler (correcting CS in the interrupt stack frame) */
     1096        size = patmPatchGenCode(pVM, pPatch, pPB,
     1097                                (pPatch->flags & PATMFL_INTHANDLER_WITH_ERRORCODE) ? &PATMIntEntryRecordErrorCode : &PATMIntEntryRecord,
     1098                                0, false);
     1099
     1100        PATCHGEN_EPILOG(pPatch, size);
     1101#ifdef VBOX_WITH_RAW_RING1
     1102    }
     1103#endif
    10901104
    10911105    // Interrupt gates set IF to 0
     
    11071121{
    11081122    uint32_t size;
     1123
     1124    Assert(!EMIsRawRing1Enabled(pVM));
    11091125
    11101126    PATCHGEN_PROLOG(pVM, pPatch);
  • trunk/src/VBox/VMM/VMMR3/PATMSSM.cpp

    r44528 r45276  
    810810        patmR3PatchConvertSSM2Mem(pPatchRec, &patch);
    811811
    812         Log(("Restoring patch %RRv -> %RRv\n", pPatchRec->patch.pPrivInstrGC, patmInfo.pPatchMemGC + pPatchRec->patch.pPatchBlockOffset));
     812        Log(("Restoring patch %RRv -> %RRv state %x\n", pPatchRec->patch.pPrivInstrGC, patmInfo.pPatchMemGC + pPatchRec->patch.pPatchBlockOffset, pPatchRec->patch.uState));
    813813        bool ret = RTAvloU32Insert(&pVM->patm.s.PatchLookupTreeHC->PatchTree, &pPatchRec->Core);
    814814        Assert(ret);
  • trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp

    r44528 r45276  
    494494        {
    495495            pgmUnlock(pVM);
     496#ifndef DEBUG_sander
    496497            AssertMsgFailed(("Range %#x not found!\n", GCPtr));
     498#endif
    497499            return VERR_INVALID_PARAMETER;
    498500        }
  • trunk/src/VBox/VMM/VMMR3/SELM.cpp

    r44528 r45276  
    8080#include <iprt/string.h>
    8181
    82 
    83 /**
    84  * Enable or disable tracking of Shadow GDT/LDT/TSS.
    85  * @{
    86  */
    87 #define SELM_TRACK_SHADOW_GDT_CHANGES
    88 #define SELM_TRACK_SHADOW_LDT_CHANGES
    89 #define SELM_TRACK_SHADOW_TSS_CHANGES
    90 /** @} */
    9182
    9283
     
    565556     * Uninstall guest GDT/LDT/TSS write access handlers.
    566557     */
    567     int rc;
     558    int rc = VINF_SUCCESS;
    568559    if (pVM->selm.s.GuestGdtr.pGdt != RTRCPTR_MAX && pVM->selm.s.fGDTRangeRegistered)
    569560    {
     561#ifdef SELM_TRACK_GUEST_GDT_CHANGES
    570562        rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GuestGdtr.pGdt);
    571563        AssertRC(rc);
     564#endif
    572565        pVM->selm.s.GuestGdtr.pGdt = RTRCPTR_MAX;
    573566        pVM->selm.s.GuestGdtr.cbGdt = 0;
     
    576569    if (pVM->selm.s.GCPtrGuestLdt != RTRCPTR_MAX)
    577570    {
     571#ifdef SELM_TRACK_GUEST_LDT_CHANGES
    578572        rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrGuestLdt);
    579573        AssertRC(rc);
     574#endif
    580575        pVM->selm.s.GCPtrGuestLdt = RTRCPTR_MAX;
    581576    }
    582577    if (pVM->selm.s.GCPtrGuestTss != RTRCPTR_MAX)
    583578    {
     579#ifdef SELM_TRACK_GUEST_TSS_CHANGES
    584580        rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrGuestTss);
    585581        AssertRC(rc);
     582#endif
    586583        pVM->selm.s.GCPtrGuestTss = RTRCPTR_MAX;
    587584        pVM->selm.s.GCSelTss      = RTSEL_MAX;
     
    619616    if (pVM->selm.s.GuestGdtr.pGdt != RTRCPTR_MAX && pVM->selm.s.fGDTRangeRegistered)
    620617    {
     618#ifdef SELM_TRACK_GUEST_GDT_CHANGES
    621619        rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GuestGdtr.pGdt);
    622620        AssertRC(rc);
     621#endif
    623622        pVM->selm.s.GuestGdtr.pGdt = RTRCPTR_MAX;
    624623        pVM->selm.s.GuestGdtr.cbGdt = 0;
     
    627626    if (pVM->selm.s.GCPtrGuestLdt != RTRCPTR_MAX)
    628627    {
     628#ifdef SELM_TRACK_GUEST_LDT_CHANGES
    629629        rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrGuestLdt);
    630630        AssertRC(rc);
     631#endif
    631632        pVM->selm.s.GCPtrGuestLdt = RTRCPTR_MAX;
    632633    }
    633634    if (pVM->selm.s.GCPtrGuestTss != RTRCPTR_MAX)
    634635    {
     636#ifdef SELM_TRACK_GUEST_TSS_CHANGES
    635637        rc = PGMHandlerVirtualDeregister(pVM, pVM->selm.s.GCPtrGuestTss);
    636638        AssertRC(rc);
     639#endif
    637640        pVM->selm.s.GCPtrGuestTss = RTRCPTR_MAX;
    638641        pVM->selm.s.GCSelTss      = RTSEL_MAX;
     
    953956    }
    954957
     958#ifdef VBOX_WITH_SAFE_STR
     959    /** Use the guest's TR selector to plug the str virtualization hole. */
     960    if (CPUMGetGuestTR(pVCpu, NULL) != 0)
     961    {
     962        Log(("SELM: Use guest TSS selector %x\n", CPUMGetGuestTR(pVCpu, NULL)));
     963        aHyperSel[SELM_HYPER_SEL_TSS] = CPUMGetGuestTR(pVCpu, NULL);
     964    }
     965#endif
     966
    955967    /*
    956968     * Work thru the copied GDT entries adjusting them for correct virtualization.
     
    960972    {
    961973        if (pGDTE->Gen.u1Present)
    962             selmGuestToShadowDesc(pGDTE);
     974            selmGuestToShadowDesc(pVM, pGDTE);
    963975
    964976        /* Next GDT entry. */
     
    9901002        VMR3Relocate(pVM, 0);
    9911003    }
    992     else if (cbEffLimit >= SELM_HYPER_DEFAULT_BASE)
     1004    else
     1005#ifdef VBOX_WITH_SAFE_STR
     1006    if (    cbEffLimit >= SELM_HYPER_DEFAULT_BASE
     1007        ||  CPUMGetGuestTR(pVCpu, NULL) != 0)       /* Our shadow TR entry was overwritten when we synced the guest's GDT. */
     1008#else
     1009    if (cbEffLimit >= SELM_HYPER_DEFAULT_BASE)
     1010#endif
    9931011        /* We overwrote all entries above, so we have to save them again. */
    9941012        selmR3SetupHyperGDTSelectors(pVM);
     
    10111029    {
    10121030        Log(("SELMR3UpdateFromCPUM: Guest's GDT is changed to pGdt=%016RX64 cbGdt=%08X\n", GDTR.pGdt, GDTR.cbGdt));
    1013 
     1031#ifdef SELM_TRACK_GUEST_GDT_CHANGES
    10141032        /*
    10151033         * [Re]Register write virtual handler for guest's GDT.
     
    10251043                                         0, selmR3GuestGDTWriteHandler, "selmRCGuestGDTWriteHandler", 0,
    10261044                                         "Guest GDT write access handler");
     1045# ifdef VBOX_WITH_RAW_RING1
     1046        /* Some guest OSes (QNX) share code and the GDT on the same page; PGMR3HandlerVirtualRegister doesn't support more than one handler, so we kick out the
     1047         * PATM handler as this one is more important.
     1048         * @todo fix this properly in PGMR3HandlerVirtualRegister
     1049         */
     1050        if (rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT)
     1051        {
     1052            LogRel(("selmR3UpdateShadowGdt: Virtual handler conflict %RGv -> kick out PATM handler for the higher priority GDT page monitor\n", GDTR.pGdt));
     1053            rc = PGMHandlerVirtualDeregister(pVM, GDTR.pGdt & PAGE_BASE_GC_MASK);
     1054            AssertRC(rc);
     1055
     1056            rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE,
     1057                                             GDTR.pGdt, GDTR.pGdt + GDTR.cbGdt /* already inclusive */,
     1058                                             0, selmR3GuestGDTWriteHandler, "selmRCGuestGDTWriteHandler", 0,
     1059                                             "Guest GDT write access handler");
     1060        }
     1061# endif
    10271062        if (RT_FAILURE(rc))
    10281063            return rc;
    1029 
     1064#endif
    10301065        /* Update saved Guest GDTR. */
    10311066        pVM->selm.s.GuestGdtr = GDTR;
     
    11371172                 pVM->selm.s.GCPtrGuestLdt, pVM->selm.s.cbLdtLimit, GCPtrLdt, cbLdt, pVM->selm.s.GuestGdtr.pGdt, pVM->selm.s.GuestGdtr.cbGdt));
    11381173
     1174#ifdef SELM_TRACK_GUEST_LDT_CHANGES
    11391175            /*
    11401176             * [Re]Register write virtual handler for guest's GDT.
     
    11461182                AssertRC(rc);
    11471183            }
    1148 #ifdef DEBUG
     1184# ifdef DEBUG
    11491185            if (pDesc->Gen.u1Present)
    11501186                Log(("LDT selector marked not present!!\n"));
    1151 #endif
     1187# endif
    11521188            rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, GCPtrLdt, GCPtrLdt + cbLdt /* already inclusive */,
    11531189                                             0, selmR3GuestLDTWriteHandler, "selmRCGuestLDTWriteHandler", 0, "Guest LDT write access handler");
     
    11661202                return rc;
    11671203            }
    1168 
     1204#else
     1205            pVM->selm.s.GCPtrGuestLdt = GCPtrLdt;
     1206#endif
    11691207            pVM->selm.s.cbLdtLimit = cbLdt;
    11701208        }
     
    12051243    /** @todo investigate how intel handle various operations on half present cross page entries. */
    12061244    off = GCPtrLdt & (sizeof(X86DESC) - 1);
    1207     AssertMsg(!off, ("LDT is not aligned on entry size! GCPtrLdt=%08x\n", GCPtrLdt));
     1245////    AssertMsg(!off, ("LDT is not aligned on entry size! GCPtrLdt=%08x\n", GCPtrLdt));
    12081246
    12091247    /* Note: Do not skip the first selector; unlike the GDT, a zero LDT selector is perfectly valid. */
     
    12391277            {
    12401278                if (pLDTE->Gen.u1Present)
    1241                     selmGuestToShadowDesc(pLDTE);
     1279                    selmGuestToShadowDesc(pVM, pLDTE);
    12421280
    12431281                /* Next LDT entry. */
     
    14381476}
    14391477
    1440 
     1478#ifdef SELM_TRACK_GUEST_GDT_CHANGES
    14411479/**
    14421480 * \#PF Handler callback for virtual access handler ranges.
     
    14651503    return VINF_PGM_HANDLER_DO_DEFAULT;
    14661504}
    1467 
    1468 
     1505#endif
     1506
     1507#ifdef SELM_TRACK_GUEST_LDT_CHANGES
    14691508/**
    14701509 * \#PF Handler callback for virtual access handler ranges.
     
    14931532    return VINF_PGM_HANDLER_DO_DEFAULT;
    14941533}
    1495 
    1496 
     1534#endif
     1535
     1536
     1537#ifdef SELM_TRACK_GUEST_TSS_CHANGES
    14971538/**
    14981539 * \#PF Handler callback for virtual access handler ranges.
     
    15261567    return VINF_PGM_HANDLER_DO_DEFAULT;
    15271568}
    1528 
     1569#endif
    15291570
    15301571/**
     
    16751716            selmSetRing1Stack(pVM, Tss.ss0 | 1, Tss.esp0);
    16761717            pVM->selm.s.fSyncTSSRing0Stack = fNoRing1Stack = false;
     1718
     1719#ifdef VBOX_WITH_RAW_RING1
     1720            /* Update our TSS structure for the guest's ring 2 stack */
     1721            selmSetRing2Stack(pVM, (Tss.ss1 & ~1) | 2, Tss.esp1);
     1722
     1723            if (    (pVM->selm.s.Tss.ss2 != ((Tss.ss1 & ~2) | 1))
     1724                ||  pVM->selm.s.Tss.esp2 != Tss.esp1)
     1725            {
     1726                Log(("SELMR3SyncTSS: Updating TSS ring 1 stack to %04X:%08X from %04X:%08X\n", Tss.ss1, Tss.esp1, (pVM->selm.s.Tss.ss2 & ~2) | 1, pVM->selm.s.Tss.esp2));
     1727            }
     1728#endif
    16771729        }
    16781730    }
     
    17111763        if (cbMonitoredTss != 0)
    17121764        {
     1765#ifdef SELM_TRACK_GUEST_TSS_CHANGES
    17131766            rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, GCPtrTss, GCPtrTss + cbMonitoredTss - 1,
    17141767                                             0, selmR3GuestTSSWriteHandler,
     
    17161769            if (RT_FAILURE(rc))
    17171770            {
     1771# ifdef VBOX_WITH_RAW_RING1
     1772                /* Some guest OSes (QNX) share code and the TSS on the same page; PGMR3HandlerVirtualRegister doesn't support more than one handler, so we kick out the
     1773                 * PATM handler as this one is more important.
     1774                 * @todo fix this properly in PGMR3HandlerVirtualRegister
     1775                 */
     1776                if (rc == VERR_PGM_HANDLER_VIRTUAL_CONFLICT)
     1777                {
     1778                    LogRel(("SELMR3SyncTSS: Virtual handler conflict %RGv -> kick out PATM handler for the higher priority TSS page monitor\n", GCPtrTss));
     1779                    rc = PGMHandlerVirtualDeregister(pVM, GCPtrTss & PAGE_BASE_GC_MASK);
     1780                    AssertRC(rc);
     1781
     1782                    rc = PGMR3HandlerVirtualRegister(pVM, PGMVIRTHANDLERTYPE_WRITE, GCPtrTss, GCPtrTss + cbMonitoredTss - 1,
     1783                                                     0, selmR3GuestTSSWriteHandler,
     1784                                                     "selmRCGuestTSSWriteHandler", 0, "Guest TSS write access handler");
     1785                    if (RT_FAILURE(rc))
     1786                    {
     1787                        STAM_PROFILE_STOP(&pVM->selm.s.StatUpdateFromCPUM, a);
     1788                        return rc;
     1789                    }
     1790                }
     1791# else
    17181792                STAM_PROFILE_STOP(&pVM->selm.s.StatUpdateFromCPUM, a);
    17191793                return rc;
    1720             }
    1721 
     1794# endif
     1795           }
     1796#endif
    17221797            /* Update saved Guest TSS info. */
    17231798            pVM->selm.s.GCPtrGuestTss       = GCPtrTss;
     
    18881963VMMR3DECL(bool) SELMR3CheckTSS(PVM pVM)
    18891964{
    1890 #ifdef VBOX_STRICT
     1965#if defined(VBOX_STRICT) && defined(SELM_TRACK_GUEST_TSS_CHANGES)
    18911966    PVMCPU pVCpu = VMMGetCpu(pVM);
    18921967
     
    20192094#endif /* !VBOX_STRICT */
    20202095}
     2096
     2097# ifdef VBOX_WITH_SAFE_STR
     2098/**
     2099 * Validates the RawR0 TR shadow GDT entry
     2100 *
     2101 * @returns true if it matches.
     2102 * @returns false and assertions on mismatch..
     2103 * @param   pVM     Pointer to the VM.
     2104 */
     2105VMMR3DECL(bool) SELMR3CheckShadowTR(PVM pVM)
     2106{
     2107#  ifdef VBOX_STRICT
     2108    PX86DESC paGdt = pVM->selm.s.paGdtR3;
     2109
     2110    /*
     2111     * TSS descriptor
     2112     */
     2113    PX86DESC pDesc = &paGdt[pVM->selm.s.aHyperSel[SELM_HYPER_SEL_TSS] >> 3];
     2114    RTRCPTR RCPtrTSS = VM_RC_ADDR(pVM, &pVM->selm.s.Tss);
     2115
     2116    if (    pDesc->Gen.u16BaseLow      != RT_LOWORD(RCPtrTSS)
     2117        ||  pDesc->Gen.u8BaseHigh1     != RT_BYTE3(RCPtrTSS)
     2118        ||  pDesc->Gen.u8BaseHigh2     != RT_BYTE4(RCPtrTSS)
     2119        ||  pDesc->Gen.u16LimitLow     != sizeof(VBOXTSS) - 1
     2120        ||  pDesc->Gen.u4LimitHigh     != 0
     2121        ||  (pDesc->Gen.u4Type         != X86_SEL_TYPE_SYS_386_TSS_AVAIL && pDesc->Gen.u4Type != X86_SEL_TYPE_SYS_386_TSS_BUSY)
     2122        ||  pDesc->Gen.u1DescType      != 0 /* system */
     2123        ||  pDesc->Gen.u2Dpl           != 0 /* supervisor */
     2124        ||  pDesc->Gen.u1Present       != 1
     2125        ||  pDesc->Gen.u1Available     != 0
     2126        ||  pDesc->Gen.u1Long          != 0
     2127        ||  pDesc->Gen.u1DefBig        != 0
     2128        ||  pDesc->Gen.u1Granularity   != 0 /* byte limit */
     2129        )
     2130    {
     2131        AssertFailed();
     2132        return false;
     2133    }
     2134#  endif
     2135    return true;
     2136}
     2137# endif
    20212138
    20222139#endif /* VBOX_WITH_RAW_MODE */
  • trunk/src/VBox/VMM/VMMR3/TRPM.cpp

    r44528 r45276  
    13301330    }
    13311331
    1332     if (EMIsRawRing0Enabled(pVM))
     1332    if (    EMIsRawRing0Enabled(pVM)
     1333#ifdef VBOX_WITH_RAW_RING1
     1334        && !EMIsRawRing1Enabled(pVM)    /* can't deal with the ambiguity of ring 1 & 2 in the patch code. */
     1335#endif
     1336       )
    13331337    {
    13341338        /*
  • trunk/src/VBox/VMM/VMMR3/VMM.cpp

    r45152 r45276  
    12571257            EMR3FatalError(pVCpu, VERR_VMM_HYPER_CR3_MISMATCH);
    12581258        PGMMapCheck(pVM);
     1259# ifdef VBOX_WITH_SAFE_STR
     1260        SELMR3CheckShadowTR(pVM);
     1261# endif
    12591262#endif
    12601263        int rc;
  • trunk/src/VBox/VMM/VMMRC/CPUMRC.cpp

    r42774 r45276  
    2525#include <VBox/vmm/patm.h>
    2626#include <VBox/vmm/trpm.h>
     27#include <VBox/vmm/em.h>
    2728#include "CPUMInternal.h"
    2829#include <VBox/vmm/vm.h>
     
    106107    //Log2(("cs:eip=%04x:%08x ss:esp=%04x:%08x cpl=%u raw/efl=%#x/%#x%s\n", pCtx->cs.Sel, pCtx->eip, pCtx->ss.Sel, pCtx->esp, uRawCpl, u32EFlags, pCtx->eflags.u, fPatch ? " patch" : ""));
    107108}
     109
     110
     111/**
     112 * Get the current privilege level of the guest.
     113 *
     114 * @returns CPL
     115 * @param   pVCpu       The current virtual CPU.
     116 * @param   pRegFrame   Pointer to the register frame.
     117 */
     118VMMDECL(uint32_t) CPUMRCGetGuestCPL(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame)
     119{
     120    /*
     121     * CPL can reliably be found in SS.DPL (hidden regs valid) or SS if not.
     122     *
     123     * Note! We used to check CS.DPL here, assuming it was always equal to
     124     * CPL even if a conforming segment was loaded.  But this truned out to
     125     * only apply to older AMD-V.  With VT-x we had an ACP2 regression
     126     * during install after a far call to ring 2 with VT-x.  Then on newer
     127     * AMD-V CPUs we have to move the VMCB.guest.u8CPL into cs.Attr.n.u2Dpl
     128     * as well as ss.Attr.n.u2Dpl to make this (and other) code work right.
     129     *
     130     * So, forget CS.DPL, always use SS.DPL.
     131     *
     132     * Note! The SS RPL is always equal to the CPL, while the CS RPL
     133     * isn't necessarily equal if the segment is conforming.
     134     * See section 4.11.1 in the AMD manual.
     135     */
     136    uint32_t uCpl;
     137    if (!pRegFrame->eflags.Bits.u1VM)
     138    {
     139        uCpl = (pRegFrame->ss.Sel & X86_SEL_RPL);
     140#ifdef VBOX_WITH_RAW_MODE_NOT_R0
     141# ifdef VBOX_WITH_RAW_RING1
     142        if (pVCpu->cpum.s.fRawEntered)
     143        {
     144            if (    EMIsRawRing1Enabled(pVCpu->CTX_SUFF(pVM))
     145                &&  uCpl == 2)
     146                uCpl = 1;
     147            else
     148            if (uCpl == 1)
     149                uCpl = 0;
     150        }
     151        Assert(uCpl != 2);  /* ring 2 support not allowed anymore. */
     152# else
     153        if (uCpl == 1)
     154            uCpl = 0;
     155# endif
     156#endif
     157    }
     158    else
     159        uCpl = 3; /* V86 has CPL=3; REM doesn't set DPL=3 in V8086 mode. See @bugref{5130}. */
     160
     161    return uCpl;
     162}
     163
     164#ifdef VBOX_WITH_RAW_RING1
     165/**
     166 * Transforms the guest CPU state to raw-ring mode.
     167 *
     168 * This function will change the any of the cs and ss register with DPL=0 to DPL=1.
     169 *
     170 * @returns VBox status. (recompiler failure)
     171 * @param   pVCpu       Pointer to the VMCPU.
     172 * @param   pCtxCore    The context core (for trap usage).
     173 * @see     @ref pg_raw
     174 */
     175VMMDECL(void) CPUMRCRecheckRawState(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore)
     176{
     177    /*
     178     * Are we in Ring-0?
     179     */
     180    if (    pCtxCore->ss.Sel
     181        &&  (pCtxCore->ss.Sel & X86_SEL_RPL) == 0
     182        &&  !pCtxCore->eflags.Bits.u1VM)
     183    {
     184        /*
     185         * Set CPL to Ring-1.
     186         */
     187        pCtxCore->ss.Sel |= 1;
     188        if (    pCtxCore->cs.Sel
     189            &&  (pCtxCore->cs.Sel & X86_SEL_RPL) == 0)
     190            pCtxCore->cs.Sel |= 1;
     191    }
     192    else
     193    {
     194        if (    EMIsRawRing1Enabled(pVCpu->CTX_SUFF(pVM))
     195            &&  !pCtxCore->eflags.Bits.u1VM
     196            &&  (pCtxCore->ss.Sel & X86_SEL_RPL) == 1)
     197        {
     198            /* Set CPL to Ring-2. */
     199            pCtxCore->ss.Sel = (pCtxCore->ss.Sel & ~X86_SEL_RPL) | 2;
     200            if (pCtxCore->cs.Sel && (pCtxCore->cs.Sel & X86_SEL_RPL) == 1)
     201                pCtxCore->cs.Sel = (pCtxCore->cs.Sel & ~X86_SEL_RPL) | 2;
     202        }
     203    }
     204
     205    /*
     206     * Assert sanity.
     207     */
     208    AssertMsg((pCtxCore->eflags.u32 & X86_EFL_IF), ("X86_EFL_IF is clear\n"));
     209    AssertReleaseMsg(pCtxCore->eflags.Bits.u2IOPL == 0,
     210                     ("X86_EFL_IOPL=%d CPL=%d\n", pCtxCore->eflags.Bits.u2IOPL, pCtxCore->ss.Sel & X86_SEL_RPL));
     211
     212    pCtxCore->eflags.u32        |= X86_EFL_IF; /* paranoia */
     213}
     214#endif /* VBOX_WITH_RAW_RING1 */
  • trunk/src/VBox/VMM/VMMRC/PATMRC.cpp

    r44363 r45276  
    155155
    156156    /* Very important check -> otherwise we have a security leak. */
     157#ifdef VBOX_WITH_RAW_RING1
     158    AssertReturn(!pRegFrame->eflags.Bits.u1VM && (pRegFrame->ss.Sel & X86_SEL_RPL) <= (unsigned) (EMIsRawRing1Enabled(pVM) ? 2 : 1), VERR_ACCESS_DENIED);
     159#else
    157160    AssertReturn(!pRegFrame->eflags.Bits.u1VM && (pRegFrame->ss.Sel & X86_SEL_RPL) == 1, VERR_ACCESS_DENIED);
     161#endif
    158162    Assert(PATMIsPatchGCAddr(pVM, pRegFrame->eip));
    159163
     
    455459    int rc;
    456460
     461#ifdef VBOX_WITH_RAW_RING1
     462    AssertReturn(!pRegFrame->eflags.Bits.u1VM && ((pRegFrame->ss.Sel & X86_SEL_RPL) == 1 || (EMIsRawRing1Enabled(pVM) && (pRegFrame->ss.Sel & X86_SEL_RPL) == 2)), VERR_ACCESS_DENIED);
     463#else
    457464    AssertReturn(!pRegFrame->eflags.Bits.u1VM && (pRegFrame->ss.Sel & X86_SEL_RPL) == 1, VERR_ACCESS_DENIED);
     465#endif
    458466
    459467    /* Int 3 in PATM generated code? (most common case) */
     
    490498            case OP_CPUID:
    491499            case OP_IRET:
     500#ifdef VBOX_WITH_RAW_RING1
     501            case OP_SMSW:
     502            case OP_MOV:     /* mov xx, CS  */
     503#endif
    492504                break;
    493505
     
    498510            case OP_LSL:
    499511            case OP_LAR:
     512#ifndef VBOX_WITH_RAW_RING1
    500513            case OP_SMSW:
     514#endif
    501515            case OP_VERW:
    502516            case OP_VERR:
  • trunk/src/VBox/VMM/VMMRC/SELMRC.cpp

    r44528 r45276  
    4444#endif
    4545
    46 
     46#ifdef SELM_TRACK_GUEST_GDT_CHANGES
    4747/**
    4848 * Synchronizes one GDT entry (guest -> shadow).
     
    123123     * Convert the guest selector to a shadow selector and update the shadow GDT.
    124124     */
    125     selmGuestToShadowDesc(&Desc);
     125    selmGuestToShadowDesc(pVM, &Desc);
    126126    PX86DESC pShwDescr = &pVM->selm.s.paGdtRC[iGDTEntry];
    127127    //Log(("O: base=%08X limit=%08X attr=%04X\n", X86DESC_BASE(*pShwDescr)), X86DESC_LIMIT(*pShwDescr), (pShwDescr->au32[1] >> 8) & 0xFFFF ));
     
    306306    return rc;
    307307}
    308 
    309 
     308#endif /* SELM_TRACK_GUEST_GDT_CHANGES */
     309
     310#ifdef SELM_TRACK_GUEST_LDT_CHANGES
    310311/**
    311312 * \#PF Virtual Handler callback for Guest write access to the Guest's own LDT.
     
    330331    return VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT;
    331332}
    332 
    333 
     333#endif
     334
     335#ifdef SELM_TRACK_GUEST_TSS_CHANGES
    334336/**
    335337 * Read wrapper used by selmRCGuestTSSWriteHandler.
     
    382384    uint32_t cb;
    383385    int rc = EMInterpretInstructionEx(pVCpu, pRegFrame, (RTGCPTR)(RTRCUINTPTR)pvFault, &cb);
    384     if (RT_SUCCESS(rc) && cb)
     386    if (    RT_SUCCESS(rc)
     387        &&  cb)
    385388    {
    386389        rc = VINF_SUCCESS;
     
    403406            STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestTSSHandledChanged);
    404407        }
     408#ifdef VBOX_WITH_RAW_RING1
     409        else
     410        if (    EMIsRawRing1Enabled(pVM)
     411            &&  PAGE_ADDRESS(&pGuestTss->esp1) == PAGE_ADDRESS(&pGuestTss->padding_ss1)
     412            &&  PAGE_ADDRESS(&pGuestTss->esp1) == PAGE_ADDRESS((uint8_t *)pGuestTss + offRange)
     413            &&  (    pGuestTss->esp1 !=  pVM->selm.s.Tss.esp2
     414                 ||  pGuestTss->ss1  != ((pVM->selm.s.Tss.ss2 & ~2) | 1)) /* undo raw-r1 */
     415           )
     416        {
     417            Log(("selmRCGuestTSSWriteHandler: R1 stack: %RTsel:%RGv -> %RTsel:%RGv\n",
     418                 (RTSEL)((pVM->selm.s.Tss.ss2 & ~2) | 1), (RTGCPTR)pVM->selm.s.Tss.esp2, (RTSEL)pGuestTss->ss1, (RTGCPTR)pGuestTss->esp1));
     419            pVM->selm.s.Tss.esp2 = pGuestTss->esp1;
     420            pVM->selm.s.Tss.ss2  = (pGuestTss->ss1 & ~1) | 2;
     421            STAM_COUNTER_INC(&pVM->selm.s.StatRCWriteGuestTSSHandledChanged);
     422        }
     423#endif
    405424        /* Handle misaligned TSS in a safe manner (just in case). */
    406425        else if (   offRange >= RT_UOFFSETOF(VBOXTSS, esp0)
     
    492511    return rc;
    493512}
    494 
    495 
     513#endif /* SELM_TRACK_GUEST_TSS_CHANGES */
     514
     515#ifdef SELM_TRACK_SHADOW_GDT_CHANGES
    496516/**
    497517 * \#PF Virtual Handler callback for Guest write access to the VBox shadow GDT.
     
    512532    return VERR_SELM_SHADOW_GDT_WRITE;
    513533}
    514 
    515 
     534#endif
     535
     536#ifdef SELM_TRACK_SHADOW_LDT_CHANGES
    516537/**
    517538 * \#PF Virtual Handler callback for Guest write access to the VBox shadow LDT.
     
    533554    return VERR_SELM_SHADOW_LDT_WRITE;
    534555}
    535 
    536 
     556#endif
     557
     558#ifdef SELM_TRACK_SHADOW_TSS_CHANGES
    537559/**
    538560 * \#PF Virtual Handler callback for Guest write access to the VBox shadow TSS.
     
    553575    return VERR_SELM_SHADOW_TSS_WRITE;
    554576}
    555 
     577#endif
     578
  • trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp

    r44362 r45276  
    304304    PVM         pVM   = TRPMCPU_2_VM(pTrpmCpu);
    305305    PVMCPU      pVCpu = TRPMCPU_2_VMCPU(pTrpmCpu);
    306     LogFlow(("TRPMGC01: cs:eip=%04x:%08x uDr6=%RTreg EFL=%x\n", pRegFrame->cs.Sel, pRegFrame->eip, uDr6, CPUMRawGetEFlags(pVCpu)));
     306    //LogFlow(("TRPMGC01: cs:eip=%04x:%08x uDr6=%RTreg EFL=%x\n", pRegFrame->cs.Sel, pRegFrame->eip, uDr6, CPUMRawGetEFlags(pVCpu)));
    307307    TRPM_ENTER_DBG_HOOK(1);
    308308
     
    445445     * PATM is using INT3s, let them have a go first.
    446446     */
     447#ifdef VBOX_WITH_RAW_RING1
     448    if (    (   (pRegFrame->ss.Sel & X86_SEL_RPL) == 1
     449             || (EMIsRawRing1Enabled(pVM) && (pRegFrame->ss.Sel & X86_SEL_RPL) == 2))
     450#else
    447451    if (    (pRegFrame->ss.Sel & X86_SEL_RPL) == 1
     452#endif
    448453        &&  !pRegFrame->eflags.Bits.u1VM)
    449454    {
     
    523528    PGMRZDynMapStartAutoSet(pVCpu);
    524529
     530#ifdef VBOX_WITH_RAW_RING1
     531    if (CPUMGetGuestCPL(pVCpu) <= (unsigned)(EMIsRawRing1Enabled(pVM) ? 1 : 0))
     532#else
    525533    if (CPUMGetGuestCPL(pVCpu) == 0)
     534#endif
    526535    {
    527536        /*
     
    949958        {
    950959            uint32_t efl = CPUMRawGetEFlags(pVCpu);
    951             if (X86_EFL_GET_IOPL(efl) >= (unsigned)(pRegFrame->ss.Sel & X86_SEL_RPL))
     960            uint32_t cpl = CPUMRCGetGuestCPL(pVCpu, pRegFrame);
     961            if (X86_EFL_GET_IOPL(efl) >= cpl)
    952962            {
    953963                LogFlow(("trpmGCTrap0dHandlerRing3: CLI/STI -> REM\n"));
     
    955965                return trpmGCExitTrap(pVM, pVCpu, VINF_EM_RESCHEDULE_REM, pRegFrame);
    956966            }
    957             LogFlow(("trpmGCTrap0dHandlerRing3: CLI/STI -> #GP(0)\n"));
     967            LogFlow(("trpmGCTrap0dHandlerRing3: CLI/STI -> #GP(0) iopl=%x, cpl=%x\n", X86_EFL_GET_IOPL(efl), cpl));
    958968            break;
    959969        }
     
    10961106    if (eflags.Bits.u2IOPL != 3)
    10971107    {
    1098         Assert(eflags.Bits.u2IOPL == 0);
     1108        Assert(EMIsRawRing1Enabled(pVM) || eflags.Bits.u2IOPL == 0);
    10991109
    11001110        rc = TRPMForwardTrap(pVCpu, pRegFrame, 0xD, 0, TRPM_TRAP_HAS_ERRORCODE, TRPM_TRAP, 0xd);
  • trunk/src/VBox/VMM/include/PATMA.h

    r44528 r45276  
    146146extern PATCHASMRECORD PATMPushf16Record;
    147147extern PATCHASMRECORD PATMIretRecord;
     148extern PATCHASMRECORD PATMIretRing1Record;
    148149extern PATCHASMRECORD PATMCpuidRecord;
    149150extern PATCHASMRECORD PATMLoopRecord;
  • trunk/src/VBox/VMM/include/SELMInternal.h

    r44528 r45276  
    2525#include <VBox/log.h>
    2626#include <iprt/x86.h>
     27#include <VBox/vmm/em.h>
    2728
    2829
     
    3334 * @{
    3435 */
     36
     37/**
     38 * Enable or disable tracking of Shadow GDT/LDT/TSS.
     39 * @{
     40 */
     41#define SELM_TRACK_SHADOW_GDT_CHANGES
     42#define SELM_TRACK_SHADOW_LDT_CHANGES
     43#define SELM_TRACK_SHADOW_TSS_CHANGES
     44/** @} */
     45
     46/**
     47 * Enable or disable tracking of Guest GDT/LDT/TSS.
     48 * @{
     49 */
     50#define SELM_TRACK_GUEST_GDT_CHANGES
     51#define SELM_TRACK_GUEST_LDT_CHANGES
     52#define SELM_TRACK_GUEST_TSS_CHANGES
     53/** @} */
     54
    3555
    3656/** The number of GDTS allocated for our GDT. (full size) */
     
    203223
    204224void           selmSetRing1Stack(PVM pVM, uint32_t ss, RTGCPTR32 esp);
     225#ifdef VBOX_WITH_RAW_RING1
     226void           selmSetRing2Stack(PVM pVM, uint32_t ss, RTGCPTR32 esp);
     227#endif
    205228
    206229RT_C_DECLS_END
     
    362385 * Converts a guest GDT or LDT entry to a shadow table entry.
    363386 *
     387 * @param   pVM                 The VM handle.
    364388 * @param   pDesc       Guest entry on input, shadow entry on return.
    365389 */
    366 DECL_FORCE_INLINE(void) selmGuestToShadowDesc(PX86DESC pDesc)
     390DECL_FORCE_INLINE(void) selmGuestToShadowDesc(PVM pVM, PX86DESC pDesc)
    367391{
    368392    /*
     
    391415            pDesc->Gen.u1Available = 1;
    392416        }
     417# ifdef VBOX_WITH_RAW_RING1
     418        else
     419        if (    pDesc->Gen.u2Dpl == 1
     420//            &&  EMIsRawRing1Enabled(pVM)
     421            &&      (pDesc->Gen.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF))
     422                !=  (X86_SEL_TYPE_CODE | X86_SEL_TYPE_CONF) )
     423        {
     424            pDesc->Gen.u2Dpl       = 2;
     425            pDesc->Gen.u1Available = 1;
     426        }
     427# endif
    393428        else
    394429            pDesc->Gen.u1Available = 0;
  • trunk/src/recompiler/Makefile.kmk

    r42604 r45276  
    7070ifdef IEM_VERIFICATION_MODE
    7171 VBoxRemPrimary_DEFS          += IEM_VERIFICATION_MODE
     72endif
     73ifdef VBOX_WITH_RAW_RING1
     74 VBoxRemPrimary_DEFS          += VBOX_WITH_RAW_RING1
    7275endif
    7376VBoxRemPrimary_DEFS.linux      = _GNU_SOURCE
  • trunk/src/recompiler/VBoxRecompiler.c

    r44528 r45276  
    13711371         */
    13721372        case EXCP_EXECUTE_RAW:
    1373             Log2(("REMR3Run: cpu_exec -> EXCP_EXECUTE_RAW\n"));
     1373            Log2(("REMR3Run: cpu_exec -> EXCP_EXECUTE_RAW pc=%RGv\n", pVM->rem.s.Env.eip));
    13741374            rc = VINF_EM_RESCHEDULE_RAW;
    13751375            break;
     
    16331633        }
    16341634
     1635# ifdef VBOX_WITH_RAW_RING1
     1636        /* Only ring 0 and 1 supervisor code. */
     1637        if (EMIsRawRing1Enabled(env->pVM))
     1638        {
     1639            if (((fFlags >> HF_CPL_SHIFT) & 3) == 2)   /* ring 1 code is moved into ring 2, so we can't support ring-2 in that case. */
     1640            {
     1641                Log2(("raw r0 mode refused: CPL %d\n", (fFlags >> HF_CPL_SHIFT) & 3));
     1642                return false;
     1643            }
     1644        }
     1645        else
     1646# endif
    16351647        // Only R0
    16361648        if (((fFlags >> HF_CPL_SHIFT) & 3) != 0)
     
    16651677#endif
    16661678
     1679#ifndef VBOX_WITH_RAW_RING1
     1680        if (((env->eflags >> IOPL_SHIFT) & 3) != 0)
     1681        {
     1682            Log2(("raw r0 mode refused: IOPL %d\n", ((env->eflags >> IOPL_SHIFT) & 3)));
     1683            return false;
     1684        }
     1685#endif
    16671686        env->state |= CPU_RAW_RING0;
    16681687    }
     
    17641783    if (pVM->rem.s.fIgnoreInvlPg || pVM->rem.s.cIgnoreAll)
    17651784        return;
    1766     Log(("remR3FlushPage: GCPtr=%RGv\n", GCPtr));
     1785    LogFlow(("remR3FlushPage: GCPtr=%RGv\n", GCPtr));
    17671786    Assert(pVM->rem.s.fInREM || pVM->rem.s.fInStateSync);
    17681787
  • trunk/src/recompiler/target-i386/op_helper.c

    r43387 r45276  
    232232#ifdef VBOX
    233233    /* Trying to load a selector with CPL=1? */
    234     if ((env->hflags & HF_CPL_MASK) == 0 && (selector & 3) == 1 && (env->state & CPU_RAW_RING0))
     234    /* @todo this is a hack to correct the incorrect checking order for pending interrupts in the patm iret replacement code (corrected in the ring-1 version) */
     235    /* @todo in theory the iret could fault and we'd still need this. */
     236    if ((env->hflags & HF_CPL_MASK) == 0 && (selector & 3) == 1 && (env->state & CPU_RAW_RING0) && !EMIsRawRing1Enabled(env->pVM))
    235237    {
    236238        Log(("RPL 1 -> sel %04X -> %04X\n", selector, selector & 0xfffc));
     
    238240    }
    239241#endif /* VBOX */
    240 
     242       
    241243    if (selector & 0x4)
    242244        dt = &env->ldt;
     
    345347    if (cpl == 0 && (selector & 3) == 1 && (env->state & CPU_RAW_RING0))
    346348    {
    347         Log(("RPL 1 -> sel %04X -> %04X\n", selector, selector & 0xfffc));
     349        Log(("RPL 1 -> sel %04X -> %04X (tss_load_seg)\n", selector, selector & 0xfffc));
    348350        selector = selector & 0xfffc;
    349351    }
     
    25562558
    25572559#ifdef VBOX
    2558     Log(("helper_ltr: old tr=%RTsel {.base=%RGv, .limit=%RGv, .flags=%RX32} new=%RTsel\n",
    2559          (RTSEL)env->tr.selector, (RTGCPTR)env->tr.base, (RTGCPTR)env->tr.limit,
     2560    Log(("helper_ltr: pc=%RGv old tr=%RTsel {.base=%RGv, .limit=%RGv, .flags=%RX32} new=%RTsel\n",
     2561         (RTGCPTR)env->eip, (RTSEL)env->tr.selector, (RTGCPTR)env->tr.base, (RTGCPTR)env->tr.limit,
    25602562         env->tr.flags, (RTSEL)(selector & 0xffff)));
     2563    ASMAtomicOrS32((int32_t volatile *)&env->interrupt_request,
     2564                    CPU_INTERRUPT_EXTERNAL_EXIT);
    25612565#endif
    25622566    selector &= 0xffff;
     
    26372641    if (cpl == 0 && (selector & 3) == 1 && (env->state & CPU_RAW_RING0))
    26382642    {
    2639         Log(("RPL 1 -> sel %04X -> %04X\n", selector, selector & 0xfffc));
     2643        Log(("RPL 1 -> sel %04X -> %04X (helper_load_seg)\n", selector, selector & 0xfffc));
    26402644        selector = selector & 0xfffc;
    26412645    }
     
    31693173        if (is_iret) {
    31703174            POPL(ssp, sp, sp_mask, new_eflags);
     3175#define LOG_GROUP LOG_GROUP_REM
    31713176#if defined(VBOX) && defined(DEBUG)
    3172             printf("iret: new CS     %04X\n", new_cs);
    3173             printf("iret: new EIP    %08X\n", (uint32_t)new_eip);
    3174             printf("iret: new EFLAGS %08X\n", new_eflags);
    3175             printf("iret: EAX=%08x\n", (uint32_t)EAX);
     3177            Log(("iret: new CS     %04X (old=%x)\n", new_cs, env->segs[R_CS].selector));
     3178            Log(("iret: new EIP    %08X\n", (uint32_t)new_eip));
     3179            Log(("iret: new EFLAGS %08X\n", new_eflags));
     3180            Log(("iret: EAX=%08x\n", (uint32_t)EAX));
    31763181#endif
    31773182            if (new_eflags & VM_MASK)
     
    31813186        if ((new_cs & 0x3) == 1 && (env->state & CPU_RAW_RING0))
    31823187        {
    3183 # ifdef DEBUG
    3184             printf("RPL 1 -> new_cs %04X -> %04X\n", new_cs, new_cs & 0xfffc);
     3188# ifdef VBOX_WITH_RAW_RING1
     3189            if (   !EMIsRawRing1Enabled(env->pVM)
     3190                ||  env->segs[R_CS].selector == (new_cs & 0xfffc))
     3191            {
     3192                Log(("RPL 1 -> new_cs %04X -> %04X\n", new_cs, new_cs & 0xfffc));
     3193                new_cs = new_cs & 0xfffc;
     3194            }
     3195            else
     3196            {
     3197                /* Ugly assumption: assume a genuine switch to ring-1. */
     3198                Log(("Genuine switch to ring-1 (iret)\n"));
     3199            }
     3200# else
     3201            Log(("RPL 1 -> new_cs %04X -> %04X\n", new_cs, new_cs & 0xfffc));
     3202            new_cs = new_cs & 0xfffc;
    31853203# endif
    3186             new_cs = new_cs & 0xfffc;
    3187         }
     3204        }
     3205# ifdef VBOX_WITH_RAW_RING1
     3206        else
     3207        if ((new_cs & 0x3) == 2 && (env->state & CPU_RAW_RING0) && EMIsRawRing1Enabled(env->pVM))
     3208        {
     3209            Log(("RPL 2 -> new_cs %04X -> %04X\n", new_cs, (new_cs & 0xfffc) | 1));
     3210            new_cs = (new_cs & 0xfffc) | 1;
     3211        }
     3212# endif
    31883213#endif
    31893214    } else {
     
    32003225    {
    32013226#if defined(VBOX) && defined(DEBUG)
    3202         printf("new_cs & 0xfffc) == 0\n");
     3227        Log(("new_cs & 0xfffc) == 0\n"));
    32033228#endif
    32043229        raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
     
    32073232    {
    32083233#if defined(VBOX) && defined(DEBUG)
    3209         printf("load_segment failed\n");
     3234        Log(("load_segment failed\n"));
    32103235#endif
    32113236        raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
     
    32153240    {
    32163241#if defined(VBOX) && defined(DEBUG)
    3217         printf("e2 mask %08x\n", e2);
     3242        Log(("e2 mask %08x\n", e2));
    32183243#endif
    32193244        raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
     
    32243249    {
    32253250#if defined(VBOX) && defined(DEBUG)
    3226         printf("rpl < cpl (%d vs %d)\n", rpl, cpl);
     3251        Log(("rpl < cpl (%d vs %d)\n", rpl, cpl));
    32273252#endif
    32283253        raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
    32293254    }
    32303255    dpl = (e2 >> DESC_DPL_SHIFT) & 3;
     3256
    32313257    if (e2 & DESC_C_MASK) {
    32323258        if (dpl > rpl)
    32333259        {
    32343260#if defined(VBOX) && defined(DEBUG)
    3235             printf("dpl > rpl (%d vs %d)\n", dpl, rpl);
     3261            Log(("dpl > rpl (%d vs %d)\n", dpl, rpl));
    32363262#endif
    32373263            raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
     
    32413267        {
    32423268#if defined(VBOX) && defined(DEBUG)
    3243             printf("dpl != rpl (%d vs %d) e1=%x e2=%x\n", dpl, rpl, e1, e2);
     3269            Log(("dpl != rpl (%d vs %d) e1=%x e2=%x\n", dpl, rpl, e1, e2));
    32443270#endif
    32453271            raise_exception_err(EXCP0D_GPF, new_cs & 0xfffc);
     
    32493275    {
    32503276#if defined(VBOX) && defined(DEBUG)
    3251         printf("DESC_P_MASK e2=%08x\n", e2);
     3277        Log(("DESC_P_MASK e2=%08x\n", e2));
    32523278#endif
    32533279        raise_exception_err(EXCP0B_NOSEG, new_cs & 0xfffc);
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