When running turbostat on a virtual machine the error

turbostat: msr 0 offset 0xe2 read failed: Input/output error

is output to the user.

/dev/msr and perf do not work on a virtual machine.  turbostat is
dependent on that support so turbostat does not work either.

A common way of determining if the system is a virtual machine is to
search /proc/cpuinfo flags entry for "hypervisor".  turbostat must output
a proper error message when found.

Signed-off-by: Prarit Bhargava <pra...@redhat.com>
Cc: Len Brown <len.br...@intel.com>
Cc: Len Brown <l...@kernel.org>
---
 tools/power/x86/turbostat/turbostat.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/tools/power/x86/turbostat/turbostat.c 
b/tools/power/x86/turbostat/turbostat.c
index 0dafba2c1e7d..ca1ea68bc4e8 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -5088,6 +5088,34 @@ void cmdline(int argc, char **argv)
        }
 }
 
+int has_hypervisor(void)
+{
+       FILE *cpuinfo;
+       char *flags, *hypervisor;
+       char *buffer;
+
+       /* On VMs /proc/cpuinfo contains a "flags" entry for hypervisor */
+       cpuinfo = fopen_or_die("/proc/cpuinfo", "ro");
+
+       buffer = malloc(4096);
+       if (!buffer)
+               err(-ENOMEM, "buffer malloc fail");
+
+       fread(buffer, 1024, 1, cpuinfo);
+
+       flags = strstr(buffer, "flags");
+       rewind(cpuinfo);
+       fseek(cpuinfo, flags - buffer, SEEK_SET);
+       fgets(buffer, 4096, cpuinfo);
+       fclose(cpuinfo);
+
+       hypervisor = strstr(buffer, "hypervisor");
+
+       free(buffer);
+
+       return !!hypervisor;
+}
+
 int main(int argc, char **argv)
 {
        outf = stderr;
@@ -5097,6 +5125,12 @@ int main(int argc, char **argv)
        if (!quiet)
                print_version();
 
+       if (has_hypervisor()) {
+               fprintf(outf,
+                       "turbostat is not supported on virtual machines.\n");
+               return -ENXIO;
+       }
+
        probe_sysfs();
 
        turbostat_init();
-- 
1.8.5.5

Reply via email to