libvirt/tests/cputestdata/cpu-gather.sh
Jiri Denemark ab3d6ea0da cputest: Add support for MSR features to cpu-gather.sh
This patch adds an inline python code for reading MSR features. Since
reading MSRs is a privileged operation, we have to read them from
/dev/cpu/*/msr if it is readable (i.e., the script runs as root) or
fallback to using KVM ioctl which can be done by any user that can start
virtual machines.

The python code is inlined rather than provided in a separate script
because whenever there's an issue with proper detection of CPU features,
we ask the reporter to run cpu-gather.sh script to give us all data we
need to know about the host CPU. Asking them to run several scripts
would likely result in one of them being ignored or forgotten.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2019-04-12 22:53:39 +02:00

111 lines
2.4 KiB
Bash
Executable File

#!/bin/bash
#
# The cpuid tool can be usually found in a package called "cpuid". If your
# distro does not provide such package, you can find the sources or binary
# packages at http://www.etallen.com/cpuid.html
grep 'model name' /proc/cpuinfo | head -n1
cpuid -1r
echo
for python in python3 python2; do
$python <<EOF
from __future__ import print_function
from struct import pack, unpack
from fcntl import ioctl
import sys, errno
IA32_ARCH_CAPABILITIES_MSR = 0x10a
KVM_GET_MSRS = 0xc008ae88
def print_msr(msr, via=None):
if via is None:
print("MSR:")
else:
print("MSR via %s:" % via)
print(" 0x%x: 0x%016x" % (IA32_ARCH_CAPABILITIES_MSR, msr))
print()
try:
fd = open("/dev/cpu/0/msr", "rb")
fd.seek(IA32_ARCH_CAPABILITIES_MSR)
buf = fd.read(8)
msr = unpack("=Q", buf)[0]
print_msr(msr)
sys.exit(0)
except IOError as e:
# The MSR is not supported on the host
if e.errno == errno.EIO:
sys.exit(0)
try:
fd = open("/dev/kvm", "r")
bufIn = pack("=LLLLQ", 1, 0, IA32_ARCH_CAPABILITIES_MSR, 0, 0)
bufOut = ioctl(fd, KVM_GET_MSRS, bufIn)
msr = unpack("=LLLLQ", bufOut)[4]
print_msr(msr, via="KVM")
except IOError as e:
pass
EOF
if [[ $? -eq 0 ]]; then
break
fi
done
qemu=qemu-system-x86_64
for cmd in /usr/bin/$qemu /usr/bin/qemu-kvm /usr/libexec/qemu-kvm; do
if [[ -x $cmd ]]; then
qemu=$cmd
break
fi
done
qom_get()
{
path='/machine/unattached/device[0]'
echo '{"execute":"qom-get","arguments":{"path":"'$path'",' \
'"property":"'$1'"},"id":"'$1'"}'
}
model_expansion()
{
mode=$1
model=$2
echo '{"execute":"query-cpu-model-expansion","arguments":' \
'{"type":"'"$mode"'","model":'"$model"'},"id":"model-expansion"}'
}
model=$(
$qemu -machine accel=kvm -cpu host -nodefaults -nographic -qmp stdio <<EOF
{"execute":"qmp_capabilities"}
$(model_expansion static '{"name":"host"}')
{"execute":"quit"}
EOF
)
model=$(
echo "$model" | \
sed -ne 's/^{"return": {"model": {\(.*{.*}\)}}, .*/{\1}/p'
)
$qemu -machine accel=kvm -cpu host -nodefaults -nographic -qmp stdio <<EOF
{"execute":"qmp_capabilities"}
$(
if [ "x$model" != x ]; then
model_expansion full "$model"
else
qom_get feature-words
qom_get family
qom_get model
qom_get stepping
qom_get model-id
fi
)
{"execute":"query-cpu-definitions","id":"definitions"}
{"execute":"quit"}
EOF