mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 19:41:16 +00:00
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>
111 lines
2.4 KiB
Bash
Executable File
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
|