diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 8b050a043995bffd22fe3ab24f8792250cc41dcd..6ba8087c108ba37e68e3ddffe7661aafdda36db9 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2593,6 +2593,19 @@ qemuDomainRemoveInactive(virQEMUDriverPtr driver,
     virObjectRef(vm);
 
     virDomainObjListRemove(driver->domains, vm);
+    /*
+     * virDomainObjListRemove() leaves the domain unlocked so it can
+     * be unref'd for other drivers that depend on that, but we still
+     * need to reset a job and we have a reference from the API that
+     * called this function.  So we need to lock it back.  This is
+     * just a workaround for the qemu driver.
+     *
+     * XXX: Ideally, the global handling of domain objects and object
+     *      lists would be refactored so we don't need hacks like
+     *      this, but since that requires refactor of all drivers,
+     *      it's a work for another day.
+     */
+    virObjectLock(vm);
     virObjectUnref(cfg);
 
     if (haveJob)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 694c5cd65bb9a6caa213f74ad0de8cbb33275bbc..505778ec2f05f3a73dcce398db728719d9cdd1c2 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -295,12 +295,12 @@ qemuProcessHandleMonitorEOF(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
 
     if (priv->beingDestroyed) {
         VIR_DEBUG("Domain is being destroyed, EOF is expected");
-        goto unlock;
+        goto cleanup;
     }
 
     if (!virDomainObjIsActive(vm)) {
         VIR_DEBUG("Domain %p is not active, ignoring EOF", vm);
-        goto unlock;
+        goto cleanup;
     }
 
     if (priv->monJSON && !priv->gotShutdown) {
@@ -323,15 +323,11 @@ qemuProcessHandleMonitorEOF(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
     qemuProcessStop(driver, vm, stopReason, stopFlags);
     virDomainAuditStop(vm, auditReason);
 
-    if (!vm->persistent) {
+    if (!vm->persistent)
         qemuDomainRemoveInactive(driver, vm);
-        goto cleanup;
-    }
-
- unlock:
-    virObjectUnlock(vm);
 
  cleanup:
+    virObjectUnlock(vm);
     if (event)
         qemuDomainEventQueue(driver, event);
 }
@@ -5703,6 +5699,8 @@ qemuProcessAutoDestroy(virDomainObjPtr dom,
 
     VIR_DEBUG("vm=%s, conn=%p", dom->def->name, conn);
 
+    virObjectRef(dom);
+
     if (priv->job.asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN)
         stopFlags |= VIR_QEMU_PROCESS_STOP_MIGRATED;
 
@@ -5727,15 +5725,14 @@ qemuProcessAutoDestroy(virDomainObjPtr dom,
 
     qemuDomainObjEndJob(driver, dom);
 
-    if (!dom->persistent) {
+    if (!dom->persistent)
         qemuDomainRemoveInactive(driver, dom);
-        dom = NULL;
-    }
 
     if (event)
         qemuDomainEventQueue(driver, event);
 
  cleanup:
+    virDomainObjEndAPI(&dom);
     return dom;
 }