From nobody Sat Feb 7 07:09:36 2026 Received: from mail-pf1-f181.google.com (mail-pf1-f181.google.com [209.85.210.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 46F25199252 for ; Mon, 2 Feb 2026 03:43:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770003786; cv=none; b=MxH90JU/V0dgcVXJqe5Amc8xvuBw/3Iw/SWVbh0YCuvKDfS2goRNuFE6aO8NwCDatBYVG33OzIQQt4kS/HSZ36lm4Rx6fLZL3GaZQx7HxbqT5WMVQtqzRwxs/+RbW8/RaICkCB3PyCkbid0+0EVnAQn9S3OGasycQBfIxiFBjpQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770003786; c=relaxed/simple; bh=qTAdGUCkDGx1xb17AYbZLDKLQQ4D31ys42/GgmhOhYM=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=lQsGtRwDtMRA0oAYEHOMmF0TmN8zyCD3blX/tLQ/o4HZqXFCeFwemSTCM6kIopDzDqKR9JRqW+hBjAzU8G1epdnjUm0TuGet2ulw7TujraMWLKa9SiDkGlUhNEGT1+WXQUFQ9G/fg/09sxZEBaTH7xlSsnzudeuQG/UIHKvlukI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=snu.ac.kr; spf=pass smtp.mailfrom=snu.ac.kr; dkim=pass (1024-bit key) header.d=snu.ac.kr header.i=@snu.ac.kr header.b=gJwllH6u; arc=none smtp.client-ip=209.85.210.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=snu.ac.kr Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=snu.ac.kr Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=snu.ac.kr header.i=@snu.ac.kr header.b="gJwllH6u" Received: by mail-pf1-f181.google.com with SMTP id d2e1a72fcca58-81e821c3d4eso3325773b3a.3 for ; Sun, 01 Feb 2026 19:43:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=snu.ac.kr; s=google; t=1770003779; x=1770608579; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=ciqKfRVLG/v0I+8MoGvldwMxozTJ9igVf8oG/EyCvGY=; b=gJwllH6u7VoAgBEwE/ENVq3aAl6D1tj+oy69B4jY7Xa9I+k8nm1bZ5+earW7kJyN0E l+SwFBHfimKDAMHr3ihB6rHMccIlsLjTPYIqbHl86NgZdlaA1myexwNnLU6y1IR3+i9S DJ1MZmTLXZlSPeq7GYUjNM28vsgPsvrtA9LuM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770003779; x=1770608579; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=ciqKfRVLG/v0I+8MoGvldwMxozTJ9igVf8oG/EyCvGY=; b=r0qVEGNKXDANhEyjrlOqzq7YZIk128eTyMHcKDEmP+zusur5/Aw8+vAmiplHRPG/E4 81xIFxLCGTmvTFrODyM/MitsH8do1+0m3z/u6jb0ppJZ2a2f2GnH3i4f9DF3luABlrbm QffC/+Yz3EQAsBzblp/4eutriJFeLFfrGlpRH2LuO0g/g1uGEKV8usp4yhdUrIJDTeXy gkdMC3s6c3VsA7J+4RQdkwOEBbMf1sfutvlutWY6IJNIwtB8eZb8N9UDob2je2yD0Njf kBEHHYjlKVAtceb01C3Rvul/k6wH6N1E9Y08G6ZjpwLjVYcmA3CSpjiaXxZdCTl9piMk IoSA== X-Gm-Message-State: AOJu0YzmKXXHAaHxBkQycmZCK9iYAt+cKw3tqzTfyd5a770woDfVrq36 57QY+HKOLkIjCzyda1KGNUO83lTUoE5mEL0ucoBd9tCoSZgatr6zJMzK4y7suf4eCvY= X-Gm-Gg: AZuq6aIvlU9kJEiyUTM3g0CsNJ9QDvqsEzk/qx8fdlLTNh2Y+jJIBAWTPyPjT3WkXWa 92VkfECTFpMPnwvbcq5H9nsZYSKaFixqJrkKk0WySPVuSw+nBfaJyalquoW6DNKqvM9msqeJ+/e 2teinfR/ScvmxuSVdzXcBxo1PeB4AtaB+57T2WcWV2JXZm7as7YbcE/yHWdfG+1xOCfmP7LdXuf 9I2fDwvUkLIjkIi4NDaeBnG1U8CQWS4wVrHugSCP+uBPsbd/JDOHOlLGS0kYwUuXLawetEIzI8s f+901JYzUsE4SmmmgRMfX7HDH5OInxNcrDt6fCrTcOsz0hHUwW7e6TtGjESipvnCFbqSGr0B0Ec +GObYJ5oU6+I1+kg2O00zCojj1yUs0MvEAZ8JpklkJnG8gCdg9/Enesnr1nNcIb3pUBOu3vMy50 j474VsVgvp X-Received: by 2002:a05:6a00:428b:b0:81e:12f1:d83 with SMTP id d2e1a72fcca58-823ab72da2emr8897889b3a.42.1770003779577; Sun, 01 Feb 2026 19:42:59 -0800 (PST) Received: from jun-B650M-K.. ([211.54.62.160]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-82379b6a5desm12875225b3a.28.2026.02.01.19.42.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 01 Feb 2026 19:42:59 -0800 (PST) From: Seongjun Hong To: jan.kiszka@siemens.com, kbingham@kernel.org Cc: linux-kernel@vger.kernel.org, akpm@linux-foundation.org, Seongjun Hong Subject: [PATCH v2] scripts/gdb: implement x86_page_ops in mm.py Date: Mon, 2 Feb 2026 12:42:41 +0900 Message-Id: <20260202034241.649268-1-hsj0512@snu.ac.kr> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Implement all member functions of x86_page_ops strictly following the logic of aarch64_page_ops. This includes full support for SPARSEMEM and standard page translation functions. This fixes compatibility with 'lx-' commands on x86_64, preventing AttributeErrors when using lx-pfn_to_page and others. Signed-off-by: Seongjun Hong --- Changes in v2: * Implement full x86_page_ops including SPARSEMEM support to match aarch64. scripts/gdb/linux/constants.py.in | 2 +- scripts/gdb/linux/mm.py | 173 +++++++++++++++++++++++++++++- 2 files changed, 173 insertions(+), 2 deletions(-) diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constant= s.py.in index c3886739a028..11fd4ba6ba85 100644 --- a/scripts/gdb/linux/constants.py.in +++ b/scripts/gdb/linux/constants.py.in @@ -150,8 +150,8 @@ LX_CONFIG(CONFIG_ARM64_64K_PAGES) if IS_BUILTIN(CONFIG_ARM64): LX_VALUE(CONFIG_ARM64_PA_BITS) LX_VALUE(CONFIG_ARM64_VA_BITS) - LX_VALUE(CONFIG_PAGE_SHIFT) LX_VALUE(CONFIG_ARCH_FORCE_MAX_ORDER) +LX_VALUE(CONFIG_PAGE_SHIFT) LX_CONFIG(CONFIG_SPARSEMEM) LX_CONFIG(CONFIG_SPARSEMEM_EXTREME) LX_CONFIG(CONFIG_SPARSEMEM_VMEMMAP) diff --git a/scripts/gdb/linux/mm.py b/scripts/gdb/linux/mm.py index 7571aebbe650..d78908f6664d 100644 --- a/scripts/gdb/linux/mm.py +++ b/scripts/gdb/linux/mm.py @@ -26,8 +26,179 @@ class page_ops(): raise gdb.GdbError('Only support CONFIG_SPARSEMEM_VMEMMAP now') if constants.LX_CONFIG_ARM64 and utils.is_target_arch('aarch64'): self.ops =3D aarch64_page_ops() + elif utils.is_target_arch('x86_64') or utils.is_target_arch('x86-6= 4'): + self.ops =3D x86_page_ops() else: - raise gdb.GdbError('Only support aarch64 now') + raise gdb.GdbError('Only support aarch64 and x86_64 now') + +class x86_page_ops(): + def __init__(self): + self.struct_page_size =3D utils.get_page_type().sizeof + self.PAGE_SHIFT =3D constants.LX_CONFIG_PAGE_SHIFT + self.PAGE_SIZE =3D 1 << self.PAGE_SHIFT + self.PAGE_MASK =3D (~(self.PAGE_SIZE - 1)) & ((1 << 64) - 1) + + self.PAGE_OFFSET =3D int(gdb.parse_and_eval("page_offset_base")) + self.VMEMMAP_START =3D int(gdb.parse_and_eval("vmemmap_base")) + self.PHYS_BASE =3D int(gdb.parse_and_eval("phys_base")) + self.START_KERNEL_map =3D 0xffffffff80000000 + + self.KERNEL_START =3D gdb.parse_and_eval("_text") + self.KERNEL_END =3D gdb.parse_and_eval("_end") + + self.VMALLOC_START =3D int(gdb.parse_and_eval("vmalloc_base")) + if self.VMALLOC_START =3D=3D 0xffffc90000000000: + self.VMALLOC_END =3D self.VMALLOC_START + (32 * 1024 * 1024 * = 1024 * 1024) - 1 + elif self.VMALLOC_START =3D=3D 0xffa0000000000000: + self.VMALLOC_END =3D self.VMALLOC_START + (12800 * 1024 * 1024= * 1024 * 1024) - 1 + else: + self.VMALLOC_END =3D self.VMALLOC_START + (12800 * 1024 * 1024= * 1024 * 1024) - 1 + + self.MAX_PHYSMEM_BITS =3D 46 + self.SECTION_SIZE_BITS =3D 27 + self.MAX_ORDER =3D 10 + + self.SECTIONS_SHIFT =3D self.MAX_PHYSMEM_BITS - self.SECTION_SIZE_= BITS + self.NR_MEM_SECTIONS =3D 1 << self.SECTIONS_SHIFT + self.PFN_SECTION_SHIFT =3D self.SECTION_SIZE_BITS - self.PAGE_SHIFT + self.PAGES_PER_SECTION =3D 1 << self.PFN_SECTION_SHIFT + self.PAGE_SECTION_MASK =3D (~(self.PAGES_PER_SECTION - 1)) & ((1 <= < 64) - 1) + + if constants.LX_CONFIG_SPARSEMEM_EXTREME: + self.SECTIONS_PER_ROOT =3D self.PAGE_SIZE // gdb.lookup_type("= struct mem_section").sizeof + else: + self.SECTIONS_PER_ROOT =3D 1 + + self.NR_SECTION_ROOTS =3D DIV_ROUND_UP(self.NR_MEM_SECTIONS, self.= SECTIONS_PER_ROOT) + self.SECTION_ROOT_MASK =3D self.SECTIONS_PER_ROOT - 1 + + try: + self.SECTION_HAS_MEM_MAP =3D 1 << int(gdb.parse_and_eval('SECT= ION_HAS_MEM_MAP_BIT')) + self.SECTION_IS_EARLY =3D 1 << int(gdb.parse_and_eval('SECTION= _IS_EARLY_BIT')) + except: + self.SECTION_HAS_MEM_MAP =3D 1 << 0 + self.SECTION_IS_EARLY =3D 1 << 3 + + self.SUBSECTION_SHIFT =3D 21 + self.PAGES_PER_SUBSECTION =3D 1 << (self.SUBSECTION_SHIFT - self.P= AGE_SHIFT) + + if constants.LX_CONFIG_NUMA and constants.LX_CONFIG_NODES_SHIFT: + self.NODE_SHIFT =3D constants.LX_CONFIG_NODES_SHIFT + else: + self.NODE_SHIFT =3D 0 + + self.MAX_NUMNODES =3D 1 << self.NODE_SHIFT + + self.vmemmap =3D gdb.Value(self.VMEMMAP_START).cast(utils.get_page= _type().pointer()) + + def kasan_reset_tag(self, addr): + return addr + + def SECTION_NR_TO_ROOT(self, sec): + return sec // self.SECTIONS_PER_ROOT + + def __nr_to_section(self, nr): + root =3D self.SECTION_NR_TO_ROOT(nr) + mem_section =3D gdb.parse_and_eval("mem_section") + return mem_section[root][nr & self.SECTION_ROOT_MASK] + + def pfn_to_section_nr(self, pfn): + return pfn >> self.PFN_SECTION_SHIFT + + def section_nr_to_pfn(self, sec): + return sec << self.PFN_SECTION_SHIFT + + def __pfn_to_section(self, pfn): + return self.__nr_to_section(self.pfn_to_section_nr(pfn)) + + def pfn_to_section(self, pfn): + return self.__pfn_to_section(pfn) + + def subsection_map_index(self, pfn): + return (pfn & ~(self.PAGE_SECTION_MASK)) // self.PAGES_PER_SUBSECT= ION + + def pfn_section_valid(self, ms, pfn): + if constants.LX_CONFIG_SPARSEMEM_VMEMMAP: + idx =3D self.subsection_map_index(pfn) + return test_bit(idx, ms['usage']['subsection_map']) + else: + return True + + def valid_section(self, mem_section): + if mem_section !=3D None and (mem_section['section_mem_map'] & sel= f.SECTION_HAS_MEM_MAP): + return True + return False + + def early_section(self, mem_section): + if mem_section !=3D None and (mem_section['section_mem_map'] & sel= f.SECTION_IS_EARLY): + return True + return False + + def pfn_valid(self, pfn): + ms =3D None + if self.PHYS_PFN(self.PFN_PHYS(pfn)) !=3D pfn: + return False + if self.pfn_to_section_nr(pfn) >=3D self.NR_MEM_SECTIONS: + return False + ms =3D self.__pfn_to_section(pfn) + + if not self.valid_section(ms): + return False + return self.early_section(ms) or self.pfn_section_valid(ms, pfn) + + def PFN_PHYS(self, pfn): + return pfn << self.PAGE_SHIFT + + def PHYS_PFN(self, phys): + return phys >> self.PAGE_SHIFT + + def __phys_to_virt(self, pa): + return pa + self.PAGE_OFFSET + + def __virt_to_phys(self, va): + if va >=3D self.START_KERNEL_map: + return va - self.START_KERNEL_map + self.PHYS_BASE + else: + return va - self.PAGE_OFFSET + + def virt_to_phys(self, va): + return self.__virt_to_phys(va) + + def virt_to_page(self, va): + return self.pfn_to_page(self.virt_to_pfn(va)) + + def __pa(self, va): + return self.__virt_to_phys(va) + + def __va(self, pa): + return self.__phys_to_virt(pa) + + def pfn_to_kaddr(self, pfn): + return self.__va(pfn << self.PAGE_SHIFT) + + def virt_to_pfn(self, va): + return self.PHYS_PFN(self.__virt_to_phys(va)) + + def sym_to_pfn(self, x): + return self.PHYS_PFN(self.__virt_to_phys(x)) + + def page_to_pfn(self, page): + return int(page.cast(utils.get_page_type().pointer()) - self.vmemm= ap) + + def pfn_to_page(self, pfn): + return self.vmemmap + pfn + + def page_to_phys(self, page): + return self.PFN_PHYS(self.page_to_pfn(page)) + + def page_to_virt(self, page): + return self.__va(self.page_to_phys(page)) + + def page_address(self, page): + return self.page_to_virt(page) + + def folio_address(self, folio): + return self.page_address(folio['page'].address) =20 class aarch64_page_ops(): def __init__(self): --=20 2.34.1