将 PTE 设置为指向不同的物理页面 - Linux 内核

Posted

技术标签:

【中文标题】将 PTE 设置为指向不同的物理页面 - Linux 内核【英文标题】:Setting a PTE to point a different physical page - Linux Kernel 【发布时间】:2015-06-18 20:24:17 【问题描述】:

是否可以将 PTE 指向不同的物理页面?

假设我当前处于某个进程 A 的上下文中的内核模式,该进程 A 当前将地址 400k 映射到物理页号。 5. 我可以将该地址(400k)映射到物理页号吗? 6 ? (例如) 如果有,怎么做?

我尝试使用此 API:

set_pte / clear_pte / mk_pte / pfn_to_page

但到目前为止还没有运气。

编辑:

一些代码:

static pte_t *walk_page_table(struct mm_struct *mm, size_t addr)

    pgd_t *pgd;
    pud_t *pud;
    pmd_t *pmd;
    pte_t *ptep;
    spinlock_t *ptl;
    struct vm_area_struct* vma = mm->mmap;

    pgd = pgd_offset(mm, addr);
    if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
        return NULL;

    pud = pud_offset(pgd, addr);
    if (pud_none(*pud) || unlikely(pud_bad(*pud)))
        return NULL;

    pmd = pmd_offset(pud, addr);
    if (pmd_none(*pmd))
        return NULL;

    ptep = pte_offset_map(pmd, addr);

    return ptep;


bool change_pte(size_t address, size_t new_page_phys_address)

    pte_t *p = walk_page_table(current->mm, address);
    pte_t new_pte;

    if (!p)
        return false;

    new_pte = pfn_pte(new_page_phys_address >> PAGE_SHIFT,
                      PAGE_KERNEL_EXEC);
    set_pte(p, new_pte);
    __flush_tlb_one(address);

    return true;

一些测试代码:

  struct pt_regs* regs = task_pt_regs(current);
  hexDump("someData", regs->ip, some_size);
  void * newPage = kmalloc(PAGE_SIZE,GFP_KERNEL);
  memset(newPage,0,PAGE_SIZE);
  change_pte(regs->ip, virtual_to_physical(newPage));
  hexDump("post someData", regs->ip, some_size);

【问题讨论】:

拜托,具体一点,“没有运气”是什么意思,你到底试过什么(给个代码sn-p) 添加了一些代码 ;) 谢谢。 如何测试这段代码?您的期望是什么? 我只是打印更改前后的页面内容。它确实改变了。但不是我所期望的 :( 编辑:我的意思是我在更改后打印虚拟地址指向的内容 请给出测试change_pte的代码 【参考方案1】:

让我与您分享一个建议。似乎没有证据表明kmalloc 将返回页面对齐地址(我不确定,但您可以检查一下)。让我做一个插图:

   page1  page2      remapped uspace page
|    000|000   |        |   000|
|    000|000   |        |   000|
    ^                    ^
    |                    |
 newPage               reg->ip

尝试使用 get_free_page 而不是 kmalloc。如果这没有帮助,我会尝试重复你的实验。

【讨论】:

好的,试过了:调用 change_pte 后我得到零(例如,如果之前的数据是 f5a6a7b0,那么 post change_pte 数据是:00000000。我必须做错事。 恐怕我听不懂。你有 memset(newPage,0,PAGE_SIZE) 页面映射到 reg->ip。为什么数据不应该是 0? 不,我不再这样做了。它目前有一些我希望它指向的真实数据。不再为零。 更新您帖子中的测试代码。您是否也尝试过回读您的 pte 或返回页面(例如,使用后续页面)?此检查可能适合您的情况。 是的,成功了。如果不使用 __flush_tlb_one,则输出后更改 (set_pte) 保持不变。否则(使用 __flush_tlb_one)输出全为零。

以上是关于将 PTE 设置为指向不同的物理页面 - Linux 内核的主要内容,如果未能解决你的问题,请参考以下文章

MIT-JOS系列:用户态访问页表项详解

PTE和Windows缺页异常

14.PTD与的基址

将指向当前页面的带有href的链接设置为活动链接(如果在subnav中,则将其父级设置为活动链接)

Linux内存管理的基本框架??

什么是真正的 pte(相对于 NUMA 中的迁移 pte)