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@xxxxxxxxxx> --- tests/cputestdata/cpu-gather.py | 34 ++++++++++++++++++++++++++++ tests/cputestdata/cpu-gather.sh | 40 --------------------------------- 2 files changed, 34 insertions(+), 40 deletions(-) diff --git a/tests/cputestdata/cpu-gather.py b/tests/cputestdata/cpu-gather.py index 75cf290a28..db2348b460 100755 --- a/tests/cputestdata/cpu-gather.py +++ b/tests/cputestdata/cpu-gather.py @@ -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") diff --git a/tests/cputestdata/cpu-gather.sh b/tests/cputestdata/cpu-gather.sh index f84215e777..427b81a64b 100755 --- a/tests/cputestdata/cpu-gather.sh +++ b/tests/cputestdata/cpu-gather.sh @@ -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 -- 2.26.2