Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux EPT PTE和主机PTE条目之间的关系是什么?_Linux_Memory Management_X86 64_Virtualization - Fatal编程技术网

Linux EPT PTE和主机PTE条目之间的关系是什么?

Linux EPT PTE和主机PTE条目之间的关系是什么?,linux,memory-management,x86-64,virtualization,Linux,Memory Management,X86 64,Virtualization,我试图通过X86主机中的虚拟化,找出Linux系统中EPT PTE和主机PTE之间的关系。 例如,当虚拟机监控程序通过提供主机内存页来设置EPT条目时,当来宾在来宾中写入该页时会发生什么情况? 在上述情况下,EPT条目是“脏的”,该主机页的主机PTE条目是否仍然是脏的 我为Linux编写了一个简单的hypervisor,它支持EPT。我发现当来宾写入页面时,EPT条目中设置了脏位,但通过检查主机PTE条目,我没有找到脏位集 在EPT违规处理程序中,我调用kmalloc为来宾获取主机页。然后,我使

我试图通过X86主机中的虚拟化,找出Linux系统中EPT PTE和主机PTE之间的关系。
例如,当虚拟机监控程序通过提供主机内存页来设置EPT条目时,当来宾在来宾中写入该页时会发生什么情况?
在上述情况下,EPT条目是“脏的”,该主机页的主机PTE条目是否仍然是脏的

我为Linux编写了一个简单的hypervisor,它支持EPT。我发现当来宾写入页面时,EPT条目中设置了脏位,但通过检查主机PTE条目,我没有找到脏位集

在EPT违规处理程序中,我调用kmalloc为来宾获取主机页。然后,我使用以下代码检查该页面的主机PTE条目

void pgtable_walk(unsigned long addr)
{
    pgd_t *pgd;
    pud_t *pud;
    pmd_t *pmd;
    pte_t *pte;
    pte_t  cpte;
    unsigned long page_mask;
    unsigned int level;
    phys_addr_t phys_addr;
    unsigned long offset;

    pgd = pgd_offset(current->mm, addr);
    printk(KERN_ALERT "pgd is : %lx\n", (unsigned long)pgd->pgd);
    printk(KERN_ALERT "pgd index: %lx\n", (unsigned long)pgd_index(addr));
    pud = pud_offset(pgd, addr);
    printk(KERN_ALERT "pud is : %lx\n", (unsigned long)pud->pud);
    printk(KERN_ALERT "pud index: %lx\n", (unsigned long)pud_index(addr));
    pmd = pmd_offset(pud, addr);
    printk(KERN_ALERT "pmd is : %lx\n", (unsigned long)pmd->pmd);
    printk(KERN_ALERT "pmd index: %lx\n", (unsigned long)pmd_index(addr));
    if(!pmd_large(*pmd)) {
        pte = pte_offset_kernel(pmd, addr);
        printk(KERN_ALERT "pte is : %lx\n", (unsigned long)pte->pte);
        printk(KERN_ALERT "pte index: %lx\n", (unsigned long)pte_index(addr));
        level = 2;
    } else {
        pte = (pte_t *)pmd;
        level = 1;
    }
    page_mask = page_level_mask(level);
    phys_addr = pte_pfn(*pte) << PAGE_SHIFT;
    offset    = addr & ~page_mask;

    printk("Final Phys Addr: %lx, dirty=%x, pte=%lx\n",
            (unsigned long)(phys_addr | offset), pte_dirty(*pte), pte_val(*pte));
}
void pgtable_walk(无符号长地址)
{
pgd_t*pgd;
布丁;
pmd_t*pmd;
私人有限公司;
pte_t cpte;
无符号长页屏蔽;
无符号整数级;
物理地址;
无符号长偏移量;
pgd=pgd_偏移量(当前->毫米,地址);
printk(内核警报“pgd为:%lx\n”,(无符号长)pgd->pgd);
printk(KERN_警报“pgd索引:%lx\n”,(无符号长)pgd_索引(addr));
pud=pud_偏移量(pgd,addr);
printk(内核警报“pud为:%lx\n”,(无符号长)pud->pud);
printk(KERN_警报“pud索引:%lx\n”,(无符号长)pud_索引(addr));
pmd=pmd_偏移量(pud,addr);
printk(内核警报“pmd为:%lx\n”,(无符号长)pmd->pmd);
printk(KERN_警报“pmd索引:%lx\n”,(无符号长)pmd_索引(addr));
如果(!pmd_大(*pmd)){
pte=pte_偏移量_内核(pmd,addr);
printk(内核警报“pte为:%lx\n”,(无符号长)pte->pte);
printk(KERN_警报“pte索引:%lx\n”,(无符号长)pte_索引(addr));
级别=2;
}否则{
pte=(pte_t*)pmd;
级别=1;
}
页面屏蔽=页面级别屏蔽(级别);

物理地址=pte\U pfn(*pte)处理器只能在执行写入时用于转换虚拟地址的PTE中设置脏位。因此,当来宾写入页面时,处理器在来宾PTE和EPT中设置脏位。*在来宾中发生写入时,处理器没有指向主机页表的指针,我也没有我不知道该页是否映射到任何主机页表中。因此,如果主机中的软件想知道该页是否脏,它必须查看EPT


*EPT脏位仅在可选EPT A/D功能可用时设置,并通过在VMCS的EPTP字段中设置位6来启用(请参阅“英特尔SDM”第28.2.5节)。

通过我的更多测试和您的评论,我对EPT PTE和主机PTE有了更好的理解。您的评论是正确答案。