Hi Lianbo

Kernel commit 55564814a838 ("arm64/mm: Move PTE_PRESENT_INVALID
to overlay PTE_NG"), which is contained in Linux 6.10 and
later kernels, changed the format of swap entries on arm64.
Without the patch, the "vtop" command cannot display swap information

before:
    crash> vtop 2000000
    VIRTUAL     PHYSICAL
    2000000     (not mapped)

    PAGE DIRECTORY: ffffff8106356000
       PGD: ffffff8106356000 => 800000186355003
       PMD: ffffff8106355080 => 8000001476f5003
       PTE: ffffff80c76f5000 => 101a62004

       PTE       OFFSET: 1055330
    vtop: cannot determine swap location

without the patch:
    crash> vtop 2000000
    VIRTUAL     PHYSICAL
    2000000     (not mapped)

    PAGE DIRECTORY: ffffff8106356000
       PGD: ffffff8106356000 => 800000186355003
       PMD: ffffff8106355080 => 8000001476f5003
       PTE: ffffff80c76f5000 => 101a62004

       PTE                     SWAP                  OFFSET
    101a62004  /first_stage_ramdisk/dev/block/zram0  1055330

          VMA           START       END     FLAGS FILE
    ffffff81a06e8b00    2000000   22000000 100073

    SWAP: /first_stage_ramdisk/dev/block/zram0  OFFSET: 1055330

Link: https://lore.kernel.org/r/20240503144604.151095-4-ryan.roberts@arm.com
Signed-off-by: Guanyou.Chen <chenguanyou@xiaomi.com>
---
 arm64.c  | 11 ++++++++++-
 memory.c |  5 ++++-
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/arm64.c b/arm64.c
index 1723595..c125655 100644
--- a/arm64.c
+++ b/arm64.c
@@ -712,7 +712,16 @@ arm64_init(int when)
            }
        }

-       if (THIS_KERNEL_VERSION >= LINUX(5,19,0)) {
+       if (THIS_KERNEL_VERSION >= LINUX(6,10,0)) {
+           ms->__SWP_TYPE_BITS = 5;
+           ms->__SWP_TYPE_SHIFT = 6;
+           ms->__SWP_TYPE_MASK = ((1UL << ms->__SWP_TYPE_BITS) - 1);
+           ms->__SWP_OFFSET_SHIFT = 12;
+           ms->__SWP_OFFSET_BITS = 50;
+           ms->__SWP_OFFSET_MASK = ((1UL << ms->__SWP_OFFSET_BITS) - 1);
+           ms->PTE_PROT_NONE = 0; /* unused */
+           ms->PTE_FILE = 0;  /* unused */
+       } else if (THIS_KERNEL_VERSION >= LINUX(5,19,0)) {
            ms->__SWP_TYPE_BITS = 5;
            ms->__SWP_TYPE_SHIFT = 3;
            ms->__SWP_TYPE_MASK = ((1UL << ms->__SWP_TYPE_BITS) - 1);
diff --git a/memory.c b/memory.c
index 400d31a..cbc8d2f 100644
--- a/memory.c
+++ b/memory.c
@@ -16415,6 +16415,8 @@ get_swapdev(ulong type, char *buf)
    ulong vfsmnt;
    char *devname;
    char buf1[BUFSIZE];
+   int swap_file_is_file =
+       STREQ(MEMBER_TYPE_NAME("swap_info_struct", "swap_file"), "file");

    swap_info_init();

@@ -16474,7 +16476,8 @@ get_swapdev(ulong type, char *buf)
            vfsmnt = ULONG(vt->swap_info_struct +
                OFFSET(swap_info_struct_swap_vfsmnt));
                get_pathname(swap_file, buf, BUFSIZE, 1, vfsmnt);
-                } else if (VALID_MEMBER (swap_info_struct_old_block_size)) {
+                } else if (VALID_MEMBER (swap_info_struct_old_block_size)
+                   || swap_file_is_file) {
            devname = vfsmount_devname(file_to_vfsmnt(swap_file),
                buf1, BUFSIZE);
            get_pathname(file_to_dentry(swap_file),
--
2.34.1

Thanks.
Guanyou