On Sat, Mar 19, 2016 at 2:52 AM, Paolo Bonzini <pbonzini@xxxxxxxxxx> wrote: > Check that it doesn't cause an infinite stream of vmexits. > > Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> > --- > x86/vmx.h | 9 +++++++-- > x86/vmx_tests.c | 26 ++++++++++++++++++++++++++ > 2 files changed, 33 insertions(+), 2 deletions(-) > > diff --git a/x86/vmx.h b/x86/vmx.h > index 0cb995d..146f082 100644 > --- a/x86/vmx.h > +++ b/x86/vmx.h > @@ -549,12 +549,17 @@ static inline int vmcs_save(struct vmcs **vmcs) > return ret; > } > > -static inline void invept(unsigned long type, u64 eptp) > +static inline bool invept(unsigned long type, u64 eptp) > { > + bool ret; > + u64 rflags = read_rflags() | X86_EFLAGS_CF | X86_EFLAGS_ZF; Why explicitly set these bits prior to invept? > + > struct { > u64 eptp, gpa; > } operand = {eptp, 0}; > - asm volatile("invept %0, %1\n" ::"m"(operand),"r"(type)); > + asm volatile("push %1; popf; invept %2, %3; setbe %0" > + : "=q" (ret) : "r" (rflags), "m"(operand),"r"(type) : "cc"); > + return ret; > } > > static inline void invvpid(unsigned long type, u16 vpid, u64 gva) > diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c > index 0145cad..dd3af58 100644 > --- a/x86/vmx_tests.c > +++ b/x86/vmx_tests.c > @@ -1029,6 +1029,28 @@ t1: > // Test EPT access to L1 MMIO > vmx_set_test_stage(6); > report("EPT - MMIO access", *((u32 *)0xfee00030UL) == apic_version); > + > + // Test invalid operand for INVEPT > + vmcall(); > + report("EPT - unsupported INVEPT", vmx_get_test_stage() == 7); > +} > + > +bool invept_test(int type, u64 eptp) > +{ > + bool ret, supported; > + > + supported = ept_vpid.val & (EPT_CAP_INVEPT_SINGLE >> INVEPT_SINGLE << type); > + ret = invept(type, eptp); > + > + if (ret == !supported) > + return false; Nit: Is there a precedent for using bool as the return type and indicating success with false? I found this a little confusing; the pattern I'm more familiar with is an int return type and 0 for success. > + > + if (!supported) > + printf("WARNING: unsupported invept passed!\n"); > + else > + printf("WARNING: invept failed!\n"); > + > + return true; > } > > static int ept_exit_handler() > @@ -1084,6 +1106,10 @@ static int ept_exit_handler() > data_page1_pte_pte & (~EPT_PRESENT)); > ept_sync(INVEPT_SINGLE, eptp); > break; > + case 6: > + if (!invept_test(0, eptp)) > + vmx_inc_test_stage(); > + break; > // Should not reach here > default: > printf("ERROR - unexpected stage, %d.\n", > -- > 2.5.0 > > -- 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