diff --git a/nixos/modules/virtualisation/libvirtd.nix b/nixos/modules/virtualisation/libvirtd.nix
index b24ea0f33c9e..e07fb0f8fe44 100644
--- a/nixos/modules/virtualisation/libvirtd.nix
+++ b/nixos/modules/virtualisation/libvirtd.nix
@@ -15,7 +15,7 @@ let
   '';
   qemuConfigFile = pkgs.writeText "qemu.conf" ''
     ${optionalString cfg.qemuOvmf ''
-      nvram = ["${pkgs.OVMF.fd}/FV/OVMF_CODE.fd:${pkgs.OVMF.fd}/FV/OVMF_VARS.fd"]
+      nvram = ["/run/libvirt/nix-ovmf/OVMF_CODE.fd:/run/libvirt/nix-ovmf/OVMF_VARS.fd"]
     ''}
     ${cfg.qemuVerbatimConfig}
   '';
@@ -102,9 +102,7 @@ in {
 
   config = mkIf cfg.enable {
 
-    environment.systemPackages = with pkgs;
-      [ libvirt netcat-openbsd ]
-       ++ optional cfg.enableKVM qemu_kvm;
+    environment.systemPackages = with pkgs; [ libvirt netcat-openbsd ];
 
     boot.kernelModules = [ "tun" ];
 
@@ -129,7 +127,6 @@ in {
           dnsmasq
           ebtables
         ]
-        ++ optional cfg.enableKVM qemu_kvm
         ++ optional vswitch.enable vswitch.package;
 
       preStart = ''
@@ -155,23 +152,18 @@ in {
         # Copy generated qemu config to libvirt directory
         cp -f ${qemuConfigFile} /var/lib/libvirt/qemu.conf
 
-        # libvirtd puts the full path of the emulator binary in the machine
-        # config file. But this path can unfortunately be garbage collected
-        # while still being used by the virtual machine. So update the
-        # emulator path on each startup to something valid (re-scan $PATH).
-        for file in /var/lib/libvirt/qemu/*.xml /var/lib/libvirt/lxc/*.xml; do
-            test -f "$file" || continue
-            # get (old) emulator path from config file
-            emulator=$("${pkgs.xmlstarlet}/bin/xmlstarlet" select --template --value-of "/domain/devices/emulator" "$file")
-            # get a (definitely) working emulator path by re-scanning $PATH
-            new_emulator=$(PATH=${pkgs.libvirt}/libexec:$PATH command -v $(basename "$emulator"))
-            # write back
-            "${pkgs.xmlstarlet}/bin/xmlstarlet" edit --inplace --update "/domain/devices/emulator" -v "$new_emulator" "$file"
+        # stable (not GC'able as in /nix/store) paths for using in <emulator> section of xml configs
+        mkdir -p /run/libvirt/nix-emulators
+        ln -s --force ${pkgs.libvirt}/libexec/libvirt_lxc /run/libvirt/nix-emulators/
+        ${optionalString pkgs.stdenv.isAarch64 "ln -s --force ${pkgs.qemu}/bin/qemu-system-aarch64 /run/libvirt/nix-emulators/"}
+        ${optionalString cfg.enableKVM         "ln -s --force ${pkgs.qemu_kvm}/bin/qemu-kvm        /run/libvirt/nix-emulators/"}
 
-            # Also refresh the OVMF path. Files with no matches are ignored.
-            "${pkgs.xmlstarlet}/bin/xmlstarlet" edit --inplace --update "/domain/os/loader" -v "${pkgs.OVMF.fd}/FV/OVMF_CODE.fd" "$file"
-        done
-      ''; # */
+        ${optionalString cfg.qemuOvmf ''
+            mkdir -p /run/libvirt/nix-ovmf
+            ln -s --force ${pkgs.OVMF.fd}/FV/OVMF_CODE.fd /run/libvirt/nix-ovmf/
+            ln -s --force ${pkgs.OVMF.fd}/FV/OVMF_VARS.fd /run/libvirt/nix-ovmf/
+        ''}
+      '';
 
       serviceConfig = {
         Type = "notify";
diff --git a/pkgs/development/libraries/libvirt/default.nix b/pkgs/development/libraries/libvirt/default.nix
index 805a4c0b63db..b3066c4eed82 100644
--- a/pkgs/development/libraries/libvirt/default.nix
+++ b/pkgs/development/libraries/libvirt/default.nix
@@ -1,6 +1,6 @@
 { stdenv, fetchurl, fetchpatch
 , pkgconfig, makeWrapper
-, libxml2, gnutls, devicemapper, perl, python2, attr
+, coreutils, libxml2, gnutls, devicemapper, perl, python2, attr
 , iproute, iptables, readline, lvm2, utillinux, systemd, libpciaccess, gettext
 , libtasn1, ebtables, libgcrypt, yajl, pmutils, libcap_ng, libapparmor
 , dnsmasq, libnl, libpcap, libxslt, xhtml1, numad, numactl, perlPackages
@@ -12,11 +12,11 @@ with stdenv.lib;
 # if you update, also bump pythonPackages.libvirt or it will break
 stdenv.mkDerivation rec {
   name = "libvirt-${version}";
-  version = "3.5.0";
+  version = "3.6.0";
 
   src = fetchurl {
     url = "http://libvirt.org/sources/${name}.tar.xz";
-    sha256 = "05mm4xdw6g960rwvc9189nhxpm1vrilnmpl4h4m1lha11pivlqr9";
+    sha256 = "0gcyql5dp6j370kvik9hjhxirrg89m7l1q52yq0g75h7jpv9fb1s";
   };
 
   patches = [ ./build-on-bsd.patch ];
@@ -36,6 +36,13 @@ stdenv.mkDerivation rec {
     PATH=${stdenv.lib.makeBinPath [ iproute iptables ebtables lvm2 systemd ]}:$PATH
     substituteInPlace configure \
       --replace 'as_dummy="/bin:/usr/bin:/usr/sbin"' 'as_dummy="${numad}/bin"'
+
+    # the path to qemu-kvm will be stored in VM's .xml and .save files
+    # do not use "''${qemu_kvm}/bin/qemu-kvm" to avoid bound VMs to particular qemu derivations
+    substituteInPlace src/qemu/qemu_capabilities.c \
+      --replace '"/usr/libexec/qemu-kvm"' '"/run/libvirt/nix-emulators/${if stdenv.isAarch64 then "qemu-system-aarch64" else "qemu-kvm"}"'
+    substituteInPlace src/lxc/lxc_conf.c \
+      --replace 'lxc_path,' '"/run/libvirt/nix-emulators/libvirt_lxc",'
   '' + ''
     PATH=${dnsmasq}/bin:$PATH
     patchShebangs . # fixes /usr/bin/python references
@@ -77,6 +84,8 @@ stdenv.mkDerivation rec {
       --replace "lock/subsys" "lock"
     sed -e "/gettext\.sh/a \\\n# Added in nixpkgs:\ngettext() { \"${gettext}/bin/gettext\" \"\$@\"; }" \
         -i "$out/libexec/libvirt-guests.sh"
+
+    substituteInPlace $out/lib/systemd/system/libvirtd.service --replace /bin/kill ${coreutils}/bin/kill
   '' + optionalString stdenv.isLinux ''
     rm $out/lib/systemd/system/{virtlockd,virtlogd}.*
     wrapProgram $out/sbin/libvirtd \
diff --git a/pkgs/top-level/python-packages.nix b/pkgs/top-level/python-packages.nix
index 1333c071b3e9..e8ee822bb588 100644
--- a/pkgs/top-level/python-packages.nix
+++ b/pkgs/top-level/python-packages.nix
@@ -26512,13 +26512,13 @@ EOF
   };
 
   libvirt = let
-    version = "3.5.0";
+    version = "3.6.0";
   in assert version == pkgs.libvirt.version; pkgs.stdenv.mkDerivation rec {
     name = "libvirt-python-${version}";
 
     src = pkgs.fetchurl {
       url = "http://libvirt.org/sources/python/${name}.tar.gz";
-      sha256 = "06mc0cm4k90z8vxaslk3ifpajg8w8dvm0m2mxwcd6fdzps8fwpsw";
+      sha256 = "1l0s9cx38qb6x5xj32r531xap11m93c3gag30idj8fzkn74cpfgc";
     };
 
     buildInputs = with self; [ python pkgs.pkgconfig pkgs.libvirt lxml ];