Какова связь между EPT PTE и входом в PTE хоста? - PullRequest
2 голосов
/ 09 апреля 2019

Я пытаюсь выяснить связь между PTE EPT и PTE хоста в системе Linux с виртуализацией на хосте X86.
Например, когда гипервизор устанавливает запись EPT, предоставляя страницу памяти хоста, что произойдет, когда гость запишет эту страницу в гостевой системе?
В вышеприведенном случае запись EPT является «грязной», является ли запись PTE хоста на этой странице хоста все еще грязной или нет?

Я написал простой гипервизор для Linux, который поддерживает 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));
}

Если это так, как Linux узнает, какая страница грязная или нет?

1 Ответ

2 голосов
/ 18 апреля 2019

Процессор может устанавливать «грязный» бит в PTE, которые используются для преобразования виртуального адреса при выполнении записи.Поэтому, когда гость записывает на страницу, процессор устанавливает грязные биты в гостевом PTE и в EPT. * В то время, когда запись происходит в гостевой системе, у процессора нет указателя на таблицы страниц хоста, а такжеон знает, отображается ли страница в каких-либо таблицах хост-страниц.Поэтому, если программное обеспечение на хосте хочет выяснить, не является ли страница грязной, оно должно посмотреть на EPT.

* Бит EPT для грязной установки устанавливается только в том случае, если доступна и включена дополнительная функция EPT A / D.установив бит 6 в поле EPTP в VMCS.(См. Раздел 28.2.5 Intel SDM.)

...