void vt_ept_updatecr3 (void) { ulong cr3, cr4; u32 tmpl, tmph; u64 tmp64; vt_paging_flush_guest_tlb (); if (!current->u.vt.lma && current->u.vt.vr.pg) { asm_vmread (VMCS_CR4_READ_SHADOW, &cr4); if (cr4 & CR4_PAE_BIT) { asm_vmread (VMCS_GUEST_CR3, &cr3); cr3 &= 0xFFFFFFE0; read_gphys_q (cr3 + 0x0, &tmp64, 0); conv64to32 (tmp64, &tmpl, &tmph); asm_vmwrite (VMCS_GUEST_PDPTE0, tmpl); asm_vmwrite (VMCS_GUEST_PDPTE0_HIGH, tmph); read_gphys_q (cr3 + 0x8, &tmp64, 0); conv64to32 (tmp64, &tmpl, &tmph); asm_vmwrite (VMCS_GUEST_PDPTE1, tmpl); asm_vmwrite (VMCS_GUEST_PDPTE1_HIGH, tmph); read_gphys_q (cr3 + 0x10, &tmp64, 0); conv64to32 (tmp64, &tmpl, &tmph); asm_vmwrite (VMCS_GUEST_PDPTE2, tmpl); asm_vmwrite (VMCS_GUEST_PDPTE2_HIGH, tmph); read_gphys_q (cr3 + 0x18, &tmp64, 0); conv64to32 (tmp64, &tmpl, &tmph); asm_vmwrite (VMCS_GUEST_PDPTE3, tmpl); asm_vmwrite (VMCS_GUEST_PDPTE3_HIGH, tmph); } } }
void vt_ept_clear_all (void) { struct vt_ept *ept; ept = current->u.vt.ept; memset (ept->ncr3tbl, 0, PAGESIZE); ept->cnt = 0; vt_paging_flush_guest_tlb (); }
void vt_paging_invalidate (ulong addr) { #ifdef CPU_MMU_SPT_DISABLE if (current->u.vt.vr.pg) { vt_paging_flush_guest_tlb (); return; } #endif if (ept_enabled ()) panic ("invlpg while ept enabled"); else cpu_mmu_spt_invalidate (addr); }
static void vt_ept_map_page (bool write, u64 gphys) { int l; bool fakerom; u64 hphys; u32 hattr; struct vt_ept *ept; u64 *p, *q, e; ept = current->u.vt.ept; q = ept->ncr3tbl; q += (gphys >> (EPT_LEVELS * 9 + 3)) & 0x1FF; p = q; for (l = EPT_LEVELS - 1; l > 0; l--) { e = *p; if (!(e & EPTE_READ)) { if (ept->cnt + l > NUM_OF_EPTBL) { /* printf ("!"); */ memset (ept->ncr3tbl, 0, PAGESIZE); ept->cnt = 0; vt_paging_flush_guest_tlb (); l = EPT_LEVELS - 1; p = q; } break; } e &= ~PAGESIZE_MASK; e |= (gphys >> (9 * l)) & 0xFF8; p = (u64 *)phys_to_virt (e); } for (; l > 0; l--) { *p = ept->tbl_phys[ept->cnt] | EPTE_READEXEC | EPTE_WRITE; p = ept->tbl[ept->cnt++]; memset (p, 0, PAGESIZE); p += (gphys >> (9 * l + 3)) & 0x1FF; } hphys = current->gmm.gp2hp (gphys, &fakerom) & ~PAGESIZE_MASK; if (fakerom && write) panic ("EPT: Writing to VMM memory."); hattr = (cache_get_gmtrr_type (gphys) << EPTE_MT_SHIFT) | EPTE_READEXEC | EPTE_WRITE; if (fakerom) hattr &= ~EPTE_WRITE; *p = hphys | hattr; #ifdef CONFIG_SSLAB //updateOwnerVMIDofEPTPage(0, hphys >> PAGE_ID_SHIFT, (U8_t)hattr); #endif }
void vt_paging_updatecr3 (void) { #ifdef CPU_MMU_SPT_DISABLE if (current->u.vt.vr.pg) { vt_update_vmcs_guest_cr3 (); vt_paging_flush_guest_tlb (); return; } #endif if (ept_enabled ()) { vt_update_vmcs_guest_cr3 (); vt_ept_updatecr3 (); } else { cpu_mmu_spt_updatecr3 (); } }