All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [kvm-unit-tests PATCH] vpid test case
       [not found] <1447160116-14716-1-git-send-email-wanpeng.li@hotmail.com>
@ 2015-11-11 13:11 ` Paolo Bonzini
  0 siblings, 0 replies; only message in thread
From: Paolo Bonzini @ 2015-11-11 13:11 UTC (permalink / raw)
  To: Wanpeng Li; +Cc: kvm, linux-kernel



On 10/11/2015 13:55, Wanpeng Li wrote:
> VPID test case for invvpid single and invvpid all.
> 
> Signed-off-by: Wanpeng Li <wanpeng.li@hotmail.com>
> ---
>  x86/vmx.c       | 17 ++++++++++++++++
>  x86/vmx.h       | 17 ++++++++++++++++
>  x86/vmx_tests.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 97 insertions(+)
> 
> diff --git a/x86/vmx.c b/x86/vmx.c
> index 51e63a0..f05cd33 100644
> --- a/x86/vmx.c
> +++ b/x86/vmx.c
> @@ -386,6 +386,23 @@ int set_ept_pte(unsigned long *pml4, unsigned long guest_addr,
>  	return 0;
>  }
>  
> +void vpid_sync(int type, u16 vpid)
> +{
> +	switch(type) {
> +	case INVVPID_SINGLE:
> +		if (ept_vpid.val & VPID_CAP_INVVPID_SINGLE) {
> +			invvpid(INVVPID_SINGLE, vpid, 0);
> +			break;
> +		}
> +	case INVVPID_ALL:
> +		if (ept_vpid.val & VPID_CAP_INVVPID_ALL) {
> +			invvpid(INVVPID_ALL, vpid, 0);
> +			break;
> +		}
> +	default:
> +		printf("WARNING: invvpid is not supported\n");
> +	}
> +}
>  
>  static void init_vmcs_ctrl(void)
>  {
> diff --git a/x86/vmx.h b/x86/vmx.h
> index 3571248..b6a4878 100644
> --- a/x86/vmx.h
> +++ b/x86/vmx.h
> @@ -460,6 +460,9 @@ enum Ctrl1 {
>  #define EPT_CAP_INVEPT_SINGLE	(1ull << 25)
>  #define EPT_CAP_INVEPT_ALL	(1ull << 26)
>  #define EPT_CAP_AD_FLAG	(1ull << 21)
> +#define VPID_CAP_INVVPID (1ull << 32)
> +#define VPID_CAP_INVVPID_SINGLE  (1ull << 41)
> +#define VPID_CAP_INVVPID_ALL  (1ull << 42)
>  
>  #define PAGE_SIZE_2M		(512 * PAGE_SIZE)
>  #define PAGE_SIZE_1G		(512 * PAGE_SIZE_2M)
> @@ -485,6 +488,9 @@ enum Ctrl1 {
>  #define INVEPT_SINGLE		1
>  #define INVEPT_GLOBAL		2
>  
> +#define INVVPID_SINGLE      1
> +#define INVVPID_ALL         2
> +
>  #define ACTV_ACTIVE		0
>  #define ACTV_HLT		1
>  
> @@ -544,8 +550,19 @@ static inline void invept(unsigned long type, u64 eptp)
>  	asm volatile("invept %0, %1\n" ::"m"(operand),"r"(type));
>  }
>  
> +static inline void invvpid(unsigned long type, u16 vpid, u64 gva)
> +{
> +	struct {
> +		u64 vpid : 16;
> +		u64 rsvd : 48;
> +		u64 gva;
> +	} operand = {vpid, 0, gva};
> +	asm volatile("invvpid %0, %1\n" ::"m"(operand),"r"(type));
> +}
> +
>  void print_vmexit_info();
>  void ept_sync(int type, u64 eptp);
> +void vpid_sync(int type, u16 vpid);
>  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 79552fd..451fdd7 100644
> --- a/x86/vmx_tests.c
> +++ b/x86/vmx_tests.c
> @@ -1150,6 +1150,68 @@ static int ept_exit_handler()
>  	return VMX_TEST_VMEXIT;
>  }
>  
> +static int vpid_init()
> +{
> +	u32 ctrl_cpu1;
> +
> +	if (!(ctrl_cpu_rev[0].clr & CPU_SECONDARY) ||
> +		!(ctrl_cpu_rev[1].clr & CPU_VPID)) {
> +		printf("\tVPID is not supported");
> +		return VMX_TEST_EXIT;
> +	}
> +
> +	ctrl_cpu1 = vmcs_read(CPU_EXEC_CTRL1);
> +	ctrl_cpu1 |= CPU_VPID;
> +	vmcs_write(CPU_EXEC_CTRL1, ctrl_cpu1);
> +	return VMX_TEST_START;
> +}
> +
> +static void vpid_main()
> +{
> +	vmx_set_test_stage(0);
> +	vmcall();
> +	report("INVVPID SINGLE", vmx_get_test_stage() == 0);
> +	vmx_set_test_stage(1);
> +	vmcall();
> +	report("INVVPID ALL", vmx_get_test_stage() == 1);
> +}
> +
> +static int vpid_exit_handler()
> +{
> +	u64 guest_rip;
> +	ulong reason;
> +	u32 insn_len;
> +	u32 exit_qual;
> +
> +	guest_rip = vmcs_read(GUEST_RIP);
> +	reason = vmcs_read(EXI_REASON) & 0xff;
> +	insn_len = vmcs_read(EXI_INST_LEN);
> +	exit_qual = vmcs_read(EXI_QUALIFICATION);
> +
> +	switch (reason) {
> +	case VMX_VMCALL:
> +		switch(vmx_get_test_stage()) {
> +		case 0:
> +			vpid_sync(INVVPID_SINGLE, 1);
> +			break;
> +		case 1:
> +			vpid_sync(INVVPID_ALL, 1);
> +			break;
> +		default:
> +			printf("ERROR: unexpected stage, %d\n",
> +					vmx_get_test_stage());
> +			print_vmexit_info();
> +			return VMX_TEST_VMEXIT;
> +		}
> +		vmcs_write(GUEST_RIP, guest_rip + insn_len);
> +		return VMX_TEST_RESUME;
> +	default:
> +		printf("Unknown exit reason, %d\n", reason);
> +		print_vmexit_info();
> +	}
> +	return VMX_TEST_VMEXIT;
> +}
> +
>  #define TIMER_VECTOR	222
>  
>  static volatile bool timer_fired;
> @@ -1547,6 +1609,7 @@ struct vmx_test vmx_tests[] = {
>  	{ "instruction intercept", insn_intercept_init, insn_intercept_main,
>  		insn_intercept_exit_handler, NULL, {0} },
>  	{ "EPT framework", ept_init, ept_main, ept_exit_handler, NULL, {0} },
> +	{ "VPID", vpid_init, vpid_main, vpid_exit_handler, NULL, {0} },
>  	{ "interrupt", interrupt_init, interrupt_main,
>  		interrupt_exit_handler, NULL, {0} },
>  	{ "debug controls", dbgctls_init, dbgctls_main, dbgctls_exit_handler,
> 

Applied, thanks!

Paolo

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2015-11-11 13:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1447160116-14716-1-git-send-email-wanpeng.li@hotmail.com>
2015-11-11 13:11 ` [kvm-unit-tests PATCH] vpid test case Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.