Re: [PATCH kvm-unit-tests 1/2] x86: vmx: test invalid operand for INVEPT

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux