From 3ea952163f0c28cd88f8473bb015df892c4247bf Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 26 May 2011 15:40:59 +0100 Subject: [PATCH] Add IA64-specific tests for virtualization (RHBZ#707508). Xen IA64 HVM does not provide a simple way to detect the hypervisor. If we are lucky and PV-on-HVM drivers are installed and loaded, then there will be a /sys/bus/xen directory. Otherwise we add a timing attack to see if we can detect generic virtualization. Since this is a big hack, it is only enabled on IA64 and only used when all other methods of detection have failed. This commit also adds `uname -p` to all tests (enabling arch detection so we only run the above tests on IA64). --- .gitignore | 2 ++ Makefile.am | 16 ++++++++++ configure.ac | 4 +++ tests/baremetal/sbin/uname | 2 ++ tests/esx4.1/sbin/uname | 2 ++ tests/hyperv/sbin/uname | 2 ++ tests/kvm-explicit-cpu/sbin/uname | 2 ++ tests/kvm/sbin/uname | 2 ++ tests/linux-vserver/sbin/uname | 2 ++ tests/lx86/sbin/uname | 2 ++ tests/parallels-desktop/sbin/uname | 2 ++ tests/qemu/sbin/uname | 2 ++ tests/rhel5-xen-dom0/sbin/uname | 2 ++ tests/rhel5-xen-domU-hvm/sbin/uname | 2 ++ tests/rhel5-xen-domU-pv/sbin/uname | 2 ++ tests/zvm/sbin/uname | 2 ++ virt-what-ia64-xen-rdtsc-test.c | 58 +++++++++++++++++++++++++++++++++++++ virt-what.in | 21 ++++++++++++++ virt-what.pod | 9 ++++++ 19 files changed, 136 insertions(+) create mode 100755 tests/baremetal/sbin/uname create mode 100755 tests/esx4.1/sbin/uname create mode 100755 tests/hyperv/sbin/uname create mode 100755 tests/kvm-explicit-cpu/sbin/uname create mode 100755 tests/kvm/sbin/uname create mode 100755 tests/linux-vserver/sbin/uname create mode 100755 tests/lx86/sbin/uname create mode 100755 tests/parallels-desktop/sbin/uname create mode 100755 tests/qemu/sbin/uname create mode 100755 tests/rhel5-xen-dom0/sbin/uname create mode 100755 tests/rhel5-xen-domU-hvm/sbin/uname create mode 100755 tests/rhel5-xen-domU-pv/sbin/uname create mode 100755 tests/zvm/sbin/uname create mode 100644 virt-what-ia64-xen-rdtsc-test.c diff --git a/.gitignore b/.gitignore index 4f171bb..3be575f 100644 --- a/.gitignore +++ b/.gitignore @@ -7,10 +7,12 @@ /aclocal.m4 /autom4te.cache /compile +/config.guess /config.h /config.h.in /config.log /config.status +/config.sub /configure /depcomp /install-sh diff --git a/Makefile.am b/Makefile.am index 2dfed9c..aa97852 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,6 +21,9 @@ AM_CPPFLAGS = -Wall sbin_SCRIPTS = virt-what libexec_PROGRAMS = virt-what-cpuid-helper +if HOST_CPU_IA64 +libexec_PROGRAMS += virt-what-ia64-xen-rdtsc-test +endif man_MANS = virt-what.1 @@ -53,46 +56,55 @@ EXTRA_DIST = \ tests/baremetal/proc/self/status \ tests/baremetal/sbin/dmidecode \ tests/baremetal/sbin/id \ + tests/baremetal/sbin/uname \ tests/baremetal/sbin/virt-what-cpuid-helper \ tests/esx4.1/proc/cpuinfo \ tests/esx4.1/proc/self/status \ tests/esx4.1/sbin/dmidecode \ tests/esx4.1/sbin/id \ + tests/esx4.1/sbin/uname \ tests/esx4.1/sbin/virt-what-cpuid-helper \ tests/hyperv/proc/cpuinfo \ tests/hyperv/proc/self/status \ tests/hyperv/sbin/dmidecode \ tests/hyperv/sbin/id \ + tests/hyperv/sbin/uname \ tests/hyperv/sbin/virt-what-cpuid-helper \ tests/kvm/proc/cpuinfo \ tests/kvm/proc/self/status \ tests/kvm/sbin/dmidecode \ tests/kvm/sbin/id \ + tests/kvm/sbin/uname \ tests/kvm/sbin/virt-what-cpuid-helper \ tests/kvm-explicit-cpu/proc/cpuinfo \ tests/kvm-explicit-cpu/proc/self/status \ tests/kvm-explicit-cpu/sbin/dmidecode \ tests/kvm-explicit-cpu/sbin/id \ + tests/kvm-explicit-cpu/sbin/uname \ tests/kvm-explicit-cpu/sbin/virt-what-cpuid-helper \ tests/linux-vserver/proc/cpuinfo \ tests/linux-vserver/proc/self/status \ tests/linux-vserver/sbin/dmidecode \ tests/linux-vserver/sbin/id \ + tests/linux-vserver/sbin/uname \ tests/linux-vserver/sbin/virt-what-cpuid-helper \ tests/lx86/proc/cpuinfo \ tests/lx86/proc/self/status \ tests/lx86/sbin/dmidecode \ tests/lx86/sbin/id \ + tests/lx86/sbin/uname \ tests/lx86/sbin/virt-what-cpuid-helper \ tests/parallels-desktop/proc/cpuinfo \ tests/parallels-desktop/proc/self/status \ tests/parallels-desktop/sbin/dmidecode \ tests/parallels-desktop/sbin/id \ + tests/parallels-desktop/sbin/uname \ tests/parallels-desktop/sbin/virt-what-cpuid-helper \ tests/qemu/proc/cpuinfo \ tests/qemu/proc/self/status \ tests/qemu/sbin/dmidecode \ tests/qemu/sbin/id \ + tests/qemu/sbin/uname \ tests/qemu/sbin/virt-what-cpuid-helper \ tests/rhel5-xen-dom0/proc/cpuinfo \ tests/rhel5-xen-dom0/proc/self/status \ @@ -104,6 +116,7 @@ EXTRA_DIST = \ tests/rhel5-xen-dom0/proc/xen/xsd_port \ tests/rhel5-xen-dom0/sbin/dmidecode \ tests/rhel5-xen-dom0/sbin/id \ + tests/rhel5-xen-dom0/sbin/uname \ tests/rhel5-xen-dom0/sbin/virt-what-cpuid-helper \ tests/rhel5-xen-dom0/sys/hypervisor/properties/pagesize \ tests/rhel5-xen-dom0/sys/hypervisor/properties/changeset \ @@ -123,6 +136,7 @@ EXTRA_DIST = \ tests/rhel5-xen-domU-hvm/proc/self/status \ tests/rhel5-xen-domU-hvm/sbin/dmidecode \ tests/rhel5-xen-domU-hvm/sbin/id \ + tests/rhel5-xen-domU-hvm/sbin/uname \ tests/rhel5-xen-domU-hvm/sbin/virt-what-cpuid-helper \ tests/rhel5-xen-domU-pv/proc/cpuinfo \ tests/rhel5-xen-domU-pv/proc/self/status \ @@ -132,6 +146,7 @@ EXTRA_DIST = \ tests/rhel5-xen-domU-pv/proc/xen/xenbus \ tests/rhel5-xen-domU-pv/sbin/dmidecode \ tests/rhel5-xen-domU-pv/sbin/id \ + tests/rhel5-xen-domU-pv/sbin/uname \ tests/rhel5-xen-domU-pv/sbin/virt-what-cpuid-helper \ tests/rhel5-xen-domU-pv/sys/hypervisor/properties/pagesize \ tests/rhel5-xen-domU-pv/sys/hypervisor/properties/changeset \ @@ -152,5 +167,6 @@ EXTRA_DIST = \ tests/zvm/proc/sysinfo \ tests/zvm/sbin/dmidecode \ tests/zvm/sbin/id \ + tests/zvm/sbin/uname \ tests/zvm/sbin/virt-what-cpuid-helper \ $(TESTS) diff --git a/configure.ac b/configure.ac index 0aa7deb..8e75938 100644 --- a/configure.ac +++ b/configure.ac @@ -28,6 +28,10 @@ test "x$U" != "x" && AC_MSG_ERROR([Compiler not ANSI compliant]) AM_PROG_CC_C_O +dnl Architecture we are compiling for. +AC_CANONICAL_HOST +AM_CONDITIONAL([HOST_CPU_IA64], [ test "x$host_cpu" = "xia64" ]) + dnl Produce output files. AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([virt-what],[chmod +x virt-what]) diff --git a/tests/baremetal/sbin/uname b/tests/baremetal/sbin/uname new file mode 100755 index 0000000..ab0ec89 --- /dev/null +++ b/tests/baremetal/sbin/uname @@ -0,0 +1,2 @@ +#!/bin/sh - +echo x86_64 diff --git a/tests/esx4.1/sbin/uname b/tests/esx4.1/sbin/uname new file mode 100755 index 0000000..ab0ec89 --- /dev/null +++ b/tests/esx4.1/sbin/uname @@ -0,0 +1,2 @@ +#!/bin/sh - +echo x86_64 diff --git a/tests/hyperv/sbin/uname b/tests/hyperv/sbin/uname new file mode 100755 index 0000000..ab0ec89 --- /dev/null +++ b/tests/hyperv/sbin/uname @@ -0,0 +1,2 @@ +#!/bin/sh - +echo x86_64 diff --git a/tests/kvm-explicit-cpu/sbin/uname b/tests/kvm-explicit-cpu/sbin/uname new file mode 100755 index 0000000..ab0ec89 --- /dev/null +++ b/tests/kvm-explicit-cpu/sbin/uname @@ -0,0 +1,2 @@ +#!/bin/sh - +echo x86_64 diff --git a/tests/kvm/sbin/uname b/tests/kvm/sbin/uname new file mode 100755 index 0000000..ab0ec89 --- /dev/null +++ b/tests/kvm/sbin/uname @@ -0,0 +1,2 @@ +#!/bin/sh - +echo x86_64 diff --git a/tests/linux-vserver/sbin/uname b/tests/linux-vserver/sbin/uname new file mode 100755 index 0000000..ab0ec89 --- /dev/null +++ b/tests/linux-vserver/sbin/uname @@ -0,0 +1,2 @@ +#!/bin/sh - +echo x86_64 diff --git a/tests/lx86/sbin/uname b/tests/lx86/sbin/uname new file mode 100755 index 0000000..ef865f9 --- /dev/null +++ b/tests/lx86/sbin/uname @@ -0,0 +1,2 @@ +#!/bin/sh - +echo i686 diff --git a/tests/parallels-desktop/sbin/uname b/tests/parallels-desktop/sbin/uname new file mode 100755 index 0000000..ab0ec89 --- /dev/null +++ b/tests/parallels-desktop/sbin/uname @@ -0,0 +1,2 @@ +#!/bin/sh - +echo x86_64 diff --git a/tests/qemu/sbin/uname b/tests/qemu/sbin/uname new file mode 100755 index 0000000..ab0ec89 --- /dev/null +++ b/tests/qemu/sbin/uname @@ -0,0 +1,2 @@ +#!/bin/sh - +echo x86_64 diff --git a/tests/rhel5-xen-dom0/sbin/uname b/tests/rhel5-xen-dom0/sbin/uname new file mode 100755 index 0000000..ab0ec89 --- /dev/null +++ b/tests/rhel5-xen-dom0/sbin/uname @@ -0,0 +1,2 @@ +#!/bin/sh - +echo x86_64 diff --git a/tests/rhel5-xen-domU-hvm/sbin/uname b/tests/rhel5-xen-domU-hvm/sbin/uname new file mode 100755 index 0000000..ab0ec89 --- /dev/null +++ b/tests/rhel5-xen-domU-hvm/sbin/uname @@ -0,0 +1,2 @@ +#!/bin/sh - +echo x86_64 diff --git a/tests/rhel5-xen-domU-pv/sbin/uname b/tests/rhel5-xen-domU-pv/sbin/uname new file mode 100755 index 0000000..ab0ec89 --- /dev/null +++ b/tests/rhel5-xen-domU-pv/sbin/uname @@ -0,0 +1,2 @@ +#!/bin/sh - +echo x86_64 diff --git a/tests/zvm/sbin/uname b/tests/zvm/sbin/uname new file mode 100755 index 0000000..f416bcf --- /dev/null +++ b/tests/zvm/sbin/uname @@ -0,0 +1,2 @@ +#!/bin/sh - +echo s390 diff --git a/virt-what-ia64-xen-rdtsc-test.c b/virt-what-ia64-xen-rdtsc-test.c new file mode 100644 index 0000000..75c8ae3 --- /dev/null +++ b/virt-what-ia64-xen-rdtsc-test.c @@ -0,0 +1,58 @@ +/* virt-what-ia64-xen-rdtsc-test + * Copyright (C) 2011 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __ia64__ +#error "error in Makefile - this program should only be compiled for ia64 host" +#endif + +/* This program is ugly, but possibly the only way to detect + * virtualized Xen HVM guests on IA64. + */ + +#include +#include +#include + +static inline unsigned long +rdtsc (void) +{ + unsigned long res; + asm volatile ("mov %0=ar.itc" : "=r"(res)); + return res; +} + +int +main () +{ + unsigned long old, new; + int virt; + int i; + + virt = 1; + + for (i = 16; i--; ) { + old = rdtsc (); new = rdtsc (); + /*printf("%ld\n", new - old);*/ + if (new - old < 30) { + virt = 0; + break; + } + } + + exit (virt); +} diff --git a/virt-what.in b/virt-what.in index a27be10..74ffab2 100644 --- a/virt-what.in +++ b/virt-what.in @@ -87,6 +87,11 @@ cpuid=`virt-what-cpuid-helper` dmi=`LANG=C dmidecode 2>&1` +# Architecture. +# Note for the purpose of testing, we only call uname with -p option. + +arch=`uname -p` + # Check for VMware. # cpuid check added by Chetan Loke. @@ -188,6 +193,22 @@ elif [ -f $root/sys/hypervisor/type ] && # enough information at present to tell whether this is dom0 # or domU. XXX echo xen +elif [ "$arch" = "ia64" ]; then + if [ -d $root/sys/bus/xen -a ! -d $root/sys/bus/xen-backend ]; then + # PV-on-HVM drivers installed in a Xen guest. + echo xen + echo xen-domU + else + # There is no virt leaf on IA64 HVM. This is a last-ditch + # attempt to detect something is virtualized by using a + # timing attack. + virt-what-ia64-xen-rdtsc-test > /dev/null 2>&1 + case "$?" in + 0) ;; # not virtual + 1) # Could be some sort of virt, or could just be a bit slow. + echo virt + esac + fi fi # Check for QEMU/KVM. diff --git a/virt-what.pod b/virt-what.pod index 4304297..7769ee9 100644 --- a/virt-what.pod +++ b/virt-what.pod @@ -113,6 +113,15 @@ This is a User-Mode Linux (UML) guest. Status: contributed by Laurent Léonard +=item B + +Some sort of virtualization appears to be present, but we are not sure +what it is. In some very rare corner cases where we know that +virtualization is hard to detect, we will try a timing attack to see +if certain machine instructions are running much more slowly than they +should be, which would indicate virtualization. In this case, the +generic fact C is printed. + =item B This is Hitachi Virtualization Manager (HVM) Virtage -- 1.8.3.1