diff options
-rwxr-xr-x | scripts/kvm/kvm_stat | 125 |
1 files changed, 67 insertions, 58 deletions
diff --git a/scripts/kvm/kvm_stat b/scripts/kvm/kvm_stat index bf948b9cc0..42d35f5d95 100755 --- a/scripts/kvm/kvm_stat +++ b/scripts/kvm/kvm_stat @@ -213,62 +213,72 @@ X86_EXIT_REASONS = { 'svm': SVM_EXIT_REASONS, } -SC_PERF_EVT_OPEN = None -EXIT_REASONS = None - IOCTL_NUMBERS = { - 'SET_FILTER' : 0x40082406, - 'ENABLE' : 0x00002400, - 'DISABLE' : 0x00002401, - 'RESET' : 0x00002403, + 'SET_FILTER': 0x40082406, + 'ENABLE': 0x00002400, + 'DISABLE': 0x00002401, + 'RESET': 0x00002403, } -def x86_init(flag): - global SC_PERF_EVT_OPEN - global EXIT_REASONS - - SC_PERF_EVT_OPEN = 298 - EXIT_REASONS = X86_EXIT_REASONS[flag] - -def s390_init(): - global SC_PERF_EVT_OPEN - - SC_PERF_EVT_OPEN = 331 - -def ppc_init(): - global SC_PERF_EVT_OPEN - global IOCTL_NUMBERS - - SC_PERF_EVT_OPEN = 319 +class Arch(object): + """Class that encapsulates global architecture specific data like + syscall and ioctl numbers. - IOCTL_NUMBERS['ENABLE'] = 0x20002400 - IOCTL_NUMBERS['DISABLE'] = 0x20002401 - IOCTL_NUMBERS['SET_FILTER'] = 0x80002406 | (ctypes.sizeof(ctypes.c_char_p) - << 16) + """ + @staticmethod + def get_arch(): + machine = os.uname()[4] + + if machine.startswith('ppc'): + return ArchPPC() + elif machine.startswith('aarch64'): + return ArchA64() + elif machine.startswith('s390'): + return ArchS390() + else: + # X86_64 + for line in open('/proc/cpuinfo'): + if not line.startswith('flags'): + continue + + flags = line.split() + if 'vmx' in flags: + return ArchX86(VMX_EXIT_REASONS) + if 'svm' in flags: + return ArchX86(SVM_EXIT_REASONS) + return + +class ArchX86(Arch): + def __init__(self, exit_reasons): + self.sc_perf_evt_open = 298 + self.ioctl_numbers = IOCTL_NUMBERS + self.exit_reasons = exit_reasons + +class ArchPPC(Arch): + def __init__(self): + self.sc_perf_evt_open = 319 + self.ioctl_numbers = IOCTL_NUMBERS + self.ioctl_numbers['ENABLE'] = 0x20002400 + self.ioctl_numbers['DISABLE'] = 0x20002401 -def aarch64_init(): - global SC_PERF_EVT_OPEN - global EXIT_REASONS + # PPC comes in 32 and 64 bit and some generated ioctl + # numbers depend on the wordsize. + char_ptr_size = ctypes.sizeof(ctypes.c_char_p) + self.ioctl_numbers['SET_FILTER'] = 0x80002406 | char_ptr_size << 16 - SC_PERF_EVT_OPEN = 241 - EXIT_REASONS = AARCH64_EXIT_REASONS +class ArchA64(Arch): + def __init__(self): + self.sc_perf_evt_open = 241 + self.ioctl_numbers = IOCTL_NUMBERS + self.exit_reasons = AARCH64_EXIT_REASONS -def detect_platform(): - machine = os.uname()[4] +class ArchS390(Arch): + def __init__(self): + self.sc_perf_evt_open = 331 + self.ioctl_numbers = IOCTL_NUMBERS + self.exit_reasons = None - if machine.startswith('ppc'): - ppc_init() - elif machine.startswith('aarch64'): - aarch64_init() - elif machine.startswith('s390'): - s390_init() - else: - for line in file('/proc/cpuinfo').readlines(): - if line.startswith('flags'): - for flag in line.split(): - if flag in X86_EXIT_REASONS: - x86_init(flag) - return +ARCH = Arch.get_arch() def walkdir(path): @@ -304,11 +314,10 @@ def get_online_cpus(): def get_filters(): - detect_platform() filters = {} filters['kvm_userspace_exit'] = ('reason', USERSPACE_EXIT_REASONS) - if EXIT_REASONS: - filters['kvm_exit'] = ('exit_reason', EXIT_REASONS) + if ARCH.exit_reasons: + filters['kvm_exit'] = ('exit_reason', ARCH.exit_reasons) return filters libc = ctypes.CDLL('libc.so.6', use_errno=True) @@ -328,9 +337,9 @@ class perf_event_attr(ctypes.Structure): ('bp_len', ctypes.c_uint64), ] def perf_event_open(attr, pid, cpu, group_fd, flags): - return syscall(SC_PERF_EVT_OPEN, ctypes.pointer(attr), ctypes.c_int(pid), - ctypes.c_int(cpu), ctypes.c_int(group_fd), - ctypes.c_long(flags)) + return syscall(ARCH.sc_perf_evt_open, ctypes.pointer(attr), + ctypes.c_int(pid), ctypes.c_int(cpu), + ctypes.c_int(group_fd), ctypes.c_long(flags)) PERF_TYPE_TRACEPOINT = 2 PERF_FORMAT_GROUP = 1 << 3 @@ -388,19 +397,19 @@ class Event(object): 'while calling sys_perf_event_open().') if trace_filter: - fcntl.ioctl(fd, IOCTL_NUMBERS['SET_FILTER'], + fcntl.ioctl(fd, ARCH.ioctl_numbers['SET_FILTER'], trace_filter) self.fd = fd def enable(self): - fcntl.ioctl(self.fd, IOCTL_NUMBERS['ENABLE'], 0) + fcntl.ioctl(self.fd, ARCH.ioctl_numbers['ENABLE'], 0) def disable(self): - fcntl.ioctl(self.fd, IOCTL_NUMBERS['DISABLE'], 0) + fcntl.ioctl(self.fd, ARCH.ioctl_numbers['DISABLE'], 0) def reset(self): - fcntl.ioctl(self.fd, IOCTL_NUMBERS['RESET'], 0) + fcntl.ioctl(self.fd, ARCH.ioctl_numbers['RESET'], 0) class TracepointProvider(object): def __init__(self): |