Index: /trunk/doc/manual/en_US/user_Networking.xml
===================================================================
--- /trunk/doc/manual/en_US/user_Networking.xml	(revision 41841)
+++ /trunk/doc/manual/en_US/user_Networking.xml	(revision 41842)
@@ -770,3 +770,28 @@
       </footnote></para>
   </sect1>
+
+  <sect1 id="network_bandwidth_limit">
+    <title>Limiting bandwidth for network I/O</title>
+
+    <para>Starting with version 4.2, VirtualBox allows for limiting the
+    maximum bandwidth used for network transmission. Several network adapters
+    of one VM may share limits through bandwidth groups. It is possible
+    to have more than one such limit.</para>
+
+    <para>Limits are configured through
+    <computeroutput>VBoxManage</computeroutput>. The example below creates a
+    bandwidth group named "Limit", sets the limit to 20 Mbit/s and assigns the
+    group to the first and second adapters of the VM:<screen>VBoxManage bandwidthctl "VM name" add Limit --type network --limit 20m
+VBoxManage modifyvm "VM name" --nicbandwidthgroup1 Limit
+VBoxManage modifyvm "VM name" --nicbandwidthgroup2 Limit</screen></para>
+
+    <para>All adapters in a group share the bandwidth limit, meaning that in the
+    example above the bandwidth of both adapters combined can never exceed 20
+    Mbit/s. However, if one disk doesn't require bandwidth the other can use the
+    remaining bandwidth of its group.</para>
+
+    <para>The limits for each group can be changed while the VM is running,
+    with changes being picked up immediately. The example below changes the
+    limit for the group created in the example above to 100 Kbit/s:<screen>VBoxManage bandwidthctl "VM name" set Limit --limit 100k</screen></para>
+  </sect1>
 </chapter>
Index: /trunk/doc/manual/user_ChangeLogImpl.xml
===================================================================
--- /trunk/doc/manual/user_ChangeLogImpl.xml	(revision 41841)
+++ /trunk/doc/manual/user_ChangeLogImpl.xml	(revision 41842)
@@ -20,4 +20,9 @@
       <listitem>
         <para>GUI: network operations manager</para>
+      </listitem>
+
+      <listitem>
+        <para>Resource control: added support for limiting network IO
+          bandwidth; see <xref linkend="network_bandwidth_limit" /></para>
       </listitem>
 
Index: /trunk/include/VBox/settings.h
===================================================================
--- /trunk/include/VBox/settings.h	(revision 41841)
+++ /trunk/include/VBox/settings.h	(revision 41842)
@@ -670,5 +670,5 @@
 {
     BandwidthGroup()
-        : cMaxMbPerSec(0),
+        : cMaxBytesPerSec(0),
           enmType(BandwidthGroupType_Null)
     {}
@@ -677,10 +677,10 @@
     {
         return (   (strName      == i.strName)
-                && (cMaxMbPerSec == i.cMaxMbPerSec)
+                && (cMaxBytesPerSec == i.cMaxBytesPerSec)
                 && (enmType      == i.enmType));
     }
 
     com::Utf8Str         strName;
-    uint32_t             cMaxMbPerSec;
+    uint64_t             cMaxBytesPerSec;
     BandwidthGroupType_T enmType;
 };
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageBandwidthControl.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageBandwidthControl.cpp	(revision 41841)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageBandwidthControl.cpp	(revision 41842)
@@ -44,4 +44,52 @@
 
 /**
+ * Parses a string in the following format "n[k|m|g|K|M|G]". Stores the value
+ * of n expressed in bytes to *pLimit. k meas kilobit, while K means kilobyte.
+ *
+ * @returns Error message or NULL if successful.
+ * @param   pcszLimit       The string to parse.
+ * @param   pLimit          Where to store the result.
+ */
+static const char *parseLimit(const char *pcszLimit, LONG64 *pLimit)
+{
+    int iMultiplier = _1M;
+    char *pszNext = NULL;
+    int rc = RTStrToInt64Ex(pcszLimit, &pszNext, 10, pLimit);
+
+    switch (rc)
+    {
+        case VINF_SUCCESS:
+            break;
+        case VWRN_NUMBER_TOO_BIG:
+            return "Limit is too big\n";
+        case VWRN_TRAILING_CHARS:
+            switch (*pszNext)
+            {
+                case 'G': iMultiplier = _1G;       break;
+                case 'M': iMultiplier = _1M;       break;
+                case 'K': iMultiplier = _1K;       break;
+                case 'g': iMultiplier = 125000000; break;
+                case 'm': iMultiplier = 125000;    break;
+                case 'k': iMultiplier = 125;       break;
+                default:  return "Invalid unit suffix. Valid suffixes are: k, m, g, K, M, G\n";
+            }
+            break;
+        case VWRN_TRAILING_SPACES:
+            return "Trailing spaces in limit!\n";
+        case VERR_NO_DIGITS:
+            return "No digits in limit specifier\n";
+        default:
+            return "Invalid limit specifier\n";
+    }
+    if (*pLimit <= 0)
+        return "Limit must be positive\n";
+    if (*pLimit > INT64_MAX / iMultiplier)
+        return "Limit is too big\n";
+    *pLimit *= iMultiplier;
+
+    return NULL;
+}
+
+/**
  * Handles the 'bandwidthctl myvm add' sub-command.
  * @returns Exit code.
@@ -55,5 +103,5 @@
         {
             { "--type",   't', RTGETOPT_REQ_STRING },
-            { "--limit",  'l', RTGETOPT_REQ_UINT32 }
+            { "--limit",  'l', RTGETOPT_REQ_STRING }
         };
 
@@ -61,5 +109,5 @@
     Bstr name(a->argv[2]);
     const char *pszType  = NULL;
-    ULONG cMaxMbPerSec   = UINT32_MAX;
+    LONG64 cMaxBytesPerSec   = INT64_MAX;
 
     int c;
@@ -85,5 +133,15 @@
             case 'l': // limit
             {
-                cMaxMbPerSec = ValueUnion.u32;
+                if (ValueUnion.psz)
+                {
+                    const char *pcszError = parseLimit(ValueUnion.psz, &cMaxBytesPerSec);
+                    if (pcszError)
+                    {
+                        errorArgument(pcszError);
+                        return RTEXITCODE_FAILURE;
+                    }
+                }
+                else
+                    rc = E_FAIL;
                 break;
             }
@@ -110,5 +168,5 @@
     }
     
-    CHECK_ERROR2_RET(bwCtrl, CreateBandwidthGroup(name.raw(), enmType, cMaxMbPerSec), RTEXITCODE_FAILURE);
+    CHECK_ERROR2_RET(bwCtrl, CreateBandwidthGroup(name.raw(), enmType, cMaxBytesPerSec), RTEXITCODE_FAILURE);
 
     return RTEXITCODE_SUCCESS;
@@ -126,10 +184,10 @@
     static const RTGETOPTDEF g_aBWCtlAddOptions[] =
         {
-            { "--limit",  'l', RTGETOPT_REQ_UINT32 }
+            { "--limit",  'l', RTGETOPT_REQ_STRING }
         };
 
 
     Bstr name(a->argv[2]);
-    ULONG cMaxMbPerSec   = UINT32_MAX;
+    LONG64 cMaxBytesPerSec   = INT64_MAX;
 
     int c;
@@ -146,5 +204,15 @@
             case 'l': // limit
             {
-                cMaxMbPerSec = ValueUnion.u32;
+                if (ValueUnion.psz)
+                {
+                    const char *pcszError = parseLimit(ValueUnion.psz, &cMaxBytesPerSec);
+                    if (pcszError)
+                    {
+                        errorArgument(pcszError);
+                        return RTEXITCODE_FAILURE;
+                    }
+                }
+                else
+                    rc = E_FAIL;
                 break;
             }
@@ -160,10 +228,10 @@
 
     
-    if (cMaxMbPerSec != UINT32_MAX)
+    if (cMaxBytesPerSec != INT64_MAX)
     {
         ComPtr<IBandwidthGroup> bwGroup;
         CHECK_ERROR2_RET(bwCtrl, GetBandwidthGroup(name.raw(), bwGroup.asOutParam()), RTEXITCODE_FAILURE);
         if (SUCCEEDED(rc))
-            CHECK_ERROR2_RET(bwGroup, COMSETTER(MaxMbPerSec)(cMaxMbPerSec), RTEXITCODE_FAILURE);
+            CHECK_ERROR2_RET(bwGroup, COMSETTER(MaxBytesPerSec)(cMaxBytesPerSec), RTEXITCODE_FAILURE);
     }
 
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 41841)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp	(revision 41842)
@@ -514,8 +514,9 @@
         RTStrmPrintf(pStrm,
                      "VBoxManage bandwidthctl     <uuid|vmname>\n"
-                     "                            add <name> --type <disk|network> --limit <megabytes per second> |\n"
-                     "                            set <name> --limit <megabytes per second> |\n"
+                     "                            add <name> --type disk|network --limit <megabytes per second>[k|m|g|K|M|G] |\n"
+                     "                            set <name> --limit <megabytes per second>[k|m|g|K|M|G] |\n"
                      "                            remove <name> |\n"
                      "                            list [--machinereadable]\n"
+                     "                            (limit units: k=kilobit, m=megabit, g=gigabit, K=kilobyte, M=megabyte, G=gigabyte)\n"
                      "\n");
 
Index: /trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp
===================================================================
--- /trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp	(revision 41841)
+++ /trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp	(revision 41842)
@@ -260,16 +260,62 @@
     {
         Bstr strName;
-        ULONG cMaxMbPerSec;
+        LONG64 cMaxBytesPerSec;
         BandwidthGroupType_T enmType;
 
         CHECK_ERROR_RET(bwGroups[i], COMGETTER(Name)(strName.asOutParam()), rc);
         CHECK_ERROR_RET(bwGroups[i], COMGETTER(Type)(&enmType), rc);
-        CHECK_ERROR_RET(bwGroups[i], COMGETTER(MaxMbPerSec)(&cMaxMbPerSec), rc);
+        CHECK_ERROR_RET(bwGroups[i], COMGETTER(MaxBytesPerSec)(&cMaxBytesPerSec), rc);
 
         const char *pszType = bwGroupTypeToString(enmType);
         if (details == VMINFO_MACHINEREADABLE)
-            RTPrintf("BandwidthGroup%zu=%ls,%s,%d\n", i, strName.raw(), pszType, cMaxMbPerSec);
+            RTPrintf("BandwidthGroup%zu=%ls,%s,%lld\n", i, strName.raw(), pszType, cMaxBytesPerSec);
         else
-            RTPrintf("Name: '%ls', Type: %s, Limit: %d Mbytes/sec\n", strName.raw(), pszType, cMaxMbPerSec);
+        {
+            const char *pszUnits = "";
+            LONG64 cBytes = cMaxBytesPerSec;
+            if (!(cBytes % _1G))
+            {
+                pszUnits = "G";
+                cBytes /= _1G;
+            }
+            else if (!(cBytes % _1M))
+            {
+                pszUnits = "M";
+                cBytes /= _1M;
+            }
+            else if (!(cBytes % _1K))
+            {
+                pszUnits = "K";
+                cBytes /= _1K;
+            }
+            const char *pszNetUnits = NULL;
+            if (enmType == BandwidthGroupType_Network)
+            {
+                /*
+                 * We want to report network rate limit in bits/s, not bytes.
+                 * Only if it cannot be express it in kilobits we will fall
+                 * back to reporting it in bytes.
+                 */
+                LONG64 cBits = cMaxBytesPerSec;
+                if (!(cBits % 125))
+                {
+                    cBits /= 125;
+                    pszNetUnits = "k";
+                    if (!(cBits % 1000000))
+                    {
+                        cBits /= 1000000;
+                        pszNetUnits = "g";
+                    }
+                    else if (!(cBits % 1000))
+                    {
+                        cBits /= 1000;
+                        pszNetUnits = "m";
+                    }
+                    RTPrintf("Name: '%ls', Type: %s, Limit: %lld %sbits/sec (%lld %sbytes/sec)\n", strName.raw(), pszType, cBits, pszNetUnits, cBytes, pszUnits);
+                }
+            }
+            if (!pszNetUnits)
+                RTPrintf("Name: '%ls', Type: %s, Limit: %lld %sbytes/sec\n", strName.raw(), pszType, cBytes, pszUnits);
+        }
     }
     if (details != VMINFO_MACHINEREADABLE)
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 41841)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 41842)
@@ -16495,6 +16495,6 @@
     </attribute>
 
-    <attribute name="maxMbPerSec" type="unsigned long">
-      <desc>The maximum number of MBytes which can be transfered by all
+    <attribute name="maxBytesPerSec" type="long long">
+      <desc>The maximum number of bytes which can be transfered by all
         entities attached to this group during one second.</desc>
     </attribute>
@@ -16533,6 +16533,6 @@
         <desc>The type of the bandwidth group (network or disk).</desc>
       </param>
-      <param name="maxMbPerSec" type="unsigned long" dir="in">
-        <desc>The maximum number of MBytes which can be transfered by all
+      <param name="maxBytesPerSec" type="long long" dir="in">
+        <desc>The maximum number of bytes which can be transfered by all
           entities attached to this group during one second.</desc>
       </param>
Index: /trunk/src/VBox/Main/include/BandwidthControlImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/BandwidthControlImpl.h	(revision 41841)
+++ /trunk/src/VBox/Main/include/BandwidthControlImpl.h	(revision 41842)
@@ -52,5 +52,5 @@
     void uninit();
 
-    STDMETHOD(CreateBandwidthGroup) (IN_BSTR aName, BandwidthGroupType_T aType, ULONG aMaxMbPerSec);
+    STDMETHOD(CreateBandwidthGroup) (IN_BSTR aName, BandwidthGroupType_T aType, LONG64 aMaxBytesPerSec);
     STDMETHOD(DeleteBandwidthGroup) (IN_BSTR aName);
     STDMETHOD(COMGETTER(NumGroups)) (ULONG *aGroups);
Index: /trunk/src/VBox/Main/include/BandwidthGroupImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/BandwidthGroupImpl.h	(revision 41841)
+++ /trunk/src/VBox/Main/include/BandwidthGroupImpl.h	(revision 41842)
@@ -44,5 +44,5 @@
                  const Utf8Str &aName,
                  BandwidthGroupType_T aType,
-                 ULONG aMaxMbPerSec);
+                 LONG64 aMaxBytesPerSec);
     HRESULT init(BandwidthControl *aParent, BandwidthGroup *aThat, bool aReshare = false);
     HRESULT initCopy(BandwidthControl *aParent, BandwidthGroup *aThat);
@@ -55,6 +55,6 @@
     STDMETHOD(COMGETTER(Type))(BandwidthGroupType_T *aType);
     STDMETHOD(COMGETTER(Reference))(ULONG *aReferences);
-    STDMETHOD(COMGETTER(MaxMbPerSec))(ULONG *aMaxMbPerSec);
-    STDMETHOD(COMSETTER(MaxMbPerSec))(ULONG aMaxMbPerSec);
+    STDMETHOD(COMGETTER(MaxBytesPerSec))(LONG64 *aMaxBytesPerSec);
+    STDMETHOD(COMSETTER(MaxBytesPerSec))(LONG64 aMaxBytesPerSec);
 
     // public methods only for internal purposes
@@ -65,5 +65,5 @@
     const Utf8Str &getName() const;
     BandwidthGroupType_T getType() const;
-    ULONG getMaxMbPerSec() const;
+    LONG64 getMaxBytesPerSec() const;
     ULONG getReferences() const;
 
Index: /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 41841)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl.cpp	(revision 41842)
@@ -5158,10 +5158,10 @@
         {
             /* No need to call in the EMT thread. */
-            ULONG cMax;
+            LONG64 cMax;
             Bstr strName;
             BandwidthGroupType_T enmType;
             rc = aBandwidthGroup->COMGETTER(Name)(strName.asOutParam());
             if (SUCCEEDED(rc))
-                rc = aBandwidthGroup->COMGETTER(MaxMbPerSec)(&cMax);
+                rc = aBandwidthGroup->COMGETTER(MaxBytesPerSec)(&cMax);
             if (SUCCEEDED(rc))
                 rc = aBandwidthGroup->COMGETTER(Type)(&enmType);
@@ -5172,9 +5172,9 @@
                 if (enmType == BandwidthGroupType_Disk)
                     vrc = PDMR3AsyncCompletionBwMgrSetMaxForFile(ptrVM, Utf8Str(strName).c_str(),
-                                                                 cMax * _1M);
+                                                                 cMax);
 #ifdef VBOX_WITH_NETSHAPER
                 else if (enmType == BandwidthGroupType_Network)
                     vrc = PDMR3NsBwGroupSetLimit(ptrVM, Utf8Str(strName).c_str(),
-                                                                 cMax * 1000);
+                                                 cMax);
                 else
                     rc = E_NOTIMPL;
Index: /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 41841)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 41842)
@@ -1032,10 +1032,10 @@
         {
             Bstr strName;
-            ULONG cMaxMbPerSec;
+            LONG64 cMaxBytesPerSec;
             BandwidthGroupType_T enmType;
 
             hrc = bwGroups[i]->COMGETTER(Name)(strName.asOutParam());                       H();
             hrc = bwGroups[i]->COMGETTER(Type)(&enmType);                                   H();
-            hrc = bwGroups[i]->COMGETTER(MaxMbPerSec)(&cMaxMbPerSec);                       H();
+            hrc = bwGroups[i]->COMGETTER(MaxBytesPerSec)(&cMaxBytesPerSec);                       H();
 
             if (enmType == BandwidthGroupType_Disk)
@@ -1043,6 +1043,6 @@
                 PCFGMNODE pBwGroup;
                 InsertConfigNode(pAcFileBwGroups, Utf8Str(strName).c_str(), &pBwGroup);
-                InsertConfigInteger(pBwGroup, "Max", cMaxMbPerSec * _1M);
-                InsertConfigInteger(pBwGroup, "Start", cMaxMbPerSec * _1M);
+                InsertConfigInteger(pBwGroup, "Max", cMaxBytesPerSec);
+                InsertConfigInteger(pBwGroup, "Start", cMaxBytesPerSec);
                 InsertConfigInteger(pBwGroup, "Step", 0);
             }
@@ -1053,5 +1053,5 @@
                 PCFGMNODE pBwGroup;
                 InsertConfigNode(pNetworkBwGroups, Utf8Str(strName).c_str(), &pBwGroup);
-                InsertConfigInteger(pBwGroup, "Max", cMaxMbPerSec * 1000); // @todo: _1M);
+                InsertConfigInteger(pBwGroup, "Max", cMaxBytesPerSec);
             }
 #endif /* VBOX_WITH_NETSHAPER */
Index: /trunk/src/VBox/Main/src-server/BandwidthControlImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/BandwidthControlImpl.cpp	(revision 41841)
+++ /trunk/src/VBox/Main/src-server/BandwidthControlImpl.cpp	(revision 41842)
@@ -410,5 +410,5 @@
 }
 
-STDMETHODIMP BandwidthControl::CreateBandwidthGroup(IN_BSTR aName, BandwidthGroupType_T aType, ULONG aMaxMbPerSec)
+STDMETHODIMP BandwidthControl::CreateBandwidthGroup(IN_BSTR aName, BandwidthGroupType_T aType, LONG64 aMaxBytesPerSec)
 {
     AutoCaller autoCaller(this);
@@ -432,5 +432,5 @@
     group.createObject();
 
-    rc = group->init(this, aName, aType, aMaxMbPerSec);
+    rc = group->init(this, aName, aType, aMaxBytesPerSec);
     if (FAILED(rc)) return rc;
 
@@ -537,5 +537,5 @@
     {
         const settings::BandwidthGroup &gr = *it;
-        rc = CreateBandwidthGroup(Bstr(gr.strName).raw(), gr.enmType, gr.cMaxMbPerSec);
+        rc = CreateBandwidthGroup(Bstr(gr.strName).raw(), gr.enmType, gr.cMaxBytesPerSec);
         if (FAILED(rc)) break;
     }
@@ -562,5 +562,5 @@
         group.strName      = (*it)->getName();
         group.enmType      = (*it)->getType();
-        group.cMaxMbPerSec = (*it)->getMaxMbPerSec();
+        group.cMaxBytesPerSec = (*it)->getMaxBytesPerSec();
 
         data.llBandwidthGroups.push_back(group);
Index: /trunk/src/VBox/Main/src-server/BandwidthGroupImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/BandwidthGroupImpl.cpp	(revision 41841)
+++ /trunk/src/VBox/Main/src-server/BandwidthGroupImpl.cpp	(revision 41842)
@@ -35,5 +35,5 @@
     BackupableBandwidthGroupData()
         : enmType(BandwidthGroupType_Null),
-          aMaxMbPerSec(0),
+          aMaxBytesPerSec(0),
           cReferences(0)
     { }
@@ -41,5 +41,5 @@
     Utf8Str                 strName;
     BandwidthGroupType_T    enmType;
-    ULONG                   aMaxMbPerSec;
+    LONG64                  aMaxBytesPerSec;
     ULONG                   cReferences;
 };
@@ -87,5 +87,5 @@
                              const Utf8Str &aName,
                              BandwidthGroupType_T aType,
-                             ULONG aMaxMbPerSec)
+                             LONG64 aMaxBytesPerSec)
 {
     LogFlowThisFunc(("aParent=%p aName=\"%s\"\n",
@@ -111,5 +111,5 @@
     m->bd->enmType = aType;
     m->bd->cReferences = 0;
-    m->bd->aMaxMbPerSec = aMaxMbPerSec;
+    m->bd->aMaxBytesPerSec = aMaxBytesPerSec;
 
     /* Confirm a successful initialization */
@@ -268,7 +268,7 @@
 }
 
-STDMETHODIMP BandwidthGroup::COMGETTER(MaxMbPerSec)(ULONG *aMaxMbPerSec)
-{
-    CheckComArgOutPointerValid(aMaxMbPerSec);
+STDMETHODIMP BandwidthGroup::COMGETTER(MaxBytesPerSec)(LONG64 *aMaxBytesPerSec)
+{
+    CheckComArgOutPointerValid(aMaxBytesPerSec);
 
     AutoCaller autoCaller(this);
@@ -277,10 +277,10 @@
     AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
 
-    *aMaxMbPerSec = m->bd->aMaxMbPerSec;
-
-    return S_OK;
-}
-
-STDMETHODIMP BandwidthGroup::COMSETTER(MaxMbPerSec)(ULONG aMaxMbPerSec)
+    *aMaxBytesPerSec = m->bd->aMaxBytesPerSec;
+
+    return S_OK;
+}
+
+STDMETHODIMP BandwidthGroup::COMSETTER(MaxBytesPerSec)(LONG64 aMaxBytesPerSec)
 {
     AutoCaller autoCaller(this);
@@ -290,5 +290,5 @@
 
     m->bd.backup();
-    m->bd->aMaxMbPerSec = aMaxMbPerSec;
+    m->bd->aMaxBytesPerSec = aMaxBytesPerSec;
 
     /* inform direct session if any. */
@@ -392,7 +392,7 @@
 }
 
-ULONG BandwidthGroup::getMaxMbPerSec() const
-{
-    return m->bd->aMaxMbPerSec;
+LONG64 BandwidthGroup::getMaxBytesPerSec() const
+{
+    return m->bd->aMaxBytesPerSec;
 }
 
Index: /trunk/src/VBox/Main/xml/Settings.cpp
===================================================================
--- /trunk/src/VBox/Main/xml/Settings.cpp	(revision 41841)
+++ /trunk/src/VBox/Main/xml/Settings.cpp	(revision 41842)
@@ -2796,5 +2796,9 @@
                         throw ConfigFileError(this, pelmBandwidthGroup, N_("Missing BandwidthGroup/@type attribute"));
 
-                    pelmBandwidthGroup->getAttributeValue("maxMbPerSec", gr.cMaxMbPerSec);
+                    if (!pelmBandwidthGroup->getAttributeValue("maxBytesPerSec", gr.cMaxBytesPerSec))
+                    {
+                        pelmBandwidthGroup->getAttributeValue("maxMbPerSec", gr.cMaxBytesPerSec);
+                        gr.cMaxBytesPerSec *= _1M;
+                    }
                     hw.ioSettings.llBandwidthGroups.push_back(gr);
                 }
@@ -4029,5 +4033,8 @@
                 }
                 pelmThis->setAttribute("type", pcszType);
-                pelmThis->setAttribute("maxMbPerSec", gr.cMaxMbPerSec);
+                if (m->sv >= SettingsVersion_v1_13)
+                    pelmThis->setAttribute("maxBytesPerSec", gr.cMaxBytesPerSec);
+                else
+                    pelmThis->setAttribute("maxMbPerSec", gr.cMaxBytesPerSec / _1M);
             }
         }
@@ -4665,4 +4672,21 @@
     }
 
+    if (m->sv < SettingsVersion_v1_13)
+    {
+        // VirtualBox 4.2 changes the units for bandwidth group limits.
+        for (BandwidthGroupList::const_iterator it = hardwareMachine.ioSettings.llBandwidthGroups.begin();
+             it != hardwareMachine.ioSettings.llBandwidthGroups.end();
+             ++it)
+        {
+            const BandwidthGroup &gr = *it;
+            if (gr.cMaxBytesPerSec % _1M)
+            {
+                // Bump version if a limit cannot be expressed in megabytes
+                m->sv = SettingsVersion_v1_13;
+                break;
+            }
+        }
+    }
+
     if (m->sv < SettingsVersion_v1_12)
     {
