【问题标题】:Check validity of virtual memory address检查虚拟内存地址的有效性
【发布时间】:2012-06-21 09:01:47
【问题描述】:

我正在遍历 VMALLOC_START 和 VMALLOC_END 之间的页面,我想要 检查我每次得到的地址是否有效。 我该如何管理?

我这样遍历页面:

unsigned long *p;

    for(p = (unsigned long *) VMALLOC_START; p <= (unsigned long *) (VMALLOC_END - PAGE_SIZE); p += PAGE_SIZE)
    {
            //How to check if p is OK to access it?     

    }

谢谢!

【问题讨论】:

    标签: linux linux-kernel linux-device-driver kernel


    【解决方案1】:

    最简单的方法是尝试将其变红,然后捕获异常。

    通过使用内联汇编在__ex_table 部分定义一个条目来捕获异常。
    异常表条目包含一个指向内存访问指令的指针和一个指向恢复地址的指针。如果这条指令发生segfault,EIP会被设置为recovery地址。

    类似这样的东西(我没有测试过,我可能遗漏了一些东西):

    void *ptr=whatever;
    int ok=1;
    asm(
        "1: mov (%1),%1\n"    // Try to access
        "jmp 3f\n"            // Success - skip error handling
        "2: mov $0,%0\n"      // Error - set ok=0
        "3:\n"                // Jump here on success
        "\n.section __ex_table,\"a\""
        ".long 1b,2b\n"       // Use .quad for 64bit.
        ".prev\n"
        :"=r"(ok) : "r"(ptr)
    );
    

    【讨论】:

    • 您好,感谢您的回复。这个解决方案是不可移植的,对吧?我正在尝试用纯 C 来管理它。现在我有这个实现,但我认为它有问题:github.com/PanosSakkos/shedder/blob/master/src/… 任何想法都会非常受欢迎:) 谢谢!
    • 我认为没有便携式解决方案。我认为您的代码也不可移植。它也不处理大页面(例如,在 x86 中,您可以拥有一个 2MB 的页面,这意味着 pmd 有时直接指向物理地址(或类似的东西)。
    • 这里phrack.org/issues.html?id=3&issue=61(搜索“未映射问题”)似乎说明了一种可移植的(纯C)方式来做到这一点。我就是看不懂,因为写的太烂了。谢谢!
    • 该代码根本不可移植。它不使用正确的 Linux 宏,而是使用硬编码常量(例如,假定页表始终位于 0xc0101000),并且仅适用于特定的 Linux 版本、特定配置和 x86。
    • 你是对的,我把它描述为“便携”是不好的 ^_^ 我发现了这个功能:lxr.linux.no/linux+v3.6.6/arch/x86/mm/pageattr.c#L333 我想我应该使用它,如果它返回一个不存在的页面,我应该带它到虚拟机,但如何?另外,如果页面太长(如您所述)我该怎么办?谢谢!
    猜你喜欢
    • 2018-07-09
    • 2014-09-06
    • 2021-09-01
    • 2023-03-17
    • 2021-07-25
    • 2012-03-21
    • 2014-09-15
    • 2021-09-11
    • 1970-01-01
    相关资源
    最近更新 更多