Index: /trunk/src/VBox/Devices/Parallel/DevParallel.cpp
===================================================================
--- /trunk/src/VBox/Devices/Parallel/DevParallel.cpp	(revision 23988)
+++ /trunk/src/VBox/Devices/Parallel/DevParallel.cpp	(revision 23989)
@@ -561,9 +561,20 @@
 #ifdef IN_RING3
 /**
- * Saves a state of the serial port device.
- *
- * @returns VBox status code.
- * @param   pDevIns     The device instance.
- * @param   pSSMHandle  The handle to save the state to.
+ * @copydoc FNSSMDEVLIVEEXEC
+ */
+static DECLCALLBACK(int) parallelLiveExec(PPDMDEVINS pDevIns,
+                                          PSSMHANDLE pSSMHandle,
+                                          uint32_t uPass)
+{
+    ParallelState *pThis = PDMINS_2_DATA(pDevIns, ParallelState *);
+
+    SSMR3PutS32(pSSMHandle, pThis->irq);
+    SSMR3PutU32(pSSMHandle, pThis->base);
+    SSMR3PutU32(pSSMHandle, ~0); /* sanity/terminator */
+    return VINF_SSM_DONT_CALL_AGAIN;
+}
+
+/**
+ * @copydoc FNSSMDEVSAVEEXEC
  */
 static DECLCALLBACK(int) parallelSaveExec(PPDMDEVINS pDevIns,
@@ -575,18 +586,11 @@
     SSMR3PutU8(pSSMHandle, pThis->reg_status);
     SSMR3PutU8(pSSMHandle, pThis->reg_control);
-    SSMR3PutS32(pSSMHandle, pThis->irq);
-    SSMR3PutU32(pSSMHandle, pThis->base);
-
-    return SSMR3PutU32(pSSMHandle, ~0); /* sanity/terminator */
-}
-
-/**
- * Loads a saved serial port device state.
- *
- * @returns VBox status code.
- * @param   pDevIns     The device instance.
- * @param   pSSMHandle  The handle to the saved state.
- * @param   uVersion    The data unit version number.
- * @param   uPass       The data pass.
+
+    parallelLiveExec(pDevIns, pSSMHandle, 0);
+    return VINF_SUCCESS;
+}
+
+/**
+ * @copydoc FNSSMDEVLOADEXEC
  */
 static DECLCALLBACK(int) parallelLoadExec(PPDMDEVINS pDevIns,
@@ -599,11 +603,16 @@
     AssertMsgReturn(uVersion == PARALLEL_SAVED_STATE_VERSION, ("%d\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
     Assert(uPass == SSM_PASS_FINAL); NOREF(uPass);
-
-    SSMR3GetU8(pSSMHandle, &pThis->reg_data);
-    SSMR3GetU8(pSSMHandle, &pThis->reg_status);
-    SSMR3GetU8(pSSMHandle, &pThis->reg_control);
-    SSMR3GetS32(pSSMHandle, &pThis->irq);
-    SSMR3GetU32(pSSMHandle, &pThis->base);
-
+    if (uPass == SSM_PASS_FINAL)
+    {
+        SSMR3GetU8(pSSMHandle, &pThis->reg_data);
+        SSMR3GetU8(pSSMHandle, &pThis->reg_status);
+        SSMR3GetU8(pSSMHandle, &pThis->reg_control);
+    }
+
+    /* the config */
+    int32_t  iIrq;
+    SSMR3GetS32(pSSMHandle, &iIrq);
+    uint32_t uIoBase;
+    SSMR3GetU32(pSSMHandle, &uIoBase);
     uint32_t u32;
     int rc = SSMR3GetU32(pSSMHandle, &u32);
@@ -611,4 +620,16 @@
         return rc;
     AssertMsgReturn(u32 == ~0U, ("%#x\n", u32), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
+
+    if (pThis->irq != iIrq)
+    {
+        LogRel(("Parallel: IRQ changed: config=%#x state=%#x\n", pThis->irq, iIrq));
+        return VERR_SSM_LOAD_CONFIG_MISMATCH;
+    }
+
+    if (pThis->base != uIoBase)
+    {
+        LogRel(("Parallel: IOBase changed: config=%#x state=%#x\n", pThis->base, uIoBase));
+        return VERR_SSM_LOAD_CONFIG_MISMATCH;
+    }
 
     /* not necessary... but it doesn't harm. */
@@ -802,5 +823,6 @@
     }
 
-    rc = PDMDevHlpSSMRegister(pDevIns, PARALLEL_SAVED_STATE_VERSION, sizeof(*pThis), parallelSaveExec, parallelLoadExec);
+    rc = PDMDevHlpSSMRegister3(pDevIns, PARALLEL_SAVED_STATE_VERSION, sizeof(*pThis),
+                               parallelLiveExec, parallelSaveExec, parallelLoadExec);
     if (RT_FAILURE(rc))
         return rc;
