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

Linux kernel 将PTE设置为指向不同的物理页-Linux内核,linux-kernel,paging,tlb,Linux Kernel,Paging,Tlb,是否可以将PTE点设置为不同的物理页面 假设我当前在某个进程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\u t addr) { pgd_t

是否可以将PTE点设置为不同的物理页面

假设我当前在某个进程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\u t addr)
{
pgd_t*pgd;
布丁;
pmd_t*pmd;
pte_t*ptep;
自旋锁紧;
结构vm_区域结构*vma=mm->mmap;
pgd=pgd_偏移量(mm,addr);
如果(pgd_无(*pgd)|不太可能(pgd_坏(*pgd)))
返回NULL;
pud=pud_偏移量(pgd,addr);
如果(pud_none(*pud)|不太可能(pud_bad(*pud)))
返回NULL;
pmd=pmd_偏移量(pud,addr);
如果(pmd_无(*pmd))
返回NULL;
ptep=pte_偏移量_映射(pmd,addr);
返回ptep;
}
bool change_pte(大小地址、大小新页面物理地址)
{
pte_t*p=步行页面_表(当前->毫米,地址);
新私人有限公司;
如果(!p)
返回false;
new_pte=pfn_pte(new_page_phys_address>>page_SHIFT,
页面(内核)(执行);;
集合(p,新集合);
__一个(地址);
返回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);

让我和你分享一个建议。似乎没有证据表明,
kmalloc
将返回页面对齐的地址(我不确定,但您可以检查它)。让我举例说明:

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

尝试使用get_free_页面而不是kmalloc。如果这不起作用,我将尝试重复你的实验。

请具体说明,“运气不佳”是什么意思,以及你到底做了什么(给出一段代码片段)添加了一些代码;)谢谢。你如何测试这段代码?你的期望是什么?我只是在更改前后打印页面内容。它确实改变了。但不是我所期望的:(编辑:我的意思是我在更改后打印虚拟地址指向的内容请,给出测试更改的代码好的,尝试了:我在调用更改后得到零(例如,如果以前的数据是f5a6a7b0,那么更改后的数据是:00000000。我一定是做错了什么。恐怕我不明白。您有memset(newPage,0,PAGE\u SIZE)你映射到注册->ip的页面。为什么数据不应该是0?不,我不再是了。它当前有一些我想要它指向的真实数据。不再是零。更新你帖子中的测试代码。你也尝试过回读你的pte或回读页面(例如使用follow page)?此检查可能适合您的情况。是的,成功。如果未使用uuu flush_tlb_one,则更改后的输出(set_pte)保持不变。否则(使用uu flush_tlb_one),输出为全零。