lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Wed, 11 Nov 2015 14:11:05 +0100
From:	Paolo Bonzini <pbonzini@...hat.com>
To:	Wanpeng Li <wanpeng.li@...mail.com>
Cc:	kvm@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [kvm-unit-tests PATCH] vpid test case



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@...mail.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
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ