All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jan Kiszka <jan.kiszka@web.de>
To: Arthur Chunqi Li <yzt356@gmail.com>
Cc: kvm@vger.kernel.org, gleb@redhat.com, pbonzini@redhat.com
Subject: Re: [PATCH 1/4] kvm-unit-tests: VMX: Add test cases for PAT and EFER
Date: Thu, 15 Aug 2013 09:17:28 +0200	[thread overview]
Message-ID: <520C8088.6070607@web.de> (raw)
In-Reply-To: <1376409368-7016-2-git-send-email-yzt356@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 7560 bytes --]

On 2013-08-13 17:56, Arthur Chunqi Li wrote:
> Add test cases for ENT_LOAD_PAT, ENT_LOAD_EFER, EXI_LOAD_PAT,
> EXI_SAVE_PAT, EXI_LOAD_EFER, EXI_SAVE_PAT flags in enter/exit
> control fields.
> 
> Signed-off-by: Arthur Chunqi Li <yzt356@gmail.com>
> ---
>  x86/vmx.h       |    7 +++
>  x86/vmx_tests.c |  185 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 192 insertions(+)
> 
> diff --git a/x86/vmx.h b/x86/vmx.h
> index 28595d8..18961f1 100644
> --- a/x86/vmx.h
> +++ b/x86/vmx.h
> @@ -152,10 +152,12 @@ enum Encoding {
>  	GUEST_DEBUGCTL		= 0x2802ul,
>  	GUEST_DEBUGCTL_HI	= 0x2803ul,
>  	GUEST_EFER		= 0x2806ul,
> +	GUEST_PAT		= 0x2804ul,
>  	GUEST_PERF_GLOBAL_CTRL	= 0x2808ul,
>  	GUEST_PDPTE		= 0x280aul,
>  
>  	/* 64-Bit Host State */
> +	HOST_PAT		= 0x2c00ul,
>  	HOST_EFER		= 0x2c02ul,
>  	HOST_PERF_GLOBAL_CTRL	= 0x2c04ul,
>  
> @@ -330,11 +332,15 @@ enum Ctrl_exi {
>  	EXI_HOST_64             = 1UL << 9,
>  	EXI_LOAD_PERF		= 1UL << 12,
>  	EXI_INTA                = 1UL << 15,
> +	EXI_SAVE_PAT		= 1UL << 18,
> +	EXI_LOAD_PAT		= 1UL << 19,
> +	EXI_SAVE_EFER		= 1UL << 20,
>  	EXI_LOAD_EFER           = 1UL << 21,
>  };
>  
>  enum Ctrl_ent {
>  	ENT_GUEST_64            = 1UL << 9,
> +	ENT_LOAD_PAT		= 1UL << 14,
>  	ENT_LOAD_EFER           = 1UL << 15,
>  };
>  
> @@ -354,6 +360,7 @@ enum Ctrl0 {
>  	CPU_NMI_WINDOW		= 1ul << 22,
>  	CPU_IO			= 1ul << 24,
>  	CPU_IO_BITMAP		= 1ul << 25,
> +	CPU_MSR_BITMAP		= 1ul << 28,
>  	CPU_SECONDARY		= 1ul << 31,
>  };
>  
> diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
> index c1b39f4..61b0cef 100644
> --- a/x86/vmx_tests.c
> +++ b/x86/vmx_tests.c
> @@ -1,4 +1,15 @@
>  #include "vmx.h"
> +#include "msr.h"
> +#include "processor.h"
> +#include "vm.h"
> +
> +u64 ia32_pat;
> +u64 ia32_efer;
> +
> +static inline void vmcall()
> +{
> +	asm volatile("vmcall");
> +}
>  
>  void basic_init()
>  {
> @@ -76,6 +87,176 @@ int vmenter_exit_handler()
>  	return VMX_TEST_VMEXIT;
>  }
>  
> +void msr_bmp_init()
> +{
> +	void *msr_bitmap;
> +	u32 ctrl_cpu0;
> +
> +	msr_bitmap = alloc_page();
> +	memset(msr_bitmap, 0x0, PAGE_SIZE);
> +	ctrl_cpu0 = vmcs_read(CPU_EXEC_CTRL0);
> +	ctrl_cpu0 |= CPU_MSR_BITMAP;
> +	vmcs_write(CPU_EXEC_CTRL0, ctrl_cpu0);
> +	vmcs_write(MSR_BITMAP, (u64)msr_bitmap);
> +}

Better safe this function for the test case where you actually stress
the bitmap.

Jan

> +
> +static void test_ctrl_pat_init()
> +{
> +	u64 ctrl_ent;
> +	u64 ctrl_exi;
> +
> +	msr_bmp_init();
> +	ctrl_ent = vmcs_read(ENT_CONTROLS);
> +	ctrl_exi = vmcs_read(EXI_CONTROLS);
> +	vmcs_write(ENT_CONTROLS, ctrl_ent | ENT_LOAD_PAT);
> +	vmcs_write(EXI_CONTROLS, ctrl_exi | (EXI_SAVE_PAT | EXI_LOAD_PAT));
> +	ia32_pat = rdmsr(MSR_IA32_CR_PAT);
> +	vmcs_write(GUEST_PAT, 0x0);
> +	vmcs_write(HOST_PAT, ia32_pat);
> +}
> +
> +static void test_ctrl_pat_main()
> +{
> +	u64 guest_ia32_pat;
> +
> +	guest_ia32_pat = rdmsr(MSR_IA32_CR_PAT);
> +	if (!(ctrl_enter_rev.clr & ENT_LOAD_PAT))
> +		printf("\tENT_LOAD_PAT is not supported.\n");
> +	else {
> +		if (guest_ia32_pat != 0) {
> +			report("Entry load PAT", 0);
> +			return;
> +		}
> +	}
> +	wrmsr(MSR_IA32_CR_PAT, 0x6);
> +	vmcall();
> +	guest_ia32_pat = rdmsr(MSR_IA32_CR_PAT);
> +	if (ctrl_enter_rev.clr & ENT_LOAD_PAT) {
> +		if (guest_ia32_pat != ia32_pat) {
> +			report("Entry load PAT", 0);
> +			return;
> +		}
> +		report("Entry load PAT", 1);
> +	}
> +}
> +
> +static int test_ctrl_pat_exit_handler()
> +{
> +	u64 guest_rip;
> +	ulong reason;
> +	u64 guest_pat;
> +
> +	guest_rip = vmcs_read(GUEST_RIP);
> +	reason = vmcs_read(EXI_REASON) & 0xff;
> +	switch (reason) {
> +	case VMX_VMCALL:
> +		guest_pat = vmcs_read(GUEST_PAT);
> +		if (!(ctrl_exit_rev.clr & EXI_SAVE_PAT)) {
> +			printf("\tEXI_SAVE_PAT is not supported\n");
> +			vmcs_write(GUEST_PAT, 0x6);
> +		} else {
> +			if (guest_pat == 0x6)
> +				report("Exit save PAT", 1);
> +			else
> +				report("Exit save PAT", 0);
> +		}
> +		if (!(ctrl_exit_rev.clr & EXI_LOAD_PAT))
> +			printf("\tEXI_LOAD_PAT is not supported\n");
> +		else {
> +			if (rdmsr(MSR_IA32_CR_PAT) == ia32_pat)
> +				report("Exit load PAT", 1);
> +			else
> +				report("Exit load PAT", 0);
> +		}
> +		vmcs_write(GUEST_PAT, ia32_pat);
> +		vmcs_write(GUEST_RIP, guest_rip + 3);
> +		return VMX_TEST_RESUME;
> +	default:
> +		printf("ERROR : Undefined exit reason, reason = %d.\n", reason);
> +		break;
> +	}
> +	return VMX_TEST_VMEXIT;
> +}
> +
> +static void test_ctrl_efer_init()
> +{
> +	u64 ctrl_ent;
> +	u64 ctrl_exi;
> +
> +	msr_bmp_init();
> +	ctrl_ent = vmcs_read(ENT_CONTROLS) | ENT_LOAD_EFER;
> +	ctrl_exi = vmcs_read(EXI_CONTROLS) | EXI_SAVE_EFER | EXI_LOAD_EFER;
> +	vmcs_write(ENT_CONTROLS, ctrl_ent & ctrl_enter_rev.clr);
> +	vmcs_write(EXI_CONTROLS, ctrl_exi & ctrl_exit_rev.clr);
> +	ia32_efer = rdmsr(MSR_EFER);
> +	vmcs_write(GUEST_EFER, ia32_efer ^ EFER_NX);
> +	vmcs_write(HOST_EFER, ia32_efer ^ EFER_NX);
> +}
> +
> +static void test_ctrl_efer_main()
> +{
> +	u64 guest_ia32_efer;
> +
> +	guest_ia32_efer = rdmsr(MSR_EFER);
> +	if (!(ctrl_enter_rev.clr & ENT_LOAD_EFER))
> +		printf("\tENT_LOAD_EFER is not supported.\n");
> +	else {
> +		if (guest_ia32_efer != (ia32_efer ^ EFER_NX)) {
> +			report("Entry load EFER", 0);
> +			return;
> +		}
> +	}
> +	wrmsr(MSR_EFER, ia32_efer);
> +	vmcall();
> +	guest_ia32_efer = rdmsr(MSR_EFER);
> +	if (ctrl_enter_rev.clr & ENT_LOAD_EFER) {
> +		if (guest_ia32_efer != ia32_efer) {
> +			report("Entry load EFER", 0);
> +			return;
> +		}
> +		report("Entry load EFER", 1);
> +	}
> +}
> +
> +static int test_ctrl_efer_exit_handler()
> +{
> +	u64 guest_rip;
> +	ulong reason;
> +	u64 guest_efer;
> +
> +	guest_rip = vmcs_read(GUEST_RIP);
> +	reason = vmcs_read(EXI_REASON) & 0xff;
> +	switch (reason) {
> +	case VMX_VMCALL:
> +		guest_efer = vmcs_read(GUEST_EFER);
> +		if (!(ctrl_exit_rev.clr & EXI_SAVE_EFER)) {
> +			printf("\tEXI_SAVE_EFER is not supported\n");
> +			vmcs_write(GUEST_EFER, ia32_efer);
> +		} else {
> +			if (guest_efer == ia32_efer)
> +				report("Exit save EFER", 1);
> +			else
> +				report("Exit save EFER", 0);
> +		}
> +		if (!(ctrl_exit_rev.clr & EXI_LOAD_EFER)) {
> +			printf("\tEXI_LOAD_EFER is not supported\n");
> +			wrmsr(MSR_EFER, ia32_efer ^ EFER_NX);
> +		} else {
> +			if (rdmsr(MSR_EFER) == (ia32_efer ^ EFER_NX))
> +				report("Exit load EFER", 1);
> +			else
> +				report("Exit load EFER", 0);
> +		}
> +		vmcs_write(GUEST_PAT, ia32_efer);
> +		vmcs_write(GUEST_RIP, guest_rip + 3);
> +		return VMX_TEST_RESUME;
> +	default:
> +		printf("ERROR : Undefined exit reason, reason = %d.\n", reason);
> +		break;
> +	}
> +	return VMX_TEST_VMEXIT;
> +}
> +
>  /* name/init/guest_main/exit_handler/syscall_handler/guest_regs
>     basic_* just implement some basic functions */
>  struct vmx_test vmx_tests[] = {
> @@ -83,5 +264,9 @@ struct vmx_test vmx_tests[] = {
>  		basic_syscall_handler, {0} },
>  	{ "vmenter", basic_init, vmenter_main, vmenter_exit_handler,
>  		basic_syscall_handler, {0} },
> +	{ "control field PAT", test_ctrl_pat_init, test_ctrl_pat_main,
> +		test_ctrl_pat_exit_handler, basic_syscall_handler, {0} },
> +	{ "control field EFER", test_ctrl_efer_init, test_ctrl_efer_main,
> +		test_ctrl_efer_exit_handler, basic_syscall_handler, {0} },
>  	{ NULL, NULL, NULL, NULL, NULL, {0} },
>  };
> 



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 263 bytes --]

  reply	other threads:[~2013-08-15  7:17 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-13 15:56 [PATCH 0/4] kvm-unit-tests: Add a series of test cases Arthur Chunqi Li
2013-08-13 15:56 ` [PATCH 1/4] kvm-unit-tests: VMX: Add test cases for PAT and EFER Arthur Chunqi Li
2013-08-15  7:17   ` Jan Kiszka [this message]
2013-08-15  7:41     ` Arthur Chunqi Li
2013-08-15  7:48       ` Jan Kiszka
2013-08-15  8:05         ` Arthur Chunqi Li
2013-08-15  8:09           ` Jan Kiszka
2013-08-13 15:56 ` [PATCH 2/4] kvm-unit-tests: VMX: Add test cases for CR0/4 shadowing Arthur Chunqi Li
2013-08-15  7:30   ` Jan Kiszka
2013-08-15  7:40     ` Arthur Chunqi Li
2013-08-15  7:47       ` Jan Kiszka
2013-08-15  7:59         ` Arthur Chunqi Li
2013-08-15  8:07           ` Jan Kiszka
2013-08-18 14:07           ` Paolo Bonzini
2013-08-18 14:32             ` Gmail
2013-08-13 15:56 ` [PATCH 3/4] kvm-unit-tests: VMX: Add test cases for I/O bitmaps Arthur Chunqi Li
2013-08-15  7:40   ` Jan Kiszka
2013-08-15  7:51     ` Arthur Chunqi Li
2013-08-15  7:58       ` Jan Kiszka
2013-08-15  8:09         ` Arthur Chunqi Li
2013-08-15  8:13           ` Jan Kiszka
2013-08-15  8:20             ` Arthur Chunqi Li
2013-08-15  8:23               ` Jan Kiszka
2013-08-15 10:43                 ` Arthur Chunqi Li
2013-08-13 15:56 ` [PATCH 4/4] kvm-unit-tests: VMX: Add test cases for instruction interception Arthur Chunqi Li
2013-08-15  8:06   ` Jan Kiszka
2013-08-15  8:16     ` Arthur Chunqi Li
2013-08-15  8:20       ` Jan Kiszka
2013-08-15  8:35         ` Arthur Chunqi Li
2013-08-15  8:40           ` Jan Kiszka
2013-08-15  8:48             ` Arthur Chunqi Li
2013-08-15  9:15               ` Jan Kiszka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=520C8088.6070607@web.de \
    --to=jan.kiszka@web.de \
    --cc=gleb@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=yzt356@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.