Index: trunk/src/VBox/VMM/TRPM.cpp
===================================================================
--- trunk/src/VBox/VMM/TRPM.cpp	(revision 5394)
+++ trunk/src/VBox/VMM/TRPM.cpp	(revision 5395)
@@ -519,4 +519,6 @@
 
     STAM_REG(pVM, &pVM->trpm.s.StatTrap0dDisasm,        STAMTYPE_PROFILE_ADV, "/TRPM/Trap0d/Prof/Disasm",         STAMUNIT_TICKS_PER_CALL, "Profiling trpmGCTrap0dHandler.");
+    STAM_REG(pVM, &pVM->trpm.s.StatTrap0dRing0RdTsc,    STAMTYPE_COUNTER, "/TRPM/Trap0d/RdTsc-R0",                    STAMUNIT_OCCURENCES, "Number of RDTSC #GPs from guest ring-0.");
+    STAM_REG(pVM, &pVM->trpm.s.StatTrap0dRing3RdTsc,    STAMTYPE_COUNTER, "/TRPM/Trap0d/RdTsc-R3",                    STAMUNIT_OCCURENCES, "Number of RDTSC #GPs from guest ring-3.");
 
     /*
Index: trunk/src/VBox/VMM/TRPMInternal.h
===================================================================
--- trunk/src/VBox/VMM/TRPMInternal.h	(revision 5394)
+++ trunk/src/VBox/VMM/TRPMInternal.h	(revision 5395)
@@ -175,4 +175,6 @@
     STAMPROFILEADV  StatForwardProfHC;
     STAMPROFILEADV  StatTrap0dDisasm;
+    STAMCOUNTER     StatTrap0dRing0RdTsc;   /**< Number of RDTSC #GPs from guest ring-0. */
+    STAMCOUNTER     StatTrap0dRing3RdTsc;   /**< Number of RDTSC #GPs from guest ring-3. */
 
     /* R3: Statistics for interrupt handlers (allocated on the hypervisor heap). */
Index: trunk/src/VBox/VMM/TRPMInternal.mac
===================================================================
--- trunk/src/VBox/VMM/TRPMInternal.mac	(revision 5394)
+++ trunk/src/VBox/VMM/TRPMInternal.mac	(revision 5395)
@@ -64,4 +64,6 @@
     .StatForwardProfHC        resb STAMPROFILEADV_size
     .StatTrap0dDisasm         resb STAMPROFILEADV_size
+    .StatTrap0dRing0RdTsc     resb STAMCOUNTER_size
+    .StatTrap0dRing3RdTsc     resb STAMCOUNTER_size
 
     .paStatForwardedIRQR3  RTR3PTR_RES 1
Index: trunk/src/VBox/VMM/VMMGC/TRPMGCHandlers.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMGC/TRPMGCHandlers.cpp	(revision 5394)
+++ trunk/src/VBox/VMM/VMMGC/TRPMGCHandlers.cpp	(revision 5395)
@@ -525,4 +525,18 @@
     switch (pCpu->pCurInstr->opcode)
     {
+        /*
+         * Since we're usually trapping RDTSC there may be a high volume
+         * of these instructions. So, put it first and go straight to
+         * the emulation function to save time.
+         */
+        case OP_RDTSC:
+            STAM_COUNTER_INC(&pVM->trpm.s.StatTrap0dRing0RdTsc);
+            rc = EMInterpretRdtsc(pVM, pRegFrame);
+            if (RT_SUCCESS(rc))
+                pRegFrame->eip += pCpu->opsize;
+            else if (rc == VERR_EM_INTERPRETER)
+                rc = VINF_EM_RAW_EXCEPTION_PRIVILEGED;
+            return trpmGCExitTrap(pVM, rc, pRegFrame);
+
         case OP_INT3:
             /*
@@ -585,5 +599,4 @@
         case OP_LLDT:
         case OP_STI:
-        case OP_RDTSC:
         case OP_CLTS:
         {
@@ -622,20 +635,4 @@
     switch (pCpu->pCurInstr->opcode)
     {
-        /*
-         * STI and CLI are I/O privileged, i.e. if IOPL
-         */
-        case OP_STI:
-        case OP_CLI:
-        {
-            uint32_t efl = CPUMRawGetEFlags(pVM, pRegFrame);
-            if (X86_EFL_GET_IOPL(efl) >= (unsigned)(pRegFrame->ss & X86_SEL_RPL))
-            {
-                LogFlow(("trpmGCTrap0dHandlerRing3: CLI/STI -> REM\n"));
-                return trpmGCExitTrap(pVM, VINF_EM_RESCHEDULE_REM, pRegFrame);
-            }
-            LogFlow(("trpmGCTrap0dHandlerRing3: CLI/STI -> #GP(0)\n"));
-            break;
-        }
-
         /*
          * INT3 and INT xx are ring-switching.
@@ -679,14 +676,29 @@
         /*
          * Handle virtualized TSC reads.
+         * Call the emulation function directly to skip unnecessary overhead.
          */
         case OP_RDTSC:
-        {
-            uint32_t cbIgnored;
-            rc = EMInterpretInstructionCPU(pVM, pCpu, pRegFrame, PC, &cbIgnored);
-            if (VBOX_SUCCESS(rc))
+            STAM_COUNTER_INC(&pVM->trpm.s.StatTrap0dRing3RdTsc);
+            rc = EMInterpretRdtsc(pVM, pRegFrame);
+            if (RT_SUCCESS(rc))
                 pRegFrame->eip += pCpu->opsize;
             else if (rc == VERR_EM_INTERPRETER)
                 rc = VINF_EM_RAW_EXCEPTION_PRIVILEGED;
             return trpmGCExitTrap(pVM, rc, pRegFrame);
+
+        /*
+         * STI and CLI are I/O privileged, i.e. if IOPL
+         */
+        case OP_STI:
+        case OP_CLI:
+        {
+            uint32_t efl = CPUMRawGetEFlags(pVM, pRegFrame);
+            if (X86_EFL_GET_IOPL(efl) >= (unsigned)(pRegFrame->ss & X86_SEL_RPL))
+            {
+                LogFlow(("trpmGCTrap0dHandlerRing3: CLI/STI -> REM\n"));
+                return trpmGCExitTrap(pVM, VINF_EM_RESCHEDULE_REM, pRegFrame);
+            }
+            LogFlow(("trpmGCTrap0dHandlerRing3: CLI/STI -> #GP(0)\n"));
+            break;
         }
     }
