Index: /trunk/doc/manual/en_US/man_VBoxManage-modifyvm.xml
===================================================================
--- /trunk/doc/manual/en_US/man_VBoxManage-modifyvm.xml	(revision 92537)
+++ /trunk/doc/manual/en_US/man_VBoxManage-modifyvm.xml	(revision 92538)
@@ -617,4 +617,15 @@
       <arg>--pci-detach=<replaceable>host-PCI-address</replaceable></arg>
     </cmdsynopsis>
+
+    <cmdsynopsis id="synopsis-vboxmanage-modifyvm-testing">
+      <command>VBoxManage modifyvm</command>
+      <group choice="req">
+        <arg choice="plain"><replaceable>uuid</replaceable></arg>
+        <arg choice="plain"><replaceable>vmname</replaceable></arg>
+      </group>
+      <arg>--testing-enabled=<group choice="plain"><arg choice="plain">on</arg><arg choice="plain">off</arg></group></arg>
+      <arg>--testing-mmio=<group choice="plain"><arg choice="plain">on</arg><arg choice="plain">off</arg></group></arg>
+      <arg>--testing-cfg-dword<replaceable>idx</replaceable>=<replaceable>value</replaceable></arg>
+    </cmdsynopsis>
   </refsynopsisdiv>
 
@@ -2652,4 +2663,32 @@
       </variablelist>
     </refsect2>
+    <refsect2 id="vboxmanage-modifyvm-testing">
+      <title>Testing (ValidationKit / Bootsector)</title>
+      <para>
+        These options are for configuring the testing functionality of the VMM
+        device and almost exclusively used by the bootsector testcases in the
+        ValidationKit.
+      </para>
+      <remark role="help-copy-synopsis"/>
+      <variablelist>
+        <varlistentry>
+          <term><option>--testing-enabled=on | off</option></term>
+          <listitem><para>Enabled the testing functionality of the VMMDev. See VMMDevTesting.h for details. </para></listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--testing-mmio=on | off</option></term>
+          <listitem><para>Enabled the MMIO region of the VMMDev testing feature.</para></listitem>
+        </varlistentry>
+        <varlistentry>
+          <term><option>--testing-cfg-dword<replaceable>idx</replaceable>=<replaceable>value</replaceable></option></term>
+          <listitem><para>
+                This sets one of the 10 dword configuration values. The
+                <replaceable>idx</replaceable> must be in the range 0 thru 9.
+                The <replaceable>value</replaceable> is limited to 32 bits (dword).
+            </para></listitem>
+        </varlistentry>
+      </variablelist>
+    </refsect2>
+
   </refsect1>
 
@@ -2672,8 +2711,9 @@
     <title>See Also</title>
     <para>
+      <xref linkend="vboxmanage-showvminfo" />,
       <xref linkend="vboxmanage-controlvm" />,
       <xref linkend="vboxmanage-createvm" />,
-      <xref linkend="vboxmanage-list" />,
       <xref linkend="vboxmanage-startvm" />
+      <xref linkend="vboxmanage-list" />
     </para>
   </refsect1>
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp	(revision 92537)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp	(revision 92538)
@@ -296,5 +296,5 @@
  * react a little slower than in the ideal case).
  */
-HRESULT showProgress(ComPtr<IProgress> progress, unsigned int fFlags)
+HRESULT showProgress(ComPtr<IProgress> progress, uint32_t fFlags)
 {
     using namespace com;
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h	(revision 92537)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h	(revision 92538)
@@ -238,5 +238,4 @@
 RTEXITCODE errorGetOpt(USAGECATEGORY enmCommand, int rc, union RTGETOPTUNION const *pValueUnion);
 RTEXITCODE errorGetOptEx(USAGECATEGORY enmCommand, uint64_t fSubcommandScope, int rc, union RTGETOPTUNION const *pValueUnion);
-RTEXITCODE errorArgument(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
 
 void printUsageInternal(USAGECATEGORY enmCommand, PRTSTREAM pStrm);
@@ -253,12 +252,15 @@
 RTEXITCODE  errorGetOpt(int rcGetOpt, union RTGETOPTUNION const *pValueUnion);
 RTEXITCODE  errorFetchValue(int iValueNo, const char *pszOption, int rcGetOptFetchValue, union RTGETOPTUNION const *pValueUnion);
-RTEXITCODE  errorSyntax(const char *pszFormat, ...);
-
-
-#define SHOW_PROGRESS_NONE      0
-#define SHOW_PROGRESS_DESC      (1u << 0)
-#define SHOW_PROGRESS           (1u << 1)
-#define SHOW_PROGRESS_DETAILS   (1u << 2)
-HRESULT showProgress(ComPtr<IProgress> progress, unsigned int fFlags = SHOW_PROGRESS);
+RTEXITCODE  errorSyntax(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+RTEXITCODE  errorSyntaxV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
+HRESULT     errorSyntaxHr(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+RTEXITCODE  errorArgument(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+HRESULT     errorArgumentHr(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
+
+# define SHOW_PROGRESS_NONE     0
+# define SHOW_PROGRESS_DESC     RT_BIT_32(0)
+# define SHOW_PROGRESS          RT_BIT_32(1)
+# define SHOW_PROGRESS_DETAILS  RT_BIT_32(2)
+HRESULT showProgress(ComPtr<IProgress> progress, uint32_t fFlags = SHOW_PROGRESS);
 #endif
 
@@ -309,6 +311,8 @@
 HRESULT showBandwidthGroups(ComPtr<IBandwidthControl> &bwCtrl,
                             VMINFO_DETAILS details);
-void outputMachineReadableString(const char *pszName, const char *pszValue);
-void outputMachineReadableString(const char *pszName, com::Bstr const *pbstrValue);
+void outputMachineReadableString(const char *pszName, const char *pszValue, bool fQuoteName = false);
+void outputMachineReadableString(const char *pszName, com::Bstr const *pbstrValue, bool fQuoteName = false);
+void outputMachineReadableStringWithFmtName(const char *pszValue, bool fQuoteName, const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR(3, 4);
+void outputMachineReadableStringWithFmtName(com::Bstr const *pbstrValue, bool fQuoteName, const char *pszNameFmt, ...) RT_IPRT_FORMAT_ATTR(3, 4);
 void outputMachineReadableBool(const char *pszName, BOOL const *pfValue);
 void outputMachineReadableBool(const char *pszName, bool const *pfValue);
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 92537)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 92538)
@@ -247,7 +247,7 @@
  * @returns RTEXITCODE_SYNTAX.
  * @param   pszFormat           Custom error message format string.
- * @param   ...                 Format arguments.
- */
-RTEXITCODE errorSyntax(const char *pszFormat, ...)
+ * @param   va                  Format arguments.
+ */
+RTEXITCODE errorSyntaxV(const char *pszFormat, va_list va)
 {
     Assert(g_enmCurCommand != HELP_CMD_VBOXMANAGE_INVALID);
@@ -255,8 +255,8 @@
     showLogo(g_pStdErr);
 
-    va_list va;
-    va_start(va, pszFormat);
-    RTMsgErrorV(pszFormat, va);
-    va_end(va);
+    va_list vaCopy;
+    va_copy(vaCopy, va);
+    RTMsgErrorV(pszFormat, vaCopy);
+    va_end(vaCopy);
 
     RTStrmPutCh(g_pStdErr, '\n');
@@ -266,9 +266,71 @@
         /* Usage was very long, repeat the error message. */
         RTStrmPutCh(g_pStdErr, '\n');
-        va_start(va, pszFormat);
         RTMsgErrorV(pszFormat, va);
-        va_end(va);
     }
     return RTEXITCODE_SYNTAX;
+}
+
+
+/**
+ * Display current (sub)command usage and the custom error message.
+ *
+ * @returns RTEXITCODE_SYNTAX.
+ * @param   pszFormat           Custom error message format string.
+ * @param   ...                 Format arguments.
+ */
+RTEXITCODE errorSyntax(const char *pszFormat, ...)
+{
+    va_list va;
+    va_start(va, pszFormat);
+    RTEXITCODE rcExit = errorSyntaxV(pszFormat, va);
+    va_end(va);
+    return rcExit;
+}
+
+
+/**
+ * Display current (sub)command usage and the custom error message.
+ *
+ * @returns E_INVALIDARG
+ * @param   pszFormat           Custom error message format string.
+ * @param   ...                 Format arguments.
+ */
+HRESULT errorSyntaxHr(const char *pszFormat, ...)
+{
+    va_list va;
+    va_start(va, pszFormat);
+    errorSyntaxV(pszFormat, va);
+    va_end(va);
+    return E_INVALIDARG;
+}
+
+
+/**
+ * Print an error message without the syntax stuff.
+ *
+ * @returns RTEXITCODE_SYNTAX.
+ */
+RTEXITCODE errorArgument(const char *pszFormat, ...)
+{
+    va_list args;
+    va_start(args, pszFormat);
+    RTMsgErrorV(pszFormat, args);
+    va_end(args);
+    return RTEXITCODE_SYNTAX;
+}
+
+
+/**
+ * Print an error message without the syntax stuff.
+ *
+ * @returns E_INVALIDARG.
+ */
+HRESULT errorArgumentHr(const char *pszFormat, ...)
+{
+    va_list args;
+    va_start(args, pszFormat);
+    RTMsgErrorV(pszFormat, args);
+    va_end(args);
+    return E_INVALIDARG;
 }
 
@@ -1060,4 +1122,5 @@
 }
 
+
 /**
  * errorSyntax for RTGetOpt users.
@@ -1074,15 +1137,2 @@
 }
 
-/**
- * Print an error message without the syntax stuff.
- *
- * @returns RTEXITCODE_SYNTAX.
- */
-RTEXITCODE errorArgument(const char *pszFormat, ...)
-{
-    va_list args;
-    va_start(args, pszFormat);
-    RTMsgErrorV(pszFormat, args);
-    va_end(args);
-    return RTEXITCODE_SYNTAX;
-}
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp	(revision 92537)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp	(revision 92538)
@@ -613,4 +613,61 @@
 {
     RTPrintf("%s=\"%llu\"\n", pszName, *puValue);
+}
+
+
+/**
+ * Helper for parsing extra data config.
+ * @returns true, false, or -1 if invalid.
+ */
+static int parseCfgmBool(Bstr const *pbstr)
+{
+    /* GetExtraData returns empty strings if the requested data wasn't
+       found, so fend that off first: */
+    size_t cwcLeft = pbstr->length();
+    if (!cwcLeft)
+        return false;
+    PCRTUTF16 pwch = pbstr->raw();
+
+    /* Skip type prefix: */
+    if (   cwcLeft >= 8
+        && pwch[0] == 'i'
+        && pwch[1] == 'n'
+        && pwch[2] == 't'
+        && pwch[3] == 'e'
+        && pwch[4] == 'g'
+        && pwch[5] == 'e'
+        && pwch[6] == 'r'
+        && pwch[7] == ':')
+    {
+        pwch    += 8;
+        cwcLeft -= 8;
+    }
+
+    /* Hex prefix? */
+    bool fHex = false;
+    if (   cwcLeft >= 2
+        && pwch[0] == '0'
+        && (pwch[1] == 'x' || pwch[1] == 'X'))
+    {
+        pwch    += 2;
+        cwcLeft -= 2;
+        fHex     = true;
+    }
+
+    /* Empty string is wrong: */
+    if (cwcLeft == 0)
+        return -1;
+
+    /* Check that it's all digits and return when we find a non-zero
+       one or reaches the end: */
+    do
+    {
+        RTUTF16 const wc = *pwch++;
+        if (!RT_C_IS_DIGIT(wc) && (!fHex || !RT_C_IS_XDIGIT(wc)))
+            return -1;
+        if (wc != '0')
+            return true;
+    } while (--cwcLeft > 0);
+    return false;
 }
 
@@ -2773,4 +2830,32 @@
     }
 
+    /* VMMDev testing config (extra data) */
+    if (details != VMINFO_MACHINEREADABLE)
+    {
+        Bstr bstr;
+        CHECK_ERROR2I_RET(machine, GetExtraData(Bstr("VBoxInternal/Devices/VMMDev/0/Config/TestingEnabled").raw(),
+                                                bstr.asOutParam()), hrcCheck);
+        int const fEnabled = parseCfgmBool(&bstr);
+
+        CHECK_ERROR2I_RET(machine, GetExtraData(Bstr("VBoxInternal/Devices/VMMDev/0/Config/TestingMMIO").raw(),
+                                                bstr.asOutParam()), hrcCheck);
+        int const fMmio = parseCfgmBool(&bstr);
+        if (fEnabled || fMmio)
+        {
+            RTPrintf("%-28s %s, %s %s\n",
+                     Info::tr("VMMDev Testing"),
+                     fEnabled > 0 ? Info::tr("enabled") : fEnabled == 0 ? Info::tr("disabled") : Info::tr("misconfigured"),
+                     Info::tr("MMIO:"),
+                     fMmio    > 0 ? Info::tr("enabled") : fMmio    == 0 ? Info::tr("disabled") : Info::tr("misconfigured"));
+            for (uint32_t i = 0; i < 10; i++)
+            {
+                BstrFmt bstrName("VBoxInternal/Devices/VMMDev/0/Config/TestingCfgDword%u", i);
+                CHECK_ERROR2I_RET(machine, GetExtraData(bstrName.raw(), bstr.asOutParam()), hrcCheck);
+                if (bstr.isNotEmpty())
+                    RTPrintf("%-28s %ls\n", FmtNm(szNm, "VMMDev Testing Cfg Dword%u:", i), bstr.raw());
+            }
+        }
+    }
+
     /*
      * Snapshots.
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp	(revision 92537)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp	(revision 92538)
@@ -249,5 +249,8 @@
 #endif
     MODIFYVM_DEFAULTFRONTEND,
-    MODIFYVM_VMPROC_PRIORITY
+    MODIFYVM_VMPROC_PRIORITY,
+    MODIFYVM_TESTING_ENABLED,
+    MODIFYVM_TESTING_MMIO,
+    MODIFYVM_TESTING_CFG_DWORD,
 };
 
@@ -452,4 +455,7 @@
     OPT2("--default-frontend",              "--defaultfrontend",        MODIFYVM_DEFAULTFRONTEND,           RTGETOPT_REQ_STRING),
     OPT1("--vm-process-priority",                                       MODIFYVM_VMPROC_PRIORITY,           RTGETOPT_REQ_STRING),
+    OPT1("--testing-enabled",                                           MODIFYVM_TESTING_ENABLED,           RTGETOPT_REQ_BOOL_ONOFF),
+    OPT1("--testing-mmio",                                              MODIFYVM_TESTING_MMIO,              RTGETOPT_REQ_BOOL_ONOFF),
+    OPT1("--testing-cfg-dword",                                         MODIFYVM_TESTING_CFG_DWORD,         RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX),
 };
 
@@ -458,4 +464,27 @@
     RTStrmPrintf(g_pStdErr, ModifyVM::tr("Warning: '--vrdp%s' is deprecated. Use '--vrde%s'.\n"), pszOption, pszOption);
 }
+
+
+/**
+ * Wrapper around IMachine::SetExtraData that does the error reporting.
+ *
+ * @returns COM result code.
+ * @param   rSessionMachine The IMachine.
+ * @param   pszVariable     The variable to set.
+ * @param   pszValue        The value to set.  To delete pass empty string, not
+ *                          NULL.
+ */
+static HRESULT setExtraData(ComPtr<IMachine> &rSessionMachine, const char *pszVariable, const char *pszValue)
+{
+    HRESULT hrc = rSessionMachine->SetExtraData(Bstr(pszVariable).raw(), Bstr(pszValue).raw());
+    if (FAILED(hrc))
+    {
+        char *pszContext = RTStrAPrintf2(ModifyVM::tr("IMachine::SetExtraData('%s', '%s')"), pszVariable, pszValue);
+        com::GlueHandleComError(rSessionMachine, pszContext, hrc, __FILE__, __LINE__);
+        RTStrFree(pszContext);
+    }
+    return hrc;
+}
+
 
 #ifdef VBOX_WITH_PCI_PASSTHROUGH
@@ -3413,10 +3442,31 @@
             }
 
+            case MODIFYVM_TESTING_ENABLED:
+                rc = setExtraData(sessionMachine, "VBoxInternal/Devices/VMMDev/0/Config/TestingEnabled", ValueUnion.f ? "1" : "");
+                break;
+
+            case MODIFYVM_TESTING_MMIO:
+                rc = setExtraData(sessionMachine, "VBoxInternal/Devices/VMMDev/0/Config/TestingMMIO", ValueUnion.f ? "1" : "");
+                break;
+
+            case MODIFYVM_TESTING_CFG_DWORD:
+                if (GetOptState.uIndex <= 9)
+                {
+                    char szVar[128];
+                    RTStrPrintf(szVar, sizeof(szVar), "VBoxInternal/Devices/VMMDev/0/Config/TestingCfgDword%u",
+                                GetOptState.uIndex);
+                    char szValue[32];
+                    RTStrPrintf(szValue, sizeof(szValue), "%u", ValueUnion.u32);
+                    rc = setExtraData(sessionMachine, szVar, szValue);
+                }
+                else
+                    rc = errorArgumentHr(ModifyVM::tr("--testing-cfg-dword index %u is out of range: 0 thru 9"),
+                                         GetOptState.uIndex);
+                break;
+
             default:
-            {
                 errorGetOpt(USAGE_MODIFYVM, c, &ValueUnion);
                 rc = E_FAIL;
                 break;
-            }
         }
     }
