cpu-gather: Move msr decoding to new script

Fixes the leaking file descriptors. Does not silently ignore errors
(e.g. permission denied on /dev/cpu/0/msr if run as non-root) and
always attempt to read from /dev/kvm if /dev/cpu/0/msr failed.

'gather_msr()' returns a dictionary of values, as a later patch will
add more registers to be interrogated.

Signed-off-by: Tim Wiederhake <twiederh@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Tim Wiederhake 2020-12-15 17:24:53 +01:00 committed by Michal Privoznik
parent 7f59cbcc16
commit 3e04b68ccd
2 changed files with 34 additions and 40 deletions

View File

@ -1,8 +1,11 @@
#!/usr/bin/env python3
import argparse
import fcntl
import os
import struct
import subprocess
import sys
def gather_name(args):
@ -38,6 +41,31 @@ def gather_cpuid_leaves(args):
yield line.strip()
def gather_msr():
IA32_ARCH_CAPABILITIES_MSR = 0x10a
KVM_GET_MSRS = 0xc008ae88
try:
with open("/dev/cpu/0/msr", "rb") as f:
f.seek(IA32_ARCH_CAPABILITIES_MSR)
buf = f.read(8)
msr = struct.unpack("=Q", buf)[0]
return "", {IA32_ARCH_CAPABILITIES_MSR: msr}
except IOError as e:
print("Warning: {}".format(e), file=sys.stderr)
try:
bufIn = struct.pack("=LLLLQ", 1, 0, IA32_ARCH_CAPABILITIES_MSR, 0, 0)
with open("/dev/kvm", "rb") as f:
bufOut = fcntl.ioctl(f, KVM_GET_MSRS, bufIn)
msr = struct.unpack("=LLLLQ", bufOut)[4]
return " via KVM", {IA32_ARCH_CAPABILITIES_MSR: msr}
except IOError as e:
print("Warning: {}".format(e), file=sys.stderr)
return None, {}
def main():
parser = argparse.ArgumentParser(description="Gather cpu test data")
parser.add_argument(
@ -61,6 +89,12 @@ def main():
print(" {}".format(leave))
print()
via, msr = gather_msr()
if via is not None:
print("MSR{}:".format(via))
for key, value in sorted(msr.items()):
print(" 0x{:x}: 0x{:016x}\n".format(int(key), value))
print(end="", flush=True)
os.environ["CPU_GATHER_PY"] = "true"
subprocess.check_call("./cpu-gather.sh")

View File

@ -5,46 +5,6 @@ if [ -z "${CPU_GATHER_PY}" ]; then
exit 1
fi
python3 <<EOF
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
qemu=qemu-system-x86_64
for cmd in /usr/bin/$qemu /usr/bin/qemu-kvm /usr/libexec/qemu-kvm; do
if [[ -x $cmd ]]; then