第三级页面表间接源代码与x86 Linux内核中的汇编不同

发布于 2025-02-12 12:13:24 字数 2793 浏览 3 评论 0原文

我正在使用4个级别的页面表(禁用LA57),并试图了解获取第三级页面虚拟地址的实现。但是源代码和拆卸之间遇到了差异。

source code

static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address)
{
    return p4d_pgtable(*p4d) + pud_index(address);
}

source code > p4d_pgtablepud_index呼叫在结果组件中置于 (以下)。这是他们的源代码。

static inline pud_t *p4d_pgtable(p4d_t p4d)
{
    return (pud_t *)__va(p4d_val(p4d) & p4d_pfn_mask(p4d));
}

pud_index

static inline unsigned long pud_index(unsigned long address)
{
    return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1);
}

href =“ https://elixir.bootlin.com/linux/v5.19-rc2/source/include/include/linux/pgtable.h#l77” rel =“ nofollow noreferrer ” href =“ https://elixir.bootlin.com/linux/v5.19-rc2/source/arch/x86/include/asm/pgtable_64_types.h#l80”代码>和ptrs_per_pud

/*
 * 3rd level page
 */
#define PUD_SHIFT   30
#define PTRS_PER_PUD    512

问题:根据pud_index源代码,我期望将其用0x1epud_shift)进行编译,然后和0x1ffptrs_per_pud -1)和和anded。但是拆卸pud_offset显示不同的值。

拆卸

(gdb) disas pud_offset
Dump of assembler code for function pud_offset:
   0xffffffff812bfc40 <+0>:     push   rbp
   0xffffffff812bfc41 <+1>:     mov    rbp,rsp 
   0xffffffff812bfc44 <+4>:     mov    rax,rdi
   0xffffffff812bfc47 <+7>:     nop    DWORD PTR [rax]
   0xffffffff812bfc4a <+10>:    and    rax,QWORD PTR [rip+0x142936f]        # 0xffffffff826e8fc0 <physical_mask>
   0xffffffff812bfc51 <+17>:    shr    rsi,0x1b #  <---- 0x1b is 27, but 3rd level starts at bit 30
   0xffffffff812bfc55 <+21>:    pop    rbp
   0xffffffff812bfc56 <+22>:    and    rax,0xfffffffffffff000
   0xffffffff812bfc5c <+28>:    and    esi,0xff8 # <---- 4088, but there are 512 entries at the 3rd level
   0xffffffff812bfc62 <+34>:    add    rax,QWORD PTR [rip+0x14122df]        # 0xffffffff826d1f48 <page_offset_base>
   0xffffffff812bfc69 <+41>:    lea    rax,[rax+rsi*1]
   0xffffffff812bfc6d <+45>:    ret
End of assembler dump.

我们在拆卸输出中所拥有的是地址通过0x1b(27),然后使用0xff8 (4088或511&lt;&lt; 3)。

您是否知道为什么会发生这种情况?

I'm using 4 levels page table (LA57 disabled) and tried to understand the implementation of getting virtual address of the 3rd level page. But encountered difference between source code and it's disassemble.

Source code:

static inline pud_t *pud_offset(p4d_t *p4d, unsigned long address)
{
    return p4d_pgtable(*p4d) + pud_index(address);
}

Both p4d_pgtable and pud_index calls were inlined in the resulting assembly (below). Here are their source code.

p4d_pgtable:

static inline pud_t *p4d_pgtable(p4d_t p4d)
{
    return (pud_t *)__va(p4d_val(p4d) & p4d_pfn_mask(p4d));
}

pud_index:

static inline unsigned long pud_index(unsigned long address)
{
    return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1);
}

PUD_SHIFT and PTRS_PER_PUD

/*
 * 3rd level page
 */
#define PUD_SHIFT   30
#define PTRS_PER_PUD    512

The problem: According to the pud_index source code I expected it to be compiled with the shift right by 0x1e (PUD_SHIFT) and then anded with 0x1ff (PTRS_PER_PUD - 1). But disassembling pud_offset shows different values.

Disassemble:

(gdb) disas pud_offset
Dump of assembler code for function pud_offset:
   0xffffffff812bfc40 <+0>:     push   rbp
   0xffffffff812bfc41 <+1>:     mov    rbp,rsp 
   0xffffffff812bfc44 <+4>:     mov    rax,rdi
   0xffffffff812bfc47 <+7>:     nop    DWORD PTR [rax]
   0xffffffff812bfc4a <+10>:    and    rax,QWORD PTR [rip+0x142936f]        # 0xffffffff826e8fc0 <physical_mask>
   0xffffffff812bfc51 <+17>:    shr    rsi,0x1b #  <---- 0x1b is 27, but 3rd level starts at bit 30
   0xffffffff812bfc55 <+21>:    pop    rbp
   0xffffffff812bfc56 <+22>:    and    rax,0xfffffffffffff000
   0xffffffff812bfc5c <+28>:    and    esi,0xff8 # <---- 4088, but there are 512 entries at the 3rd level
   0xffffffff812bfc62 <+34>:    add    rax,QWORD PTR [rip+0x14122df]        # 0xffffffff826d1f48 <page_offset_base>
   0xffffffff812bfc69 <+41>:    lea    rax,[rax+rsi*1]
   0xffffffff812bfc6d <+45>:    ret
End of assembler dump.

What we have in the disassemble output is the address shifted right by 0x1b(27) and then anded with 0xff8 (4088 or 511 << 3).

Do you have any idea of why it might happen?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文