From patchwork Sat Dec 31 17:12:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitrii Bundin X-Patchwork-Id: 13086153 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id CA4C0C4332F for ; Sat, 31 Dec 2022 17:14:12 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 556CC8E0002; Sat, 31 Dec 2022 12:14:12 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 4DF448E0001; Sat, 31 Dec 2022 12:14:12 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 359E98E0002; Sat, 31 Dec 2022 12:14:12 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id 21EA48E0001 for ; Sat, 31 Dec 2022 12:14:12 -0500 (EST) Received: from smtpin07.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay09.hostedemail.com (Postfix) with ESMTP id E279D80391 for ; Sat, 31 Dec 2022 17:14:11 +0000 (UTC) X-FDA: 80303249502.07.330360F Received: from mail-pf1-f174.google.com (mail-pf1-f174.google.com [209.85.210.174]) by imf21.hostedemail.com (Postfix) with ESMTP id 531CF1C000E for ; Sat, 31 Dec 2022 17:14:10 +0000 (UTC) Authentication-Results: imf21.hostedemail.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=ka+ONasP; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (imf21.hostedemail.com: domain of dmitrii.bundin.a@gmail.com designates 209.85.210.174 as permitted sender) smtp.mailfrom=dmitrii.bundin.a@gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1672506850; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:in-reply-to: references:references:dkim-signature; bh=pBJs4mY/D+ZwJGNCJVKUlWrXepuhs6bh7m8A/RKMgZg=; b=UUZj6H6yoDhKdq6PMgImKQbhKND6Z4mwyBj1C0bTuyFVqvBb3qMgG9QX1RqYJMb43wlFxn 9XiOVOA3JI9cONJhHtvN/gqO9oMLxMnmmBFWnA/C4/HnpNbVTzNkCFVBClguX1OSeABp/3 jSn70KteverRO3K0dAbQB5Mx6mOiAKs= ARC-Authentication-Results: i=1; imf21.hostedemail.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=ka+ONasP; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (imf21.hostedemail.com: domain of dmitrii.bundin.a@gmail.com designates 209.85.210.174 as permitted sender) smtp.mailfrom=dmitrii.bundin.a@gmail.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1672506850; a=rsa-sha256; cv=none; b=lYgRqBS5fDkzaNvrWovUdFcSG97kWXwV6C88NLSal1vdiRgyXN8xSLAogORuBZl1JDXfvm jJV0YhlKAwq/WhCaJrnI8C5oH8axIvx1z4viu6WWnyTAOaiaQ6jG2jdh/BG3gNbKKpXLIS ptnG3U0p+QxEq8cy2KtMzRsoCKuG0U8= Received: by mail-pf1-f174.google.com with SMTP id k137so11450719pfd.8 for ; Sat, 31 Dec 2022 09:14:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=pBJs4mY/D+ZwJGNCJVKUlWrXepuhs6bh7m8A/RKMgZg=; b=ka+ONasPV0NGAT+kb7L1DOdLyCVQh4HVEjdaHNBXYSq2jVz1ayF++MXNeKTy+oHITx /uNnLMQEf0yv16DuHZ51gK1GC96S1q1IOw7nnRtYST41tc0EALiD41sXrK4h+8PAlh7O t0W3N9T3pUMGz5MzIl7uCWzevzeRxt747jiQuKshFYnS3BqCBFKXfBly9vLZIve6IuZm 1JUhprooq7LbTJSH5fJCZgyS4ahdMel/iRm+P+OT7tA9ZpMO87uXW3It51DXe/dLUcqQ DgOOwFTFGfgV/Tt7FMpVOqpPZFtGjkGWKIt8jRWSEV/sR0oD+pIQ4s8qhj1OyKrwz6y6 EXHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=references:in-reply-to:message-id:date:subject:cc:to:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=pBJs4mY/D+ZwJGNCJVKUlWrXepuhs6bh7m8A/RKMgZg=; b=PuMDq/UsjBt/xSR8jVM8uIjXHG06GtOgDZpbZaC4B4iqtke96Mk6SCExMuI1Ub5kC+ Px11cB2/p1MIoqCP0pX6EQWzlA97Vg8AmD1zNR4wrpxYf5iQ4J4+bOhQLbNG8pq3mGna FPQVvsKzkh/HzWjgRcFNgkSQKLb7Vhu50kOX29FT1TF1xBDhTwvraDUJXcGHu5K1ZMZK /ch8B/PAAbMwNQP0BEcP2R/ro8NbwowIOaOZQICdxJfpoMhK1R5ebQNH/XUCDzFe9Po/ janH+CmL6duBmlFfyrmLcN5nbnibKGUGiT5h2ernm5jvX1cSeYhderxuvju/UKjHZ5iF Ii9A== X-Gm-Message-State: AFqh2kpT6tHKrHLf6z1dqDkmQknelluSYTPz5QJDKtDi4K+7tPkZb6BV Gw3cnpaqrrdc2duY28C3ScU= X-Google-Smtp-Source: AMrXdXsS5UhCBnOcrKq75pm+buUGEr+RDiMV7xv5jnU2Lw7TCPP7uOcUqr+8ZajEPTzjACkzWiY8Uw== X-Received: by 2002:aa7:99ce:0:b0:582:243c:49c9 with SMTP id v14-20020aa799ce000000b00582243c49c9mr3403194pfi.28.1672506848896; Sat, 31 Dec 2022 09:14:08 -0800 (PST) Received: from localhost.localdomain ([116.58.254.36]) by smtp.gmail.com with ESMTPSA id f26-20020aa7969a000000b0058103f45d9esm9033091pfk.82.2022.12.31.09.14.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 31 Dec 2022 09:14:08 -0800 (PST) From: Dmitrii Bundin To: dmitrii.bundin.a@gmail.com Cc: akpm@linux-foundation.org, gregkh@linuxfoundation.org, jan.kiszka@siemens.com, kbingham@kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, mingo@redhat.com, vbabka@suse.cz, x86@kernel.org Subject: [PATCH v2] scripts/gdb: add mm introspection utils Date: Sat, 31 Dec 2022 20:12:58 +0300 Message-Id: <20221231171258.7907-1-dmitrii.bundin.a@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221230163512.23736-1-dmitrii.bundin.a@gmail.com> References: <20221230163512.23736-1-dmitrii.bundin.a@gmail.com> X-Rspamd-Queue-Id: 531CF1C000E X-Rspamd-Server: rspam09 X-Rspam-User: X-Stat-Signature: 1w9h1bam76syuhe8w9mo4or48hsnhyn9 X-HE-Tag: 1672506850-377694 X-HE-Meta: U2FsdGVkX1/ujklw3kQPaqIr6s4MVgASzlYANXtMqxIhKXCTu3Q/KHYKfj7aKz7+sllCpj0oIwYSXBoP8yxoOEDw5b58pvmAIH1lSsTHpCu5B4d9Sfhq3B+Eqk7vnLw0jGwofntCKIxNP8WIZ2yMhpIOYM7M9n3cPTvlkgZ0gFKgzIgYqucRTrb5VIIDQ8tqsBRvhkuI6PDiL7BoRxi4Zw+rFBW1HVHks+8flGFNG62Pv5IgPVkOo7LomdMFP/3YIXQS6NxI91ND2d5vLXCyh66i28GFnHgUnmA375oJ2RXSRCj9MYDEyn59iyv0h5ZQAl0g9kR1RQjPxxTAFt2qG2FZoTrbA0Heci+eq8m6PT+ZUVBxnQXewARfjrjR1zcvcbpWCVFLhrY4aakNTpPO+CZ2AnANHEgoAmS/MhdwxLf/W9FsqGsq8azkQ5jHfD0BIUfoFIjouOVmTMsi9inui+NYjGUDWI4Wz3EZ76aa1YppmwSMKDP/hYYRwXP1tEe62bveO4NuqfLPw2uUuO3dwenbknYvPYFNU65LKOYOwwtjjh2nnHBYDhNt2a0SpgV7wVpUJOCuwUgwRi91P8WCHkklGJxTEH0vXoKZzrDfikD0YitAXo+UnKGB9KSyzoo+BKpDf03/wEHHsuCmpbXL7VKszn9aS5dpRwQKJhAQiwykEYB8ZfFvnS0IJPaEEpWWYAMqj9UTFdr4KpiuzFy8lnLHzpe+9Ou4AZmyZEe2joEajgVIcXgC/ONK4Cvqb5qKXp673fE36MZHeoSRB22n3ycecmqOhDLNKxFZUNAySIDw3PoRcwX6Mpel7qBhRCVS+5TuOYiHuqyA4OI028sSYSV338k6oJAlNed6rwbX0BiVrnseS3Kdwaxz1vhbH162U58WLkLGYc65zDWuCUs4Ky8qDZmUr5a3AXP+NMr1gb2tBcnpBil4fa/6pZhOlDzAj2acQFQoyXLbk+l/HyE NimorSB6 5r1cCimbxPlL+yxYARdDSNGvu7nWekT9OklhyiCmfomZXkAq6rFBh3zO6oc7RsmX8bI/evAipzQQX+B76W8rZkBN2xKYK8oAalsEHivPCCoeh+zUCYnJ0JE0Wv+IStWr/ZITdIflbtJ9LORHz1gZNxAeTTFajNF3czjmhbQLBxb+qhP2KbKSF/Fxs1VvxFwNwOyUF X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: This command provides a way to traverse the entire page hierarchy by a given virtual address on x86. In addition to qemu's commands info tlb/info mem it provides the complete information about the paging structure for an arbitrary virtual address. It supports 4KB/2MB/1GB and 5 level paging. Here is an example output for 2MB success translation: (gdb) translate-vm address CR3: CR3 BINARY DATA: 0x10c1d2002 NEXT ENTRY PHYSICALL ADDRESS: 0x10c1d2000 --- PAGE LEVEL WRITE THROUGH(bit 3): False PAGE LEVEL CACHE DISABLED(bit 4): False LEVEL 4: ENTRY ADDRESS: 0xffff88810c1d27f0 PAGE ENTRY BINARY DATA: 0x8000000105dca067 NEXT ENTRY PHYSICALL ADDRESS: 0x105dca000 --- ENTRY PRESENT(bit 0): True READ/WRITE ACCESS ALLOWED(bit 1): True USER ACCESS ALLOWED(bit 2): True PAGE LEVEL WRITE THROUGH(bit 3): False PAGE LEVEL CACHE DISABLED(bit 4): False ENTRY HAS BEEN ACCESSED(bit 5): True PAGE SIZE(bit 7): False RESTART TO ORDINARY(bit 11): False EXECUTE DISABLE(bit 63): True LEVEL 3: ENTRY ADDRESS: 0xffff888105dca9d0 PAGE ENTRY BINARY DATA: 0x105c87067 NEXT ENTRY PHYSICALL ADDRESS: 0x105c87000 --- ENTRY PRESENT(bit 0): True READ/WRITE ACCESS ALLOWED(bit 1): True USER ACCESS ALLOWED(bit 2): True PAGE LEVEL WRITE THROUGH(bit 3): False PAGE LEVEL CACHE DISABLED(bit 4): False ENTRY HAS BEEN ACCESSED(bit 5): True PAGE SIZE(bit 7): False RESTART TO ORDINARY(bit 11): False EXECUTE DISABLE(bit 63): False LEVEL 2: ENTRY ADDRESS: 0xffff888105c87698 PAGE ENTRY BINARY DATA: 0x80000001622008e7 PAGE SIZE: 2MB PAGE PHYSICALL ADDRESS: 0x162200000 --- ENTRY PRESENT(bit 0): True READ/WRITE ACCESS ALLOWED(bit 1): True USER ACCESS ALLOWED(bit 2): True PAGE LEVEL WRITE THROUGH(bit 3): False PAGE LEVEL CACHE DISABLED(bit 4): False ENTRY HAS BEEN ACCESSED(bit 5): True PAGE DIRTY(bit 6): True PAGE SIZE(bit 7): True GLOBAL TRANSLATION(bit 8): False RESTART TO ORDINARY(bit 11): True PAT(bit 12): False PROTECTION KEY(bits (62, 59)): 0 EXECUTE DISABLE(bit 63): True Signed-off-by: Dmitrii Bundin --- Changes in v2: https://lore.kernel.org/all/20221230163512.23736-1-dmitrii.bundin.a@gmail.com/ - Fix commit message to mention x86 explicitly - Assign page_offset_base to a constant in case CONFIG_DYNAMIC_MEMORY_LAYOUT is disabled scripts/gdb/linux/mm.py | 222 +++++++++++++++++++++++++++++++++++++ scripts/gdb/vmlinux-gdb.py | 1 + 2 files changed, 223 insertions(+) create mode 100644 scripts/gdb/linux/mm.py diff --git a/scripts/gdb/linux/mm.py b/scripts/gdb/linux/mm.py new file mode 100644 index 000000000000..1b1d59872b25 --- /dev/null +++ b/scripts/gdb/linux/mm.py @@ -0,0 +1,222 @@ +# +# gdb helper commands and functions for Linux kernel debugging +# +# routines to introspect page table +# +# Authors: +# Dmitrii Bundin +# +# This work is licensed under the terms of the GNU GPL version 2. +# + +import gdb + +from linux import utils + +PHYSICAL_ADDRESS_MASK = gdb.parse_and_eval('0xfffffffffffff') + + +def page_mask(level=1): + # 4KB + if level == 1: + return gdb.parse_and_eval('(u64) ~0xfff') + # 2MB + elif level == 2: + return gdb.parse_and_eval('(u64) ~0x1fffff') + # 1GB + elif level == 3: + return gdb.parse_and_eval('(u64) ~0x3fffffff') + else: + raise Exception(f'Unknown page level: {level}') + + +#page_offset_base in case CONFIG_DYNAMIC_MEMORY_LAYOUT is disabled +POB_NO_DYNAMIC_MEM_LAYOUT = '0xffff888000000000' +def _page_offset_base(): + pob_symbol = gdb.lookup_global_symbol('page_offset_base') + pob = pob_symbol.name if pob_symbol else POB_NO_DYNAMIC_MEM_LAYOUT + return gdb.parse_and_eval(pob) + + +def is_bit_defined_tupled(data, offset): + return offset, bool(data >> offset & 1) + +def content_tupled(data, bit_start, bit_end): + return (bit_end, bit_start), data >> bit_start & ((1 << (1 + bit_end - bit_start)) - 1) + +def entry_va(level, phys_addr, translating_va): + def start_bit(level): + if level == 5: + return 48 + elif level == 4: + return 39 + elif level == 3: + return 30 + elif level == 2: + return 21 + elif level == 1: + return 12 + else: + raise Exception(f'Unknown level {level}') + + entry_offset = ((translating_va >> start_bit(level)) & 511) * 8 + entry_va = _page_offset_base() + phys_addr + entry_offset + return entry_va + +class Cr3(): + def __init__(self, cr3, page_levels): + self.cr3 = cr3 + self.page_levels = page_levels + self.page_level_write_through = is_bit_defined_tupled(cr3, 3) + self.page_level_cache_disabled = is_bit_defined_tupled(cr3, 4) + self.next_entry_physical_address = cr3 & PHYSICAL_ADDRESS_MASK & page_mask() + + def next_entry(self, va): + next_level = self.page_levels + return PageHierarchyEntry(entry_va(next_level, self.next_entry_physical_address, va), next_level) + + def mk_string(self): + return f"""\ +CR3: + CR3 BINARY DATA: {hex(self.cr3)} + NEXT ENTRY PHYSICALL ADDRESS: {hex(self.next_entry_physical_address)} + --- + PAGE LEVEL WRITE THROUGH(bit {self.page_level_write_through[0]}): {self.page_level_write_through[1]} + PAGE LEVEL CACHE DISABLED(bit {self.page_level_cache_disabled[0]}): {self.page_level_cache_disabled[1]} +""" + + +class PageHierarchyEntry(): + def __init__(self, address, level): + data = int.from_bytes( + memoryview(gdb.selected_inferior().read_memory(address, 8)), + "little" + ) + if level == 1: + self.is_page = True + self.entry_present = is_bit_defined_tupled(data, 0) + self.read_write = is_bit_defined_tupled(data, 1) + self.user_access_allowed = is_bit_defined_tupled(data, 2) + self.page_level_write_through = is_bit_defined_tupled(data, 3) + self.page_level_cache_disabled = is_bit_defined_tupled(data, 4) + self.entry_was_accessed = is_bit_defined_tupled(data, 5) + self.dirty = is_bit_defined_tupled(data, 6) + self.pat = is_bit_defined_tupled(data, 7) + self.global_translation = is_bit_defined_tupled(data, 8) + self.page_physical_address = data & PHYSICAL_ADDRESS_MASK & page_mask(level) + self.next_entry_physical_address = None + self.hlat_restart_with_ordinary = is_bit_defined_tupled(data, 11) + self.protection_key = content_tupled(data, 59, 62) + self.executed_disable = is_bit_defined_tupled(data, 63) + else: + page_size = is_bit_defined_tupled(data, 7) + page_size_bit = page_size[1] + self.is_page = page_size_bit + self.entry_present = is_bit_defined_tupled(data, 0) + self.read_write = is_bit_defined_tupled(data, 1) + self.user_access_allowed = is_bit_defined_tupled(data, 2) + self.page_level_write_through = is_bit_defined_tupled(data, 3) + self.page_level_cache_disabled = is_bit_defined_tupled(data, 4) + self.entry_was_accessed = is_bit_defined_tupled(data, 5) + self.page_size = page_size + self.dirty = is_bit_defined_tupled( + data, 6) if page_size_bit else None + self.global_translation = is_bit_defined_tupled( + data, 8) if page_size_bit else None + self.pat = is_bit_defined_tupled( + data, 12) if page_size_bit else None + self.page_physical_address = data & PHYSICAL_ADDRESS_MASK & page_mask(level) if page_size_bit else None + self.next_entry_physical_address = None if page_size_bit else data & PHYSICAL_ADDRESS_MASK & page_mask() + self.hlat_restart_with_ordinary = is_bit_defined_tupled(data, 11) + self.protection_key = content_tupled(data, 59, 62) if page_size_bit else None + self.executed_disable = is_bit_defined_tupled(data, 63) + self.address = address + self.page_entry_binary_data = data + self.page_hierarchy_level = level + + def next_entry(self, va): + if self.is_page or not self.entry_present[1]: + return None + + next_level = self.page_hierarchy_level - 1 + return PageHierarchyEntry(entry_va(next_level, self.next_entry_physical_address, va), next_level) + + + def mk_string(self): + if not self.entry_present[1]: + return f"""\ +LEVEL {self.page_hierarchy_level}: + ENTRY ADDRESS: {hex(self.address)} + PAGE ENTRY BINARY DATA: {hex(self.page_entry_binary_data)} + --- + PAGE ENTRY IS NOT PRESENT! +""" + elif self.is_page: + return f"""\ +LEVEL {self.page_hierarchy_level}: + ENTRY ADDRESS: {hex(self.address)} + PAGE ENTRY BINARY DATA: {hex(self.page_entry_binary_data)} + PAGE SIZE: {'1GB' if self.page_hierarchy_level == 3 else '2MB' if self.page_hierarchy_level == 2 else '4KB' if self.page_hierarchy_level == 1 else 'Unknown page size for level:' + self.page_hierarchy_level} + PAGE PHYSICALL ADDRESS: {hex(self.page_physical_address)} + --- + ENTRY PRESENT(bit {self.entry_present[0]}): {self.entry_present[1]} + READ/WRITE ACCESS ALLOWED(bit {self.read_write[0]}): {self.read_write[1]} + USER ACCESS ALLOWED(bit {self.user_access_allowed[0]}): {self.user_access_allowed[1]} + PAGE LEVEL WRITE THROUGH(bit {self.page_level_write_through[0]}): {self.page_level_write_through[1]} + PAGE LEVEL CACHE DISABLED(bit {self.page_level_cache_disabled[0]}): {self.page_level_cache_disabled[1]} + ENTRY HAS BEEN ACCESSED(bit {self.entry_was_accessed[0]}): {self.entry_was_accessed[1]} + PAGE DIRTY(bit {self.dirty[0]}): {self.dirty[1]} + """ + \ + ("" if self.page_hierarchy_level == 1 else f"""PAGE SIZE(bit {self.page_size[0]}): {self.page_size[1]} + """) + \ + f"""GLOBAL TRANSLATION(bit {self.global_translation[0]}): {self.global_translation[1]} + RESTART TO ORDINARY(bit {self.hlat_restart_with_ordinary[0]}): {self.hlat_restart_with_ordinary[1]} + PAT(bit {self.pat[0]}): {self.pat[1]} + PROTECTION KEY(bits {self.protection_key[0]}): {self.protection_key[1]} + EXECUTE DISABLE(bit {self.executed_disable[0]}): {self.executed_disable[1]} +""" + else: + return f"""\ +LEVEL {self.page_hierarchy_level}: + ENTRY ADDRESS: {hex(self.address)} + PAGE ENTRY BINARY DATA: {hex(self.page_entry_binary_data)} + NEXT ENTRY PHYSICALL ADDRESS: {hex(self.next_entry_physical_address)} + --- + ENTRY PRESENT(bit {self.entry_present[0]}): {self.entry_present[1]} + READ/WRITE ACCESS ALLOWED(bit {self.read_write[0]}): {self.read_write[1]} + USER ACCESS ALLOWED(bit {self.user_access_allowed[0]}): {self.user_access_allowed[1]} + PAGE LEVEL WRITE THROUGH(bit {self.page_level_write_through[0]}): {self.page_level_write_through[1]} + PAGE LEVEL CACHE DISABLED(bit {self.page_level_cache_disabled[0]}): {self.page_level_cache_disabled[1]} + ENTRY HAS BEEN ACCESSED(bit {self.entry_was_accessed[0]}): {self.entry_was_accessed[1]} + PAGE SIZE(bit {self.page_size[0]}): {self.page_size[1]} + RESTART TO ORDINARY(bit {self.hlat_restart_with_ordinary[0]}): {self.hlat_restart_with_ordinary[1]} + EXECUTE DISABLE(bit {self.executed_disable[0]}): {self.executed_disable[1]} +""" + + +class TranslateVM(gdb.Command): + """Prints the entire paging structure used to translate a given virtual address. + +Having an address space of the currently executed process translates the virtual address +and prints detailed information of all paging structure levels used for the transaltion.""" + + def __init__(self): + super(TranslateVM, self).__init__('translate-vm', gdb.COMMAND_USER) + + def invoke(self, arg, from_tty): + if utils.is_target_arch("x86"): + vm_address = gdb.parse_and_eval(f'{arg}') + cr3_data = gdb.parse_and_eval('$cr3') + cr4 = gdb.parse_and_eval('$cr4') + page_levels = 5 if cr4 & (1 << 12) else 4 + page_entry = Cr3(cr3_data, page_levels) + while page_entry: + gdb.write(page_entry.mk_string()) + page_entry = page_entry.next_entry(vm_address) + else: + gdb.GdbError("Virtual address translation is not" + "supported for this arch") + + + +TranslateVM() diff --git a/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py index 4136dc2c59df..27bd7339bccc 100644 --- a/scripts/gdb/vmlinux-gdb.py +++ b/scripts/gdb/vmlinux-gdb.py @@ -37,3 +37,4 @@ else: import linux.clk import linux.genpd import linux.device + import linux.mm