From 01b54241c6d28b73ba54994b3adf536098d54d90 Mon Sep 17 00:00:00 2001 From: Li Fei1 Date: Mon, 1 Mar 2021 15:01:13 +0800 Subject: [PATCH] hv: ept: only treak execution right for large pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To mitigate the page size change MCE vulnerability (CVE-2018-12207), ACRN would clear the execution permission in the EPT paging-structure entries for large pages and then intercept an EPT execution-permission violation caused by an attempt to execution an instruction in the guest. However, the current code would clear the execution permission in the EPT paging- structure entries for small pages too when we clearing the the execution permission for large pages. This would trigger extra EPT violation VM exits. This patch fix this issue. Signed-off-by: Li Fei1 Acked-by: Eddie Dong Tracked-On: #5788 --- hypervisor/arch/x86/pagetable.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/hypervisor/arch/x86/pagetable.c b/hypervisor/arch/x86/pagetable.c index f4ffdc5e6..cf2b70ab3 100644 --- a/hypervisor/arch/x86/pagetable.c +++ b/hypervisor/arch/x86/pagetable.c @@ -309,6 +309,7 @@ static void add_pde(const uint64_t *pdpte, uint64_t paddr_start, uint64_t vaddr_ uint64_t vaddr = vaddr_start; uint64_t paddr = paddr_start; uint64_t index = pde_index(vaddr); + uint64_t local_prot = prot; dev_dbg(DBG_LEVEL_MMU, "%s, paddr: 0x%lx, vaddr: [0x%lx - 0x%lx]\n", __func__, paddr, vaddr, vaddr_end); @@ -324,8 +325,8 @@ static void add_pde(const uint64_t *pdpte, uint64_t paddr_start, uint64_t vaddr_ mem_aligned_check(paddr, PDE_SIZE) && mem_aligned_check(vaddr, PDE_SIZE) && (vaddr_next <= vaddr_end)) { - mem_ops->tweak_exe_right(&prot); - set_pgentry(pde, paddr | (prot | PAGE_PSE), mem_ops); + mem_ops->tweak_exe_right(&local_prot); + set_pgentry(pde, paddr | (local_prot | PAGE_PSE), mem_ops); if (vaddr_next < vaddr_end) { paddr += (vaddr_next - vaddr); vaddr = vaddr_next; @@ -358,6 +359,7 @@ static void add_pdpte(const uint64_t *pml4e, uint64_t paddr_start, uint64_t vadd uint64_t vaddr = vaddr_start; uint64_t paddr = paddr_start; uint64_t index = pdpte_index(vaddr); + uint64_t local_prot = prot; dev_dbg(DBG_LEVEL_MMU, "%s, paddr: 0x%lx, vaddr: [0x%lx - 0x%lx]\n", __func__, paddr, vaddr, vaddr_end); for (; index < PTRS_PER_PDPTE; index++) { @@ -372,8 +374,8 @@ static void add_pdpte(const uint64_t *pml4e, uint64_t paddr_start, uint64_t vadd mem_aligned_check(paddr, PDPTE_SIZE) && mem_aligned_check(vaddr, PDPTE_SIZE) && (vaddr_next <= vaddr_end)) { - mem_ops->tweak_exe_right(&prot); - set_pgentry(pdpte, paddr | (prot | PAGE_PSE), mem_ops); + mem_ops->tweak_exe_right(&local_prot); + set_pgentry(pdpte, paddr | (local_prot | PAGE_PSE), mem_ops); if (vaddr_next < vaddr_end) { paddr += (vaddr_next - vaddr); vaddr = vaddr_next;