diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 6119108b0d..50563c5439 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -661,9 +661,9 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
     bool iface_connected = false;
     int actualType;
 
-    if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_HOST_NET_ADD)) {
-        qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-                        _("installed qemu version does not support host_net_add"));
+    /* preallocate new slot for device */
+    if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets+1) < 0) {
+        virReportOOMError();
         return -1;
     }
 
@@ -672,9 +672,27 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
      * to the one defined in the network definition.
      */
     if (networkAllocateActualDevice(net) < 0)
-        goto cleanup;
+        return -1;
 
     actualType = virDomainNetGetActualType(net);
+
+    if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
+        /* This is really a "smart hostdev", so it should be attached
+         * as a hostdev (the hostdev code will reach over into the
+         * netdev-specific code as appropriate), then also added to
+         * the nets list (see cleanup:) if successful.
+         */
+        ret = qemuDomainAttachHostDevice(driver, vm,
+                                         virDomainNetGetActualHostdev(net));
+        goto cleanup;
+    }
+
+    if (!qemuCapsGet(priv->qemuCaps, QEMU_CAPS_HOST_NET_ADD)) {
+        qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                        _("installed qemu version does not support host_net_add"));
+        goto cleanup;
+    }
+
     if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
         actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
         if ((tapfd = qemuNetworkIfaceConnect(vm->def, conn, driver, net,
@@ -693,9 +711,6 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
             goto cleanup;
     }
 
-    if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets+1) < 0)
-        goto no_memory;
-
     if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NET_NAME) ||
         qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
         if (qemuAssignDeviceNetAlias(vm->def, net, -1) < 0)
@@ -826,10 +841,10 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
 
     ret = 0;
 
-    vm->def->nets[vm->def->nnets++] = net;
-
 cleanup:
-    if (ret < 0) {
+    if (!ret) {
+        vm->def->nets[vm->def->nnets++] = net;
+    } else {
         if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
             (net->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) &&
             releaseaddr &&
@@ -2032,7 +2047,13 @@ int qemuDomainDetachHostDevice(struct qemud_driver *driver,
         return -1;
     }
 
-    return qemuDomainDetachThisHostDevice(driver, vm, detach, idx);
+    /* If this is a network hostdev, we need to use the higher-level detach
+     * function so that mac address / virtualport are reset
+     */
+    if (detach->parent.type == VIR_DOMAIN_DEVICE_NET)
+        return qemuDomainDetachNetDevice(driver, vm, &detach->parent);
+    else
+        return qemuDomainDetachThisHostDevice(driver, vm, detach, idx);
 }
 
 int
@@ -2056,6 +2077,13 @@ qemuDomainDetachNetDevice(struct qemud_driver *driver,
         }
     }
 
+    if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
+        ret = qemuDomainDetachThisHostDevice(driver, vm,
+                                             virDomainNetGetActualHostdev(detach),
+                                             -1);
+        goto cleanup;
+    }
+
     if (!detach) {
         qemuReportError(VIR_ERR_OPERATION_FAILED,
                         _("network device %02x:%02x:%02x:%02x:%02x:%02x not found"),
@@ -2156,14 +2184,13 @@ qemuDomainDetachNetDevice(struct qemud_driver *driver,
         ignore_value(virNetDevOpenvswitchRemovePort(
                         virDomainNetGetActualBridgeName(detach),
                         detach->ifname));
-
-    networkReleaseActualDevice(detach);
-    virDomainNetRemove(vm->def, i);
-    virDomainNetDefFree(detach);
-
     ret = 0;
-
 cleanup:
+    if (!ret) {
+        networkReleaseActualDevice(detach);
+        virDomainNetRemove(vm->def, i);
+        virDomainNetDefFree(detach);
+    }
     VIR_FREE(hostnet_name);
     return ret;
 }