Skip to content
Snippets Groups Projects
Commit 10b7d1f5 authored by Shivendra Pratap's avatar Shivendra Pratap
Browse files

lrdp_v2 : Fix VA translations for kernel versions > v4.20


Since kernel v5.0, there is a dedicated region of size 128MB
kept aside for BPF programs(BPF_JIT_REGION) which were
previously using module region. Also in v5.4, kernel VA space
was flipped to accomodate support for kasan shadow and 52bit VA.
Hence we are updating the VA space calculations in parser to make
it work on newer kernel.

Adding few changes on linux banner read and match for cleanup.

There was an unmonitored variable ramdump.version being used in
debug_image_v2 cauing version check failure. Adding a change to
use kernel_version.
Fix intend in debug_image_v2.

Briefly, the calculations are updated as below:

_PAGE_END(va)		= (-(UL(1) << ((va) - 1))) = 0xffffffc000000000
KASAN_SHADOW_END	= (_PAGE_END(VA_BITS_MIN)) = 0xffffffc000000000
BPF_JIT_REGION_START	= (KASAN_SHADOW_END)
BPF_JIT_REGION_SIZE	= (SZ_128M)
BPF_JIT_REGION_END	= (BPF_JIT_REGION_START + BPF_JIT_REGION_SIZE) = 0xffffffc000000000 + 0x8000000
MODULES_VADDR		= (BPF_JIT_REGION_END)
MODULES_END		= (MODULES_VADDR + MODULES_VSIZE) = 0xffffffc000000000 + 0x8000000 + 0x8000000 = 0xffffffc010000000
KIMAGE_VADDR		= (MODULES_END) = 0xffffffc010000000

Change-Id: I5a65b327e015970d68c41210fc813105fd6cb4b8
Signed-off-by: default avatarSai Prakash Ranjan <saiprakash.ranjan@codeaurora.org>
Signed-off-by: default avatarShivendra Pratap <spratap@codeaurora.org>
parent cfebbeeb
No related branches found
No related tags found
No related merge requests found
......@@ -135,8 +135,7 @@ class DebugImage_v2():
self.dump_type_lookup_table = []
self.dump_table_id_lookup_table = []
self.dump_data_id_lookup_table = {}
version = re.findall(r'\d+', ramdump.version)
if int(version[0]) > 3:
if ramdump.kernel_version > (3, 9, 9):
self.event_call = 'struct trace_event_call'
self.event_class = 'struct trace_event_class'
else:
......@@ -191,7 +190,7 @@ class DebugImage_v2():
try:
cpuss_parser_path = local_settings.cpuss_parser_path
cpuss_parser_json = local_settings.cpuss_parser_json
except AttributeError:
except AttributeError:
print_out_str('Could not find cpuss_parser_path . Please define cpuss_parser_path in local_settings')
return
offset = None
......
......@@ -522,6 +522,7 @@ class RamDump():
self.ipc_log_help = options.ipc_help
self.use_stdout = options.stdout
self.kernel_version = (0, 0, 0)
self.linux_banner = None
self.minidump = options.minidump
self.elffile = None
self.ram_elf_file = None
......@@ -605,17 +606,31 @@ class RamDump():
self.page_offset = options.page_offset
self.setup_symbol_tables()
va_bits = 39
modules_vsize = 0x08000000
self.va_start = (0xffffffffffffffff << va_bits) \
& 0xffffffffffffffff
if self.address_of("kasan_init") is None:
self.kasan_shadow_size = 0
if self.get_kernel_version() > (4, 20, 0):
va_bits = 39
modules_vsize = 0x08000000
bpf_jit_vsize = 0x08000000
self.page_end = (0xffffffffffffffff << (va_bits - 1)) & 0xffffffffffffffff
if self.address_of("kasan_init") is None:
self.kasan_shadow_size = 0
else:
self.kasan_shadow_size = 1 << (va_bits - 3)
self.kimage_vaddr = self.page_end + self.kasan_shadow_size + modules_vsize + \
bpf_jit_vsize
else:
self.kasan_shadow_size = 1 << (va_bits - 3)
va_bits = 39
modules_vsize = 0x08000000
self.va_start = (0xffffffffffffffff << va_bits) & 0xffffffffffffffff
if self.address_of("kasan_init") is None:
self.kasan_shadow_size = 0
else:
self.kasan_shadow_size = 1 << (va_bits - 3)
self.kimage_vaddr = self.va_start + self.kasan_shadow_size + \
modules_vsize
self.kimage_vaddr = self.va_start + self.kasan_shadow_size + \
modules_vsize
print_out_str("Kernel version vmlinux: {0}".format(self.kernel_version))
self.kimage_vaddr = self.kimage_vaddr + self.get_kaslr_offset()
self.modules_end = self.page_offset
if self.arm64:
......@@ -695,7 +710,7 @@ class RamDump():
'!!! This is a BUG in the parser and should be reported.')
sys.exit(1)
if not self.get_matched_version():
if not self.match_version():
print_out_str('!!! Could not get the Linux version!')
print_out_str(
'!!! Your vmlinux is probably wrong for these dumps')
......@@ -796,6 +811,28 @@ class RamDump():
def is_config_defined(self, config):
return config in self.config_dict
def get_kernel_version(self):
if self.kernel_version == (0, 0, 0):
vm_v = self.gdbmi.get_value_of_string('linux_banner')
if vm_v is None:
print_out_str('!!! Could not read linux_banner from vmlinux!')
sys.exit(1)
v = re.search('Linux version (\d{0,2}\.\d{0,2}\.\d{0,2})', vm_v)
if v is None:
print_out_str('!!! Could not extract version info!')
sys.exit(1)
self.version = v.group(1)
match = re.search('(\d+)\.(\d+)\.(\d+)', self.version)
if match is not None:
self.version = tuple(map(int, match.groups()))
self.kernel_version = self.version
self.linux_banner = vm_v
else:
print_out_str('!!! Could not extract version info! {0}'.format(self.version))
sys.exit(1)
return self.kernel_version
def kernel_virt_to_phys(self, addr):
if self.minidump:
return minidump_util.minidump_virt_to_phys(self.ebi_files_minidump,addr)
......@@ -804,47 +841,37 @@ class RamDump():
if self.kimage_voffset is None:
return addr - self.page_offset + self.phys_offset
else:
if addr & (1 << (va_bits - 1)):
return addr - self.page_offset + self.phys_offset
if self.kernel_version > (4, 20, 0):
if not (addr & (1 << (va_bits - 1))):
return addr - self.page_offset + self.phys_offset
else:
return addr - (self.kimage_voffset)
else:
return addr - (self.kimage_voffset)
if addr & (1 << (va_bits - 1)):
return addr - self.page_offset + self.phys_offset
else:
return addr - (self.kimage_voffset)
def get_matched_version(self):
def match_version(self):
banner_addr = self.address_of('linux_banner')
if banner_addr is not None:
banner_addr = self.kernel_virt_to_phys(banner_addr)
vm_v = self.gdbmi.get_value_of_string('linux_banner')
if vm_v is None:
print_out_str('!!! Could not read banner address from vmlinux!')
return False
banner_len = len(vm_v)
banner_len = len(self.linux_banner)
b = self.read_cstring(banner_addr, banner_len, False)
if b is None:
print_out_str('!!! Could not read banner address!')
print_out_str('!!! Banner not found in dumps!')
return False
v = re.search('Linux version (\d{0,2}\.\d{0,2}\.\d{0,2})', b)
if v is None:
print_out_str('!!! Could not match version! {0}'.format(b))
return False
self.version = v.group(1)
match = re.search('(\d+)\.(\d+)\.(\d+)', self.version)
if match is not None:
self.kernel_version = tuple(map(int, match.groups()))
else:
print_out_str('!!! Could not extract version info! {0}'.format(self.version))
print_out_str('Linux Banner: ' + b.rstrip())
print_out_str('version = {0}'.format(self.version))
if str(vm_v) in str(b):
print_out_str("Linux banner from vmlinux = %s" % vm_v)
if str(self.linux_banner) in str(b):
print_out_str("Linux banner from vmlinux = %s" % self.linux_banner)
print_out_str("Linux banner from dump = %s" % b)
return True
else:
print_out_str("Expected Linux banner = %s" % vm_v)
print_out_str("But Linux banner got = %s" % b)
print_out_str("Expected Linux banner = %s" % self.linux_banner)
print_out_str("Linux banner in Dumps = %s" % b)
return False
else:
print_out_str('!!! Could not lookup banner address')
print_out_str('!!! linux_banner sym not found in vmlinux')
return False
def print_command_line(self):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment