diff --git a/hypervisor/arch/x86/ept.c b/hypervisor/arch/x86/ept.c index a8da5e77d..a5e185c65 100644 --- a/hypervisor/arch/x86/ept.c +++ b/hypervisor/arch/x86/ept.c @@ -258,20 +258,17 @@ int ept_misconfig_vmexit_handler(__unused struct vcpu *vcpu) return status; } -int ept_mr_add(const struct vm *vm, uint64_t hpa_arg, - uint64_t gpa_arg, uint64_t size, uint32_t prot_arg) +int ept_mr_add(const struct vm *vm, uint64_t *pml4_page, + uint64_t hpa, uint64_t gpa, uint64_t size, uint64_t prot_orig) { - struct mem_map_params map_params; uint16_t i; struct vcpu *vcpu; - uint64_t hpa = hpa_arg; - uint64_t gpa = gpa_arg; - uint32_t prot = prot_arg; + int ret; + uint64_t prot = prot_orig; - /* Setup memory map parameters */ - map_params.page_table_type = PTT_EPT; - map_params.pml4_base = vm->arch_vm.nworld_eptp; - map_params.pml4_inverted = vm->arch_vm.m2p; + dev_dbg(ACRN_DBG_EPT, "%s, vm[%d] hpa: 0x%016llx gpa: 0x%016llx ", + __func__, vm->vm_id, hpa, gpa); + dev_dbg(ACRN_DBG_EPT, "size: 0x%016llx prot: 0x%016x\n", size, prot); /* EPT & VT-d share the same page tables, set SNP bit * to force snooping of PCIe devices if the page @@ -280,21 +277,18 @@ int ept_mr_add(const struct vm *vm, uint64_t hpa_arg, if ((prot & IA32E_EPT_MT_MASK) != IA32E_EPT_UNCACHED) { prot |= IA32E_EPT_SNOOP_CTRL; } - /* TODO: replace map_mem with mmu_add once SOS has add - * HC_VM_WRITE_PROTECT_PAGE support. - */ - map_mem(&map_params, (void *)hpa, - (void *)gpa, size, prot); + + ret = mmu_add(pml4_page, hpa, gpa, size, prot, PTT_EPT); + if (ret == 0) { + ret = mmu_add((uint64_t *)vm->arch_vm.m2p, + gpa, hpa, size, prot, PTT_EPT); + } foreach_vcpu(i, vm, vcpu) { vcpu_make_request(vcpu, ACRN_REQUEST_EPT_FLUSH); } - dev_dbg(ACRN_DBG_EPT, "%s, hpa: 0x%016llx gpa: 0x%016llx ", - __func__, hpa, gpa); - dev_dbg(ACRN_DBG_EPT, "size: 0x%016llx prot: 0x%x\n", size, prot); - - return 0; + return ret; } int ept_mr_modify(const struct vm *vm, uint64_t *pml4_page, @@ -323,23 +317,19 @@ int ept_mr_del(const struct vm *vm, uint64_t *pml4_page, int ret; uint64_t hpa = gpa2hpa(vm, gpa); + dev_dbg(ACRN_DBG_EPT, "%s,vm[%d] gpa 0x%llx size 0x%llx\n", + __func__, vm->vm_id, gpa, size); + ret = mmu_modify_or_del(pml4_page, gpa, size, 0UL, 0UL, PTT_EPT, MR_DEL); - if (ret < 0) { - return ret; - } - - if (hpa != 0UL) { + if ((ret == 0) && (hpa != 0UL)) { ret = mmu_modify_or_del((uint64_t *)vm->arch_vm.m2p, - hpa, size, 0UL, 0UL, PTT_EPT, MR_DEL); + hpa, size, 0UL, 0UL, PTT_EPT, MR_DEL); } foreach_vcpu(i, vm, vcpu) { vcpu_make_request(vcpu, ACRN_REQUEST_EPT_FLUSH); } - dev_dbg(ACRN_DBG_EPT, "%s, gpa 0x%llx size 0x%llx\n", - __func__, gpa, size); - - return 0; + return ret; } diff --git a/hypervisor/arch/x86/guest/guest.c b/hypervisor/arch/x86/guest/guest.c index 5033ff818..a15350758 100644 --- a/hypervisor/arch/x86/guest/guest.c +++ b/hypervisor/arch/x86/guest/guest.c @@ -564,6 +564,7 @@ int prepare_vm0_memmap_and_e820(struct vm *vm) uint64_t attr_uc = (EPT_RWX | EPT_UNCACHED); struct e820_entry *entry; uint64_t hv_hpa; + uint64_t *pml4_page = (uint64_t *)vm->arch_vm.nworld_eptp; rebuild_vm0_e820(); dev_dbg(ACRN_DBG_GUEST, @@ -571,7 +572,8 @@ int prepare_vm0_memmap_and_e820(struct vm *vm) e820_mem.mem_bottom, e820_mem.mem_top); /* create real ept map for all ranges with UC */ - ept_mr_add(vm, e820_mem.mem_bottom, e820_mem.mem_bottom, + ept_mr_add(vm, pml4_page, + e820_mem.mem_bottom, e820_mem.mem_bottom, (e820_mem.mem_top - e820_mem.mem_bottom), attr_uc); @@ -579,7 +581,7 @@ int prepare_vm0_memmap_and_e820(struct vm *vm) for (i = 0U; i < e820_entries; i++) { entry = &e820[i]; if (entry->type == E820_TYPE_RAM) { - ept_mr_modify(vm, (uint64_t *)vm->arch_vm.nworld_eptp, + ept_mr_modify(vm, pml4_page, entry->baseaddr, entry->length, EPT_WB, EPT_MT_MASK); } @@ -599,8 +601,7 @@ int prepare_vm0_memmap_and_e820(struct vm *vm) * will cause EPT violation if sos accesses hv memory */ hv_hpa = get_hv_image_base(); - ept_mr_del(vm, (uint64_t *)vm->arch_vm.nworld_eptp, - hv_hpa, CONFIG_RAM_SIZE); + ept_mr_del(vm, pml4_page, hv_hpa, CONFIG_RAM_SIZE); return 0; } diff --git a/hypervisor/arch/x86/guest/vlapic.c b/hypervisor/arch/x86/guest/vlapic.c index 81a2157eb..7597441ce 100644 --- a/hypervisor/arch/x86/guest/vlapic.c +++ b/hypervisor/arch/x86/guest/vlapic.c @@ -2055,11 +2055,15 @@ int vlapic_create(struct vcpu *vcpu) } if (is_vcpu_bsp(vcpu)) { - ept_mr_add(vcpu->vm, + uint64_t *pml4_page = + (uint64_t *)vcpu->vm->arch_vm.nworld_eptp; + ept_mr_del(vcpu->vm, pml4_page, + DEFAULT_APIC_BASE, CPU_PAGE_SIZE); + + ept_mr_add(vcpu->vm, pml4_page, vlapic_apicv_get_apic_access_addr(vcpu->vm), DEFAULT_APIC_BASE, CPU_PAGE_SIZE, - IA32E_EPT_W_BIT | IA32E_EPT_R_BIT | - IA32E_EPT_UNCACHED); + EPT_WR | EPT_RD | EPT_UNCACHED); } } else { /*No APICv support*/ diff --git a/hypervisor/arch/x86/pagetable.c b/hypervisor/arch/x86/pagetable.c index 880671b5e..b78c77830 100644 --- a/hypervisor/arch/x86/pagetable.c +++ b/hypervisor/arch/x86/pagetable.c @@ -344,6 +344,7 @@ static int add_pde(uint64_t *pdpte, uint64_t paddr_start, vaddr = vaddr_next; continue; } + return 0; } else { ret = construct_pgentry(ptt, pde); if (ret != 0) { diff --git a/hypervisor/arch/x86/trusty.c b/hypervisor/arch/x86/trusty.c index cabef151f..452fc01f3 100644 --- a/hypervisor/arch/x86/trusty.c +++ b/hypervisor/arch/x86/trusty.c @@ -166,6 +166,9 @@ void destroy_secure_world(struct vm *vm, bool need_clr_mem) { void *pdpt_addr; struct vm *vm0 = get_vm_from_vmid(0U); + uint64_t hpa = vm->sworld_control.sworld_memory.base_hpa; + uint64_t gpa = vm->sworld_control.sworld_memory.base_gpa_in_sos; + uint64_t size = vm->sworld_control.sworld_memory.length; if (vm0 == NULL) { pr_err("Parse vm0 context failed."); @@ -173,23 +176,18 @@ void destroy_secure_world(struct vm *vm, bool need_clr_mem) } if (need_clr_mem) { /* clear trusty memory space */ - (void)memset(HPA2HVA(vm->sworld_control.sworld_memory.base_hpa), - 0U, vm->sworld_control.sworld_memory.length); + (void)memset(HPA2HVA(hpa), 0U, size); } /* restore memory to SOS ept mapping */ - if (ept_mr_add(vm0, vm->sworld_control.sworld_memory.base_hpa, - vm->sworld_control.sworld_memory.base_gpa_in_sos, - vm->sworld_control.sworld_memory.length, - EPT_RWX | EPT_WB) != 0) { + if (ept_mr_add(vm0, vm0->arch_vm.nworld_eptp, + hpa, gpa, size, EPT_RWX | EPT_WB) != 0) { pr_warn("Restore trusty mem to SOS failed"); } /* Restore memory to guest normal world */ - if (ept_mr_add(vm, vm->sworld_control.sworld_memory.base_hpa, - vm->sworld_control.sworld_memory.base_gpa_in_uos, - vm->sworld_control.sworld_memory.length, - EPT_RWX | EPT_WB) != 0) { + if (ept_mr_add(vm, vm->arch_vm.nworld_eptp, + hpa, gpa, size, EPT_RWX | EPT_WB) != 0) { pr_warn("Restore trusty mem to nworld failed"); } diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index c56535932..cf257803d 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -422,6 +422,7 @@ static int32_t local_set_vm_memory_region(struct vm *vm, { uint64_t hpa, base_paddr; uint64_t prot; + uint64_t *pml4_page; if ((region->size & (CPU_PAGE_SIZE - 1UL)) != 0UL) { pr_err("%s: [vm%d] map size 0x%x is not page aligned", @@ -442,6 +443,7 @@ static int32_t local_set_vm_memory_region(struct vm *vm, return -EFAULT; } + pml4_page = (uint64_t *)target_vm->arch_vm.nworld_eptp; if (region->type != MR_DEL) { prot = 0UL; /* access right */ @@ -467,11 +469,10 @@ static int32_t local_set_vm_memory_region(struct vm *vm, prot |= EPT_UNCACHED; } /* create gpa to hpa EPT mapping */ - return ept_mr_add(target_vm, hpa, + return ept_mr_add(target_vm, pml4_page, hpa, region->gpa, region->size, prot); } else { - return ept_mr_del(target_vm, - (uint64_t *)target_vm->arch_vm.nworld_eptp, + return ept_mr_del(target_vm, pml4_page, region->gpa, region->size); } diff --git a/hypervisor/include/arch/x86/mmu.h b/hypervisor/include/arch/x86/mmu.h index 32bc5c76e..cb633462e 100644 --- a/hypervisor/include/arch/x86/mmu.h +++ b/hypervisor/include/arch/x86/mmu.h @@ -380,8 +380,8 @@ void destroy_ept(struct vm *vm); uint64_t gpa2hpa(const struct vm *vm, uint64_t gpa); uint64_t local_gpa2hpa(const struct vm *vm, uint64_t gpa, uint32_t *size); uint64_t hpa2gpa(const struct vm *vm, uint64_t hpa); -int ept_mr_add(const struct vm *vm, uint64_t hpa_arg, - uint64_t gpa_arg, uint64_t size, uint32_t prot_arg); +int ept_mr_add(const struct vm *vm, uint64_t *pml4_page, uint64_t hpa, + uint64_t gpa, uint64_t size, uint64_t prot_orig); int ept_mr_modify(const struct vm *vm, uint64_t *pml4_page, uint64_t gpa, uint64_t size, uint64_t prot_set, uint64_t prot_clr);