diff mbox series

[kvm-unit-tests] x86: VMX: Check EPT AD bits when enabled in ept_access_paddr()

Message ID 20191128095422.26757-1-oupton@google.com (mailing list archive)
State New, archived
Headers show
Series [kvm-unit-tests] x86: VMX: Check EPT AD bits when enabled in ept_access_paddr() | expand

Commit Message

Oliver Upton Nov. 28, 2019, 9:54 a.m. UTC
Modify the test helper, ept_access_paddr(), to test the correctness
of the L1's EPT AD bits when enabled. After a successful guest access,
assert that the accessed bit (bit 8) has been set on all EPT entries
which were used in the translation of the guest-physical address.

Since ept_access_paddr() tests an EPT mapping that backs a guest paging
structure, processor accesses are treated as writes and the dirty bit
(bit 9) is set accordingly. Assert that the dirty bit is set on the leaf
EPT entry.

Signed-off-by: Oliver Upton <oupton@google.com>
---
 x86/vmx_tests.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

Comments

Paolo Bonzini Jan. 21, 2020, 12:29 p.m. UTC | #1
On 28/11/19 10:54, Oliver Upton wrote:
> Modify the test helper, ept_access_paddr(), to test the correctness
> of the L1's EPT AD bits when enabled. After a successful guest access,
> assert that the accessed bit (bit 8) has been set on all EPT entries
> which were used in the translation of the guest-physical address.
> 
> Since ept_access_paddr() tests an EPT mapping that backs a guest paging
> structure, processor accesses are treated as writes and the dirty bit
> (bit 9) is set accordingly. Assert that the dirty bit is set on the leaf
> EPT entry.
> 
> Signed-off-by: Oliver Upton <oupton@google.com>
> ---
>  x86/vmx_tests.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
> index a456bd1..325dde7 100644
> --- a/x86/vmx_tests.c
> +++ b/x86/vmx_tests.c
> @@ -1135,6 +1135,11 @@ static void ept_disable_ad_bits(void)
>  	vmcs_write(EPTP, eptp);
>  }
>  
> +static int ept_ad_enabled(void)
> +{
> +	return eptp & EPTP_AD_FLAG;
> +}
> +
>  static void ept_enable_ad_bits_or_skip_test(void)
>  {
>  	if (!ept_ad_bits_supported())
> @@ -2500,6 +2505,8 @@ static void ept_access_paddr(unsigned long ept_access, unsigned long pte_ad,
>  	unsigned long *ptep;
>  	unsigned long gpa;
>  	unsigned long orig_epte;
> +	unsigned long epte;
> +	int i;
>  
>  	/* Modify the guest PTE mapping data->gva according to @pte_ad.  */
>  	ptep = get_pte_level(current_page_table(), data->gva, /*level=*/1);
> @@ -2536,6 +2543,17 @@ static void ept_access_paddr(unsigned long ept_access, unsigned long pte_ad,
>  		do_ept_access_op(op);
>  	} else {
>  		do_ept_access_op(op);
> +		if (ept_ad_enabled()) {
> +			for (i = EPT_PAGE_LEVEL; i > 0; i--) {
> +				TEST_ASSERT(get_ept_pte(pml4, gpa, i, &epte));
> +				TEST_ASSERT(epte & EPT_ACCESS_FLAG);
> +				if (i == 1)
> +					TEST_ASSERT(epte & EPT_DIRTY_FLAG);
> +				else
> +					TEST_ASSERT_EQ(epte & EPT_DIRTY_FLAG, 0);
> +			}
> +		}
> +
>  		ept_untwiddle(gpa, /*level=*/1, orig_epte);
>  	}
>  
> 

Queued, thanks.

Paolo
diff mbox series

Patch

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index a456bd1..325dde7 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -1135,6 +1135,11 @@  static void ept_disable_ad_bits(void)
 	vmcs_write(EPTP, eptp);
 }
 
+static int ept_ad_enabled(void)
+{
+	return eptp & EPTP_AD_FLAG;
+}
+
 static void ept_enable_ad_bits_or_skip_test(void)
 {
 	if (!ept_ad_bits_supported())
@@ -2500,6 +2505,8 @@  static void ept_access_paddr(unsigned long ept_access, unsigned long pte_ad,
 	unsigned long *ptep;
 	unsigned long gpa;
 	unsigned long orig_epte;
+	unsigned long epte;
+	int i;
 
 	/* Modify the guest PTE mapping data->gva according to @pte_ad.  */
 	ptep = get_pte_level(current_page_table(), data->gva, /*level=*/1);
@@ -2536,6 +2543,17 @@  static void ept_access_paddr(unsigned long ept_access, unsigned long pte_ad,
 		do_ept_access_op(op);
 	} else {
 		do_ept_access_op(op);
+		if (ept_ad_enabled()) {
+			for (i = EPT_PAGE_LEVEL; i > 0; i--) {
+				TEST_ASSERT(get_ept_pte(pml4, gpa, i, &epte));
+				TEST_ASSERT(epte & EPT_ACCESS_FLAG);
+				if (i == 1)
+					TEST_ASSERT(epte & EPT_DIRTY_FLAG);
+				else
+					TEST_ASSERT_EQ(epte & EPT_DIRTY_FLAG, 0);
+			}
+		}
+
 		ept_untwiddle(gpa, /*level=*/1, orig_epte);
 	}