Index: trunk/src/VBox/VMM/VMMAll/APICAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/APICAll.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMAll/APICAll.cpp	(revision 64655)
@@ -228,5 +228,6 @@
         /* 7 */     { "write reserved bits of MSR",    "",                            VINF_CPUM_R3_MSR_WRITE },
         /* 8 */     { "write an invalid value to MSR", "",                            VINF_CPUM_R3_MSR_WRITE },
-        /* 9 */     { "write MSR",                     "disallowed by configuration", VINF_CPUM_R3_MSR_WRITE }
+        /* 9 */     { "write MSR",                     "disallowed by configuration", VINF_CPUM_R3_MSR_WRITE },
+        /* 10 */    { "read MSR",                      "disallowed by configuration", VINF_CPUM_R3_MSR_READ }
     };
     AssertCompile(RT_ELEMENTS(s_aAccess) == APICMSRACCESS_COUNT);
@@ -1858,7 +1859,12 @@
 
 /**
- * @interface_method_impl{PDMAPICREG,pfnReadMsrR3}
- */
-APICBOTHCBDECL(VBOXSTRICTRC) apicReadMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value)
+ * Reads an APIC MSR.
+ *
+ * @returns Strict VBox status code.
+ * @param   pVCpu           The cross context virtual CPU structure.
+ * @param   u32Reg          The MSR being read.
+ * @param   pu64Value       Where to store the read value.
+ */
+VMM_INT_DECL(VBOXSTRICTRC) APICReadMsr(PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value)
 {
     /*
@@ -1868,7 +1874,17 @@
     Assert(u32Reg >= MSR_IA32_X2APIC_ID && u32Reg <= MSR_IA32_X2APIC_SELF_IPI);
     Assert(pu64Value);
-    RT_NOREF_PV(pDevIns);
-
+
+    /*
+     * Is the APIC enabled?
+     */
     PCAPIC pApic = VM_TO_APIC(pVCpu->CTX_SUFF(pVM));
+    if (apicIsEnabled(pVCpu))
+    { /* likely */ }
+    else
+    {
+        return apicMsrAccessError(pVCpu, u32Reg, pApic->enmMaxMode == PDMAPICMODE_NONE ?
+                                                 APICMSRACCESS_READ_DISALLOWED_CONFIG : APICMSRACCESS_READ_RSVD_OR_UNKNOWN);
+    }
+
 #ifndef IN_RING3
     if (pApic->fRZEnabled)
@@ -1962,7 +1978,12 @@
 
 /**
- * @interface_method_impl{PDMAPICREG,pfnWriteMsrR3}
- */
-APICBOTHCBDECL(VBOXSTRICTRC) apicWriteMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value)
+ * Writes an APIC MSR.
+ *
+ * @returns Strict VBox status code.
+ * @param   pVCpu           The cross context virtual CPU structure.
+ * @param   u32Reg          The MSR being written.
+ * @param   pu64Value       The value to write.
+ */
+VMM_INT_DECL(VBOXSTRICTRC) APICWriteMsr(PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value)
 {
     /*
@@ -1971,7 +1992,17 @@
     VMCPU_ASSERT_EMT(pVCpu);
     Assert(u32Reg >= MSR_IA32_X2APIC_ID && u32Reg <= MSR_IA32_X2APIC_SELF_IPI);
-    RT_NOREF_PV(pDevIns);
-
+
+    /*
+     * Is the APIC enabled?
+     */
     PCAPIC pApic = VM_TO_APIC(pVCpu->CTX_SUFF(pVM));
+    if (apicIsEnabled(pVCpu))
+    { /* likely */ }
+    else
+    {
+        return apicMsrAccessError(pVCpu, u32Reg, pApic->enmMaxMode == PDMAPICMODE_NONE ?
+                                                 APICMSRACCESS_WRITE_DISALLOWED_CONFIG : APICMSRACCESS_WRITE_RSVD_OR_UNKNOWN);
+    }
+
 #ifndef IN_RING3
     if (pApic->fRZEnabled)
@@ -2123,10 +2154,13 @@
 
 /**
- * @interface_method_impl{PDMAPICREG,pfnSetBaseMsrR3}
- */
-APICBOTHCBDECL(VBOXSTRICTRC) apicSetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint64_t u64BaseMsr)
+ * Sets the APIC base MSR.
+ *
+ * @returns Strict VBox status code.
+ * @param   pVCpu       The cross context virtual CPU structure.
+ * @param   u64BaseMsr  The value to set.
+ */
+VMM_INT_DECL(VBOXSTRICTRC) APICSetBaseMsr(PVMCPU pVCpu, uint64_t u64BaseMsr)
 {
     Assert(pVCpu);
-    NOREF(pDevIns);
 
 #ifdef IN_RING3
@@ -2255,5 +2289,4 @@
 
 #else  /* !IN_RING3 */
-    RT_NOREF_PV(pDevIns);
     RT_NOREF_PV(pVCpu);
     RT_NOREF_PV(u64BaseMsr);
@@ -2264,11 +2297,13 @@
 
 /**
- * @interface_method_impl{PDMAPICREG,pfnGetBaseMsrR3}
- */
-APICBOTHCBDECL(uint64_t) apicGetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu)
-{
-    RT_NOREF_PV(pDevIns);
+ * Gets the APIC base MSR (no checks are performed wrt APIC hardware or its
+ * state).
+ *
+ * @returns The base MSR value.
+ * @param   pVCpu       The cross context virtual CPU structure.
+ */
+VMM_INT_DECL(uint64_t) APICGetBaseMsrNoCheck(PVMCPU pVCpu)
+{
     VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);
-
     PCAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
     return pApicCpu->uApicBaseMsr;
@@ -2277,10 +2312,42 @@
 
 /**
- * @interface_method_impl{PDMAPICREG,pfnSetTprR3}
- */
-APICBOTHCBDECL(void) apicSetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr)
-{
-    RT_NOREF_PV(pDevIns);
-    apicSetTprEx(pVCpu, u8Tpr, false /* fForceX2ApicBehaviour */);
+ * Gets the APIC base MSR.
+ *
+ * @returns Strict VBox status code.
+ * @param   pVCpu       The cross context virtual CPU structure.
+ * @param   pu64Value   Where to store the MSR value.
+ */
+VMM_INT_DECL(VBOXSTRICTRC) APICGetBaseMsr(PVMCPU pVCpu, uint64_t *pu64Value)
+{
+    VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);
+
+    PCAPIC pApic = VM_TO_APIC(pVCpu->CTX_SUFF(pVM));
+    if (pApic->enmMaxMode != PDMAPICMODE_NONE)
+    {
+        *pu64Value = APICGetBaseMsrNoCheck(pVCpu);
+        return VINF_SUCCESS;
+    }
+
+#ifdef IN_RING3
+    LogRelMax(5, ("APIC%u: Reading APIC base MSR (%#x) when there is no APIC -> #GP(0)\n", pVCpu->idCpu, MSR_IA32_APICBASE));
+    return VERR_CPUM_RAISE_GP_0;
+#else
+    return VINF_CPUM_R3_MSR_WRITE;
+#endif
+}
+
+
+/**
+ * Sets the TPR (Task Priority Register).
+ *
+ * @returns VBox status code.
+ * @param   pVCpu       The cross context virtual CPU structure.
+ * @param   u8Tpr       The TPR value to set.
+ */
+VMMDECL(int) APICSetTpr(PVMCPU pVCpu, uint8_t u8Tpr)
+{
+    if (apicIsEnabled(pVCpu))
+        return VBOXSTRICTRC_VAL(apicSetTprEx(pVCpu, u8Tpr, false /* fForceX2ApicBehaviour */));
+    return VERR_PDM_NO_APIC_INSTANCE;
 }
 
@@ -2310,48 +2377,89 @@
 
 /**
- * @interface_method_impl{PDMAPICREG,pfnGetTprR3}
- */
-APICBOTHCBDECL(uint8_t) apicGetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr)
-{
-    RT_NOREF_PV(pDevIns);
+ * Gets the APIC TPR (Task Priority Register).
+ *
+ * @returns VBox status code.
+ * @param   pVCpu           The cross context virtual CPU structure.
+ * @param   pu8Tpr          Where to store the TPR.
+ * @param   pfPending       Where to store whether there is a pending interrupt
+ *                          (optional, can be NULL).
+ * @param   pu8PendingIntr  Where to store the highest-priority pending
+ *                          interrupt (optional, can be NULL).
+ */
+VMMDECL(int) APICGetTpr(PVMCPU pVCpu, uint8_t *pu8Tpr, bool *pfPending, uint8_t *pu8PendingIntr)
+{
     VMCPU_ASSERT_EMT(pVCpu);
-    PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu);
-
-    if (pfPending)
-    {
-        /*
-         * Just return whatever the highest pending interrupt is in the IRR.
-         * The caller is responsible for figuring out if it's masked by the TPR etc.
-         */
-        *pfPending = apicGetHighestPendingInterrupt(pVCpu, pu8PendingIntr);
-    }
-
-    return pXApicPage->tpr.u8Tpr;
-}
-
-
-/**
- * @interface_method_impl{PDMAPICREG,pfnGetTimerFreqR3}
- */
-APICBOTHCBDECL(uint64_t) apicGetTimerFreq(PPDMDEVINS pDevIns)
-{
-    PVM      pVM      = PDMDevHlpGetVM(pDevIns);
-    PVMCPU   pVCpu    = &pVM->aCpus[0];
-    PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
-    uint64_t uTimer   = TMTimerGetFreq(pApicCpu->CTX_SUFF(pTimer));
-    return uTimer;
-}
-
-
-/**
- * @interface_method_impl{PDMAPICREG,pfnBusDeliverR3}
- * @remarks This is a private interface between the IOAPIC and the APIC.
- */
-APICBOTHCBDECL(int) apicBusDeliver(PPDMDEVINS pDevIns, uint8_t uDest, uint8_t uDestMode, uint8_t uDeliveryMode, uint8_t uVector,
-                            uint8_t uPolarity, uint8_t uTriggerMode, uint32_t uTagSrc)
+    if (apicIsEnabled(pVCpu))
+    {
+        PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu);
+        if (pfPending)
+        {
+            /*
+             * Just return whatever the highest pending interrupt is in the IRR.
+             * The caller is responsible for figuring out if it's masked by the TPR etc.
+             */
+            *pfPending = apicGetHighestPendingInterrupt(pVCpu, pu8PendingIntr);
+        }
+
+        *pu8Tpr = pXApicPage->tpr.u8Tpr;
+        return VINF_SUCCESS;
+    }
+
+    *pu8Tpr = 0;
+    return VERR_PDM_NO_APIC_INSTANCE;
+}
+
+
+/**
+ * Gets the APIC timer frequency.
+ *
+ * @returns Strict VBox status code.
+ * @param
+ */
+VMM_INT_DECL(int) APICGetTimerFreq(PVM pVM, uint64_t *pu64Value)
+{
+    /*
+     * Validate.
+     */
+    Assert(pVM);
+    AssertPtrReturn(pu64Value, VERR_INVALID_PARAMETER);
+
+    PVMCPU pVCpu = &pVM->aCpus[0];
+    if (apicIsEnabled(pVCpu))
+    {
+        PCAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
+        *pu64Value = TMTimerGetFreq(pApicCpu->CTX_SUFF(pTimer));
+        return VINF_SUCCESS;
+    }
+    return VERR_PDM_NO_APIC_INSTANCE;
+}
+
+
+/**
+ * Delivers an interrupt message via the system bus.
+ *
+ * @returns VBox status code.
+ * @param   pVM             The cross context VM structure.
+ * @param   uDest           The destination mask.
+ * @param   uDestMode       The destination mode.
+ * @param   uDeliveryMode   The delivery mode.
+ * @param   uVector         The interrupt vector.
+ * @param   uPolarity       The interrupt line polarity.
+ * @param   uTriggerMode    The trigger mode.
+ * @param   uTagSrc         The interrupt tag (debugging).
+ */
+VMM_INT_DECL(int) APICBusDeliver(PVM pVM, uint8_t uDest, uint8_t uDestMode, uint8_t uDeliveryMode, uint8_t uVector,
+                                 uint8_t uPolarity, uint8_t uTriggerMode, uint32_t uTagSrc)
 {
     NOREF(uPolarity);
     NOREF(uTagSrc);
-    PVM pVM = PDMDevHlpGetVM(pDevIns);
+
+    /*
+     * If the APIC isn't enabled, do nothing and pretend success.
+     */
+    if (apicIsEnabled(&pVM->aCpus[0]))
+    { /* likely */ }
+    else
+        return VINF_SUCCESS;
 
     /*
@@ -2382,10 +2490,15 @@
 
 /**
- * @interface_method_impl{PDMAPICREG,pfnLocalInterruptR3}
- * @remarks This is a private interface between the PIC and the APIC.
- */
-APICBOTHCBDECL(VBOXSTRICTRC) apicLocalInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level, int rcRZ)
-{
-    NOREF(pDevIns);
+ * Assert/de-assert the local APIC's LINT0/LINT1 interrupt pins.
+ *
+ * @returns Strict VBox status code.
+ * @param   pVCpu       The cross context virtual CPU structure.
+ * @param   u8Pin       The interrupt pin (0 for LINT0 or 1 for LINT1).
+ * @param   u8Level     The level (0 for low or 1 for high).
+ * @param   rcRZ        The return code if the operation cannot be performed in
+ *                      the current context.
+ */
+VMM_INT_DECL(VBOXSTRICTRC) APICLocalInterrupt(PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level, int rcRZ)
+{
     AssertReturn(u8Pin <= 1, VERR_INVALID_PARAMETER);
     AssertReturn(u8Level <= 1, VERR_INVALID_PARAMETER);
@@ -2544,9 +2657,14 @@
 
 /**
- * @interface_method_impl{PDMAPICREG,pfnGetInterruptR3}
- */
-APICBOTHCBDECL(int) apicGetInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector, uint32_t *pu32TagSrc)
-{
-    RT_NOREF_PV(pDevIns);
+ * Gets the next highest-priority interrupt from the APIC, marking it as an
+ * "in-service" interrupt.
+ *
+ * @returns VBox status code.
+ * @param   pVCpu       The cross context virtual CPU structure.
+ * @param   pu8Vector   Where to store the vector.
+ * @param   pu32TagSrc  The source tag (debugging).
+ */
+VMM_INT_DECL(int) APICGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Vector, uint32_t *pu32TagSrc)
+{
     VMCPU_ASSERT_EMT(pVCpu);
     Assert(pu8Vector);
@@ -2905,5 +3023,5 @@
  *          interrupt shadow etc.)
  */
-VMMDECL(bool) APICQueueInterruptToService(PVMCPU pVCpu, uint8_t u8PendingIntr)
+VMM_INT_DECL(bool) APICQueueInterruptToService(PVMCPU pVCpu, uint8_t u8PendingIntr)
 {
     VMCPU_ASSERT_EMT(pVCpu);
@@ -2937,5 +3055,5 @@
  *                              in-service.
  */
-VMMDECL(void) APICDequeueInterruptFromService(PVMCPU pVCpu, uint8_t u8PendingIntr)
+VMM_INT_DECL(void) APICDequeueInterruptFromService(PVMCPU pVCpu, uint8_t u8PendingIntr)
 {
     VMCPU_ASSERT_EMT(pVCpu);
@@ -3044,5 +3162,5 @@
  *                              interrupt is pending.
  */
-VMMDECL(bool) APICGetHighestPendingInterrupt(PVMCPU pVCpu, uint8_t *pu8PendingIntr)
+VMM_INT_DECL(bool) APICGetHighestPendingInterrupt(PVMCPU pVCpu, uint8_t *pu8PendingIntr)
 {
     VMCPU_ASSERT_EMT(pVCpu);
Index: trunk/src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp	(revision 64655)
@@ -22,5 +22,5 @@
 #define LOG_GROUP LOG_GROUP_CPUM
 #include <VBox/vmm/cpum.h>
-#include <VBox/vmm/pdmapi.h>
+#include <VBox/vmm/apic.h>
 #include <VBox/vmm/hm.h>
 #include <VBox/vmm/tm.h>
@@ -217,5 +217,5 @@
 {
     RT_NOREF_PV(idMsr); RT_NOREF_PV(pRange);
-    return PDMApicGetBaseMsr(pVCpu, puValue, false /* fIgnoreErrors */);
+    return APICGetBaseMsr(pVCpu, puValue);
 }
 
@@ -225,5 +225,5 @@
 {
     RT_NOREF_PV(pVCpu); RT_NOREF_PV(idMsr); RT_NOREF_PV(pRange); RT_NOREF_PV(uValue); RT_NOREF_PV(uRawValue);
-    return PDMApicSetBaseMsr(pVCpu, uValue);
+    return APICSetBaseMsr(pVCpu, uValue);
 }
 
@@ -1215,5 +1215,5 @@
 {
     RT_NOREF_PV(pRange);
-    return PDMApicReadMsr(pVCpu, idMsr, puValue);
+    return APICReadMsr(pVCpu, idMsr, puValue);
 }
 
@@ -1223,5 +1223,5 @@
 {
     RT_NOREF_PV(pRange); RT_NOREF_PV(uRawValue);
-    return PDMApicWriteMsr(pVCpu, idMsr, uValue);
+    return APICWriteMsr(pVCpu, idMsr, uValue);
 }
 
Index: trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp	(revision 64655)
@@ -24,5 +24,5 @@
 #include <VBox/vmm/patm.h>
 #include <VBox/vmm/dbgf.h>
-#include <VBox/vmm/pdm.h>
+#include <VBox/vmm/apic.h>
 #include <VBox/vmm/pgm.h>
 #include <VBox/vmm/mm.h>
@@ -1059,5 +1059,5 @@
         {
             uint8_t u8Tpr;
-            int rc = PDMApicGetTPR(pVCpu, &u8Tpr, NULL /* pfPending */, NULL /* pu8PendingIrq */);
+            int rc = APICGetTpr(pVCpu, &u8Tpr, NULL /* pfPending */, NULL /* pu8PendingIrq */);
             if (RT_FAILURE(rc))
             {
@@ -1066,5 +1066,5 @@
                 return rc;
             }
-            *pValue = u8Tpr >> 4; /* bits 7-4 contain the task priority that go in cr8, bits 3-0*/
+            *pValue = u8Tpr >> 4; /* bits 7-4 contain the task priority that go in cr8, bits 3-0 */
             break;
         }
Index: trunk/src/VBox/VMM/VMMAll/EMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/EMAll.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMAll/EMAll.cpp	(revision 64655)
@@ -3250,5 +3250,5 @@
 
     case DISCREG_CR8:
-        return PDMApicSetTPR(pVCpu, val << 4);  /* cr8 bits 3-0 correspond to bits 7-4 of the task priority mmio register. */
+        return APICSetTpr(pVCpu, val << 4);  /* cr8 bits 3-0 correspond to bits 7-4 of the task priority mmio register. */
 
     default:
Index: trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp	(revision 64655)
@@ -560,5 +560,5 @@
         case MSR_GIM_HV_APIC_FREQ:
         {
-            int rc = PDMApicGetTimerFreq(pVM, puValue);
+            int rc = APICGetTimerFreq(pVM, puValue);
             if (RT_FAILURE(rc))
                 return VERR_CPUM_RAISE_GP_0;
Index: trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 64655)
@@ -96,4 +96,5 @@
 #include <VBox/vmm/iem.h>
 #include <VBox/vmm/cpum.h>
+#include <VBox/vmm/apic.h>
 #include <VBox/vmm/pdm.h>
 #include <VBox/vmm/pgm.h>
Index: trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h	(revision 64654)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h	(revision 64655)
@@ -4958,5 +4958,5 @@
         {
             uint8_t uTpr;
-            int rc = PDMApicGetTPR(pVCpu, &uTpr, NULL, NULL);
+            int rc = APICGetTpr(pVCpu, &uTpr, NULL, NULL);
             if (RT_SUCCESS(rc))
                 crX = uTpr >> 4;
@@ -5271,5 +5271,5 @@
 
             if (!IEM_FULL_VERIFICATION_ENABLED(pVCpu))
-                PDMApicSetTPR(pVCpu, (uint8_t)uNewCrX << 4);
+                APICSetTpr(pVCpu, (uint8_t)uNewCrX << 4);
             rcStrict = VINF_SUCCESS;
             break;
Index: trunk/src/VBox/VMM/VMMAll/PDMAll.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/PDMAll.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMAll/PDMAll.cpp	(revision 64655)
@@ -62,9 +62,7 @@
     {
         VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
-        Assert(pVM->pdm.s.Apic.CTX_SUFF(pDevIns));
-        Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt));
         uint32_t uTagSrc;
         uint8_t  uVector;
-        rc = pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, &uVector, &uTagSrc);
+        rc = APICGetInterrupt(pVCpu, &uVector, &uTagSrc);
         if (RT_SUCCESS(rc))
         {
@@ -260,195 +258,4 @@
 
 /**
- * Returns the presence of a Local APIC.
- *
- * @returns VBox true if a Local APIC is present.
- * @param   pVM         The cross context VM structure.
- */
-VMM_INT_DECL(bool) PDMHasApic(PVM pVM)
-{
-    return pVM->pdm.s.Apic.CTX_SUFF(pDevIns) != NULL;
-}
-
-
-/**
- * Set the APIC base.
- *
- * @returns Strict VBox status code.
- * @param   pVCpu       The cross context virtual CPU structure.
- * @param   u64Base     The new base.
- */
-VMMDECL(VBOXSTRICTRC) PDMApicSetBaseMsr(PVMCPU pVCpu, uint64_t u64Base)
-{
-    PVM pVM = pVCpu->CTX_SUFF(pVM);
-    if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
-    {
-        Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnSetBaseMsr));
-        VBOXSTRICTRC rcStrict = pVM->pdm.s.Apic.CTX_SUFF(pfnSetBaseMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, u64Base);
-
-        /* Update CPUM's copy of the APIC base. */
-        PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
-        Assert(pCtx);
-        pCtx->msrApicBase = pVM->pdm.s.Apic.CTX_SUFF(pfnGetBaseMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu);
-
-        return rcStrict;
-    }
-
-#ifdef IN_RING3
-    LogRelMax(5, ("PDM: APIC%U: Writing APIC base MSR (%#x) invalid since there isn't an APIC -> #GP(0)\n", pVCpu->idCpu,
-                  MSR_IA32_APICBASE));
-    return VERR_CPUM_RAISE_GP_0;
-#else
-    return VINF_CPUM_R3_MSR_WRITE;
-#endif
-}
-
-
-/**
- * Get the APIC base MSR from the APIC device.
- *
- * @returns Strict VBox status code.
- * @param   pVCpu           The cross context virtual CPU structure.
- * @param   pu64Base        Where to store the APIC base.
- * @param   fIgnoreErrors   Whether to ignore errors (i.e. not a real guest MSR
- *                          access).
- */
-VMMDECL(VBOXSTRICTRC) PDMApicGetBaseMsr(PVMCPU pVCpu, uint64_t *pu64Base, bool fIgnoreErrors)
-{
-    PVM pVM = pVCpu->CTX_SUFF(pVM);
-    if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
-    {
-        Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetBaseMsr));
-        VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);
-        *pu64Base = pVM->pdm.s.Apic.CTX_SUFF(pfnGetBaseMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu);
-        return VINF_SUCCESS;
-    }
-
-    *pu64Base = 0;
-    if (fIgnoreErrors)
-        return VINF_SUCCESS;
-
-#ifdef IN_RING3
-    LogRelMax(5, ("PDM: APIC%u: Reading APIC base MSR (%#x) invalid without an APIC instance -> #GP(0)\n", pVCpu->idCpu,
-                  MSR_IA32_APICBASE));
-    return VERR_CPUM_RAISE_GP_0;
-#else
-    return VINF_CPUM_R3_MSR_WRITE;
-#endif
-}
-
-
-/**
- * Set the TPR (Task Priority Register).
- *
- * @returns VBox status code.
- * @param   pVCpu           The cross context virtual CPU structure.
- * @param   u8TPR           The new TPR.
- */
-VMMDECL(int) PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR)
-{
-    PVM pVM = pVCpu->CTX_SUFF(pVM);
-    if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
-    {
-        Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnSetTpr));
-        pVM->pdm.s.Apic.CTX_SUFF(pfnSetTpr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, u8TPR);
-        return VINF_SUCCESS;
-    }
-    return VERR_PDM_NO_APIC_INSTANCE;
-}
-
-
-/**
- * Get the TPR (Task Priority Register).
- *
- * @returns VINF_SUCCESS or VERR_PDM_NO_APIC_INSTANCE.
- * @param   pVCpu           The cross context virtual CPU structure.
- * @param   pu8TPR          Where to store the TRP.
- * @param   pfPending       Where to store whether there is a pending interrupt
- *                          (out, optional).
- * @param   pu8PendingIntr  Where to store the highest-priority pending
- *                          interrupt (out, optional).
- *
- * @remarks No-long-jump zone!!!
- */
-VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending, uint8_t *pu8PendingIntr)
-{
-    PVM        pVM      = pVCpu->CTX_SUFF(pVM);
-    PPDMDEVINS pApicIns = pVM->pdm.s.Apic.CTX_SUFF(pDevIns);
-    if (pApicIns)
-    {
-        /*
-         * Note! We don't acquire the PDM lock here as we're just reading
-         *       information. Doing so causes massive contention as this
-         *       function is called very often by each and every VCPU.
-         */
-        Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetTpr));
-        *pu8TPR = pVM->pdm.s.Apic.CTX_SUFF(pfnGetTpr)(pApicIns, pVCpu, pfPending, pu8PendingIntr);
-        return VINF_SUCCESS;
-    }
-    *pu8TPR = 0;
-    return VERR_PDM_NO_APIC_INSTANCE;
-}
-
-
-/**
- * Write a MSR in APIC range.
- *
- * @returns Strict VBox status code.
- * @param   pVCpu           The cross context virtual CPU structure.
- * @param   u32Reg          MSR to write.
- * @param   u64Value        Value to write.
- */
-VMM_INT_DECL(VBOXSTRICTRC) PDMApicWriteMsr(PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value)
-{
-    PVM pVM = pVCpu->CTX_SUFF(pVM);
-    if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
-    {
-        AssertPtr(pVM->pdm.s.Apic.CTX_SUFF(pfnWriteMsr));
-        return pVM->pdm.s.Apic.CTX_SUFF(pfnWriteMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, u32Reg, u64Value);
-    }
-    return VERR_CPUM_RAISE_GP_0;
-}
-
-
-/**
- * Read a MSR in APIC range.
- *
- * @returns Strict VBox status code.
- * @param   pVCpu           The cross context virtual CPU structure.
- * @param   u32Reg          MSR to read.
- * @param   pu64Value       Where to store the value read.
- */
-VMM_INT_DECL(VBOXSTRICTRC) PDMApicReadMsr(PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value)
-{
-    PVM pVM = pVCpu->CTX_SUFF(pVM);
-    if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
-    {
-        AssertPtr(pVM->pdm.s.Apic.CTX_SUFF(pfnReadMsr));
-        return pVM->pdm.s.Apic.CTX_SUFF(pfnReadMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, u32Reg, pu64Value);
-    }
-    return VERR_CPUM_RAISE_GP_0;
-}
-
-
-/**
- * Gets the frequency of the APIC timer.
- *
- * @returns VBox status code.
- * @param   pVM             The cross context VM structure.
- * @param   pu64Value       Where to store the frequency.
- */
-VMM_INT_DECL(int) PDMApicGetTimerFreq(PVM pVM, uint64_t *pu64Value)
-{
-    if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
-    {
-        AssertPtr(pVM->pdm.s.Apic.CTX_SUFF(pfnGetTimerFreq));
-        *pu64Value = pVM->pdm.s.Apic.CTX_SUFF(pfnGetTimerFreq)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns));
-        return VINF_SUCCESS;
-    }
-    return VERR_PDM_NO_APIC_INSTANCE;
-}
-
-
-/**
  * Locks PDM.
  * This might call back to Ring-3 in order to deal with lock contention in GC and R3.
Index: trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp	(revision 64655)
@@ -1610,5 +1610,5 @@
     bool    fPendingIntr;
     uint8_t u8Tpr;
-    int rc = PDMApicGetTPR(pVCpu, &u8Tpr, &fPendingIntr, NULL /* pu8PendingIrq */);
+    int rc = APICGetTpr(pVCpu, &u8Tpr, &fPendingIntr, NULL /* pu8PendingIrq */);
     AssertRCReturn(rc, rc);
 
@@ -3290,5 +3290,5 @@
                 && (pMixedCtx->msrLSTAR & 0xff) != pSvmTransient->u8GuestTpr)
             {
-                int rc = PDMApicSetTPR(pVCpu, pMixedCtx->msrLSTAR & 0xff);
+                int rc = APICSetTpr(pVCpu, pMixedCtx->msrLSTAR & 0xff);
                 AssertRC(rc);
                 HMCPU_CF_SET(pVCpu, HM_CHANGED_SVM_GUEST_APIC_STATE);
@@ -3296,5 +3296,5 @@
             else if (pSvmTransient->u8GuestTpr != pVmcb->ctrl.IntCtrl.n.u8VTPR)
             {
-                int rc = PDMApicSetTPR(pVCpu, pVmcb->ctrl.IntCtrl.n.u8VTPR << 4);
+                int rc = APICSetTpr(pVCpu, pVmcb->ctrl.IntCtrl.n.u8VTPR << 4);
                 AssertRC(rc);
                 HMCPU_CF_SET(pVCpu, HM_CHANGED_SVM_GUEST_APIC_STATE);
@@ -4004,5 +4004,5 @@
             case HMTPRINSTR_READ:
             {
-                int rc = PDMApicGetTPR(pVCpu, &u8Tpr, &fPending, NULL /* pu8PendingIrq */);
+                int rc = APICGetTpr(pVCpu, &u8Tpr, &fPending, NULL /* pu8PendingIrq */);
                 AssertRC(rc);
 
@@ -4026,5 +4026,5 @@
                     u8Tpr = (uint8_t)pPatch->uSrcOperand;
 
-                int rc2 = PDMApicSetTPR(pVCpu, u8Tpr);
+                int rc2 = APICSetTpr(pVCpu, u8Tpr);
                 AssertRC(rc2);
                 HMCPU_CF_SET(pVCpu, HM_CHANGED_SVM_GUEST_APIC_STATE);
@@ -4657,5 +4657,5 @@
             {
                 /* Our patch code uses LSTAR for TPR caching for 32-bit guests. */
-                int rc2 = PDMApicSetTPR(pVCpu, pCtx->eax & 0xff);
+                int rc2 = APICSetTpr(pVCpu, pCtx->eax & 0xff);
                 AssertRC(rc2);
                 HMCPU_CF_SET(pVCpu, HM_CHANGED_SVM_GUEST_APIC_STATE);
Index: trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp	(revision 64655)
@@ -3417,5 +3417,5 @@
             uint8_t u8Tpr         = 0;
             uint8_t u8PendingIntr = 0;
-            rc = PDMApicGetTPR(pVCpu, &u8Tpr, &fPendingIntr, &u8PendingIntr);
+            rc = APICGetTpr(pVCpu, &u8Tpr, &fPendingIntr, &u8PendingIntr);
             AssertRCReturn(rc, rc);
 
@@ -8962,12 +8962,18 @@
         /*
          * If the TPR was raised by the guest, it wouldn't cause a VM-exit immediately. Instead we sync the TPR lazily whenever
-         * we eventually get a VM-exit for any reason. This maybe expensive as PDMApicSetTPR() can longjmp to ring-3 and which is
-         * why it's done here as it's easier and no less efficient to deal with it here than making hmR0VmxSaveGuestState()
-         * cope with longjmps safely (see VMCPU_FF_HM_UPDATE_CR3 handling).
+         * we eventually get a VM-exit for any reason.
+         *
+         * This maybe expensive as PDMApicSetTPR() can longjmp to ring-3 and which is why it's done here as it's easier and
+         * no less efficient to deal with it here than making hmR0VmxSaveGuestState() cope with longjmps safely
+         * (see VMCPU_FF_HM_UPDATE_CR3 handling).
          */
+        /** @todo r=ramshankar: The 2nd para in the above comment is
+         *        outdated, we no longer longjmp to ring-3 on setting
+         *        the TPR, but regardless we can probably rework this
+         *        portion of the code a bit. */
         if (   (pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW)
             && pVmxTransient->u8GuestTpr != pVCpu->hm.s.vmx.pbVirtApic[0x80])
         {
-            rc = PDMApicSetTPR(pVCpu, pVCpu->hm.s.vmx.pbVirtApic[0x80]);
+            rc = APICSetTpr(pVCpu, pVCpu->hm.s.vmx.pbVirtApic[0x80]);
             AssertRC(rc);
             HMCPU_CF_SET(pVCpu, HM_CHANGED_VMX_GUEST_APIC_STATE);
Index: trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp	(revision 64655)
@@ -30,4 +30,5 @@
 #include <VBox/vmm/patm.h>
 #include <VBox/vmm/hm.h>
+#include <VBox/vmm/apic.h>
 
 #include <VBox/log.h>
@@ -447,20 +448,6 @@
     PVM    pVM   = pDevIns->Internal.s.pVMR0;
     PVMCPU pVCpu = &pVM->aCpus[0];      /* for PIC we always deliver to CPU 0, MP use APIC */
-
-    if (pVM->pdm.s.Apic.pfnLocalInterruptR0)
-    {
-        LogFlow(("pdmR0PicHlp_SetInterruptFF: caller='%p'/%d: Setting local interrupt on LAPIC\n",
-                 pDevIns, pDevIns->iInstance));
-        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
-        /** @todo rcRZ propagation to pfnLocalInterrupt from caller. */
-        pVM->pdm.s.Apic.pfnLocalInterruptR0(pVM->pdm.s.Apic.pDevInsR0, pVCpu, 0 /* u8Pin */, 1 /* u8Level */,
-                                            VINF_SUCCESS /* rcRZ */);
-        return;
-    }
-
-    LogFlow(("pdmR0PicHlp_SetInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 1\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
-
-    VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+    /** @todo r=ramshankar: Propagating rcRZ and make all callers handle it? */
+    APICLocalInterrupt(pVCpu, 0 /* u8Pin */, 1 /* u8Level */, VINF_SUCCESS /* rcRZ */);
 }
 
@@ -472,21 +459,6 @@
     PVM    pVM   = pDevIns->Internal.s.pVMR0;
     PVMCPU pVCpu = &pVM->aCpus[0];      /* for PIC we always deliver to CPU 0, MP use APIC */
-
-    if (pVM->pdm.s.Apic.pfnLocalInterruptR0)
-    {
-        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
-        LogFlow(("pdmR0PicHlp_ClearInterruptFF: caller='%s'/%d: Clearing local interrupt on LAPIC\n",
-                 pDevIns, pDevIns->iInstance));
-        /* Lower the LAPIC's LINT0 line instead of signaling the CPU directly. */
-        /** @todo rcRZ propagation to pfnLocalInterrupt from caller. */
-        pVM->pdm.s.Apic.pfnLocalInterruptR0(pVM->pdm.s.Apic.pDevInsR0, pVCpu, 0 /* u8Pin */, 0 /* u8Level */,
-                                            VINF_SUCCESS /* rcRZ */);
-        return;
-    }
-
-    LogFlow(("pdmR0PicHlp_ClearInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 0\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
-
-    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+    /** @todo r=ramshankar: Propagating rcRZ and make all callers handle it? */
+    APICLocalInterrupt(pVCpu, 0 /* u8Pin */, 0 /* u8Level */, VINF_SUCCESS /* rcRZ */);
 }
 
@@ -529,16 +501,13 @@
 
 /** @interface_method_impl{PDMIOAPICHLPR0,pfnApicBusDeliver} */
-static DECLCALLBACK(int) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
-                                                       uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc)
+static DECLCALLBACK(int) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
+                                                       uint8_t u8DeliveryMode, uint8_t uVector, uint8_t u8Polarity,
+                                                       uint8_t u8TriggerMode, uint32_t uTagSrc)
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
     PVM pVM = pDevIns->Internal.s.pVMR0;
-    LogFlow(("pdmR0IoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n",
-             pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc));
-    Assert(pVM->pdm.s.Apic.pDevInsR0);
-    if (pVM->pdm.s.Apic.pfnBusDeliverR0)
-        return pVM->pdm.s.Apic.pfnBusDeliverR0(pVM->pdm.s.Apic.pDevInsR0, u8Dest, u8DestMode, u8DeliveryMode, iVector,
-                                               u8Polarity, u8TriggerMode, uTagSrc);
-    return VINF_SUCCESS;
+    LogFlow(("pdmR0IoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 uVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n",
+             pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, uVector, u8Polarity, u8TriggerMode, uTagSrc));
+    return APICBusDeliver(pVM, u8Dest, u8DestMode, u8DeliveryMode, uVector, u8Polarity, u8TriggerMode, uTagSrc);
 }
 
Index: trunk/src/VBox/VMM/VMMR3/APIC.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 64655)
@@ -1687,48 +1687,5 @@
      * Register the APIC with PDM.
      */
-    PDMAPICREG ApicReg;
-    RT_ZERO(ApicReg);
-    ApicReg.u32Version              = PDM_APICREG_VERSION;
-    ApicReg.pfnGetInterruptR3       = apicGetInterrupt;
-    ApicReg.pfnSetBaseMsrR3         = apicSetBaseMsr;
-    ApicReg.pfnGetBaseMsrR3         = apicGetBaseMsr;
-    ApicReg.pfnSetTprR3             = apicSetTpr;
-    ApicReg.pfnGetTprR3             = apicGetTpr;
-    ApicReg.pfnWriteMsrR3           = apicWriteMsr;
-    ApicReg.pfnReadMsrR3            = apicReadMsr;
-    ApicReg.pfnBusDeliverR3         = apicBusDeliver;
-    ApicReg.pfnLocalInterruptR3     = apicLocalInterrupt;
-    ApicReg.pfnGetTimerFreqR3       = apicGetTimerFreq;
-
-    /*
-     * We always require R0 functionality (e.g. apicGetTpr() called by HMR0 VT-x/AMD-V code).
-     * Hence, 'fRZEnabled' strictly only applies to MMIO and MSR read/write handlers returning
-     * to ring-3. We still need other handlers like apicGetTpr() in ring-0 for now.
-     */
-    {
-        ApicReg.pszGetInterruptRC   = "apicGetInterrupt";
-        ApicReg.pszSetBaseMsrRC     = "apicSetBaseMsr";
-        ApicReg.pszGetBaseMsrRC     = "apicGetBaseMsr";
-        ApicReg.pszSetTprRC         = "apicSetTpr";
-        ApicReg.pszGetTprRC         = "apicGetTpr";
-        ApicReg.pszWriteMsrRC       = "apicWriteMsr";
-        ApicReg.pszReadMsrRC        = "apicReadMsr";
-        ApicReg.pszBusDeliverRC     = "apicBusDeliver";
-        ApicReg.pszLocalInterruptRC = "apicLocalInterrupt";
-        ApicReg.pszGetTimerFreqRC   = "apicGetTimerFreq";
-
-        ApicReg.pszGetInterruptR0   = "apicGetInterrupt";
-        ApicReg.pszSetBaseMsrR0     = "apicSetBaseMsr";
-        ApicReg.pszGetBaseMsrR0     = "apicGetBaseMsr";
-        ApicReg.pszSetTprR0         = "apicSetTpr";
-        ApicReg.pszGetTprR0         = "apicGetTpr";
-        ApicReg.pszWriteMsrR0       = "apicWriteMsr";
-        ApicReg.pszReadMsrR0        = "apicReadMsr";
-        ApicReg.pszBusDeliverR0     = "apicBusDeliver";
-        ApicReg.pszLocalInterruptR0 = "apicLocalInterrupt";
-        ApicReg.pszGetTimerFreqR0   = "apicGetTimerFreq";
-    }
-
-    rc = PDMDevHlpAPICRegister(pDevIns, &ApicReg);
+    rc = PDMDevHlpAPICRegister(pDevIns);
     AssertLogRelRCReturn(rc, rc);
 
@@ -1736,5 +1693,4 @@
      * Initialize the APIC state.
      */
-    /* First insert/remove the MSR range of the x2APIC. */
     if (pApic->enmMaxMode == PDMAPICMODE_X2APIC)
     {
@@ -1751,6 +1707,5 @@
     /* Tell CPUM about the APIC feature level so it can adjust APICBASE MSR GP mask and CPUID bits. */
     apicR3SetCpuIdFeatureLevel(pVM, pApic->enmMaxMode);
-
-    /* Initialize the state. */
+    /* Finally, initialize the state. */
     rc = apicR3InitState(pVM);
     AssertRCReturn(rc, rc);
Index: trunk/src/VBox/VMM/VMMR3/CPUM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 64655)
@@ -111,5 +111,5 @@
 #include <VBox/vmm/cpumctx-v1_6.h>
 #include <VBox/vmm/pgm.h>
-#include <VBox/vmm/pdmapi.h>
+#include <VBox/vmm/apic.h>
 #include <VBox/vmm/mm.h>
 #include <VBox/vmm/em.h>
@@ -1158,5 +1158,5 @@
      * continues to reside in the APIC device and we cache it here in the VCPU for all further accesses.
      */
-    PDMApicGetBaseMsr(pVCpu, &pCtx->msrApicBase, true /* fIgnoreErrors */);
+    pCtx->msrApicBase = APICGetBaseMsrNoCheck(pVCpu);
     LogRel(("CPUM%u: Cached APIC base MSR = %#RX64\n", pVCpu->idCpu, pVCpu->cpum.s.Guest.msrApicBase));
 }
@@ -1608,5 +1608,5 @@
 
         /* Cache the local APIC base from the APIC device. During init. this is done in CPUMR3ResetCpu(). */
-        PDMApicGetBaseMsr(pVCpu, &pVCpu->cpum.s.Guest.msrApicBase, true /* fIgnoreErrors */);
+        pVCpu->cpum.s.Guest.msrApicBase = APICGetBaseMsrNoCheck(pVCpu);
         LogRel(("CPUM%u: Cached APIC base MSR = %#RX64\n", idCpu, pVCpu->cpum.s.Guest.msrApicBase));
 
@@ -2530,5 +2530,5 @@
             {
                 PVMCPU pVCpu = &pVM->aCpus[i];
-                PDMApicGetBaseMsr(pVCpu, &pVCpu->cpum.s.Guest.msrApicBase, true /* fIgnoreErrors */);
+                pVCpu->cpum.s.Guest.msrApicBase = APICGetBaseMsrNoCheck(pVCpu);
                 LogRel(("CPUM%u: Cached APIC base MSR = %#RX64\n", i, pVCpu->cpum.s.Guest.msrApicBase));
             }
Index: trunk/src/VBox/VMM/VMMR3/CPUMDbg.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/CPUMDbg.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMR3/CPUMDbg.cpp	(revision 64655)
@@ -23,5 +23,5 @@
 #include <VBox/vmm/cpum.h>
 #include <VBox/vmm/dbgf.h>
-#include <VBox/vmm/pdmapi.h>
+#include <VBox/vmm/apic.h>
 #include "CPUMInternal.h"
 #include <VBox/vmm/vm.h>
@@ -422,5 +422,5 @@
         case 3: rc = CPUMSetGuestCR3(pVCpu, u64Value); break;
         case 4: rc = CPUMSetGuestCR4(pVCpu, u64Value); break;
-        case 8: rc = PDMApicSetTPR(pVCpu, (uint8_t)(u64Value << 4)); break;
+        case 8: rc = APICSetTpr(pVCpu, (uint8_t)(u64Value << 4)); break;
         default:
             AssertFailedReturn(VERR_IPE_NOT_REACHED_DEFAULT_CASE);
Index: trunk/src/VBox/VMM/VMMR3/GIMMinimal.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/GIMMinimal.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMR3/GIMMinimal.cpp	(revision 64655)
@@ -24,5 +24,5 @@
 #include <VBox/vmm/cpum.h>
 #include <VBox/vmm/tm.h>
-#include <VBox/vmm/pdmapi.h>
+#include <VBox/vmm/apic.h>
 #include "GIMInternal.h"
 #include <VBox/vmm/vm.h>
@@ -97,5 +97,5 @@
      *
      * This is done in the init. completed routine as we need PDM to be
-     * initialized (otherwise PDMApicGetTimerFreq() would fail).
+     * initialized (otherwise APICGetTimerFreq() would fail).
      */
     CPUMCPUIDLEAF HyperLeaf;
@@ -114,5 +114,5 @@
          */
         uint64_t uApicFreq;
-        rc = PDMApicGetTimerFreq(pVM, &uApicFreq);
+        rc = APICGetTimerFreq(pVM, &uApicFreq);
         AssertLogRelRCReturn(rc, rc);
 
Index: trunk/src/VBox/VMM/VMMR3/PDM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/PDM.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMR3/PDM.cpp	(revision 64655)
@@ -530,18 +530,5 @@
      */
     if (pVM->pdm.s.Apic.pDevInsRC)
-    {
         pVM->pdm.s.Apic.pDevInsRC           += offDelta;
-        pVM->pdm.s.Apic.pfnGetInterruptRC   += offDelta;
-        pVM->pdm.s.Apic.pfnSetBaseMsrRC     += offDelta;
-        pVM->pdm.s.Apic.pfnGetBaseMsrRC     += offDelta;
-        pVM->pdm.s.Apic.pfnSetTprRC         += offDelta;
-        pVM->pdm.s.Apic.pfnGetTprRC         += offDelta;
-        pVM->pdm.s.Apic.pfnWriteMsrRC       += offDelta;
-        pVM->pdm.s.Apic.pfnReadMsrRC        += offDelta;
-        pVM->pdm.s.Apic.pfnBusDeliverRC     += offDelta;
-        if (pVM->pdm.s.Apic.pfnLocalInterruptRC)
-            pVM->pdm.s.Apic.pfnLocalInterruptRC += offDelta;
-        pVM->pdm.s.Apic.pfnGetTimerFreqRC   += offDelta;
-    }
 
     /*
Index: trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMR3/PDMDevHlp.cpp	(revision 64655)
@@ -2845,120 +2845,8 @@
 
 /** @interface_method_impl{PDMDEVHLPR3,pfnAPICRegister} */
-static DECLCALLBACK(int) pdmR3DevHlp_APICRegister(PPDMDEVINS pDevIns, PPDMAPICREG pApicReg)
+static DECLCALLBACK(int) pdmR3DevHlp_APICRegister(PPDMDEVINS pDevIns)
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
     VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
-    LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: pApicReg=%p:{.u32Version=%#x, .pfnGetInterruptR3=%p, .pfnSetBaseMsrR3=%p, .pfnGetBaseMsrR3=%p, "
-             ".pfnSetTprR3=%p, .pfnGetTprR3=%p, .pfnWriteMsr3=%p, .pfnReadMsr3=%p, .pfnBusDeliverR3=%p, .pfnLocalInterruptR3=%p .pfnGetTimerFreqR3=%p, pszGetInterruptRC=%p:{%s}, pszSetBaseMsrRC=%p:{%s}, pszGetBaseMsrRC=%p:{%s}, "
-             ".pszSetTprRC=%p:{%s}, .pszGetTprRC=%p:{%s}, .pszWriteMsrRC=%p:{%s}, .pszReadMsrRC=%p:{%s}, .pszBusDeliverRC=%p:{%s}, .pszLocalInterruptRC=%p:{%s}, .pszGetTimerFreqRC=%p:{%s}}\n",
-             pDevIns->pReg->szName, pDevIns->iInstance, pApicReg, pApicReg->u32Version, pApicReg->pfnGetInterruptR3, pApicReg->pfnSetBaseMsrR3,
-             pApicReg->pfnGetBaseMsrR3, pApicReg->pfnSetTprR3, pApicReg->pfnGetTprR3, pApicReg->pfnWriteMsrR3, pApicReg->pfnReadMsrR3, pApicReg->pfnBusDeliverR3, pApicReg->pfnLocalInterruptR3, pApicReg->pfnGetTimerFreqR3, pApicReg->pszGetInterruptRC,
-             pApicReg->pszGetInterruptRC, pApicReg->pszSetBaseMsrRC, pApicReg->pszSetBaseMsrRC, pApicReg->pszGetBaseMsrRC, pApicReg->pszGetBaseMsrRC,
-             pApicReg->pszSetTprRC, pApicReg->pszSetTprRC, pApicReg->pszGetTprRC, pApicReg->pszGetTprRC, pApicReg->pszWriteMsrRC, pApicReg->pszWriteMsrRC, pApicReg->pszReadMsrRC, pApicReg->pszReadMsrRC, pApicReg->pszBusDeliverRC,
-             pApicReg->pszBusDeliverRC, pApicReg->pszLocalInterruptRC, pApicReg->pszLocalInterruptRC, pApicReg->pszGetTimerFreqRC, pApicReg->pszGetTimerFreqRC));
-
-    /*
-     * Validate input.
-     */
-    if (pApicReg->u32Version != PDM_APICREG_VERSION)
-    {
-        AssertMsgFailed(("u32Version=%#x expected %#x\n", pApicReg->u32Version, PDM_APICREG_VERSION));
-        LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc (version)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
-        return VERR_INVALID_PARAMETER;
-    }
-    if (    !pApicReg->pfnGetInterruptR3
-        ||  !pApicReg->pfnSetBaseMsrR3
-        ||  !pApicReg->pfnGetBaseMsrR3
-        ||  !pApicReg->pfnSetTprR3
-        ||  !pApicReg->pfnGetTprR3
-        ||  !pApicReg->pfnWriteMsrR3
-        ||  !pApicReg->pfnReadMsrR3
-        ||  !pApicReg->pfnBusDeliverR3
-        ||  !pApicReg->pfnLocalInterruptR3
-        ||  !pApicReg->pfnGetTimerFreqR3)
-    {
-        Assert(pApicReg->pfnGetInterruptR3);
-        Assert(pApicReg->pfnSetBaseMsrR3);
-        Assert(pApicReg->pfnGetBaseMsrR3);
-        Assert(pApicReg->pfnSetTprR3);
-        Assert(pApicReg->pfnGetTprR3);
-        Assert(pApicReg->pfnWriteMsrR3);
-        Assert(pApicReg->pfnReadMsrR3);
-        Assert(pApicReg->pfnBusDeliverR3);
-        Assert(pApicReg->pfnLocalInterruptR3);
-        Assert(pApicReg->pfnGetTimerFreqR3);
-        LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc (R3 callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
-        return VERR_INVALID_PARAMETER;
-    }
-    if (   (    pApicReg->pszGetInterruptRC
-            ||  pApicReg->pszSetBaseMsrRC
-            ||  pApicReg->pszGetBaseMsrRC
-            ||  pApicReg->pszSetTprRC
-            ||  pApicReg->pszGetTprRC
-            ||  pApicReg->pszWriteMsrRC
-            ||  pApicReg->pszReadMsrRC
-            ||  pApicReg->pszBusDeliverRC
-            ||  pApicReg->pszLocalInterruptRC
-            ||  pApicReg->pszGetTimerFreqRC)
-        &&  (   !VALID_PTR(pApicReg->pszGetInterruptRC)
-            ||  !VALID_PTR(pApicReg->pszSetBaseMsrRC)
-            ||  !VALID_PTR(pApicReg->pszGetBaseMsrRC)
-            ||  !VALID_PTR(pApicReg->pszSetTprRC)
-            ||  !VALID_PTR(pApicReg->pszGetTprRC)
-            ||  !VALID_PTR(pApicReg->pszWriteMsrRC)
-            ||  !VALID_PTR(pApicReg->pszReadMsrRC)
-            ||  !VALID_PTR(pApicReg->pszBusDeliverRC)
-            ||  !VALID_PTR(pApicReg->pszLocalInterruptRC)
-            ||  !VALID_PTR(pApicReg->pszGetTimerFreqRC))
-       )
-    {
-        Assert(VALID_PTR(pApicReg->pszGetInterruptRC));
-        Assert(VALID_PTR(pApicReg->pszSetBaseMsrRC));
-        Assert(VALID_PTR(pApicReg->pszGetBaseMsrRC));
-        Assert(VALID_PTR(pApicReg->pszSetTprRC));
-        Assert(VALID_PTR(pApicReg->pszGetTprRC));
-        Assert(VALID_PTR(pApicReg->pszReadMsrRC));
-        Assert(VALID_PTR(pApicReg->pszWriteMsrRC));
-        Assert(VALID_PTR(pApicReg->pszBusDeliverRC));
-        Assert(VALID_PTR(pApicReg->pszLocalInterruptRC));
-        Assert(VALID_PTR(pApicReg->pszGetTimerFreqRC));
-        LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc (RC callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
-        return VERR_INVALID_PARAMETER;
-    }
-    if (   (    pApicReg->pszGetInterruptR0
-            ||  pApicReg->pszSetBaseMsrR0
-            ||  pApicReg->pszGetBaseMsrR0
-            ||  pApicReg->pszSetTprR0
-            ||  pApicReg->pszGetTprR0
-            ||  pApicReg->pszWriteMsrR0
-            ||  pApicReg->pszReadMsrR0
-            ||  pApicReg->pszBusDeliverR0
-            ||  pApicReg->pszLocalInterruptR0
-            ||  pApicReg->pszGetTimerFreqR0)
-        &&  (   !VALID_PTR(pApicReg->pszGetInterruptR0)
-            ||  !VALID_PTR(pApicReg->pszSetBaseMsrR0)
-            ||  !VALID_PTR(pApicReg->pszGetBaseMsrR0)
-            ||  !VALID_PTR(pApicReg->pszSetTprR0)
-            ||  !VALID_PTR(pApicReg->pszGetTprR0)
-            ||  !VALID_PTR(pApicReg->pszReadMsrR0)
-            ||  !VALID_PTR(pApicReg->pszWriteMsrR0)
-            ||  !VALID_PTR(pApicReg->pszBusDeliverR0)
-            ||  !VALID_PTR(pApicReg->pszLocalInterruptR0)
-            ||  !VALID_PTR(pApicReg->pszGetTimerFreqR0))
-       )
-    {
-        Assert(VALID_PTR(pApicReg->pszGetInterruptR0));
-        Assert(VALID_PTR(pApicReg->pszSetBaseMsrR0));
-        Assert(VALID_PTR(pApicReg->pszGetBaseMsrR0));
-        Assert(VALID_PTR(pApicReg->pszSetTprR0));
-        Assert(VALID_PTR(pApicReg->pszGetTprR0));
-        Assert(VALID_PTR(pApicReg->pszReadMsrR0));
-        Assert(VALID_PTR(pApicReg->pszWriteMsrR0));
-        Assert(VALID_PTR(pApicReg->pszBusDeliverR0));
-        Assert(VALID_PTR(pApicReg->pszLocalInterruptR0));
-        Assert(VALID_PTR(pApicReg->pszGetTimerFreqR0));
-        LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc (R0 callbacks)\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
-        return VERR_INVALID_PARAMETER;
-    }
 
     /*
@@ -2969,5 +2857,5 @@
     if (pVM->pdm.s.Apic.pDevInsR3)
     {
-        AssertMsgFailed(("Only one apic device is supported!\n"));
+        AssertMsgFailed(("Only one APIC device is supported!\n"));
         LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
         return VERR_INVALID_PARAMETER;
@@ -2975,168 +2863,13 @@
 
     /*
-     * Resolve & initialize the RC bits.
-     */
-    if (pApicReg->pszGetInterruptRC)
-    {
-        int rc = pdmR3DevGetSymbolRCLazy(pDevIns, pApicReg->pszGetInterruptRC, &pVM->pdm.s.Apic.pfnGetInterruptRC);
-        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pApicReg->pszGetInterruptRC, rc));
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolRCLazy(pDevIns, pApicReg->pszSetBaseMsrRC, &pVM->pdm.s.Apic.pfnSetBaseMsrRC);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pApicReg->pszSetBaseMsrRC, rc));
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolRCLazy(pDevIns, pApicReg->pszGetBaseMsrRC, &pVM->pdm.s.Apic.pfnGetBaseMsrRC);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pApicReg->pszGetBaseMsrRC, rc));
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolRCLazy(pDevIns, pApicReg->pszSetTprRC, &pVM->pdm.s.Apic.pfnSetTprRC);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pApicReg->pszSetTprRC, rc));
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolRCLazy(pDevIns, pApicReg->pszGetTprRC, &pVM->pdm.s.Apic.pfnGetTprRC);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pApicReg->pszGetTprRC, rc));
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolRCLazy(pDevIns, pApicReg->pszWriteMsrRC, &pVM->pdm.s.Apic.pfnWriteMsrRC);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pApicReg->pszWriteMsrRC, rc));
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolRCLazy(pDevIns, pApicReg->pszReadMsrRC, &pVM->pdm.s.Apic.pfnReadMsrRC);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pApicReg->pszReadMsrRC, rc));
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolRCLazy(pDevIns, pApicReg->pszBusDeliverRC, &pVM->pdm.s.Apic.pfnBusDeliverRC);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pApicReg->pszBusDeliverRC, rc));
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolRCLazy(pDevIns, pApicReg->pszLocalInterruptRC, &pVM->pdm.s.Apic.pfnLocalInterruptRC);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pApicReg->pszLocalInterruptRC, rc));
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolRCLazy(pDevIns, pApicReg->pszGetTimerFreqRC, &pVM->pdm.s.Apic.pfnGetTimerFreqRC);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szRCMod, pApicReg->pszGetTimerFreqRC, rc));
-        }
-        if (RT_FAILURE(rc))
-        {
-            LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
-            return rc;
-        }
-        pVM->pdm.s.Apic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
-    }
-    else
-    {
-        pVM->pdm.s.Apic.pDevInsRC           = 0;
-        pVM->pdm.s.Apic.pfnGetInterruptRC   = 0;
-        pVM->pdm.s.Apic.pfnSetBaseMsrRC     = 0;
-        pVM->pdm.s.Apic.pfnGetBaseMsrRC     = 0;
-        pVM->pdm.s.Apic.pfnSetTprRC         = 0;
-        pVM->pdm.s.Apic.pfnGetTprRC         = 0;
-        pVM->pdm.s.Apic.pfnWriteMsrRC       = 0;
-        pVM->pdm.s.Apic.pfnReadMsrRC        = 0;
-        pVM->pdm.s.Apic.pfnBusDeliverRC     = 0;
-        pVM->pdm.s.Apic.pfnLocalInterruptRC = 0;
-        pVM->pdm.s.Apic.pfnGetTimerFreqRC   = 0;
-    }
-
-    /*
-     * Resolve & initialize the R0 bits.
-     */
-    if (pApicReg->pszGetInterruptR0)
-    {
-        int rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pApicReg->pszGetInterruptR0, &pVM->pdm.s.Apic.pfnGetInterruptR0);
-        AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pApicReg->pszGetInterruptR0, rc));
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pApicReg->pszSetBaseMsrR0, &pVM->pdm.s.Apic.pfnSetBaseMsrR0);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pApicReg->pszSetBaseMsrR0, rc));
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pApicReg->pszGetBaseMsrR0, &pVM->pdm.s.Apic.pfnGetBaseMsrR0);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pApicReg->pszGetBaseMsrR0, rc));
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pApicReg->pszSetTprR0, &pVM->pdm.s.Apic.pfnSetTprR0);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pApicReg->pszSetTprR0, rc));
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pApicReg->pszGetTprR0, &pVM->pdm.s.Apic.pfnGetTprR0);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pApicReg->pszGetTprR0, rc));
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pApicReg->pszWriteMsrR0, &pVM->pdm.s.Apic.pfnWriteMsrR0);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pApicReg->pszWriteMsrR0, rc));
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pApicReg->pszReadMsrR0, &pVM->pdm.s.Apic.pfnReadMsrR0);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pApicReg->pszReadMsrR0, rc));
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pApicReg->pszBusDeliverR0, &pVM->pdm.s.Apic.pfnBusDeliverR0);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pApicReg->pszBusDeliverR0, rc));
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pApicReg->pszLocalInterruptR0, &pVM->pdm.s.Apic.pfnLocalInterruptR0);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pApicReg->pszLocalInterruptR0, rc));
-        }
-        if (RT_SUCCESS(rc))
-        {
-            rc = pdmR3DevGetSymbolR0Lazy(pDevIns, pApicReg->pszGetTimerFreqR0, &pVM->pdm.s.Apic.pfnGetTimerFreqR0);
-            AssertMsgRC(rc, ("%s::%s rc=%Rrc\n", pDevIns->pReg->szR0Mod, pApicReg->pszGetTimerFreqR0, rc));
-        }
-        if (RT_FAILURE(rc))
-        {
-            LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
-            return rc;
-        }
-        pVM->pdm.s.Apic.pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
-        Assert(pVM->pdm.s.Apic.pDevInsR0);
-    }
-    else
-    {
-        pVM->pdm.s.Apic.pfnGetInterruptR0   = 0;
-        pVM->pdm.s.Apic.pfnSetBaseMsrR0     = 0;
-        pVM->pdm.s.Apic.pfnGetBaseMsrR0     = 0;
-        pVM->pdm.s.Apic.pfnSetTprR0         = 0;
-        pVM->pdm.s.Apic.pfnGetTprR0         = 0;
-        pVM->pdm.s.Apic.pfnWriteMsrR0       = 0;
-        pVM->pdm.s.Apic.pfnReadMsrR0        = 0;
-        pVM->pdm.s.Apic.pfnBusDeliverR0     = 0;
-        pVM->pdm.s.Apic.pfnLocalInterruptR0 = 0;
-        pVM->pdm.s.Apic.pfnGetTimerFreqR0   = 0;
-        pVM->pdm.s.Apic.pDevInsR0           = 0;
-    }
-
-    /*
-     * Initialize the HC bits.
-     */
-    pVM->pdm.s.Apic.pDevInsR3           = pDevIns;
-    pVM->pdm.s.Apic.pfnGetInterruptR3   = pApicReg->pfnGetInterruptR3;
-    pVM->pdm.s.Apic.pfnSetBaseMsrR3     = pApicReg->pfnSetBaseMsrR3;
-    pVM->pdm.s.Apic.pfnGetBaseMsrR3     = pApicReg->pfnGetBaseMsrR3;
-    pVM->pdm.s.Apic.pfnSetTprR3         = pApicReg->pfnSetTprR3;
-    pVM->pdm.s.Apic.pfnGetTprR3         = pApicReg->pfnGetTprR3;
-    pVM->pdm.s.Apic.pfnWriteMsrR3       = pApicReg->pfnWriteMsrR3;
-    pVM->pdm.s.Apic.pfnReadMsrR3        = pApicReg->pfnReadMsrR3;
-    pVM->pdm.s.Apic.pfnBusDeliverR3     = pApicReg->pfnBusDeliverR3;
-    pVM->pdm.s.Apic.pfnLocalInterruptR3 = pApicReg->pfnLocalInterruptR3;
-    pVM->pdm.s.Apic.pfnGetTimerFreqR3   = pApicReg->pfnGetTimerFreqR3;
-    Log(("PDM: Registered APIC device '%s'/%d pDevIns=%p\n", pDevIns->pReg->szName, pDevIns->iInstance, pDevIns));
-
+     * Initialize the RC, R0 and HC bits.
+     */
+    pVM->pdm.s.Apic.pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
+    Assert(pVM->pdm.s.Apic.pDevInsRC);
+
+    pVM->pdm.s.Apic.pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
+    Assert(pVM->pdm.s.Apic.pDevInsR0);
+
+    pVM->pdm.s.Apic.pDevInsR3 = pDevIns;
     LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VINF_SUCCESS));
     return VINF_SUCCESS;
Index: trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp	(revision 64655)
@@ -25,4 +25,5 @@
 #include <VBox/vmm/pgm.h>
 #include <VBox/vmm/hm.h>
+#include <VBox/vmm/apic.h>
 #ifdef VBOX_WITH_REM
 # include <VBox/vmm/rem.h>
@@ -51,27 +52,7 @@
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
-    PVM pVM = pDevIns->Internal.s.pVMR3;
+    PVM    pVM = pDevIns->Internal.s.pVMR3;
     PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
-
-    if (pVM->pdm.s.Apic.pfnLocalInterruptR3)
-    {
-        LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: Setting local interrupt on LAPIC\n",
-                 pDevIns->pReg->szName, pDevIns->iInstance));
-
-        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
-        /** @todo 'rcRZ' propagation to pfnLocalInterrupt from caller. */
-        pVM->pdm.s.Apic.pfnLocalInterruptR3(pVM->pdm.s.Apic.pDevInsR3, pVCpu, 0 /* u8Pin */, 1 /* u8Level */,
-                                            VINF_SUCCESS /* rcRZ */);
-        return;
-    }
-
-    LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_PIC %d -> 1\n",
-             pDevIns->pReg->szName, pDevIns->iInstance, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
-
-    VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
-#ifdef VBOX_WITH_REM
-    REMR3NotifyInterruptSet(pVM, pVCpu);
-#endif
-    VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
+    APICLocalInterrupt(pVCpu, 0 /* u8Pin */, 1 /* u8Level */, VINF_SUCCESS /* rcRZ */);
 }
 
@@ -83,25 +64,5 @@
     PVM pVM = pDevIns->Internal.s.pVMR3;
     PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
-
-    if (pVM->pdm.s.Apic.pfnLocalInterruptR3)
-    {
-        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
-        LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: Clearing local interrupt on LAPIC\n",
-                 pDevIns->pReg->szName, pDevIns->iInstance));
-
-        /* Lower the LAPIC's LINT0 line instead of signaling the CPU directly. */
-        /** @todo 'rcRZ' propagation to pfnLocalInterrupt from caller. */
-        pVM->pdm.s.Apic.pfnLocalInterruptR3(pVM->pdm.s.Apic.pDevInsR3, pVCpu, 0 /* u8Pin */, 0 /* u8Level */,
-                                            VINF_SUCCESS /* rcRZ */);
-        return;
-    }
-
-    LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_PIC %d -> 0\n",
-             pDevIns->pReg->szName, pDevIns->iInstance, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
-
-    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
-#ifdef VBOX_WITH_REM
-    REMR3NotifyInterruptClear(pVM, pVCpu);
-#endif
+    APICLocalInterrupt(pVCpu, 0 /* u8Pin */,  0 /* u8Level */, VINF_SUCCESS /* rcRZ */);
 }
 
@@ -183,14 +144,13 @@
 
 /** @interface_method_impl{PDMIOAPICHLPR3,pfnApicBusDeliver} */
-static DECLCALLBACK(int) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
-                                                        uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc)
-{
-    PDMDEV_ASSERT_DEVINS(pDevIns);
-    PVM pVM = pDevIns->Internal.s.pVMR3;
-    LogFlow(("pdmR3IoApicHlp_ApicBusDeliver: caller='%s'/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n",
-             pDevIns->pReg->szName, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc));
-    if (pVM->pdm.s.Apic.pfnBusDeliverR3)
-        return pVM->pdm.s.Apic.pfnBusDeliverR3(pVM->pdm.s.Apic.pDevInsR3, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc);
-    return VINF_SUCCESS;
+static DECLCALLBACK(int) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
+                                                       uint8_t u8DeliveryMode, uint8_t uVector, uint8_t u8Polarity,
+                                                       uint8_t u8TriggerMode, uint32_t uTagSrc)
+{
+    PDMDEV_ASSERT_DEVINS(pDevIns);
+    PVM pVM = pDevIns->Internal.s.pVMR3;
+    LogFlow(("pdmR3IoApicHlp_ApicBusDeliver: caller='%s'/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 uVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n",
+             pDevIns->pReg->szName, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, uVector, u8Polarity, u8TriggerMode, uTagSrc));
+    return APICBusDeliver(pVM, u8Dest, u8DestMode, u8DeliveryMode, uVector, u8Polarity, u8TriggerMode, uTagSrc);
 }
 
Index: trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp	(revision 64654)
+++ trunk/src/VBox/VMM/VMMRC/PDMRCDevice.cpp	(revision 64655)
@@ -29,4 +29,5 @@
 #include <VBox/vmm/vmm.h>
 #include <VBox/vmm/patm.h>
+#include <VBox/vmm/apic.h>
 
 #include <VBox/log.h>
@@ -432,20 +433,6 @@
     PVM pVM = pDevIns->Internal.s.pVMRC;
     PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
-
-    if (pVM->pdm.s.Apic.pfnLocalInterruptRC)
-    {
-        LogFlow(("pdmRCPicHlp_SetInterruptFF: caller='%p'/%d: Setting local interrupt on LAPIC\n",
-                 pDevIns, pDevIns->iInstance));
-        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
-        /** @todo 'rcRZ' propagation to pfnLocalInterrupt from caller. */
-        pVM->pdm.s.Apic.pfnLocalInterruptRC(pVM->pdm.s.Apic.pDevInsRC, pVCpu, 0 /* u8Pin */, 1 /* u8Level*/,
-                                            VINF_SUCCESS /*rcRZ*/);
-        return;
-    }
-
-    LogFlow(("pdmRCPicHlp_SetInterruptFF: caller=%p/%d: VMMCPU_FF_INTERRUPT_PIC %d -> 1\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
-
-    VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+    /** @todo r=ramshankar: Propagating rcRZ and make all callers handle it? */
+    APICLocalInterrupt(pVCpu, 0 /* u8Pin */, 1 /* u8Level */, VINF_SUCCESS /* rcRZ */);
 }
 
@@ -457,21 +444,6 @@
     PVM pVM = pDevIns->Internal.s.CTX_SUFF(pVM);
     PVMCPU pVCpu = &pVM->aCpus[0];  /* for PIC we always deliver to CPU 0, MP use APIC */
-
-    if (pVM->pdm.s.Apic.pfnLocalInterruptRC)
-    {
-        /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
-        LogFlow(("pdmRCPicHlp_ClearInterruptFF: caller='%s'/%d: Clearing local interrupt on LAPIC\n",
-                 pDevIns, pDevIns->iInstance));
-        /* Lower the LAPIC's LINT0 line instead of signaling the CPU directly. */
-        /** @todo 'rcRZ' propagation to pfnLocalInterrupt from caller. */
-        pVM->pdm.s.Apic.pfnLocalInterruptRC(pVM->pdm.s.Apic.pDevInsRC, pVCpu, 0 /* u8Pin */, 0 /* u8Level */,
-                                            VINF_SUCCESS /* rcRZ */);
-        return;
-    }
-
-    LogFlow(("pdmRCPicHlp_ClearInterruptFF: caller=%p/%d: VMCPU_FF_INTERRUPT_PIC %d -> 0\n",
-             pDevIns, pDevIns->iInstance, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
-
-    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
+    /** @todo r=ramshankar: Propagating rcRZ and make all callers handle it? */
+    APICLocalInterrupt(pVCpu, 0 /* u8Pin */, 0 /* u8Level */, VINF_SUCCESS /* rcRZ */);
 }
 
@@ -514,16 +486,13 @@
 
 /** @interface_method_impl{PDMIOAPICHLPRC,pfnApicBusDeliver} */
-static DECLCALLBACK(int) pdmRCIoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
-                                                       uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc)
+static DECLCALLBACK(int) pdmRCIoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
+                                                       uint8_t u8DeliveryMode, uint8_t uVector, uint8_t u8Polarity,
+                                                       uint8_t u8TriggerMode, uint32_t uTagSrc)
 {
     PDMDEV_ASSERT_DEVINS(pDevIns);
     PVM pVM = pDevIns->Internal.s.pVMRC;
-    LogFlow(("pdmRCIoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n",
-             pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc));
-    Assert(pVM->pdm.s.Apic.pDevInsRC);
-    if (pVM->pdm.s.Apic.pfnBusDeliverRC)
-        return pVM->pdm.s.Apic.pfnBusDeliverRC(pVM->pdm.s.Apic.pDevInsRC, u8Dest, u8DestMode, u8DeliveryMode, iVector,
-                                               u8Polarity, u8TriggerMode, uTagSrc);
-    return VINF_SUCCESS;
+    LogFlow(("pdmRCIoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 uVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n",
+             pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, uVector, u8Polarity, u8TriggerMode, uTagSrc));
+    return APICBusDeliver(pVM, u8Dest, u8DestMode, u8DeliveryMode, uVector, u8Polarity, u8TriggerMode, uTagSrc);
 }
 
Index: trunk/src/VBox/VMM/include/APICInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/APICInternal.h	(revision 64654)
+++ trunk/src/VBox/VMM/include/APICInternal.h	(revision 64655)
@@ -1042,4 +1042,6 @@
     /** MSR write disallowed due to incompatible config. */
     APICMSRACCESS_WRITE_DISALLOWED_CONFIG,
+    /** MSR read disallowed due to incompatible config. */
+    APICMSRACCESS_READ_DISALLOWED_CONFIG,
     /* Count of enum members (don't use). */
     APICMSRACCESS_COUNT
Index: trunk/src/VBox/VMM/include/PDMInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/PDMInternal.h	(revision 64654)
+++ trunk/src/VBox/VMM/include/PDMInternal.h	(revision 64655)
@@ -556,83 +556,8 @@
     /** Pointer to the APIC device instance - R3 Ptr. */
     PPDMDEVINSR3                       pDevInsR3;
-    /** @copydoc PDMAPICREG::pfnGetInterruptR3 */
-    DECLR3CALLBACKMEMBER(int,          pfnGetInterruptR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector,
-                                                          uint32_t *pu32TagSrc));
-    /** @copydoc PDMAPICREG::pfnSetBaseMsrR3 */
-    DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnSetBaseMsrR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint64_t u64Base));
-    /** @copydoc PDMAPICREG::pfnGetBaseMsrR3 */
-    DECLR3CALLBACKMEMBER(uint64_t,     pfnGetBaseMsrR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu));
-    /** @copydoc PDMAPICREG::pfnSetTprR3 */
-    DECLR3CALLBACKMEMBER(void,         pfnSetTprR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr));
-    /** @copydoc PDMAPICREG::pfnGetTprR3 */
-    DECLR3CALLBACKMEMBER(uint8_t,      pfnGetTprR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr));
-    /** @copydoc PDMAPICREG::pfnWriteMsrR3 */
-    DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsrR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value));
-    /** @copydoc PDMAPICREG::pfnReadMsrR3 */
-    DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsrR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value));
-    /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
-    DECLR3CALLBACKMEMBER(int,          pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t uDest, uint8_t uDestMode,
-                                                        uint8_t uDeliveryMode, uint8_t uVector, uint8_t uPolarity,
-                                                        uint8_t uTriggerMode, uint32_t uTagSrc));
-    /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
-    DECLR3CALLBACKMEMBER(VBOXSTRICTRC, pfnLocalInterruptR3,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level,
-                                                            int rcRZ));
-    /** @copydoc PDMAPICREG::pfnGetTimerFreqR3 */
-    DECLR3CALLBACKMEMBER(uint64_t,     pfnGetTimerFreqR3,(PPDMDEVINS pDevIns));
-
     /** Pointer to the APIC device instance - R0 Ptr. */
     PPDMDEVINSR0                       pDevInsR0;
-    /** @copydoc PDMAPICREG::pfnGetInterruptR3 */
-    DECLR0CALLBACKMEMBER(int,          pfnGetInterruptR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector,
-                                                          uint32_t *pu32TagSrc));
-    /** @copydoc PDMAPICREG::pfnSetBaseMsrR3 */
-    DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnSetBaseMsrR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint64_t u64Base));
-    /** @copydoc PDMAPICREG::pfnGetBaseMsrR3 */
-    DECLR0CALLBACKMEMBER(uint64_t,     pfnGetBaseMsrR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu));
-    /** @copydoc PDMAPICREG::pfnSetTprR3 */
-    DECLR0CALLBACKMEMBER(void,         pfnSetTprR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr));
-    /** @copydoc PDMAPICREG::pfnGetTprR3 */
-    DECLR0CALLBACKMEMBER(uint8_t,      pfnGetTprR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr));
-     /** @copydoc PDMAPICREG::pfnWriteMsrR3 */
-    DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsrR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value));
-    /** @copydoc PDMAPICREG::pfnReadMsrR3 */
-    DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsrR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value));
-    /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
-    DECLR0CALLBACKMEMBER(int,          pfnBusDeliverR0,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
-                                                        uint8_t u8DeliveryMode, uint8_t iVector, uint8_t u8Polarity,
-                                                        uint8_t u8TriggerMode, uint32_t uTagSrc));
-    /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
-    DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnLocalInterruptR0,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level,
-                                                            int rcRZ));
-    /** @copydoc PDMAPICREG::pfnGetTimerFreqR3 */
-    DECLR0CALLBACKMEMBER(uint64_t,     pfnGetTimerFreqR0,(PPDMDEVINS pDevIns));
-
     /** Pointer to the APIC device instance - RC Ptr. */
     PPDMDEVINSRC                       pDevInsRC;
-    /** @copydoc PDMAPICREG::pfnGetInterruptR3 */
-    DECLRCCALLBACKMEMBER(int,          pfnGetInterruptRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector,
-                                                          uint32_t *pu32TagSrc));
-    /** @copydoc PDMAPICREG::pfnSetBaseMsrR3 */
-    DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnSetBaseMsrRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint64_t u64Base));
-    /** @copydoc PDMAPICREG::pfnGetBaseMsrR3 */
-    DECLRCCALLBACKMEMBER(uint64_t,     pfnGetBaseMsrRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu));
-    /** @copydoc PDMAPICREG::pfnSetTprR3 */
-    DECLRCCALLBACKMEMBER(void,         pfnSetTprRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr));
-    /** @copydoc PDMAPICREG::pfnGetTprR3 */
-    DECLRCCALLBACKMEMBER(uint8_t,      pfnGetTprRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr));
-    /** @copydoc PDMAPICREG::pfnWriteMsrR3 */
-    DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnWriteMsrRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value));
-    /** @copydoc PDMAPICREG::pfnReadMsrR3 */
-    DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnReadMsrRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value));
-    /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
-    DECLRCCALLBACKMEMBER(int,          pfnBusDeliverRC,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode,
-                                                        uint8_t u8DeliveryMode, uint8_t iVector, uint8_t u8Polarity,
-                                                        uint8_t u8TriggerMode, uint32_t uTagSrc));
-    /** @copydoc PDMAPICREG::pfnLocalInterruptR3 */
-    DECLRCCALLBACKMEMBER(VBOXSTRICTRC, pfnLocalInterruptRC,(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level,
-                                                            int rcRZ));
-    /** @copydoc PDMAPICREG::pfnGetTimerFreqR3 */
-    DECLRCCALLBACKMEMBER(uint64_t,     pfnGetTimerFreqRC,(PPDMDEVINS pDevIns));
-
     uint8_t                            Alignment[4];
 } PDMAPIC;
Index: trunk/src/VBox/VMM/testcase/tstVMStruct.h
===================================================================
--- trunk/src/VBox/VMM/testcase/tstVMStruct.h	(revision 64654)
+++ trunk/src/VBox/VMM/testcase/tstVMStruct.h	(revision 64655)
@@ -446,30 +446,6 @@
     GEN_CHECK_OFF(PDM, Apic);
     GEN_CHECK_OFF_DOT(PDM, Apic.pDevInsR3);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnGetInterruptR3);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnSetBaseMsrR3);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnGetBaseMsrR3);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnSetTprR3);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnWriteMsrR3);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnReadMsrR3);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnGetTprR3);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnBusDeliverR3);
     GEN_CHECK_OFF_DOT(PDM, Apic.pDevInsR0);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnGetInterruptR0);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnSetBaseMsrR0);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnGetBaseMsrR0);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnSetTprR0);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnGetTprR0);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnWriteMsrR0);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnReadMsrR0);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnBusDeliverR0);
     GEN_CHECK_OFF_DOT(PDM, Apic.pDevInsRC);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnGetInterruptRC);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnSetBaseMsrRC);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnGetBaseMsrRC);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnSetTprRC);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnGetTprRC);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnWriteMsrRC);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnReadMsrRC);
-    GEN_CHECK_OFF_DOT(PDM, Apic.pfnBusDeliverRC);
     GEN_CHECK_OFF(PDM, IoApic);
     GEN_CHECK_OFF_DOT(PDM, IoApic.pDevInsR3);
Index: trunk/src/recompiler/VBoxREMWrapper.cpp
===================================================================
--- trunk/src/recompiler/VBoxREMWrapper.cpp	(revision 64654)
+++ trunk/src/recompiler/VBoxREMWrapper.cpp	(revision 64655)
@@ -538,4 +538,16 @@
     { REMPARMDESC_FLAGS_INT,        sizeof(PVMCPU),             NULL }
 };
+static const REMPARMDESC g_aArgsAPICGetTpr[] =
+{
+    { REMPARMDESC_FLAGS_INT,        sizeof(PVMCPU),             NULL },
+    { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t *),          NULL },
+    { REMPARMDESC_FLAGS_INT,        sizeof(bool *),             NULL },
+    { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t *),          NULL }
+};
+static const REMPARMDESC g_aArgsAPICSetTpr[] =
+{
+    { REMPARMDESC_FLAGS_INT,        sizeof(PVMCPU),             NULL },
+    { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t),            NULL }
+};
 static const REMPARMDESC g_aArgsCPUMGetGuestCpl[] =
 {
@@ -737,26 +749,4 @@
     { REMPARMDESC_FLAGS_INT,        sizeof(RTRCPTR),            NULL },
     { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t *),          NULL }
-};
-static const REMPARMDESC g_aArgsPDMApicGetBase[] =
-{
-    { REMPARMDESC_FLAGS_INT,        sizeof(PVM),                NULL },
-    { REMPARMDESC_FLAGS_INT,        sizeof(uint64_t *),         NULL }
-};
-static const REMPARMDESC g_aArgsPDMApicGetTPR[] =
-{
-    { REMPARMDESC_FLAGS_INT,        sizeof(PVMCPU),             NULL },
-    { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t *),          NULL },
-    { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t *),          NULL },
-    { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t *),          NULL }
-};
-static const REMPARMDESC g_aArgsPDMApicSetBase[] =
-{
-    { REMPARMDESC_FLAGS_INT,        sizeof(PVM),                NULL },
-    { REMPARMDESC_FLAGS_INT,        sizeof(uint64_t),           NULL }
-};
-static const REMPARMDESC g_aArgsPDMApicSetTPR[] =
-{
-    { REMPARMDESC_FLAGS_INT,        sizeof(PVMCPU),             NULL },
-    { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t),            NULL }
 };
 static const REMPARMDESC g_aArgsPDMGetInterrupt[] =
@@ -1216,4 +1206,6 @@
 {
     { "APICUpdatePendingInterrupts",            VMM_FN(APICUpdatePendingInterrupts),    &g_aArgsAPICUpdatePendingInterrupts[0],     RT_ELEMENTS(g_aArgsAPICUpdatePendingInterrupts),       REMFNDESC_FLAGS_RET_VOID,   0,                  NULL },
+    { "APICGetTpr",                             VMM_FN(APICGetTpr),                     &g_aArgsAPICGetTpr[0],                      RT_ELEMENTS(g_aArgsAPICGetTpr),                        REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
+    { "APICSetTpr",                             VMM_FN(APICSetTpr),                     &g_aArgsAPICSetTpr[0],                      RT_ELEMENTS(g_aArgsAPICSetTpr),                        REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
     { "CPUMR3RemEnter",                         VMM_FN(CPUMR3RemEnter),                 &g_aArgsCPUMR3RemEnter[0],                  RT_ELEMENTS(g_aArgsCPUMR3RemEnter),                    REMFNDESC_FLAGS_RET_INT,    sizeof(uint32_t),   NULL },
     { "CPUMR3RemLeave",                         VMM_FN(CPUMR3RemLeave),                 &g_aArgsCPUMR3RemLeave[0],                  RT_ELEMENTS(g_aArgsCPUMR3RemLeave),                    REMFNDESC_FLAGS_RET_VOID,   0,                  NULL },
@@ -1266,8 +1258,4 @@
     { "PATMIsPatchGCAddr",                      VMM_FN(PATMIsPatchGCAddr),              &g_aArgsPATMIsPatchGCAddr[0],               RT_ELEMENTS(g_aArgsPATMIsPatchGCAddr),                 REMFNDESC_FLAGS_RET_INT,    sizeof(bool),       NULL },
     { "PATMR3QueryOpcode",                      VMM_FN(PATMR3QueryOpcode),              &g_aArgsPATMR3QueryOpcode[0],               RT_ELEMENTS(g_aArgsPATMR3QueryOpcode),                 REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
-    { "PDMApicGetBaseMsr",                      VMM_FN(PDMApicGetBaseMsr),              &g_aArgsPDMApicGetBaseMsr[0],               RT_ELEMENTS(g_aArgsPDMApicGetBase),                    REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
-    { "PDMApicGetTPR",                          VMM_FN(PDMApicGetTPR),                  &g_aArgsPDMApicGetTPR[0],                   RT_ELEMENTS(g_aArgsPDMApicGetTPR),                     REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
-    { "PDMApicSetBase",                         VMM_FN(PDMApicSetBaseMsr),              &g_aArgsPDMApicSetBaseMsr[0],               RT_ELEMENTS(g_aArgsPDMApicSetBase),                    REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
-    { "PDMApicSetTPR",                          VMM_FN(PDMApicSetTPR),                  &g_aArgsPDMApicSetTPR[0],                   RT_ELEMENTS(g_aArgsPDMApicSetTPR),                     REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
     { "PDMR3DmaRun",                            VMM_FN(PDMR3DmaRun),                    &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_VOID,   0,                  NULL },
     { "PDMR3CritSectInit",                      VMM_FN(PDMR3CritSectInit),              &g_aArgsPDMR3CritSectInit[0],               RT_ELEMENTS(g_aArgsPDMR3CritSectInit),                 REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
Index: trunk/src/recompiler/VBoxRecompiler.c
===================================================================
--- trunk/src/recompiler/VBoxRecompiler.c	(revision 64654)
+++ trunk/src/recompiler/VBoxRecompiler.c	(revision 64655)
@@ -4543,5 +4543,5 @@
 void cpu_set_apic_tpr(CPUX86State *env, uint8_t val)
 {
-    int rc = PDMApicSetTPR(env->pVCpu, val << 4);       /* cr8 bits 3-0 correspond to bits 7-4 of the task priority mmio register. */
+    int rc = APICSetTpr(env->pVCpu, val << 4);       /* cr8 bits 3-0 correspond to bits 7-4 of the task priority mmio register. */
     LogFlow(("cpu_set_apic_tpr: val=%#x rc=%Rrc\n", val, rc)); NOREF(rc);
 }
@@ -4550,5 +4550,5 @@
 {
     uint8_t u8;
-    int rc = PDMApicGetTPR(env->pVCpu, &u8, NULL, NULL);
+    int rc = APICGetTpr(env->pVCpu, &u8, NULL, NULL);
     if (RT_SUCCESS(rc))
     {
