#define ept_get_my_asr(d) \ ((d)->arch.hvm_domain.my_vmx.ept_control.asr) #define ept_get_my_eptp(d) \ ((d)->arch.hvm_domain.my_vmx.ept_control.eptp) int do_my_ept_create() { struct domain *d = current->domain; struct p2m_domain *p2m = p2m_get_hostp2m(d); struct page_info *p2m_top; int i, j, k; ept_entry_t new_ept; ept_entry_t *pml4, *my_pml4; ept_entry_t *pdp, *my_pdp, *pdpe, *my_pdpe; ept_entry_t *pd, *my_pd, *pde, *my_pde; ept_entry_t *pt, *my_pt; unsigned long mfn; p2m_lock(p2m); p2m_top = p2m_alloc_ptp(p2m, PGT_l3_page_table); //PML4 if(p2m_top == NULL) { p2m_unlock(p2m); return 0; } ept_get_my_eptp(d) = ept_get_eptp(d); //for the other 3 fields... ept_get_my_asr(d) = mfn_x(page_to_mfn(p2m_top)); pml4 = map_domain_page(ept_get_asr(d)); my_pml4 = map_domain_page(ept_get_my_asr(d)); if(!ept_set_middle_entry(p2m, &new_ept)) return 0; my_pml4->epte = pml4->epte; my_pml4->mfn = new_ept.mfn; mfn = pml4->mfn; unmap_domain_page(pml4); unmap_domain_page(my_pml4); pdp = map_domain_page(mfn); my_pdp = map_domain_page(new_ept.mfn); //PDP, set 4 entries... for(i = 0; i < 4; i++) { pdpe = pdp + i; my_pdpe = my_pdp + i; if(!is_epte_present(pdpe)) continue; if(!ept_set_middle_entry(p2m, &new_ept)) return 0; my_pdpe->epte = pdpe->epte; my_pdpe->mfn = new_ept.mfn; mfn = pdpe->mfn; pd = map_domain_page(mfn); my_pd = map_domain_page(new_ept.mfn); for(j = 0; j < EPT_PAGETABLE_ENTRIES; j++) { pde = pd + j; my_pde = my_pd + j; if(!is_epte_present(pde)) continue; if(!ept_set_middle_entry(p2m, &new_ept)) return 0; my_pde->epte = pde->epte; my_pde->mfn = new_ept.mfn; mfn = pde->mfn; pt = map_domain_page(mfn); my_pt = map_domain_page(new_ept.mfn); for(k = 0; k < EPT_PAGETABLE_ENTRIES; k++) { (my_pt + k)->epte = (pt + k)->epte; } unmap_domain_page(pt); unmap_domain_page(my_pt); } unmap_domain_page(pd); unmap_domain_page(my_pd); } unmap_domain_page(pdp); unmap_domain_page(my_pdp); p2m_unlock(p2m); return 1; } int do_ept_switch() { struct domain *d = current->domain; u64 eptp; eptp = ept_get_eptp(d); ept_get_eptp(d) = ept_get_my_eptp(d); ept_get_my_eptp(d) = eptp; ept_sync_domain(d); //invalidate TLB... return 1; }