Index: /trunk/include/VBox/Graphics/VBoxVideoHost3D.h
===================================================================
--- /trunk/include/VBox/Graphics/VBoxVideoHost3D.h	(revision 71606)
+++ /trunk/include/VBox/Graphics/VBoxVideoHost3D.h	(revision 71607)
@@ -83,21 +83,24 @@
 typedef void * HVBOXCRCMDSVR;
 
-/* enables the CrCmd interface, thus the hgcm interface gets disabled.
+/** enables the CrCmd interface, thus the hgcm interface gets disabled.
  * all subsequent calls will be done in the thread Enable was done,
  * until the Disable is called */
 typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_ENABLE)(HVBOXCRCMDSVR hSvr, VBOXCRCMD_SVRENABLE_INFO *pInfo);
-/* Opposite to Enable (see above) */
+/** Opposite to Enable (see above) */
 typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_DISABLE)(HVBOXCRCMDSVR hSvr);
-/* process command */
-typedef DECLCALLBACKPTR(int8_t, PFNVBOXCRCMD_SVR_CMD)(HVBOXCRCMDSVR hSvr, const VBOXCMDVBVA_HDR *pCmd, uint32_t cbCmd);
-/* process host control */
-typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_HOSTCTL)(HVBOXCRCMDSVR hSvr, uint8_t* pCtl, uint32_t cbCmd);
-/* process guest control */
-typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_GUESTCTL)(HVBOXCRCMDSVR hSvr, uint8_t* pCtl, uint32_t cbCmd);
-/* screen resize */
-typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_RESIZE)(HVBOXCRCMDSVR hSvr, const struct VBVAINFOSCREEN *pScreen, const uint32_t *pTargetMap);
-/* process SaveState */
+/** process command */
+typedef DECLCALLBACKPTR(int8_t, PFNVBOXCRCMD_SVR_CMD)(HVBOXCRCMDSVR hSvr,
+                                                      const VBOXCMDVBVA_HDR RT_UNTRUSTED_VOLATILE_GUEST *pCmd, uint32_t cbCmd);
+/** process host control */
+typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_HOSTCTL)(HVBOXCRCMDSVR hSvr, uint8_t *pCtl, uint32_t cbCmd);
+/** process guest control */
+typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_GUESTCTL)(HVBOXCRCMDSVR hSvr, uint8_t RT_UNTRUSTED_VOLATILE_GUEST *pCtl,
+                                                        uint32_t cbCmd);
+/** screen resize */
+typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_RESIZE)(HVBOXCRCMDSVR hSvr, const struct VBVAINFOSCREEN *pScreen,
+                                                      const uint32_t *pTargetMap);
+/** process SaveState */
 typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_SAVESTATE)(HVBOXCRCMDSVR hSvr, PSSMHANDLE pSSM);
-/* process LoadState */
+/** process LoadState */
 typedef DECLCALLBACKPTR(int, PFNVBOXCRCMD_SVR_LOADSTATE)(HVBOXCRCMDSVR hSvr, PSSMHANDLE pSSM, uint32_t u32Version);
 
Index: /trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp	(revision 71606)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA_VBVA.cpp	(revision 71607)
@@ -2569,7 +2569,8 @@
             {
                 VBVAENABLE RT_UNTRUSTED_VOLATILE_GUEST *pVbvaEnable = (VBVAENABLE RT_UNTRUSTED_VOLATILE_GUEST *)pvBuffer;
-
-                uint32_t       u32ScreenId;
                 const uint32_t u32Flags = pVbvaEnable->u32Flags;
+                RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
+
+                uint32_t u32ScreenId;
                 if (u32Flags & VBVA_F_EXTENDED)
                 {
@@ -2621,4 +2622,6 @@
                 VBVACAPS RT_UNTRUSTED_VOLATILE_GUEST *pCaps = (VBVACAPS RT_UNTRUSTED_VOLATILE_GUEST *)pvBuffer;
                 pVGAState->fGuestCaps = pCaps->fCaps;
+                RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
+
                 pVGAState->pDrv->pfnVBVAGuestCapabilityUpdate(pVGAState->pDrv, pVGAState->fGuestCaps);
                 pCaps->rc = rc = VINF_SUCCESS;
@@ -2634,4 +2637,6 @@
                 VBVASCANLINECFG RT_UNTRUSTED_VOLATILE_GUEST *pCfg = (VBVASCANLINECFG RT_UNTRUSTED_VOLATILE_GUEST *)pvBuffer;
                 pVGAState->fScanLineCfg = pCfg->fFlags;
+                RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
+
                 pCfg->rc = rc = VINF_SUCCESS;
             }
@@ -2664,5 +2669,5 @@
                     inputMapping.cy = pInputMapping->cy;
                 }
-                ASMCompilerBarrier();
+                RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
 
                 LogRelFlowFunc(("VBVA: ChannelHandler: VBVA_REPORT_INPUT_MAPPING: x=%RI32, y=%RI32, cx=%RU32, cy=%RU32\n",
@@ -2685,5 +2690,5 @@
                 Report.x               = pReport->x;
                 Report.y               = pReport->y;
-                ASMCompilerBarrier();
+                RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
 
                 LogRelFlowFunc(("VBVA: ChannelHandler: VBVA_CURSOR_POSITION: fReportPosition=%RTbool, x=%RU32, y=%RU32\n",
Index: /trunk/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp
===================================================================
--- /trunk/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp	(revision 71606)
+++ /trunk/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp	(revision 71607)
@@ -25,4 +25,5 @@
 #include <VBox/vmm/pgm.h>
 #include <VBoxVideo.h>
+#include <VBox/AssertGuest.h>
 #include <iprt/semaphore.h>
 #include <iprt/thread.h>
@@ -104,6 +105,7 @@
 typedef struct VBVAEXHOSTCONTEXT
 {
-    VBVABUFFER *pVBVA;
-    uint32_t    cbMaxData; /**< Maximum number of data bytes addressible relative to pVBVA. */
+    VBVABUFFER RT_UNTRUSTED_VOLATILE_GUEST *pVBVA;
+    /** Maximum number of data bytes addressible relative to pVBVA. */
+    uint32_t                                cbMaxData;
     volatile int32_t i32State;
     volatile int32_t i32EnableState;
@@ -148,5 +150,5 @@
         struct
         {
-            uint8_t * pu8Cmd;
+            void RT_UNTRUSTED_VOLATILE_GUEST *pvCmd;
             uint32_t cbCmd;
         } cmd;
@@ -241,7 +243,7 @@
 {
 # ifndef VBOXVDBG_MEMCACHE_DISABLE
-    VBVAEXHOSTCTL *pCtl = (VBVAEXHOSTCTL*)RTMemCacheAlloc(pCmdVbva->CtlCache);
+    VBVAEXHOSTCTL *pCtl = (VBVAEXHOSTCTL *)RTMemCacheAlloc(pCmdVbva->CtlCache);
 # else
-    VBVAEXHOSTCTL *pCtl = (VBVAEXHOSTCTL*)RTMemAlloc(sizeof(VBVAEXHOSTCTL));
+    VBVAEXHOSTCTL *pCtl = (VBVAEXHOSTCTL *)RTMemAlloc(sizeof(VBVAEXHOSTCTL));
 # endif
     if (pCtl)
@@ -282,6 +284,6 @@
 
 /**
- * Worker for vboxVBVAExHPDataGet() and VBoxVBVAExHPCheckHostCtlOnDisable() that
- * gets the next control command.
+ * Worker for vboxVBVAExHPDataGetInner() and VBoxVBVAExHPCheckHostCtlOnDisable()
+ * that gets the next control command.
  *
  * @returns Pointer to command if found, NULL if not.
@@ -375,5 +377,5 @@
 
 /**
- * Worker for vboxVBVAExHPDataGet that processes PAUSE and RESUME requests.
+ * Worker for vboxVBVAExHPDataGetInner that processes PAUSE and RESUME requests.
  *
  * Unclear why these cannot be handled the normal way.
@@ -433,5 +435,5 @@
 
 /**
- * Worker for vboxVBVAExHPDataGet.
+ * Worker for vboxVBVAExHPDataGetInner.
  *
  * @retval VINF_SUCCESS
@@ -442,10 +444,10 @@
  * @thread VDMA
  */
-static int vboxVBVAExHPCmdGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppbCmd, uint32_t *pcbCmd)
+static int vboxVBVAExHPCmdGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t RT_UNTRUSTED_VOLATILE_GUEST **ppbCmd, uint32_t *pcbCmd)
 {
     Assert(pCmdVbva->i32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
     Assert(pCmdVbva->i32EnableState > VBVAEXHOSTCONTEXT_ESTATE_PAUSED);
 
-    VBVABUFFER volatile *pVBVA = pCmdVbva->pVBVA; /* This is shared with the guest, so careful! */
+    VBVABUFFER RT_UNTRUSTED_VOLATILE_GUEST *pVBVA = pCmdVbva->pVBVA; /* This is shared with the guest, so careful! */
 
     /*
@@ -454,8 +456,10 @@
     uint32_t idxRecordFirst = ASMAtomicUoReadU32(&pVBVA->indexRecordFirst);
     uint32_t idxRecordFree  = ASMAtomicReadU32(&pVBVA->indexRecordFree);
+    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
     Log(("first = %d, free = %d\n", idxRecordFirst, idxRecordFree));
     if (idxRecordFirst == idxRecordFree)
         return VINF_EOF; /* No records to process. Return without assigning output variables. */
     AssertReturn(idxRecordFirst < VBVA_MAX_RECORDS, VERR_INVALID_STATE);
+    RT_UNTRUSTED_VALIDATED_FENCE();
 
     /*
@@ -464,4 +468,5 @@
     uint32_t const cbRecordCurrent = ASMAtomicReadU32(&pVBVA->aRecords[idxRecordFirst].cbRecord);
     uint32_t const cbRecord        = cbRecordCurrent & ~VBVA_F_RECORD_PARTIAL;
+    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
     if (   (cbRecordCurrent & VBVA_F_RECORD_PARTIAL)
         || !cbRecord)
@@ -474,4 +479,5 @@
     uint32_t const offData   = ASMAtomicReadU32(&pVBVA->off32Data);
     uint32_t       cbMaxData = ASMAtomicReadU32(&pVBVA->cbData);
+    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
     AssertLogRelMsgStmt(cbMaxData <= pCmdVbva->cbMaxData, ("%#x vs %#x\n", cbMaxData, pCmdVbva->cbMaxData),
                         cbMaxData = pCmdVbva->cbMaxData);
@@ -480,9 +486,10 @@
                           ("offData=%#x cbRecord=%#x cbMaxData=%#x cbRecord\n", offData, cbRecord, cbMaxData),
                           VERR_INVALID_STATE);
+    RT_UNTRUSTED_VALIDATED_FENCE();
 
     /*
      * Just set the return values and we're done.
      */
-    *ppbCmd  = (uint8_t *)&pVBVA->au8Data[offData];
+    *ppbCmd = (uint8_t RT_UNTRUSTED_VOLATILE_GUEST *)&pVBVA->au8Data[offData];
     *pcbCmd = cbRecord;
     return VINF_SUCCESS;
@@ -497,17 +504,21 @@
 static void VBoxVBVAExHPDataCompleteCmd(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint32_t cbCmd)
 {
-    VBVABUFFER volatile *pVBVA       = pCmdVbva->pVBVA;
-
-    /* Move data head. */
-    uint32_t const       cbData      = pVBVA->cbData;
-    uint32_t const       offData     = pVBVA->off32Data;
-    if (cbData > 0)
-        ASMAtomicWriteU32(&pVBVA->off32Data, (offData + cbCmd) % cbData);
-    else
-        ASMAtomicWriteU32(&pVBVA->off32Data, 0);
-
-    /* Increment record pointer. */
-    uint32_t const       idxRecFirst = pVBVA->indexRecordFirst;
-    ASMAtomicWriteU32(&pVBVA->indexRecordFirst, (idxRecFirst + 1) % RT_ELEMENTS(pVBVA->aRecords));
+    VBVABUFFER RT_UNTRUSTED_VOLATILE_GUEST *pVBVA = pCmdVbva->pVBVA;
+    if (pVBVA)
+    {
+        /* Move data head. */
+        uint32_t const  cbData      = pVBVA->cbData;
+        uint32_t const  offData     = pVBVA->off32Data;
+        RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
+        if (cbData > 0)
+            ASMAtomicWriteU32(&pVBVA->off32Data, (offData + cbCmd) % cbData);
+        else
+            ASMAtomicWriteU32(&pVBVA->off32Data, 0);
+
+        /* Increment record pointer. */
+        uint32_t const  idxRecFirst = pVBVA->indexRecordFirst;
+        RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
+        ASMAtomicWriteU32(&pVBVA->indexRecordFirst, (idxRecFirst + 1) % RT_ELEMENTS(pVBVA->aRecords));
+    }
 }
 
@@ -528,8 +539,9 @@
  * @thread VDMA
  */
-static VBVAEXHOST_DATA_TYPE vboxVBVAExHPDataGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd)
+static VBVAEXHOST_DATA_TYPE vboxVBVAExHPDataGetInner(struct VBVAEXHOSTCONTEXT *pCmdVbva,
+                                                     uint8_t RT_UNTRUSTED_VOLATILE_GUEST **ppbCmd, uint32_t *pcbCmd)
 {
     Assert(pCmdVbva->i32State == VBVAEXHOSTCONTEXT_STATE_PROCESSING);
-    VBVAEXHOSTCTL*pCtl;
+    VBVAEXHOSTCTL *pCtl;
     bool fHostClt;
 
@@ -543,5 +555,5 @@
                 if (!vboxVBVAExHPCheckProcessCtlInternal(pCmdVbva, pCtl))
                 {
-                    *ppCmd = (uint8_t*)pCtl;
+                    *ppbCmd = (uint8_t RT_UNTRUSTED_VOLATILE_GUEST *)pCtl; /* Note! pCtl is host data, so trusted */
                     *pcbCmd = sizeof (*pCtl);
                     return VBVAEXHOST_DATA_TYPE_HOSTCTL;
@@ -549,5 +561,5 @@
                 continue; /* Processed by vboxVBVAExHPCheckProcessCtlInternal, get next. */
             }
-            *ppCmd = (uint8_t*)pCtl;
+            *ppbCmd = (uint8_t RT_UNTRUSTED_VOLATILE_GUEST *)pCtl; /* Note! pCtl is host data, so trusted */
             *pcbCmd = sizeof (*pCtl);
             return VBVAEXHOST_DATA_TYPE_GUESTCTL;
@@ -557,5 +569,5 @@
             return VBVAEXHOST_DATA_TYPE_NO_DATA;
 
-        int rc = vboxVBVAExHPCmdGet(pCmdVbva, ppCmd, pcbCmd);
+        int rc = vboxVBVAExHPCmdGet(pCmdVbva, ppbCmd, pcbCmd);
         switch (rc)
         {
@@ -580,7 +592,8 @@
  * @thread VDMA
  */
-static VBVAEXHOST_DATA_TYPE VBoxVBVAExHPDataGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd)
-{
-    VBVAEXHOST_DATA_TYPE enmType = vboxVBVAExHPDataGet(pCmdVbva, ppCmd, pcbCmd);
+static VBVAEXHOST_DATA_TYPE VBoxVBVAExHPDataGet(struct VBVAEXHOSTCONTEXT *pCmdVbva,
+                                                uint8_t RT_UNTRUSTED_VOLATILE_GUEST **ppbCmd, uint32_t *pcbCmd)
+{
+    VBVAEXHOST_DATA_TYPE enmType = vboxVBVAExHPDataGetInner(pCmdVbva, ppbCmd, pcbCmd);
     if (enmType == VBVAEXHOST_DATA_TYPE_NO_DATA)
     {
@@ -601,5 +614,5 @@
         {
             /* we are the processor now */
-            enmType = vboxVBVAExHPDataGet(pCmdVbva, ppCmd, pcbCmd);
+            enmType = vboxVBVAExHPDataGetInner(pCmdVbva, ppbCmd, pcbCmd);
             if (enmType == VBVAEXHOST_DATA_TYPE_NO_DATA)
             {
@@ -620,9 +633,10 @@
 DECLINLINE(bool) vboxVBVAExHSHasCommands(struct VBVAEXHOSTCONTEXT *pCmdVbva)
 {
-    VBVABUFFER *pVBVA = pCmdVbva->pVBVA;
+    VBVABUFFER RT_UNTRUSTED_VOLATILE_GUEST *pVBVA = pCmdVbva->pVBVA;
     if (pVBVA)
     {
         uint32_t indexRecordFirst = pVBVA->indexRecordFirst;
-        uint32_t indexRecordFree = pVBVA->indexRecordFree;
+        uint32_t indexRecordFree  = pVBVA->indexRecordFree;
+        RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
 
         if (indexRecordFirst != indexRecordFree)
@@ -717,5 +731,6 @@
  * @thread VDMA
  */
-static int VBoxVBVAExHSEnable(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVABUFFER *pVBVA, uint8_t *pbVRam, uint32_t cbVRam)
+static int VBoxVBVAExHSEnable(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVABUFFER RT_UNTRUSTED_VOLATILE_GUEST *pVBVA,
+                              uint8_t *pbVRam, uint32_t cbVRam)
 {
     if (VBoxVBVAExHSIsEnabled(pCmdVbva))
@@ -727,4 +742,5 @@
     uintptr_t offVRam = (uintptr_t)pVBVA - (uintptr_t)pbVRam;
     AssertLogRelMsgReturn(offVRam < cbVRam - sizeof(*pVBVA), ("%#p cbVRam=%#x\n", offVRam, cbVRam), VERR_OUT_OF_RANGE);
+    RT_UNTRUSTED_VALIDATED_FENCE();
 
     pCmdVbva->pVBVA     = pVBVA;
@@ -784,5 +800,5 @@
     rc = SSMR3PutU32(pSSM, pCtl->u.cmd.cbCmd);
     AssertRCReturn(rc, rc);
-    rc = SSMR3PutU32(pSSM, (uint32_t)(pCtl->u.cmd.pu8Cmd - pu8VramBase));
+    rc = SSMR3PutU32(pSSM, (uint32_t)((uintptr_t)pCtl->u.cmd.pvCmd - (uintptr_t)pu8VramBase));
     AssertRCReturn(rc, rc);
 
@@ -865,5 +881,5 @@
     rc = SSMR3GetU32(pSSM, &u32);
     AssertLogRelRCReturn(rc, rc);
-    pHCtl->u.cmd.pu8Cmd = pu8VramBase + u32;
+    pHCtl->u.cmd.pvCmd = pu8VramBase + u32;
 
     RTListAppend(&pCmdVbva->GuestCtlList, &pHCtl->Node);
@@ -924,5 +940,5 @@
  *
  */
-static int VBoxVBVAExHCtlSubmit(VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL* pCtl, VBVAEXHOSTCTL_SOURCE enmSource,
+static int VBoxVBVAExHCtlSubmit(VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL *pCtl, VBVAEXHOSTCTL_SOURCE enmSource,
                                 PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
 {
@@ -1447,5 +1463,5 @@
     {
         *pcbCtl = pVdma->pCurRemainingHostCtl->u.cmd.cbCmd;
-        return pVdma->pCurRemainingHostCtl->u.cmd.pu8Cmd;
+        return (uint8_t *)pVdma->pCurRemainingHostCtl->u.cmd.pvCmd;
     }
 
@@ -1534,5 +1550,6 @@
     }
 
-    VBVABUFFER *pVBVA = (VBVABUFFER *)HGSMIOffsetToPointerHost(pVdma->pHgsmi, u32Offset);
+    VBVABUFFER RT_UNTRUSTED_VOLATILE_GUEST *pVBVA
+        = (VBVABUFFER RT_UNTRUSTED_VOLATILE_GUEST *)HGSMIOffsetToPointerHost(pVdma->pHgsmi, u32Offset);
     if (!pVBVA)
     {
@@ -1660,5 +1677,5 @@
             {
                 if (pVdma->CrSrvInfo.pfnHostCtl)
-                    return pVdma->CrSrvInfo.pfnHostCtl(pVdma->CrSrvInfo.hSvr, pCmd->u.cmd.pu8Cmd, pCmd->u.cmd.cbCmd);
+                    return pVdma->CrSrvInfo.pfnHostCtl(pVdma->CrSrvInfo.hSvr, (uint8_t *)pCmd->u.cmd.pvCmd, pCmd->u.cmd.cbCmd);
                 WARN(("VBVAEXHOSTCTL_TYPE_GHH_BE_OPAQUE for disabled vdma VBVA\n"));
             }
@@ -1772,4 +1789,6 @@
             || idxView == UINT32_C(0xFFFFFFFF))
         {
+            RT_UNTRUSTED_VALIDATED_FENCE();
+
             RT_ZERO(*pScreen);
             pScreen->u32ViewIndex = idxView;
@@ -1785,4 +1804,5 @@
                 && idxView != UINT32_C(0xFFFFFFFF))
                 return VERR_INVALID_PARAMETER;
+            RT_UNTRUSTED_VALIDATED_FENCE();
 
             /* Special case for blanking using current video mode.
@@ -1826,8 +1846,12 @@
  * @thread  VDMA
  */
-static int vboxVDMACrGuestCtlResizeEntryProcess(struct VBOXVDMAHOST *pVdma, VBOXCMDVBVA_RESIZE_ENTRY *pEntry)
+static int vboxVDMACrGuestCtlResizeEntryProcess(struct VBOXVDMAHOST *pVdma,
+                                                VBOXCMDVBVA_RESIZE_ENTRY RT_UNTRUSTED_VOLATILE_GUEST *pEntry)
 {
     PVGASTATE pVGAState = pVdma->pVGAState;
-    VBVAINFOSCREEN Screen = pEntry->Screen;
+
+    VBVAINFOSCREEN Screen;
+    RT_COPY_VOLATILE(Screen, pEntry->Screen);
+    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
 
     /* Verify and cleanup local copy of the input data. */
@@ -1838,7 +1862,10 @@
         return rc;
     }
+    RT_UNTRUSTED_VALIDATED_FENCE();
 
     VBOXCMDVBVA_SCREENMAP_DECL(uint32_t, aTargetMap);
-    memcpy(aTargetMap, pEntry->aTargetMap, sizeof(aTargetMap));
+    RT_BCOPY_VOLATILE(aTargetMap, pEntry->aTargetMap, sizeof(aTargetMap));
+    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
+
     ASMBitClearRange(aTargetMap, pVGAState->cMonitors, VBOX_VIDEO_MAX_SCREENS);
 
@@ -1926,5 +1953,7 @@
             {
                 if (pVdma->CrSrvInfo.pfnGuestCtl)
-                    return pVdma->CrSrvInfo.pfnGuestCtl(pVdma->CrSrvInfo.hSvr, pCmd->u.cmd.pu8Cmd, pCmd->u.cmd.cbCmd);
+                    return pVdma->CrSrvInfo.pfnGuestCtl(pVdma->CrSrvInfo.hSvr,
+                                                        (uint8_t RT_UNTRUSTED_VOLATILE_GUEST *)pCmd->u.cmd.pvCmd,
+                                                        pCmd->u.cmd.cbCmd);
 
                 /* Unexpected. */
@@ -1946,8 +1975,9 @@
                 {
                     uint32_t cElements = cbCmd / sizeof(VBOXCMDVBVA_RESIZE_ENTRY);
-                    VBOXCMDVBVA_RESIZE *pResize = (VBOXCMDVBVA_RESIZE *)pCmd->u.cmd.pu8Cmd;
+                    VBOXCMDVBVA_RESIZE RT_UNTRUSTED_VOLATILE_GUEST *pResize
+                        = (VBOXCMDVBVA_RESIZE RT_UNTRUSTED_VOLATILE_GUEST *)pCmd->u.cmd.pvCmd;
                     for (uint32_t i = 0; i < cElements; ++i)
                     {
-                        VBOXCMDVBVA_RESIZE_ENTRY *pEntry = &pResize->aEntries[i];
+                        VBOXCMDVBVA_RESIZE_ENTRY RT_UNTRUSTED_VOLATILE_GUEST *pEntry = &pResize->aEntries[i];
                         int rc = vboxVDMACrGuestCtlResizeEntryProcess(pVdma, pEntry);
                         if (RT_FAILURE(rc))
@@ -1972,8 +2002,10 @@
         case VBVAEXHOSTCTL_TYPE_GHH_ENABLE_PAUSED:
         {
-            VBVAENABLE *pEnable = (VBVAENABLE *)pCmd->u.cmd.pu8Cmd;
+            VBVAENABLE RT_UNTRUSTED_VOLATILE_GUEST *pEnable = (VBVAENABLE RT_UNTRUSTED_VOLATILE_GUEST *)pCmd->u.cmd.pvCmd;
             Assert(pCmd->u.cmd.cbCmd == sizeof(VBVAENABLE));
 
-            uint32_t u32Offset = pEnable->u32Offset;
+            uint32_t const u32Offset = pEnable->u32Offset;
+            RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
+
             int rc = vdmaVBVAEnableProcess(pVdma, u32Offset);
             if (RT_SUCCESS(rc))
@@ -2030,32 +2062,25 @@
     RTGCPHYS       GCPhysPage = (RTGCPHYS)uPageNo << X86_PAGE_SHIFT;
     PGMPAGEMAPLOCK Lock;
-    int rc;
 
     if (fIn)
     {
         const void *pvPage;
-        rc = PDMDevHlpPhysGCPhys2CCPtrReadOnly(pDevIns, GCPhysPage, 0, &pvPage, &Lock);
-        if (RT_SUCCESS(rc))
-        {
-            memcpy(pbVram, pvPage, PAGE_SIZE);
-            PDMDevHlpPhysReleasePageMappingLock(pDevIns, &Lock);
-        }
-        else
-            WARN(("PDMDevHlpPhysGCPhys2CCPtrReadOnly failed %Rrc", rc));
+        int rc = PDMDevHlpPhysGCPhys2CCPtrReadOnly(pDevIns, GCPhysPage, 0, &pvPage, &Lock);
+        ASSERT_GUEST_LOGREL_MSG_RC_RETURN(rc, ("PDMDevHlpPhysGCPhys2CCPtrReadOnly %RGp -> %Rrc\n", GCPhysPage, rc), rc);
+
+        memcpy(pbVram, pvPage, PAGE_SIZE);
+        PDMDevHlpPhysReleasePageMappingLock(pDevIns, &Lock);
     }
     else
     {
         void *pvPage;
-        rc = PDMDevHlpPhysGCPhys2CCPtr(pDevIns, GCPhysPage, 0, &pvPage, &Lock);
-        if (RT_SUCCESS(rc))
-        {
-            memcpy(pvPage, pbVram, PAGE_SIZE);
-            PDMDevHlpPhysReleasePageMappingLock(pDevIns, &Lock);
-        }
-        else
-            WARN(("PDMDevHlpPhysGCPhys2CCPtr failed %Rrc", rc));
-    }
-
-    return rc;
+        int rc = PDMDevHlpPhysGCPhys2CCPtr(pDevIns, GCPhysPage, 0, &pvPage, &Lock);
+        ASSERT_GUEST_LOGREL_MSG_RC_RETURN(rc, ("PDMDevHlpPhysGCPhys2CCPtr %RGp -> %Rrc\n", GCPhysPage, rc), rc);
+
+        memcpy(pvPage, pbVram, PAGE_SIZE);
+        PDMDevHlpPhysReleasePageMappingLock(pDevIns, &Lock);
+    }
+
+    return VINF_SUCCESS;
 }
 
@@ -2067,23 +2092,27 @@
  * @thread VDMA
  */
-static int8_t vboxVDMACrCmdVbvaPageTransfer(PVGASTATE pVGAState, VBOXCMDVBVA_HDR const volatile *pHdr, uint32_t cbCmd,
-                                            const VBOXCMDVBVA_PAGING_TRANSFER_DATA *pData)
+static int8_t vboxVDMACrCmdVbvaPageTransfer(PVGASTATE pVGAState, VBOXCMDVBVA_HDR const RT_UNTRUSTED_VOLATILE_GUEST *pHdr,
+                                            uint32_t cbCmd, const VBOXCMDVBVA_PAGING_TRANSFER_DATA RT_UNTRUSTED_VOLATILE_GUEST *pData)
 {
     /*
      * Extract and validate information.
      */
-    AssertMsgReturn(cbCmd >= sizeof(VBOXCMDVBVA_PAGING_TRANSFER), ("%#x\n", cbCmd), -1);
+    ASSERT_GUEST_MSG_RETURN(cbCmd >= sizeof(VBOXCMDVBVA_PAGING_TRANSFER), ("%#x\n", cbCmd), -1);
 
     bool const fIn = RT_BOOL(pHdr->u8Flags & VBOXCMDVBVA_OPF_PAGING_TRANSFER_IN);
+    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
 
     uint32_t cbPageNumbers = cbCmd - RT_OFFSETOF(VBOXCMDVBVA_PAGING_TRANSFER, Data.aPageNumbers);
-    AssertMsgReturn(!(cbPageNumbers % sizeof(VBOXCMDVBVAPAGEIDX)), ("%#x\n", cbPageNumbers), -1);
+    ASSERT_GUEST_MSG_RETURN(!(cbPageNumbers % sizeof(VBOXCMDVBVAPAGEIDX)), ("%#x\n", cbPageNumbers), -1);
     VBOXCMDVBVAPAGEIDX const cPages = cbPageNumbers / sizeof(VBOXCMDVBVAPAGEIDX);
 
     VBOXCMDVBVAOFFSET offVRam = pData->Alloc.u.offVRAM;
-    AssertMsgReturn(!(offVRam & X86_PAGE_OFFSET_MASK), ("%#x\n", offVRam), -1);
-    AssertMsgReturn(offVRam < pVGAState->vram_size, ("%#x vs %#x\n", offVRam, pVGAState->vram_size), -1);
+    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
+    ASSERT_GUEST_MSG_RETURN(!(offVRam & X86_PAGE_OFFSET_MASK), ("%#x\n", offVRam), -1);
+    ASSERT_GUEST_MSG_RETURN(offVRam < pVGAState->vram_size, ("%#x vs %#x\n", offVRam, pVGAState->vram_size), -1);
     uint32_t cVRamPages = (pVGAState->vram_size - offVRam) >> X86_PAGE_SHIFT;
-    AssertMsgReturn(cPages <= cVRamPages, ("cPages=%#x vs cVRamPages=%#x @ offVRam=%#x\n", cPages, cVRamPages, offVRam), -1);
+    ASSERT_GUEST_MSG_RETURN(cPages <= cVRamPages, ("cPages=%#x vs cVRamPages=%#x @ offVRam=%#x\n", cPages, cVRamPages, offVRam), -1);
+
+    RT_UNTRUSTED_VALIDATED_FENCE();
 
     /*
@@ -2094,6 +2123,7 @@
     {
         uint32_t uPageNo = pData->aPageNumbers[iPage];
+        RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
         int rc = vboxVDMACrCmdVbvaProcessPagingEl(pVGAState->pDevInsR3, uPageNo, pbVRam, fIn);
-        AssertMsgReturn(RT_SUCCESS(rc), ("#%#x: uPageNo=%#x rc=%Rrc\n", iPage, uPageNo, rc), -1);
+        ASSERT_GUEST_MSG_RETURN(RT_SUCCESS(rc), ("#%#x: uPageNo=%#x rc=%Rrc\n", iPage, uPageNo, rc), -1);
     }
     return 0;
@@ -2110,38 +2140,36 @@
  * @thread VDMA
  */
-static int8_t vboxVDMACrCmdVbvaPagingFill(PVGASTATE pVGAState, VBOXCMDVBVA_PAGING_FILL *pFill)
-{
-    VBOXCMDVBVA_PAGING_FILL FillSafe = *pFill;
-    VBOXCMDVBVAOFFSET       offVRAM  = FillSafe.offVRAM;
-    if (!(offVRAM & X86_PAGE_OFFSET_MASK))
-    {
-        if (offVRAM <= pVGAState->vram_size)
-        {
-            uint32_t cbFill = FillSafe.u32CbFill;
-            AssertStmt(!(cbFill & 3), cbFill &= ~(uint32_t)3);
-
-            if (   cbFill < pVGAState->vram_size
-                && offVRAM <= pVGAState->vram_size - cbFill)
-            {
-                uint32_t      *pu32Vram = (uint32_t *)((uint8_t *)pVGAState->vram_ptrR3 + offVRAM);
-                uint32_t const u32Color = FillSafe.u32Pattern;
-
-                uint32_t cLoops = cbFill / 4;
-                while (cLoops-- > 0)
-                    pu32Vram[cLoops] = u32Color;
-
-                return 0;
-
-            }
-            else
-                WARN(("invalid cbFill"));
-
-        }
-        WARN(("invalid vram offset"));
-
-    }
-    else
-        WARN(("offVRAM address is not on page boundary\n"));
-    return -1;
+static int8_t vboxVDMACrCmdVbvaPagingFill(PVGASTATE pVGAState, VBOXCMDVBVA_PAGING_FILL RT_UNTRUSTED_VOLATILE_GUEST *pFill)
+{
+    /*
+     * Copy and validate input.
+     */
+    VBOXCMDVBVA_PAGING_FILL FillSafe;
+    RT_COPY_VOLATILE(FillSafe, *pFill);
+    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
+
+    VBOXCMDVBVAOFFSET offVRAM = FillSafe.offVRAM;
+    ASSERT_GUEST_MSG_RETURN(!(offVRAM & X86_PAGE_OFFSET_MASK), ("offVRAM=%#x\n", offVRAM), -1);
+    ASSERT_GUEST_MSG_RETURN(offVRAM <= pVGAState->vram_size, ("offVRAM=%#x\n", offVRAM), -1);
+
+    uint32_t cbFill = FillSafe.u32CbFill;
+    ASSERT_GUEST_STMT(!(cbFill & 3), cbFill &= ~(uint32_t)3);
+    ASSERT_GUEST_MSG_RETURN(   cbFill < pVGAState->vram_size
+                            && offVRAM <= pVGAState->vram_size - cbFill,
+                            ("offVRAM=%#x cbFill=%#x\n", offVRAM, cbFill), -1);
+
+    RT_UNTRUSTED_VALIDATED_FENCE();
+
+    /*
+     * Execute.
+     */
+    uint32_t      *pu32Vram = (uint32_t *)((uint8_t *)pVGAState->vram_ptrR3 + offVRAM);
+    uint32_t const u32Color = FillSafe.u32Pattern;
+
+    uint32_t cLoops = cbFill / 4;
+    while (cLoops-- > 0)
+        pu32Vram[cLoops] = u32Color;
+
+    return 0;
 }
 
@@ -2156,7 +2184,9 @@
  * @thread VDMA
  */
-static int8_t vboxVDMACrCmdVbvaProcessCmdData(struct VBOXVDMAHOST *pVdma, const VBOXCMDVBVA_HDR *pCmd, uint32_t cbCmd)
+static int8_t vboxVDMACrCmdVbvaProcessCmdData(struct VBOXVDMAHOST *pVdma, const VBOXCMDVBVA_HDR RT_UNTRUSTED_VOLATILE_GUEST *pCmd,
+                                              uint32_t cbCmd)
 {
     uint8_t bOpCode = pCmd->u8OpCode;
+    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
     switch (bOpCode)
     {
@@ -2165,18 +2195,14 @@
 
         case VBOXCMDVBVA_OPTYPE_PAGING_TRANSFER:
-            return vboxVDMACrCmdVbvaPageTransfer(pVdma->pVGAState, pCmd, cbCmd, &((VBOXCMDVBVA_PAGING_TRANSFER *)pCmd)->Data);
+            return vboxVDMACrCmdVbvaPageTransfer(pVdma->pVGAState, pCmd, cbCmd,
+                                                 &((VBOXCMDVBVA_PAGING_TRANSFER RT_UNTRUSTED_VOLATILE_GUEST *)pCmd)->Data);
 
         case VBOXCMDVBVA_OPTYPE_PAGING_FILL:
-            if (cbCmd == sizeof(VBOXCMDVBVA_PAGING_FILL))
-                return vboxVDMACrCmdVbvaPagingFill(pVdma->pVGAState, (VBOXCMDVBVA_PAGING_FILL *)pCmd);
-            WARN(("cmd too small"));
-            return -1;
+            ASSERT_GUEST_RETURN(cbCmd == sizeof(VBOXCMDVBVA_PAGING_FILL), -1);
+            return vboxVDMACrCmdVbvaPagingFill(pVdma->pVGAState, (VBOXCMDVBVA_PAGING_FILL RT_UNTRUSTED_VOLATILE_GUEST *)pCmd);
 
         default:
-            if (pVdma->CrSrvInfo.pfnCmd)
-                return pVdma->CrSrvInfo.pfnCmd(pVdma->CrSrvInfo.hSvr, pCmd, cbCmd);
-            /* Unexpected. */
-            WARN(("no HGCM"));
-            return -1;
+            ASSERT_GUEST_RETURN(pVdma->CrSrvInfo.pfnCmd != NULL, -1);
+            return pVdma->CrSrvInfo.pfnCmd(pVdma->CrSrvInfo.hSvr, pCmd, cbCmd);
     }
 }
@@ -2213,8 +2239,10 @@
  * @thread VDMA
  */
-static int8_t vboxVDMACrCmdVbvaProcess(struct VBOXVDMAHOST *pVdma, const VBOXCMDVBVA_HDR *pCmd, uint32_t cbCmd, bool fRecursion)
+static int8_t vboxVDMACrCmdVbvaProcess(struct VBOXVDMAHOST *pVdma, const VBOXCMDVBVA_HDR RT_UNTRUSTED_VOLATILE_GUEST *pCmd,
+                                       uint32_t cbCmd, bool fRecursion)
 {
     int8_t        i8Result = 0;
     uint8_t const bOpCode  = pCmd->u8OpCode;
+    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
     LogRelFlow(("VDMA: vboxVDMACrCmdVbvaProcess: ENTER, bOpCode=%u\n", bOpCode));
     switch (bOpCode)
@@ -2225,12 +2253,13 @@
              * Extract the command physical address and size.
              */
-            AssertMsgReturn(cbCmd >= sizeof(VBOXCMDVBVA_SYSMEMCMD), ("%#x\n", cbCmd), -1);
-            RTGCPHYS GCPhysCmd  = ((VBOXCMDVBVA_SYSMEMCMD *)pCmd)->phCmd;
+            ASSERT_GUEST_MSG_RETURN(cbCmd >= sizeof(VBOXCMDVBVA_SYSMEMCMD), ("%#x\n", cbCmd), -1);
+            RTGCPHYS GCPhysCmd  = ((VBOXCMDVBVA_SYSMEMCMD RT_UNTRUSTED_VOLATILE_GUEST *)pCmd)->phCmd;
+            RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
             uint32_t cbCmdPart  = X86_PAGE_SIZE - (uint32_t)(GCPhysCmd & X86_PAGE_OFFSET_MASK);
 
             uint32_t cbRealCmd  = pCmd->u8Flags;
             cbRealCmd |= (uint32_t)pCmd->u.u8PrimaryID << 8;
-            AssertMsgReturn(cbRealCmd >= sizeof(VBOXCMDVBVA_HDR), ("%#x\n", cbRealCmd), -1);
-            AssertMsgReturn(cbRealCmd <= _1M, ("%#x\n", cbRealCmd), -1);
+            ASSERT_GUEST_MSG_RETURN(cbRealCmd >= sizeof(VBOXCMDVBVA_HDR), ("%#x\n", cbRealCmd), -1);
+            ASSERT_GUEST_MSG_RETURN(cbRealCmd <= _1M, ("%#x\n", cbRealCmd), -1);
 
             /*
@@ -2242,9 +2271,5 @@
             VBOXCMDVBVA_HDR const *pRealCmdHdr = NULL;
             int rc = PDMDevHlpPhysGCPhys2CCPtrReadOnly(pDevIns, GCPhysCmd, 0, (const void **)&pRealCmdHdr, &Lock);
-            if (!RT_SUCCESS(rc))
-            {
-                WARN(("PDMDevHlpPhysGCPhys2CCPtrReadOnly failed %Rrc\n", rc));
-                return -1;
-            }
+            ASSERT_GUEST_LOGREL_MSG_RC_RETURN(rc, ("VDMA: %RGp -> %Rrc\n", GCPhysCmd, rc), -1);
             Assert((GCPhysCmd & PAGE_OFFSET_MASK) == (((uintptr_t)pRealCmdHdr) & PAGE_OFFSET_MASK));
 
@@ -2290,5 +2315,5 @@
         {
             Assert(cbCmd >= sizeof(VBOXCMDVBVA_HDR)); /* caller already checked this */
-            AssertReturn(!fRecursion, -1);
+            ASSERT_GUEST_RETURN(!fRecursion, -1);
 
             /* Skip current command. */
@@ -2299,18 +2324,15 @@
             while (cbCmd > 0)
             {
-                AssertMsgReturn(cbCmd >= sizeof(VBOXCMDVBVA_HDR), ("%#x\n", cbCmd), -1);
+                ASSERT_GUEST_MSG_RETURN(cbCmd >= sizeof(VBOXCMDVBVA_HDR), ("%#x\n", cbCmd), -1);
 
                 uint16_t cbCurCmd = pCmd->u2.complexCmdEl.u16CbCmdHost;
-                AssertMsgReturn(cbCurCmd <= cbCmd, ("cbCurCmd=%#x, cbCmd=%#x\n", cbCurCmd, cbCmd), -1);
+                RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
+                ASSERT_GUEST_MSG_RETURN(cbCurCmd <= cbCmd, ("cbCurCmd=%#x, cbCmd=%#x\n", cbCurCmd, cbCmd), -1);
 
                 i8Result = vboxVDMACrCmdVbvaProcess(pVdma, pCmd, cbCurCmd, true /*fRecursive*/);
-                if (i8Result < 0)
-                {
-                    WARN(("vboxVDMACrCmdVbvaProcess failed"));
-                    return i8Result;
-                }
+                ASSERT_GUEST_MSG_RETURN(i8Result >= 0, ("vboxVDMACrCmdVbvaProcess -> %d\n", i8Result), i8Result);
 
                 /* Advance to the next command. */
-                pCmd  = (VBOXCMDVBVA_HDR *)((uintptr_t)pCmd + cbCurCmd);
+                pCmd  = (VBOXCMDVBVA_HDR RT_UNTRUSTED_VOLATILE_GUEST *)((uintptr_t)pCmd + cbCurCmd);
                 cbCmd -= cbCurCmd;
             }
@@ -2330,12 +2352,13 @@
  * @thread VDMA
  */
-static void vboxVDMACrCmdProcess(struct VBOXVDMAHOST *pVdma, uint8_t* pbCmd, uint32_t cbCmd)
+static void vboxVDMACrCmdProcess(struct VBOXVDMAHOST *pVdma, uint8_t RT_UNTRUSTED_VOLATILE_GUEST *pbCmd, uint32_t cbCmd)
 {
     if (   cbCmd > 0
         && *pbCmd == VBOXCMDVBVA_OPTYPE_NOP)
     { /* nop */ }
-    else if (cbCmd >= sizeof(VBOXCMDVBVA_HDR))
-    {
-        PVBOXCMDVBVA_HDR pCmd = (PVBOXCMDVBVA_HDR)pbCmd;
+    else
+    {
+        ASSERT_GUEST_RETURN_VOID(cbCmd >= sizeof(VBOXCMDVBVA_HDR));
+        VBOXCMDVBVA_HDR RT_UNTRUSTED_VOLATILE_GUEST *pCmd = (VBOXCMDVBVA_HDR RT_UNTRUSTED_VOLATILE_GUEST *)pbCmd;
 
         /* check if the command is cancelled */
@@ -2348,6 +2371,4 @@
             Assert(pCmd->u8State == VBOXCMDVBVA_STATE_CANCELLED);
     }
-    else
-        WARN(("invalid command size"));
 
 }
@@ -2546,5 +2567,5 @@
     AssertReturn(cbBuffer >= RT_UOFFSETOF(VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects), VERR_INVALID_PARAMETER);
     VBOXVDMACMD_DMA_PRESENT_BLT BltSafe;
-    memcpy(&BltSafe, (void const *)pBlt, RT_UOFFSETOF(VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects));
+    RT_BCOPY_VOLATILE(&BltSafe, (void const *)pBlt, RT_UOFFSETOF(VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects));
     RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
 
@@ -2626,5 +2647,5 @@
     AssertReturn(cbBuffer >= sizeof(*pTransfer), VERR_INVALID_PARAMETER);
     VBOXVDMACMD_DMA_BPB_TRANSFER TransferSafeCopy;
-    memcpy(&TransferSafeCopy, (void const *)pTransfer, sizeof(TransferSafeCopy));
+    RT_COPY_VOLATILE(TransferSafeCopy, *pTransfer);
     RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
 
@@ -2820,6 +2841,6 @@
     while (!VBoxVDMAThreadIsTerminating(&pVdma->Thread))
     {
-        uint8_t             *pbCmd   = NULL;
-        uint32_t             cbCmd   = 0;
+        uint8_t RT_UNTRUSTED_VOLATILE_GUEST *pbCmd = NULL;
+        uint32_t                             cbCmd = 0;
         VBVAEXHOST_DATA_TYPE enmType = VBoxVBVAExHPDataGet(pCmdVbva, &pbCmd, &cbCmd);
         switch (enmType)
@@ -2873,5 +2894,5 @@
  *                      requests.  Input stat is false, so it only ever need to
  *                      be set to true.
- * @thread  VDMA
+ * @thread  EMT
  */
 static int vboxVDMACommandProcess(PVBOXVDMAHOST pVdma, VBOXVDMACBUF_DR RT_UNTRUSTED_VOLATILE_GUEST *pCmd,
@@ -3135,4 +3156,5 @@
  * @param   pCmd    The command to handle.  Considered volatile.
  * @param   cbCmd   The size of the command.  At least sizeof(VBOXVDMACBUF_DR).
+ * @thread  EMT
  */
 void vboxVDMACommand(struct VBOXVDMAHOST *pVdma, VBOXVDMACBUF_DR RT_UNTRUSTED_VOLATILE_GUEST *pCmd, uint32_t cbCmd)
@@ -3170,5 +3192,6 @@
 {
     PVBOXVDMAHOST pVdma = (PVBOXVDMAHOST)pvContext;
-    VBOXCMDVBVA_CTL *pGCtl = (VBOXCMDVBVA_CTL*)(pCtl->u.cmd.pu8Cmd - sizeof (VBOXCMDVBVA_CTL));
+    VBOXCMDVBVA_CTL RT_UNTRUSTED_VOLATILE_GUEST *pGCtl
+        = (VBOXCMDVBVA_CTL RT_UNTRUSTED_VOLATILE_GUEST *)((uintptr_t)pCtl->u.cmd.pvCmd - sizeof(VBOXCMDVBVA_CTL));
     AssertRC(rc);
     pGCtl->i32Result = rc;
@@ -3185,5 +3208,6 @@
  */
 static int vdmaVBVACtlGenericSubmit(PVBOXVDMAHOST pVdma, VBVAEXHOSTCTL_SOURCE enmSource, VBVAEXHOSTCTL_TYPE enmType,
-                                    uint8_t* pu8Cmd, uint32_t cbCmd, PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
+                                    uint8_t RT_UNTRUSTED_VOLATILE_GUEST *pbCmd, uint32_t cbCmd,
+                                    PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
 {
     int            rc;
@@ -3191,6 +3215,6 @@
     if (pHCtl)
     {
-        pHCtl->u.cmd.pu8Cmd = pu8Cmd;
-        pHCtl->u.cmd.cbCmd  = cbCmd;
+        pHCtl->u.cmd.pvCmd = pbCmd;
+        pHCtl->u.cmd.cbCmd = cbCmd;
         rc = vdmaVBVACtlSubmit(pVdma, pHCtl, enmSource, pfnComplete, pvComplete);
         if (RT_SUCCESS(rc))
@@ -3217,6 +3241,8 @@
 
     VBoxSHGSMICommandMarkAsynchCompletion(pCtl);
-    int rc = vdmaVBVACtlGenericSubmit(pVdma, VBVAEXHOSTCTL_SOURCE_GUEST, enmType, (uint8_t *)(pCtl + 1),
-                                      cbCtl - sizeof(VBOXCMDVBVA_CTL), vboxCmdVBVACmdCtlGuestCompletion, pVdma);
+    int rc = vdmaVBVACtlGenericSubmit(pVdma, VBVAEXHOSTCTL_SOURCE_GUEST, enmType,
+                                      (uint8_t RT_UNTRUSTED_VOLATILE_GUEST *)(pCtl + 1),
+                                      cbCtl - sizeof(VBOXCMDVBVA_CTL),
+                                      vboxCmdVBVACmdCtlGuestCompletion, pVdma);
     if (RT_SUCCESS(rc))
         return VINF_SUCCESS;
@@ -3235,5 +3261,5 @@
                                                           int rc, void *pvCompletion)
 {
-    VBOXCRCMDCTL* pVboxCtl = (VBOXCRCMDCTL*)pCtl->u.cmd.pu8Cmd;
+    VBOXCRCMDCTL *pVboxCtl = (VBOXCRCMDCTL *)pCtl->u.cmd.pvCmd;
     if (pVboxCtl->u.pfnInternal)
         ((PFNCRCTLCOMPLETION)pVboxCtl->u.pfnInternal)(pVboxCtl, pCtl->u.cmd.cbCmd, rc, pvCompletion);
@@ -3341,5 +3367,6 @@
  * Worker for vdmaVBVACtlEnableDisableSubmitInternal() and vdmaVBVACtlEnableSubmitSync().
  */
-static int vdmaVBVACtlEnableSubmitInternal(PVBOXVDMAHOST pVdma, VBVAENABLE *pEnable, bool fPaused, PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
+static int vdmaVBVACtlEnableSubmitInternal(PVBOXVDMAHOST pVdma, VBVAENABLE RT_UNTRUSTED_VOLATILE_GUEST *pEnable, bool fPaused,
+                                           PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
 {
     int rc;
@@ -3348,5 +3375,5 @@
     if (pHCtl)
     {
-        pHCtl->u.cmd.pu8Cmd = (uint8_t *)pEnable;
+        pHCtl->u.cmd.pvCmd  = pEnable;
         pHCtl->u.cmd.cbCmd  = sizeof(*pEnable);
         pHCtl->pfnComplete  = pfnComplete;
@@ -3356,6 +3383,6 @@
         if (RT_SUCCESS(rc))
             return VINF_SUCCESS;
-        WARN(("VBoxVDMAThreadCreate failed %d\n", rc));
-
+
+        WARN(("VBoxVDMAThreadCreate failed %Rrc\n", rc));
         VBoxVBVAExHCtlFree(&pVdma->CmdVbva, pHCtl);
     }
@@ -3411,9 +3438,8 @@
  * Worker for vdmaVBVACtlEnableDisableSubmitInternal().
  */
-static int vdmaVBVACtlDisableSubmitInternal(PVBOXVDMAHOST pVdma, VBVAENABLE *pEnable,
+static int vdmaVBVACtlDisableSubmitInternal(PVBOXVDMAHOST pVdma, VBVAENABLE RT_UNTRUSTED_VOLATILE_GUEST *pEnable,
                                             PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
 {
     int rc;
-    VBVAEXHOSTCTL* pHCtl;
     if (VBoxVBVAExHSIsDisabled(&pVdma->CmdVbva))
     {
@@ -3422,5 +3448,5 @@
     }
 
-    pHCtl = VBoxVBVAExHCtlCreate(&pVdma->CmdVbva, VBVAEXHOSTCTL_TYPE_GHH_DISABLE);
+    VBVAEXHOSTCTL *pHCtl = VBoxVBVAExHCtlCreate(&pVdma->CmdVbva, VBVAEXHOSTCTL_TYPE_GHH_DISABLE);
     if (!pHCtl)
     {
@@ -3429,6 +3455,6 @@
     }
 
-    pHCtl->u.cmd.pu8Cmd = (uint8_t*)pEnable;
-    pHCtl->u.cmd.cbCmd = sizeof (*pEnable);
+    pHCtl->u.cmd.pvCmd = pEnable;
+    pHCtl->u.cmd.cbCmd = sizeof(*pEnable);
     rc = vdmaVBVACtlSubmit(pVdma, pHCtl, VBVAEXHOSTCTL_SOURCE_GUEST, pfnComplete, pvComplete);
     if (RT_SUCCESS(rc))
@@ -3443,5 +3469,5 @@
  * Worker for vdmaVBVACtlEnableDisableSubmit().
  */
-static int vdmaVBVACtlEnableDisableSubmitInternal(PVBOXVDMAHOST pVdma, VBVAENABLE *pEnable,
+static int vdmaVBVACtlEnableDisableSubmitInternal(PVBOXVDMAHOST pVdma, VBVAENABLE RT_UNTRUSTED_VOLATILE_GUEST *pEnable,
                                                   PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
 {
@@ -3455,5 +3481,5 @@
  * Handler for vboxCmdVBVACmdCtl/VBOXCMDVBVACTL_TYPE_ENABLE.
  */
-static int vdmaVBVACtlEnableDisableSubmit(PVBOXVDMAHOST pVdma, VBOXCMDVBVA_CTL_ENABLE *pEnable)
+static int vdmaVBVACtlEnableDisableSubmit(PVBOXVDMAHOST pVdma, VBOXCMDVBVA_CTL_ENABLE RT_UNTRUSTED_VOLATILE_GUEST *pEnable)
 {
     VBoxSHGSMICommandMarkAsynchCompletion(&pEnable->Hdr);
@@ -3485,33 +3511,35 @@
 
 
-static int vdmaVBVACtlSubmitSync(PVBOXVDMAHOST pVdma, VBVAEXHOSTCTL* pCtl, VBVAEXHOSTCTL_SOURCE enmSource)
+/**
+ *
+ */
+static int vdmaVBVACtlSubmitSync(PVBOXVDMAHOST pVdma, VBVAEXHOSTCTL *pCtl, VBVAEXHOSTCTL_SOURCE enmSource)
 {
     VDMA_VBVA_CTL_CYNC_COMPLETION Data;
-    Data.rc = VERR_NOT_IMPLEMENTED;
+    Data.rc     = VERR_NOT_IMPLEMENTED;
+    Data.hEvent = NIL_RTSEMEVENT;
     int rc = RTSemEventCreate(&Data.hEvent);
-    if (!RT_SUCCESS(rc))
-    {
+    if (RT_SUCCESS(rc))
+    {
+        rc = vdmaVBVACtlSubmit(pVdma, pCtl, enmSource, vdmaVBVACtlSubmitSyncCompletion, &Data);
+        if (RT_SUCCESS(rc))
+        {
+            rc = RTSemEventWait(Data.hEvent, RT_INDEFINITE_WAIT);
+            if (RT_SUCCESS(rc))
+            {
+                rc = Data.rc;
+                if (!RT_SUCCESS(rc))
+                    WARN(("vdmaVBVACtlSubmitSyncCompletion returned %Rrc\n", rc));
+            }
+            else
+                WARN(("RTSemEventWait failed %Rrc\n", rc));
+        }
+        else
+            Log(("vdmaVBVACtlSubmit failed %Rrc\n", rc));
+
+        RTSemEventDestroy(Data.hEvent);
+    }
+    else
         WARN(("RTSemEventCreate failed %Rrc\n", rc));
-        return rc;
-    }
-
-    rc = vdmaVBVACtlSubmit(pVdma, pCtl, enmSource, vdmaVBVACtlSubmitSyncCompletion, &Data);
-    if (RT_SUCCESS(rc))
-    {
-        rc = RTSemEventWait(Data.hEvent, RT_INDEFINITE_WAIT);
-        if (RT_SUCCESS(rc))
-        {
-            rc = Data.rc;
-            if (!RT_SUCCESS(rc))
-                WARN(("vdmaVBVACtlSubmitSyncCompletion returned %Rrc\n", rc));
-        }
-        else
-            WARN(("RTSemEventWait failed %Rrc\n", rc));
-    }
-    else
-        Log(("vdmaVBVACtlSubmit failed %Rrc\n", rc));
-
-    RTSemEventDestroy(Data.hEvent);
-
     return rc;
 }
@@ -3720,9 +3748,13 @@
  * @param   cbCtl               The size of it.  This is at least
  *                              sizeof(VBOXCMDVBVA_CTL).
+ * @thread  EMT
  */
 int vboxCmdVBVACmdCtl(PVGASTATE pVGAState, VBOXCMDVBVA_CTL RT_UNTRUSTED_VOLATILE_GUEST *pCtl, uint32_t cbCtl)
 {
     struct VBOXVDMAHOST *pVdma = pVGAState->pVdma;
-    switch (pCtl->u32Type)
+    uint32_t uType = pCtl->u32Type;
+    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
+
+    switch (uType)
     {
         case VBOXCMDVBVACTL_TYPE_3DCTL:
@@ -3734,5 +3766,5 @@
         case VBOXCMDVBVACTL_TYPE_ENABLE:
             if (cbCtl == sizeof(VBOXCMDVBVA_CTL_ENABLE))
-                return vdmaVBVACtlEnableDisableSubmit(pVdma, (VBOXCMDVBVA_CTL_ENABLE *)pCtl);
+                return vdmaVBVACtlEnableDisableSubmit(pVdma, (VBOXCMDVBVA_CTL_ENABLE RT_UNTRUSTED_VOLATILE_GUEST *)pCtl);
             WARN(("incorrect enable size\n"));
             break;
@@ -3750,4 +3782,6 @@
 /**
  * Handler for VBVA_CMDVBVA_SUBMIT, see vbvaChannelHandler().
+ *
+ * @thread  EMT
  */
 int vboxCmdVBVACmdSubmit(PVGASTATE pVGAState)
@@ -3764,4 +3798,6 @@
 /**
  * Handler for VBVA_CMDVBVA_FLUSH, see vbvaChannelHandler().
+ *
+ * @thread  EMT
  */
 int vboxCmdVBVACmdFlush(PVGASTATE pVGAState)
@@ -3896,5 +3932,5 @@
     uint8_t * pu8VramBase = pVGAState->vram_ptrR3;
 
-    rc = SSMR3PutU32(pSSM, (uint32_t)(((uint8_t*)pVdma->CmdVbva.pVBVA) - pu8VramBase));
+    rc = SSMR3PutU32(pSSM, (uint32_t)((uintptr_t)pVdma->CmdVbva.pVBVA - (uintptr_t)pu8VramBase));
     AssertRCReturn(rc, rc);
 
@@ -3958,5 +3994,5 @@
 
     /* sanity */
-    pHCtl->u.cmd.pu8Cmd = NULL;
+    pHCtl->u.cmd.pvCmd = NULL;
     pHCtl->u.cmd.cbCmd = 0;
 
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/presenter/server_presenter.cpp
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/presenter/server_presenter.cpp	(revision 71606)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/presenter/server_presenter.cpp	(revision 71607)
@@ -3888,6 +3888,8 @@
 }
 
-int8_t crVBoxServerCrCmdClrFillProcess(const VBOXCMDVBVA_CLRFILL_HDR *pCmd, uint32_t cbCmd)
-{
+/** @todo RT_UNTRUSTED_VOLATILE_GUEST */
+int8_t crVBoxServerCrCmdClrFillProcess(VBOXCMDVBVA_CLRFILL_HDR const RT_UNTRUSTED_VOLATILE_GUEST *pCmdTodo, uint32_t cbCmd)
+{
+    VBOXCMDVBVA_CLRFILL_HDR const *pCmd = (VBOXCMDVBVA_CLRFILL_HDR const *)pCmdTodo;
     uint8_t u8Flags = pCmd->Hdr.u8Flags;
     uint8_t u8Cmd = (VBOXCMDVBVA_OPF_CLRFILL_TYPE_MASK & u8Flags);
@@ -3912,6 +3914,8 @@
 }
 
-int8_t crVBoxServerCrCmdBltProcess(const VBOXCMDVBVA_BLT_HDR *pCmd, uint32_t cbCmd)
-{
+/** @todo RT_UNTRUSTED_VOLATILE_GUEST */
+int8_t crVBoxServerCrCmdBltProcess(VBOXCMDVBVA_BLT_HDR const RT_UNTRUSTED_VOLATILE_GUEST *pCmdTodo, uint32_t cbCmd)
+{
+    VBOXCMDVBVA_BLT_HDR const *pCmd = (VBOXCMDVBVA_BLT_HDR const *)pCmdTodo;
     uint8_t u8Flags = pCmd->Hdr.u8Flags;
     uint8_t u8Cmd = (VBOXCMDVBVA_OPF_BLT_TYPE_MASK & u8Flags);
@@ -3955,6 +3959,8 @@
 }
 
-int8_t crVBoxServerCrCmdFlipProcess(const VBOXCMDVBVA_FLIP *pFlip, uint32_t cbCmd)
-{
+/** @todo RT_UNTRUSTED_VOLATILE_GUEST   */
+int8_t crVBoxServerCrCmdFlipProcess(VBOXCMDVBVA_FLIP const RT_UNTRUSTED_VOLATILE_GUEST *pFlipTodo, uint32_t cbCmd)
+{
+    VBOXCMDVBVA_FLIP const *pFlip = (VBOXCMDVBVA_FLIP const *)pFlipTodo;
     uint32_t hostId;
     const VBOXCMDVBVA_RECT *pPRects = pFlip->aRects;
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h	(revision 71606)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server.h	(revision 71607)
@@ -470,7 +470,7 @@
 void CrFbTexDataInit(CR_TEXDATA* pFbTex, const VBOXVR_TEXTURE *pTex, PFNCRTEXDATA_RELEASED pfnTextureReleased);
 
-int8_t crVBoxServerCrCmdBltProcess(const VBOXCMDVBVA_BLT_HDR *pCmd, uint32_t cbCmd);
-int8_t crVBoxServerCrCmdClrFillProcess(const VBOXCMDVBVA_CLRFILL_HDR *pCmd, uint32_t cbCmd);
-int8_t crVBoxServerCrCmdFlipProcess(const VBOXCMDVBVA_FLIP *pFlip, uint32_t cbCmd);
+int8_t crVBoxServerCrCmdBltProcess(VBOXCMDVBVA_BLT_HDR const RT_UNTRUSTED_VOLATILE_GUEST *pCmd, uint32_t cbCmd);
+int8_t crVBoxServerCrCmdClrFillProcess(VBOXCMDVBVA_CLRFILL_HDR const RT_UNTRUSTED_VOLATILE_GUEST *pCmd, uint32_t cbCmd);
+int8_t crVBoxServerCrCmdFlipProcess(VBOXCMDVBVA_FLIP const RT_UNTRUSTED_VOLATILE_GUEST *pFlip, uint32_t cbCmd);
 
 
Index: /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c
===================================================================
--- /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 71606)
+++ /trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_main.c	(revision 71607)
@@ -34,4 +34,5 @@
 #include <VBox/err.h>
 #include <VBox/log.h>
+#include <VBox/AssertGuest.h>
 
 #ifdef VBOXCR_LOGFPS
@@ -67,5 +68,6 @@
 int tearingdown = 0; /* can't be static */
 
-static DECLCALLBACK(int8_t) crVBoxCrCmdCmd(HVBOXCRCMDSVR hSvr, const VBOXCMDVBVA_HDR *pCmd, uint32_t cbCmd);
+static DECLCALLBACK(int8_t) crVBoxCrCmdCmd(HVBOXCRCMDSVR hSvr,
+                                           const VBOXCMDVBVA_HDR RT_UNTRUSTED_VOLATILE_GUEST *pCmd, uint32_t cbCmd);
 
 DECLINLINE(CRClient*) crVBoxServerClientById(uint32_t u32ClientID)
@@ -2873,6 +2875,8 @@
 #ifdef VBOX_WITH_CRHGSMI
 
-static int32_t crVBoxServerCmdVbvaCrCmdProcess(const struct VBOXCMDVBVA_CRCMD_CMD *pCmd, uint32_t cbCmd)
-{
+/** @todo RT_UNTRUSTED_VOLATILE_GUEST   */
+static int32_t crVBoxServerCmdVbvaCrCmdProcess(VBOXCMDVBVA_CRCMD_CMD const RT_UNTRUSTED_VOLATILE_GUEST *pCmdTodo, uint32_t cbCmd)
+{
+    VBOXCMDVBVA_CRCMD_CMD const *pCmd = (VBOXCMDVBVA_CRCMD_CMD const *)pCmdTodo;
     int32_t rc;
     uint32_t cBuffers = pCmd->cBuffers;
@@ -3233,8 +3237,12 @@
 }
 
-static int crVBoxCrConnectEx(VBOXCMDVBVA_3DCTL_CONNECT *pConnect, uint32_t u32ClientId)
+static int crVBoxCrConnectEx(VBOXCMDVBVA_3DCTL_CONNECT RT_UNTRUSTED_VOLATILE_GUEST *pConnect, uint32_t u32ClientId)
 {
     CRClient *pClient;
     int rc;
+    uint32_t const uMajorVersion = pConnect->u32MajorVersion;
+    uint32_t const uMinorVersion = pConnect->u32MinorVersion;
+    uint64_t const uPid          = pConnect->u64Pid;
+    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
 
     if (u32ClientId == CRHTABLE_HANDLE_INVALID)
@@ -3252,8 +3260,8 @@
     if (RT_SUCCESS(rc))
     {
-        rc = crVBoxServerClientObjSetVersion(pClient, pConnect->u32MajorVersion, pConnect->u32MinorVersion);
+        rc = crVBoxServerClientObjSetVersion(pClient, uMajorVersion, uMinorVersion);
         if (RT_SUCCESS(rc))
         {
-            rc = crVBoxServerClientObjSetPID(pClient, pConnect->u64Pid);
+            rc = crVBoxServerClientObjSetPID(pClient, uPid);
             if (RT_SUCCESS(rc))
             {
@@ -3264,6 +3272,5 @@
                     return VINF_SUCCESS;
                 }
-                else
-                    WARN(("CrHTablePutToSlot failed %d", rc));
+                WARN(("CrHTablePutToSlot failed %d", rc));
             }
             else
@@ -3283,56 +3290,57 @@
 }
 
-static int crVBoxCrConnect(VBOXCMDVBVA_3DCTL_CONNECT *pConnect)
+static int crVBoxCrConnect(VBOXCMDVBVA_3DCTL_CONNECT RT_UNTRUSTED_VOLATILE_GUEST *pConnect)
 {
     return crVBoxCrConnectEx(pConnect, CRHTABLE_HANDLE_INVALID);
 }
 
-static DECLCALLBACK(int) crVBoxCrCmdGuestCtl(HVBOXCRCMDSVR hSvr, uint8_t* pCmd, uint32_t cbCmd)
-{
-    VBOXCMDVBVA_3DCTL *pCtl = (VBOXCMDVBVA_3DCTL*)pCmd;
-    if (cbCmd < sizeof (VBOXCMDVBVA_3DCTL))
-    {
-        WARN(("invalid buffer size"));
-        return VERR_INVALID_PARAMETER;
-    }
-
-    switch (pCtl->u32Type)
-    {
-        case VBOXCMDVBVA3DCTL_TYPE_CONNECT:
-        {
-            if (cbCmd != sizeof (VBOXCMDVBVA_3DCTL_CONNECT))
-            {
-                WARN(("invalid command size"));
-                return VERR_INVALID_PARAMETER;
-            }
-
-            return crVBoxCrConnect((VBOXCMDVBVA_3DCTL_CONNECT*)pCtl);
-        }
-        case VBOXCMDVBVA3DCTL_TYPE_DISCONNECT:
-        {
-            if (cbCmd != sizeof (VBOXCMDVBVA_3DCTL))
-            {
-                WARN(("invalid command size"));
-                return VERR_INVALID_PARAMETER;
-            }
-
-            return crVBoxCrDisconnect(pCtl->u32CmdClientId);
-        }
-        case VBOXCMDVBVA3DCTL_TYPE_CMD:
-        {
-            VBOXCMDVBVA_3DCTL_CMD *p3DCmd;
-            if (cbCmd < sizeof (VBOXCMDVBVA_3DCTL_CMD))
-            {
-                WARN(("invalid size"));
-                return VERR_INVALID_PARAMETER;
-            }
-
-            p3DCmd = (VBOXCMDVBVA_3DCTL_CMD*)pCmd;
-
-            return crVBoxCrCmdCmd(NULL, &p3DCmd->Cmd, cbCmd - RT_OFFSETOF(VBOXCMDVBVA_3DCTL_CMD, Cmd));
-        }
-        default:
-            WARN(("crVBoxCrCmdGuestCtl: invalid function %d", pCtl->u32Type));
-            return VERR_INVALID_PARAMETER;
+/**
+ * @interface_method_impl{VBOXCRCMD_SVRINFO,pfnGuestCtl}
+ */
+static DECLCALLBACK(int) crVBoxCrCmdGuestCtl(HVBOXCRCMDSVR hSvr, uint8_t RT_UNTRUSTED_VOLATILE_GUEST *pbCmd, uint32_t cbCmd)
+{
+    /*
+     * Toplevel input validation.
+     */
+    ASSERT_GUEST_LOGREL_RETURN(cbCmd >= sizeof(VBOXCMDVBVA_3DCTL), VERR_INVALID_PARAMETER);
+    {
+        VBOXCMDVBVA_3DCTL RT_UNTRUSTED_VOLATILE_GUEST *pCtl = (VBOXCMDVBVA_3DCTL RT_UNTRUSTED_VOLATILE_GUEST*)pbCmd;
+        const uint32_t uType = pCtl->u32Type;
+        RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
+
+        ASSERT_GUEST_LOGREL_RETURN(   uType == VBOXCMDVBVA3DCTL_TYPE_CMD
+                                   || uType == VBOXCMDVBVA3DCTL_TYPE_CONNECT
+                                   || uType == VBOXCMDVBVA3DCTL_TYPE_DISCONNECT
+                                   , VERR_INVALID_PARAMETER);
+        RT_UNTRUSTED_VALIDATED_FENCE();
+
+        /*
+         * Call worker abd process the request.
+         */
+        switch (uType)
+        {
+            case VBOXCMDVBVA3DCTL_TYPE_CMD:
+                ASSERT_GUEST_LOGREL_RETURN(cbCmd >= sizeof(VBOXCMDVBVA_3DCTL_CMD), VERR_INVALID_PARAMETER);
+                {
+                    VBOXCMDVBVA_3DCTL_CMD RT_UNTRUSTED_VOLATILE_GUEST *p3DCmd
+                        = (VBOXCMDVBVA_3DCTL_CMD RT_UNTRUSTED_VOLATILE_GUEST *)pbCmd;
+                    return crVBoxCrCmdCmd(NULL, &p3DCmd->Cmd, cbCmd - RT_OFFSETOF(VBOXCMDVBVA_3DCTL_CMD, Cmd));
+                }
+
+            case VBOXCMDVBVA3DCTL_TYPE_CONNECT:
+                ASSERT_GUEST_LOGREL_RETURN(cbCmd == sizeof(VBOXCMDVBVA_3DCTL_CONNECT), VERR_INVALID_PARAMETER);
+                return crVBoxCrConnect((VBOXCMDVBVA_3DCTL_CONNECT RT_UNTRUSTED_VOLATILE_GUEST *)pCtl);
+
+            case VBOXCMDVBVA3DCTL_TYPE_DISCONNECT:
+                ASSERT_GUEST_LOGREL_RETURN(cbCmd == sizeof(VBOXCMDVBVA_3DCTL), VERR_INVALID_PARAMETER);
+                {
+                    uint32_t idClient = pCtl->u32CmdClientId;
+                    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
+                    return crVBoxCrDisconnect(idClient);
+                }
+
+            default:
+                AssertFailedReturn(VERR_IPE_NOT_REACHED_DEFAULT_CASE);
+        }
     }
 }
@@ -3512,66 +3520,50 @@
 
 
-static DECLCALLBACK(int8_t) crVBoxCrCmdCmd(HVBOXCRCMDSVR hSvr, const VBOXCMDVBVA_HDR *pCmd, uint32_t cbCmd)
-{
-    switch (pCmd->u8OpCode)
+/**
+ * @interface_method_impl{VBOXCRCMD_SVRINFO,pfnCmd}
+ */
+static DECLCALLBACK(int8_t) crVBoxCrCmdCmd(HVBOXCRCMDSVR hSvr,
+                                           const VBOXCMDVBVA_HDR RT_UNTRUSTED_VOLATILE_GUEST *pCmd, uint32_t cbCmd)
+{
+    uint8_t bOpcode = pCmd->u8OpCode;
+    RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
+    ASSERT_GUEST_LOGREL_MSG_RETURN(   bOpcode == VBOXCMDVBVA_OPTYPE_CRCMD
+                                   || bOpcode == VBOXCMDVBVA_OPTYPE_FLIP
+                                   || bOpcode == VBOXCMDVBVA_OPTYPE_BLT
+                                   || bOpcode == VBOXCMDVBVA_OPTYPE_CLRFILL,
+                                   ("%#x\n", bOpcode), -1);
+    RT_UNTRUSTED_VALIDATED_FENCE();
+
+    switch (bOpcode)
     {
         case VBOXCMDVBVA_OPTYPE_CRCMD:
-        {
-            const VBOXCMDVBVA_CRCMD *pCrCmdDr;
-            const VBOXCMDVBVA_CRCMD_CMD *pCrCmd;
-            int rc;
-            pCrCmdDr = (const VBOXCMDVBVA_CRCMD*)pCmd;
-            pCrCmd = &pCrCmdDr->Cmd;
-            if (cbCmd < sizeof (VBOXCMDVBVA_CRCMD))
+            ASSERT_GUEST_LOGREL_MSG_RETURN(cbCmd >= sizeof(VBOXCMDVBVA_CRCMD), ("cbCmd=%u\n", cbCmd), -1);
             {
-                WARN(("invalid buffer size"));
-                return -1;
-            }
-            rc = crVBoxServerCmdVbvaCrCmdProcess(pCrCmd, cbCmd - RT_OFFSETOF(VBOXCMDVBVA_CRCMD, Cmd));
-            if (RT_SUCCESS(rc))
-            {
-                /* success */
+                VBOXCMDVBVA_CRCMD const RT_UNTRUSTED_VOLATILE_GUEST *pCrCmdDr
+                    = (VBOXCMDVBVA_CRCMD const RT_UNTRUSTED_VOLATILE_GUEST *)pCmd;
+                VBOXCMDVBVA_CRCMD_CMD const RT_UNTRUSTED_VOLATILE_GUEST *pCrCmd = &pCrCmdDr->Cmd;
+                int rc = crVBoxServerCmdVbvaCrCmdProcess(pCrCmd, cbCmd - RT_OFFSETOF(VBOXCMDVBVA_CRCMD, Cmd));
+                ASSERT_GUEST_LOGREL_RC_RETURN(rc, -1);
                 return 0;
             }
 
-            WARN(("crVBoxServerCmdVbvaCrCmdProcess failed, rc %d", rc));
-            return -1;
-        }
         case VBOXCMDVBVA_OPTYPE_FLIP:
-        {
-            const VBOXCMDVBVA_FLIP *pFlip;
-
-            if (cbCmd < VBOXCMDVBVA_SIZEOF_FLIPSTRUCT_MIN)
+            ASSERT_GUEST_LOGREL_MSG_RETURN(cbCmd >= VBOXCMDVBVA_SIZEOF_FLIPSTRUCT_MIN, ("cbCmd=%u\n", cbCmd), -1);
             {
-                WARN(("invalid buffer size (cbCmd(%u) < sizeof(VBOXCMDVBVA_FLIP)(%u))", cbCmd, sizeof(VBOXCMDVBVA_FLIP)));
-                return -1;
+                VBOXCMDVBVA_FLIP const RT_UNTRUSTED_VOLATILE_GUEST *pFlip
+                    = (VBOXCMDVBVA_FLIP const RT_UNTRUSTED_VOLATILE_GUEST *)pCmd;
+                return crVBoxServerCrCmdFlipProcess(pFlip, cbCmd);
             }
 
-            pFlip = (const VBOXCMDVBVA_FLIP*)pCmd;
-            return crVBoxServerCrCmdFlipProcess(pFlip, cbCmd);
-        }
         case VBOXCMDVBVA_OPTYPE_BLT:
-        {
-            if (cbCmd < sizeof (VBOXCMDVBVA_BLT_HDR))
-            {
-                WARN(("invalid buffer size"));
-                return -1;
-            }
-
-            return crVBoxServerCrCmdBltProcess((const VBOXCMDVBVA_BLT_HDR*)pCmd, cbCmd);
-        }
+            ASSERT_GUEST_LOGREL_MSG_RETURN(cbCmd >= sizeof(VBOXCMDVBVA_BLT_HDR), ("cbCmd=%u\n", cbCmd), -1);
+            return crVBoxServerCrCmdBltProcess((VBOXCMDVBVA_BLT_HDR const RT_UNTRUSTED_VOLATILE_GUEST *)pCmd, cbCmd);
+
         case VBOXCMDVBVA_OPTYPE_CLRFILL:
-        {
-            if (cbCmd < sizeof (VBOXCMDVBVA_CLRFILL_HDR))
-            {
-                WARN(("invalid buffer size"));
-                return -1;
-            }
-
-            return crVBoxServerCrCmdClrFillProcess((const VBOXCMDVBVA_CLRFILL_HDR*)pCmd, cbCmd);
-        }
+            ASSERT_GUEST_LOGREL_MSG_RETURN(cbCmd >= sizeof(VBOXCMDVBVA_CLRFILL_HDR), ("cbCmd=%u\n", cbCmd), -1);
+            return crVBoxServerCrCmdClrFillProcess((VBOXCMDVBVA_CLRFILL_HDR const RT_UNTRUSTED_VOLATILE_GUEST *)pCmd, cbCmd);
+
         default:
-            WARN(("unsupported command"));
-            return -1;
+            AssertFailedReturn(VERR_IPE_NOT_REACHED_DEFAULT_CASE);
     }
     /* not reached */
