diff --git a/lib/hypervisor/hv_base.py b/lib/hypervisor/hv_base.py
index ebae830a173667ee04e53e3c96390f121b3f7f03..68766908e742536259766f1772d267cbe6a16afe 100644
--- a/lib/hypervisor/hv_base.py
+++ b/lib/hypervisor/hv_base.py
@@ -84,8 +84,8 @@ class BaseHypervisor(object):
     """
     raise NotImplementedError
 
-  @staticmethod
-  def GetShellCommandForConsole(instance):
+  @classmethod
+  def GetShellCommandForConsole(cls, instance):
     """Return a command for connecting to the console of an instance.
 
     """
diff --git a/lib/hypervisor/hv_fake.py b/lib/hypervisor/hv_fake.py
index 53dc6264471cf408f8600e4e9afb57062c075185..52ef62826c029008b897b54b54745fe4046bce7c 100644
--- a/lib/hypervisor/hv_fake.py
+++ b/lib/hypervisor/hv_fake.py
@@ -203,8 +203,8 @@ class FakeHypervisor(hv_base.BaseHypervisor):
 
     return result
 
-  @staticmethod
-  def GetShellCommandForConsole(instance):
+  @classmethod
+  def GetShellCommandForConsole(cls, instance):
     """Return a command for connecting to the console of an instance.
 
     """
diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py
index c01b391db21bd9d92c21a0d0b6d2ec7049ab1c7c..0316b1ba58221fe35853ebc717deef4137e226d2 100644
--- a/lib/hypervisor/hv_kvm.py
+++ b/lib/hypervisor/hv_kvm.py
@@ -576,13 +576,23 @@ class KVMHypervisor(hv_base.BaseHypervisor):
 
     return result
 
-  @staticmethod
-  def GetShellCommandForConsole(instance):
+  @classmethod
+  def GetShellCommandForConsole(cls, instance):
     """Return a command for connecting to the console of an instance.
 
     """
-    # TODO: we can either try the serial socket or suggest vnc
-    return "echo Console not available for the kvm hypervisor yet"
+    # FIXME: The socat shell is not perfect. In particular the way we start
+    # it ctrl+c will close it, rather than being passed to the other end.
+    # On the other hand if we pass the option 'raw' (or ignbrk=1) there
+    # will be no way of exiting socat (except killing it from another shell)
+    # and ctrl+c doesn't work anyway, printing ^C rather than being
+    # interpreted by kvm. For now we'll leave it this way, which at least
+    # allows a minimal interaction and changes on the machine.
+    socat_shell = ("%s STDIO,echo=0,icanon=0 UNIX-CONNECT:%s" %
+                   (constants.SOCAT_PATH,
+                    utils.ShellQuote(cls._InstanceSerial(instance.name))))
+
+    return socat_shell
 
   def Verify(self):
     """Verify the hypervisor.
diff --git a/lib/hypervisor/hv_xen.py b/lib/hypervisor/hv_xen.py
index 46a1359fede1492554eb613a461dadd39c86007a..f92b2fe6e5b1a92b7b325d7e68b1e287520f6286 100644
--- a/lib/hypervisor/hv_xen.py
+++ b/lib/hypervisor/hv_xen.py
@@ -232,8 +232,8 @@ class XenHypervisor(hv_base.BaseHypervisor):
 
     return result
 
-  @staticmethod
-  def GetShellCommandForConsole(instance):
+  @classmethod
+  def GetShellCommandForConsole(cls, instance):
     """Return a command for connecting to the console of an instance.
 
     """