@ -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):