It's incorrect to assume the context in which invept is called. Check what is supported and fallback if single context invalidation isn't supported Signed-off-by: Bandan Das <bsd@xxxxxxxxxx> --- x86/vmx.c | 20 ++++++++++++++++++++ x86/vmx.h | 1 + x86/vmx_tests.c | 14 +++++++------- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/x86/vmx.c b/x86/vmx.c index 1d28c6f..1182eef 100644 --- a/x86/vmx.c +++ b/x86/vmx.c @@ -288,6 +288,26 @@ unsigned long get_ept_pte(unsigned long *pml4, return pte; } +void ept_sync(int type, u64 eptp) +{ + switch (type) { + case INVEPT_SINGLE: + if (ept_vpid.val & EPT_CAP_INVEPT_SINGLE) { + invept(INVEPT_SINGLE, eptp); + break; + } + /* else fall through */ + case INVEPT_GLOBAL: + if (ept_vpid.val & EPT_CAP_INVEPT_ALL) { + invept(INVEPT_GLOBAL, eptp); + break; + } + /* else fall through */ + default: + printf("WARNING: invept is not supported!\n"); + } +} + int set_ept_pte(unsigned long *pml4, unsigned long guest_addr, int level, u64 pte_val) { diff --git a/x86/vmx.h b/x86/vmx.h index 351c3d9..26dd161 100644 --- a/x86/vmx.h +++ b/x86/vmx.h @@ -551,6 +551,7 @@ static inline void invept(unsigned long type, u64 eptp) } void print_vmexit_info(); +void ept_sync(int type, u64 eptp); void install_ept_entry(unsigned long *pml4, int pte_level, unsigned long guest_addr, unsigned long pte, unsigned long *pt_page); diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c index 2c2d6c4..324f074 100644 --- a/x86/vmx_tests.c +++ b/x86/vmx_tests.c @@ -1116,21 +1116,21 @@ static int ept_exit_handler() case 1: install_ept(pml4, (unsigned long)data_page1, (unsigned long)data_page1, EPT_WA); - invept(INVEPT_SINGLE, eptp); + ept_sync(INVEPT_SINGLE, eptp); break; case 2: install_ept(pml4, (unsigned long)data_page1, (unsigned long)data_page1, EPT_RA | EPT_WA | EPT_EA | (2 << EPT_MEM_TYPE_SHIFT)); - invept(INVEPT_SINGLE, eptp); + ept_sync(INVEPT_SINGLE, eptp); break; case 3: data_page1_pte = get_ept_pte(pml4, (unsigned long)data_page1, 1); set_ept_pte(pml4, (unsigned long)data_page1, 1, data_page1_pte & (~EPT_PRESENT)); - invept(INVEPT_SINGLE, eptp); + ept_sync(INVEPT_SINGLE, eptp); break; case 4: data_page1_pte = get_ept_pte(pml4, @@ -1139,7 +1139,7 @@ static int ept_exit_handler() data_page1_pte_pte = get_ept_pte(pml4, data_page1_pte, 2); set_ept_pte(pml4, data_page1_pte, 2, data_page1_pte_pte & (~EPT_PRESENT)); - invept(INVEPT_SINGLE, eptp); + ept_sync(INVEPT_SINGLE, eptp); break; // Should not reach here default: @@ -1157,7 +1157,7 @@ static int ept_exit_handler() install_ept(pml4, (unsigned long)data_page1, (unsigned long)data_page1, EPT_RA | EPT_WA | EPT_EA); - invept(INVEPT_SINGLE, eptp); + ept_sync(INVEPT_SINGLE, eptp); break; // Should not reach here default: @@ -1174,14 +1174,14 @@ static int ept_exit_handler() set_stage(get_stage() + 1); set_ept_pte(pml4, (unsigned long)data_page1, 1, data_page1_pte | (EPT_PRESENT)); - invept(INVEPT_SINGLE, eptp); + ept_sync(INVEPT_SINGLE, eptp); break; case 4: if (exit_qual == (EPT_VLT_RD | EPT_VLT_LADDR_VLD)) set_stage(get_stage() + 1); set_ept_pte(pml4, data_page1_pte, 2, data_page1_pte_pte | (EPT_PRESENT)); - invept(INVEPT_SINGLE, eptp); + ept_sync(INVEPT_SINGLE, eptp); break; default: // Should not reach here -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html