diff --git a/lib/build-vms.nix b/lib/build-vms.nix
index 8a51a23bc4ca..ceb38b4b5cf7 100644
--- a/lib/build-vms.nix
+++ b/lib/build-vms.nix
@@ -130,6 +130,7 @@ rec {
           mkdir $out
           cp ${./test-driver/Machine.pm} Machine.pm
           ${perl}/bin/perl ${./test-driver/test-driver.pl} ${network}/vms/*/bin/run-*-vm
+          find .
           for i in */coverage-data; do
             ensureDir $out/coverage-data
             mv $i $out/coverage-data/$(dirname $i)
@@ -152,7 +153,7 @@ rec {
               if ! test -e $TMPDIR/gcov/nix/store/$i; then
                   echo "copying $i"
                   mkdir -p $TMPDIR/gcov/$(echo $i | cut -c34-)
-                  rsync -rv /nix/store/$i/.coverage/ $TMPDIR/gcov/$(echo $i | cut -c34-)
+                  rsync -rv /nix/store/$i/.build/ $TMPDIR/gcov/$(echo $i | cut -c34-)
               fi
           done
 
@@ -161,7 +162,7 @@ rec {
           find $TMPDIR/gcov -name "*.gcda" -exec rm {} \;
 
           for i in $(cd $d/nix/store && ls); do
-              rsync -rv $d/nix/store/$i/.coverage/ $TMPDIR/gcov/$(echo $i | cut -c34-)
+              rsync -rv $d/nix/store/$i/.build/ $TMPDIR/gcov/$(echo $i | cut -c34-)
           done
 
           find $TMPDIR/gcov -name "*.gcda" -exec chmod 644 {} \;
@@ -171,11 +172,9 @@ rec {
           cat $TMPDIR/app.info >> $TMPDIR/full.info
       done
             
-      ${pkgs.lcov}/bin/lcov --remove $TMPDIR/full.info "/nix/store/*" > $TMPDIR/out.info
-      
       echo "making report..."
       ensureDir $out/coverage
-      ${pkgs.lcov}/bin/genhtml --show-details $TMPDIR/out.info -o $out/coverage
+      ${pkgs.lcov}/bin/genhtml --show-details $TMPDIR/full.info -o $out/coverage
 
       ensureDir $out/nix-support
       echo "report coverage $out/coverage" >> $out/nix-support/hydra-build-products
diff --git a/lib/test-driver/Machine.pm b/lib/test-driver/Machine.pm
index b30cd501a8d1..65797604735e 100644
--- a/lib/test-driver/Machine.pm
+++ b/lib/test-driver/Machine.pm
@@ -50,6 +50,12 @@ sub name {
 }
 
 
+sub stateDir {
+    my ($self) = @_;
+    return $self->{stateDir};
+}
+
+
 sub start {
     my ($self) = @_;
     return if $self->{booted};
@@ -131,7 +137,7 @@ sub execute {
 
     $self->log("running command: $command");
 
-    print { $self->{socket} } ("($command); echo '|!=EOF' \$?\n");
+    print { $self->{socket} } ("( $command ); echo '|!=EOF' \$?\n");
 
     my $out = "";
 
diff --git a/tests/subversion.nix b/tests/subversion.nix
index c55c3b5ea2cc..481ab12a4abe 100644
--- a/tests/subversion.nix
+++ b/tests/subversion.nix
@@ -20,6 +20,26 @@ let
         apacheHttpd = do pkgs.apacheHttpd;
         mod_python = do pkgs.mod_python;
         subversion = do pkgs.subversion;
+
+        # To build the kernel with coverage instrumentation, we need a
+        # special patch to make coverage data available under /proc.
+        kernel_2_6_28 = pkgs.kernel_2_6_28.override (orig: {
+          stdenv = pkgs.keepBuildTree orig.stdenv;
+          kernelPatches = orig.kernelPatches ++ pkgs.lib.singleton
+            { name = "gcov";
+              patch = pkgs.fetchurl {
+                url = http://buildfarm.st.ewi.tudelft.nl/~eelco/dist/linux-2.6.28-gcov.patch;
+                sha256 = "0ck9misa3pgh3vzyb7714ibf7ix7piyg5dvfa9r42v15scjqiyny";
+              };
+              extraConfig =
+                ''
+                  CONFIG_GCOV_PROFILE=y
+                  CONFIG_GCOV_ALL=y
+                  CONFIG_GCOV_PROC=m
+                  CONFIG_GCOV_HAMMER=n
+                '';
+            };
+        });
       };
 
 in
@@ -31,6 +51,7 @@ rec {
         { config, pkgs, ... }:
 
         {
+          boot.kernelModules = [ "gcov-proc" ];
           services.httpd.enable = true;
           services.httpd.adminAddr = "e.dolstra@tudelft.nl";
           services.httpd.extraSubservices =
@@ -109,7 +130,14 @@ rec {
 
       # Stop Apache to gather all the coverage data.
       $webserver->stopJob("httpd");
-      $webserver->execute("sleep 5"); # !!!
+      $webserver->execute("sleep 10"); # !!!
+
+      # !!! move this to build-vms.nix
+      my $kernelDir = $webserver->mustSucceed("echo \$(dirname \$(readlink -f /var/run/current-system/kernel))/.build/linux-*");
+      chomp $kernelDir;
+      my $coverageDir = "/hostfs" . $webserver->stateDir() . "/coverage-data/$kernelDir";
+      $webserver->execute("for i in \$(cd /proc/gcov && find -name module -prune -o -name '*.gcda'); do echo \$i; mkdir -p $coverageDir/\$(dirname \$i); cp -v /proc/gcov/\$i $coverageDir/\$i; done");
+      $webserver->execute("for i in \$(cd /proc/gcov/module/nix/store/*/.build/* && find -name module -prune -o -name '*.gcda'); do mkdir -p $coverageDir/\$(dirname \$i); cp /proc/gcov/module/nix/store/*/.build/*/\$i $coverageDir/\$i; done");
     '';
 
   report = makeReport test;