diff mbox

[nVMX,TEST,2/2] x86: Add test for checking APIC-access page on vmentry of L2 guests

Message ID 20180411051017.12959-3-krish.sadhukhan@oracle.com (mailing list archive)
State New, archived
Headers show

Commit Message

Krish Sadhukhan April 11, 2018, 5:10 a.m. UTC
According to the sub-section titled 'VM-Execution Control Fields' in the
section titled 'Basic VM-Entry Checks' in Intel SDM vol. 3C, the following
vmentry check must be enforced:

    If the “virtualize APIC-accesses” VM-execution control is 1, the
    APIC-access address must satisfy the following checks:

	- Bits 11:0 of the address must be 0.
	- The address should not set any bits beyond the processor’s
	  physical-address width.

This patch adds a unit-test to validate the vmentry check.

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
Reviewed-by: Mihai Carabas <mihai.carabas@oracle.com>
---
 x86/vmx_tests.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 50 insertions(+), 9 deletions(-)

Comments

Paolo Bonzini April 12, 2018, 12:05 p.m. UTC | #1
On 11/04/2018 07:10, Krish Sadhukhan wrote:
> According to the sub-section titled 'VM-Execution Control Fields' in the
> section titled 'Basic VM-Entry Checks' in Intel SDM vol. 3C, the following
> vmentry check must be enforced:
> 
>     If the “virtualize APIC-accesses” VM-execution control is 1, the
>     APIC-access address must satisfy the following checks:
> 
> 	- Bits 11:0 of the address must be 0.
> 	- The address should not set any bits beyond the processor’s
> 	  physical-address width.
> 
> This patch adds a unit-test to validate the vmentry check.
> 
> Signed-off-by: Krish Sadhukhan <krish.sadhukhan@oracle.com>
> Reviewed-by: Mihai Carabas <mihai.carabas@oracle.com>
> ---
>  x86/vmx_tests.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++---------
>  1 file changed, 50 insertions(+), 9 deletions(-)
> 
> diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
> index 613a8bd..d596d8c 100644
> --- a/x86/vmx_tests.c
> +++ b/x86/vmx_tests.c
> @@ -3430,23 +3430,40 @@ static void test_vmcs_page_values(const char *name,
>  static void test_vmcs_page_reference(u32 control_bit, enum Encoding field,
>  				     const char *field_name,
>  				     const char *control_name,
> -				     bool xfail_beyond_mapped_ram)
> +				     bool xfail_beyond_mapped_ram,
> +				     bool control_primary)
>  {
>  	u32 primary = vmcs_read(CPU_EXEC_CTRL0);
> +	u32 secondary = vmcs_read(CPU_EXEC_CTRL1);
>  	u64 page_addr;
>  
> -	if (!(ctrl_cpu_rev[0].clr & control_bit))
> -		return;
> +	if (control_primary) {
> +		if (!(ctrl_cpu_rev[0].clr & control_bit))
> +			return;
> +	} else {
> +		if (!(ctrl_cpu_rev[1].clr & control_bit))
> +			return;
> +	}
>  
>  	page_addr = vmcs_read(field);
>  
>  	report_prefix_pushf("%s enabled", control_name);
> -	vmcs_write(CPU_EXEC_CTRL0, primary | control_bit);
> +	if (control_primary) {
> +		vmcs_write(CPU_EXEC_CTRL0, primary | control_bit);
> +	} else {
> +		vmcs_write(CPU_EXEC_CTRL0, primary | CPU_SECONDARY);
> +		vmcs_write(CPU_EXEC_CTRL1, secondary | control_bit);
> +	}
>  	test_vmcs_page_values(field_name, field, false, xfail_beyond_mapped_ram);
>  	report_prefix_pop();
>  
>  	report_prefix_pushf("%s disabled", control_name);
> -	vmcs_write(CPU_EXEC_CTRL0, primary & ~control_bit);
> +	if (control_primary) {
> +		vmcs_write(CPU_EXEC_CTRL0, primary & ~control_bit);
> +	} else {
> +		vmcs_write(CPU_EXEC_CTRL0, primary & ~CPU_SECONDARY);
> +		vmcs_write(CPU_EXEC_CTRL1, secondary & ~control_bit);
> +	}
>  	test_vmcs_page_values(field_name, field, true, false);
>  	report_prefix_pop();
>  
> @@ -3463,9 +3480,11 @@ static void test_vmcs_page_reference(u32 control_bit, enum Encoding field,
>  static void test_io_bitmaps(void)
>  {
>  	test_vmcs_page_reference(CPU_IO_BITMAP, IO_BITMAP_A,
> -				 "I/O bitmap A", "Use I/O bitmaps", false);
> +				 "I/O bitmap A", "Use I/O bitmaps", false,
> +				 true);
>  	test_vmcs_page_reference(CPU_IO_BITMAP, IO_BITMAP_B,
> -				 "I/O bitmap B", "Use I/O bitmaps", false);
> +				 "I/O bitmap B", "Use I/O bitmaps", false,
> +				 true);
>  }
>  
>  /*
> @@ -3477,7 +3496,8 @@ static void test_io_bitmaps(void)
>  static void test_msr_bitmap(void)
>  {
>  	test_vmcs_page_reference(CPU_MSR_BITMAP, MSR_BITMAP,
> -				 "MSR bitmap", "Use MSR bitmaps", false);
> +				 "MSR bitmap", "Use MSR bitmaps", false,
> +				 true);
>  }
>  
>  /*
> @@ -3491,7 +3511,27 @@ static void test_msr_bitmap(void)
>  static void test_apic_virt_addr(void)
>  {
>  	test_vmcs_page_reference(CPU_TPR_SHADOW, APIC_VIRT_ADDR,
> -				 "virtual-APIC address", "Use TPR shadow", true);
> +				 "virtual-APIC address", "Use TPR shadow",
> +				 true, true);
> +}
> +
> +/*
> + * If the "virtualize APIC-accesses" VM-execution control is 1, the
> + * APIC-access address must satisfy the following checks:
> + *  - Bits 11:0 of the address must be 0.
> + *  - The address should not set any bits beyond the processor's
> + *    physical-address width.
> + * [Intel SDM]
> + */
> +static void test_apic_access_addr(void)
> +{
> +	void *apic_access_page = alloc_page();
> +
> +	vmcs_write(APIC_ACCS_ADDR, virt_to_phys(apic_access_page));
> +
> +	test_vmcs_page_reference(CPU_VIRT_APIC_ACCESSES, APIC_ACCS_ADDR,
> +				 "APIC-access address",
> +				 "virtualize APIC-accesses", true, false);
>  }
>  
>  static void set_vtpr(unsigned vtpr)
> @@ -3761,6 +3801,7 @@ static void vmx_controls_test(void)
>  	test_io_bitmaps();
>  	test_msr_bitmap();
>  	test_apic_virt_addr();
> +	test_apic_access_addr();
>  	test_tpr_threshold();
>  	test_nmi_ctrls();
>  }
> 

Looks good, thanks.

Paolo
diff mbox

Patch

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 613a8bd..d596d8c 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -3430,23 +3430,40 @@  static void test_vmcs_page_values(const char *name,
 static void test_vmcs_page_reference(u32 control_bit, enum Encoding field,
 				     const char *field_name,
 				     const char *control_name,
-				     bool xfail_beyond_mapped_ram)
+				     bool xfail_beyond_mapped_ram,
+				     bool control_primary)
 {
 	u32 primary = vmcs_read(CPU_EXEC_CTRL0);
+	u32 secondary = vmcs_read(CPU_EXEC_CTRL1);
 	u64 page_addr;
 
-	if (!(ctrl_cpu_rev[0].clr & control_bit))
-		return;
+	if (control_primary) {
+		if (!(ctrl_cpu_rev[0].clr & control_bit))
+			return;
+	} else {
+		if (!(ctrl_cpu_rev[1].clr & control_bit))
+			return;
+	}
 
 	page_addr = vmcs_read(field);
 
 	report_prefix_pushf("%s enabled", control_name);
-	vmcs_write(CPU_EXEC_CTRL0, primary | control_bit);
+	if (control_primary) {
+		vmcs_write(CPU_EXEC_CTRL0, primary | control_bit);
+	} else {
+		vmcs_write(CPU_EXEC_CTRL0, primary | CPU_SECONDARY);
+		vmcs_write(CPU_EXEC_CTRL1, secondary | control_bit);
+	}
 	test_vmcs_page_values(field_name, field, false, xfail_beyond_mapped_ram);
 	report_prefix_pop();
 
 	report_prefix_pushf("%s disabled", control_name);
-	vmcs_write(CPU_EXEC_CTRL0, primary & ~control_bit);
+	if (control_primary) {
+		vmcs_write(CPU_EXEC_CTRL0, primary & ~control_bit);
+	} else {
+		vmcs_write(CPU_EXEC_CTRL0, primary & ~CPU_SECONDARY);
+		vmcs_write(CPU_EXEC_CTRL1, secondary & ~control_bit);
+	}
 	test_vmcs_page_values(field_name, field, true, false);
 	report_prefix_pop();
 
@@ -3463,9 +3480,11 @@  static void test_vmcs_page_reference(u32 control_bit, enum Encoding field,
 static void test_io_bitmaps(void)
 {
 	test_vmcs_page_reference(CPU_IO_BITMAP, IO_BITMAP_A,
-				 "I/O bitmap A", "Use I/O bitmaps", false);
+				 "I/O bitmap A", "Use I/O bitmaps", false,
+				 true);
 	test_vmcs_page_reference(CPU_IO_BITMAP, IO_BITMAP_B,
-				 "I/O bitmap B", "Use I/O bitmaps", false);
+				 "I/O bitmap B", "Use I/O bitmaps", false,
+				 true);
 }
 
 /*
@@ -3477,7 +3496,8 @@  static void test_io_bitmaps(void)
 static void test_msr_bitmap(void)
 {
 	test_vmcs_page_reference(CPU_MSR_BITMAP, MSR_BITMAP,
-				 "MSR bitmap", "Use MSR bitmaps", false);
+				 "MSR bitmap", "Use MSR bitmaps", false,
+				 true);
 }
 
 /*
@@ -3491,7 +3511,27 @@  static void test_msr_bitmap(void)
 static void test_apic_virt_addr(void)
 {
 	test_vmcs_page_reference(CPU_TPR_SHADOW, APIC_VIRT_ADDR,
-				 "virtual-APIC address", "Use TPR shadow", true);
+				 "virtual-APIC address", "Use TPR shadow",
+				 true, true);
+}
+
+/*
+ * If the "virtualize APIC-accesses" VM-execution control is 1, the
+ * APIC-access address must satisfy the following checks:
+ *  - Bits 11:0 of the address must be 0.
+ *  - The address should not set any bits beyond the processor's
+ *    physical-address width.
+ * [Intel SDM]
+ */
+static void test_apic_access_addr(void)
+{
+	void *apic_access_page = alloc_page();
+
+	vmcs_write(APIC_ACCS_ADDR, virt_to_phys(apic_access_page));
+
+	test_vmcs_page_reference(CPU_VIRT_APIC_ACCESSES, APIC_ACCS_ADDR,
+				 "APIC-access address",
+				 "virtualize APIC-accesses", true, false);
 }
 
 static void set_vtpr(unsigned vtpr)
@@ -3761,6 +3801,7 @@  static void vmx_controls_test(void)
 	test_io_bitmaps();
 	test_msr_bitmap();
 	test_apic_virt_addr();
+	test_apic_access_addr();
 	test_tpr_threshold();
 	test_nmi_ctrls();
 }