[1/1,kvm-unit-test] nVMX x86: Check enable-EPT on vmentry of L2 guests
diff mbox series

Message ID 20181005161538.24907-2-krish.sadhukhan@oracle.com
State New
Headers show
Series
  • [1/1,kvm-unit-test] nVMX x86: Check enable-EPT on vmentry of L2 guests
Related show

Commit Message

Krish Sadhukhan Oct. 5, 2018, 4:15 p.m. UTC
According to section "Checks on VMX Controls" in Intel SDM vol 3C, the
following check needs to be enforced on vmentry of L2 guests:

  If the "unrestricted guest" VM-execution control is 1, the "enable EPT"
  VM-execution control must also be 1.

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
Reviewed-by: Mihai Carabas <mihai.carabas@oracle.com>
Reviewed-by: Mark Kanda <mark.kanda@oracle.com>
---
 x86/vmx_tests.c | 56 ++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 42 insertions(+), 14 deletions(-)

Comments

Paolo Bonzini Oct. 15, 2018, 5:11 p.m. UTC | #1
On 05/10/2018 18:15, Krish Sadhukhan wrote:
> According to section "Checks on VMX Controls" in Intel SDM vol 3C, the
> following check needs to be enforced on vmentry of L2 guests:
> 
>   If the "unrestricted guest" VM-execution control is 1, the "enable EPT"
>   VM-execution control must also be 1.
> 
> Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
> Reviewed-by: Mihai Carabas <mihai.carabas@oracle.com>
> Reviewed-by: Mark Kanda <mark.kanda@oracle.com>
> ---
>  x86/vmx_tests.c | 56 ++++++++++++++++++++++++++++++++++++++++++--------------
>  1 file changed, 42 insertions(+), 14 deletions(-)
> 
> diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
> index be166ef..8c87a8a 100644
> --- a/x86/vmx_tests.c
> +++ b/x86/vmx_tests.c
> @@ -4490,24 +4490,28 @@ static void test_eptp_ad_bit(u64 eptp, bool ctrl)
>  	report_prefix_pop();
>  
>  }
> +
>  /*
> - * If the “enable EPT†VM-execution control is 1, the EPTP VM-execution
> - * control field must satisfy the following checks:
> + * 1. If the "enable EPT" VM-execution control is 1, the "EPTP VM-execution"
> + *    control field must satisfy the following checks:
> + *
> + *     - The EPT memory type (bits 2:0) must be a value supported by the
> + *	 processor as indicated in the IA32_VMX_EPT_VPID_CAP MSR.
> + *     - Bits 5:3 (1 less than the EPT page-walk length) must be 3,
> + *	 indicating an EPT page-walk length of 4.
> + *     - Bit 6 (enable bit for accessed and dirty flags for EPT) must be
> + *	 0 if bit 21 of the IA32_VMX_EPT_VPID_CAP MSR is read as 0,
> + *	 indicating that the processor does not support accessed and dirty
> + *	 dirty flags for EPT.
> + *     - Reserved bits 11:7 and 63:N (where N is the processor's
> + *	 physical-address width) must all be 0.
>   *
> - *   —  The EPT memory type (bits 2:0) must be a value supported by the
> - *	processor as indicated in the IA32_VMX_EPT_VPID_CAP MSR.
> - *   —  Bits 5:3 (1 less than the EPT page-walk length) must be 3,
> - *	indicating an EPT page-walk length of 4.
> - *   —  Bit 6 (enable bit for accessed and dirty flags for EPT) must be
> - *	0 if bit 21 of the IA32_VMX_EPT_VPID_CAP MSR is read as 0,
> - *	indicating that the processor does not support accessed and dirty
> - *	dirty flags for EPT.
> - *   —  Reserved bits 11:7 and 63:N (where N is the processor’s
> - *	physical-address width) must all be 0.
> + * 2. If the "unrestricted guest" VM-execution control is 1, the
> + *    "enable EPT" VM-execution control must also be 1.
>   *
>   *  [Intel SDM]
>   */
> -static void test_eptp(void)
> +static void test_ept_eptp(void)
>  {
>  	u32 primary_saved = vmcs_read(CPU_EXEC_CTRL0);
>  	u32 secondary_saved = vmcs_read(CPU_EXEC_CTRL1);
> @@ -4655,6 +4659,30 @@ static void test_eptp(void)
>  		report_prefix_pop();
>  	}
>  
> +	secondary &= ~(CPU_EPT | CPU_URG);
> +	vmcs_write(CPU_EXEC_CTRL1, secondary);
> +	report_prefix_pushf("Enable-EPT disabled, unrestricted-guest disabled");
> +	test_vmx_controls(true, false);
> +	report_prefix_pop();
> +
> +	secondary |= CPU_URG;
> +	vmcs_write(CPU_EXEC_CTRL1, secondary);
> +	report_prefix_pushf("Enable-EPT disabled, unrestricted-guest enabled");
> +	test_vmx_controls(false, false);
> +	report_prefix_pop();
> +
> +	secondary |= CPU_EPT;
> +	vmcs_write(CPU_EXEC_CTRL1, secondary);
> +	report_prefix_pushf("Enable-EPT enabled, unrestricted-guest enabled");
> +	test_vmx_controls(true, false);
> +	report_prefix_pop();
> +
> +	secondary &= ~CPU_URG;
> +	vmcs_write(CPU_EXEC_CTRL1, secondary);
> +	report_prefix_pushf("Enable-EPT enabled, unrestricted-guest disabled");
> +	test_vmx_controls(true, false);
> +	report_prefix_pop();
> +
>  	vmcs_write(CPU_EXEC_CTRL0, primary_saved);
>  	vmcs_write(CPU_EXEC_CTRL1, secondary_saved);
>  	vmcs_write(EPTP, eptp_saved);
> @@ -4684,7 +4712,7 @@ static void vmx_controls_test(void)
>  	test_nmi_ctrls();
>  	test_invalid_event_injection();
>  	test_vpid();
> -	test_eptp();
> +	test_ept_eptp();
>  }
>  
>  static bool valid_vmcs_for_vmentry(void)
> 

Queued, thanks.

Paolo

Patch
diff mbox series

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index be166ef..8c87a8a 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -4490,24 +4490,28 @@  static void test_eptp_ad_bit(u64 eptp, bool ctrl)
 	report_prefix_pop();
 
 }
+
 /*
- * If the “enable EPT†VM-execution control is 1, the EPTP VM-execution
- * control field must satisfy the following checks:
+ * 1. If the "enable EPT" VM-execution control is 1, the "EPTP VM-execution"
+ *    control field must satisfy the following checks:
+ *
+ *     - The EPT memory type (bits 2:0) must be a value supported by the
+ *	 processor as indicated in the IA32_VMX_EPT_VPID_CAP MSR.
+ *     - Bits 5:3 (1 less than the EPT page-walk length) must be 3,
+ *	 indicating an EPT page-walk length of 4.
+ *     - Bit 6 (enable bit for accessed and dirty flags for EPT) must be
+ *	 0 if bit 21 of the IA32_VMX_EPT_VPID_CAP MSR is read as 0,
+ *	 indicating that the processor does not support accessed and dirty
+ *	 dirty flags for EPT.
+ *     - Reserved bits 11:7 and 63:N (where N is the processor's
+ *	 physical-address width) must all be 0.
  *
- *   —  The EPT memory type (bits 2:0) must be a value supported by the
- *	processor as indicated in the IA32_VMX_EPT_VPID_CAP MSR.
- *   —  Bits 5:3 (1 less than the EPT page-walk length) must be 3,
- *	indicating an EPT page-walk length of 4.
- *   —  Bit 6 (enable bit for accessed and dirty flags for EPT) must be
- *	0 if bit 21 of the IA32_VMX_EPT_VPID_CAP MSR is read as 0,
- *	indicating that the processor does not support accessed and dirty
- *	dirty flags for EPT.
- *   —  Reserved bits 11:7 and 63:N (where N is the processor’s
- *	physical-address width) must all be 0.
+ * 2. If the "unrestricted guest" VM-execution control is 1, the
+ *    "enable EPT" VM-execution control must also be 1.
  *
  *  [Intel SDM]
  */
-static void test_eptp(void)
+static void test_ept_eptp(void)
 {
 	u32 primary_saved = vmcs_read(CPU_EXEC_CTRL0);
 	u32 secondary_saved = vmcs_read(CPU_EXEC_CTRL1);
@@ -4655,6 +4659,30 @@  static void test_eptp(void)
 		report_prefix_pop();
 	}
 
+	secondary &= ~(CPU_EPT | CPU_URG);
+	vmcs_write(CPU_EXEC_CTRL1, secondary);
+	report_prefix_pushf("Enable-EPT disabled, unrestricted-guest disabled");
+	test_vmx_controls(true, false);
+	report_prefix_pop();
+
+	secondary |= CPU_URG;
+	vmcs_write(CPU_EXEC_CTRL1, secondary);
+	report_prefix_pushf("Enable-EPT disabled, unrestricted-guest enabled");
+	test_vmx_controls(false, false);
+	report_prefix_pop();
+
+	secondary |= CPU_EPT;
+	vmcs_write(CPU_EXEC_CTRL1, secondary);
+	report_prefix_pushf("Enable-EPT enabled, unrestricted-guest enabled");
+	test_vmx_controls(true, false);
+	report_prefix_pop();
+
+	secondary &= ~CPU_URG;
+	vmcs_write(CPU_EXEC_CTRL1, secondary);
+	report_prefix_pushf("Enable-EPT enabled, unrestricted-guest disabled");
+	test_vmx_controls(true, false);
+	report_prefix_pop();
+
 	vmcs_write(CPU_EXEC_CTRL0, primary_saved);
 	vmcs_write(CPU_EXEC_CTRL1, secondary_saved);
 	vmcs_write(EPTP, eptp_saved);
@@ -4684,7 +4712,7 @@  static void vmx_controls_test(void)
 	test_nmi_ctrls();
 	test_invalid_event_injection();
 	test_vpid();
-	test_eptp();
+	test_ept_eptp();
 }
 
 static bool valid_vmcs_for_vmentry(void)