Re: [kvm-unit-tests PATCH] x86: Do not run vmx tests if feature is unsupported by CPU

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 18/05/19 17:53, Nadav Amit wrote:
> Instruction tests of VMX should not be executed if the feature is
> unsupported by the CPU. Even if the execution controls allow to trap
> exits on the feature, the feature might be disabled, for example through
> IA32_MISC_ENABLES. Therefore, checking that the feature is supported
> through CPUID is needed.
> 
> Introduce a general mechanism to check that a feature is supported and
> use it for monitor/mwait.
> 
> Signed-off-by: Nadav Amit <nadav.amit@xxxxxxxxx>
> ---
>  x86/vmx_tests.c | 34 ++++++++++++++++++++++++++++------
>  1 file changed, 28 insertions(+), 6 deletions(-)
> 
> diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
> index cade812..bdff938 100644
> --- a/x86/vmx_tests.c
> +++ b/x86/vmx_tests.c
> @@ -842,6 +842,17 @@ extern void insn_rdseed(void);
>  u32 cur_insn;
>  u64 cr3;
>  
> +#define X86_FEATURE_MONITOR	(1 << 3)
> +#define X86_FEATURE_MCE		(1 << 7)
> +#define X86_FEATURE_PCID	(1 << 17)
> +
> +typedef bool (*supported_fn)(void);
> +
> +static bool monitor_supported(void)
> +{
> +	return cpuid(1).c & X86_FEATURE_MONITOR;
> +}
> +
>  struct insn_table {
>  	const char *name;
>  	u32 flag;
> @@ -853,6 +864,8 @@ struct insn_table {
>  	// Use FIELD_EXIT_QUAL and FIELD_INSN_INFO to define
>  	// which field need to be tested, reason is always tested
>  	u32 test_field;
> +	const supported_fn supported_fn;
> +	u8 disabled;
>  };
>  
>  /*
> @@ -868,7 +881,7 @@ static struct insn_table insn_table[] = {
>  	{"HLT",  CPU_HLT, insn_hlt, INSN_CPU0, 12, 0, 0, 0},
>  	{"INVLPG", CPU_INVLPG, insn_invlpg, INSN_CPU0, 14,
>  		0x12345678, 0, FIELD_EXIT_QUAL},
> -	{"MWAIT", CPU_MWAIT, insn_mwait, INSN_CPU0, 36, 0, 0, 0},
> +	{"MWAIT", CPU_MWAIT, insn_mwait, INSN_CPU0, 36, 0, 0, 0, &monitor_supported},
>  	{"RDPMC", CPU_RDPMC, insn_rdpmc, INSN_CPU0, 15, 0, 0, 0},
>  	{"RDTSC", CPU_RDTSC, insn_rdtsc, INSN_CPU0, 16, 0, 0, 0},
>  	{"CR3 load", CPU_CR3_LOAD, insn_cr3_load, INSN_CPU0, 28, 0x3, 0,
> @@ -881,7 +894,7 @@ static struct insn_table insn_table[] = {
>  	{"CR8 store", CPU_CR8_STORE, insn_cr8_store, INSN_CPU0, 28, 0x18, 0,
>  		FIELD_EXIT_QUAL},
>  #endif
> -	{"MONITOR", CPU_MONITOR, insn_monitor, INSN_CPU0, 39, 0, 0, 0},
> +	{"MONITOR", CPU_MONITOR, insn_monitor, INSN_CPU0, 39, 0, 0, 0, &monitor_supported},
>  	{"PAUSE", CPU_PAUSE, insn_pause, INSN_CPU0, 40, 0, 0, 0},
>  	// Flags for Secondary Processor-Based VM-Execution Controls
>  	{"WBINVD", CPU_WBINVD, insn_wbinvd, INSN_CPU1, 54, 0, 0, 0},
> @@ -904,13 +917,19 @@ static struct insn_table insn_table[] = {
>  
>  static int insn_intercept_init(struct vmcs *vmcs)
>  {
> -	u32 ctrl_cpu;
> +	u32 ctrl_cpu, cur_insn;
>  
>  	ctrl_cpu = ctrl_cpu_rev[0].set | CPU_SECONDARY;
>  	ctrl_cpu &= ctrl_cpu_rev[0].clr;
>  	vmcs_write(CPU_EXEC_CTRL0, ctrl_cpu);
>  	vmcs_write(CPU_EXEC_CTRL1, ctrl_cpu_rev[1].set);
>  	cr3 = read_cr3();
> +
> +	for (cur_insn = 0; insn_table[cur_insn].name != NULL; cur_insn++) {
> +		if (insn_table[cur_insn].supported_fn == NULL)
> +			continue;
> +		insn_table[cur_insn].disabled = !insn_table[cur_insn].supported_fn();
> +	}
>  	return VMX_TEST_START;
>  }
>  
> @@ -928,6 +947,12 @@ static void insn_intercept_main(void)
>  			continue;
>  		}
>  
> +		if (insn_table[cur_insn].disabled) {
> +			printf("\tFeature required for %s is not supported.\n",
> +			       insn_table[cur_insn].name);
> +			continue;
> +		}
> +
>  		if ((insn_table[cur_insn].type == INSN_CPU0 &&
>  		     !(ctrl_cpu_rev[0].set & insn_table[cur_insn].flag)) ||
>  		    (insn_table[cur_insn].type == INSN_CPU1 &&
> @@ -6841,9 +6866,6 @@ static void vmentry_movss_shadow_test(void)
>  	vmcs_write(GUEST_RFLAGS, X86_EFLAGS_FIXED);
>  }
>  
> -#define X86_FEATURE_PCID       (1 << 17)
> -#define X86_FEATURE_MCE        (1 << 7)
> -
>  static int write_cr4_checking(unsigned long val)
>  {
>  	asm volatile(ASM_TRY("1f")
> 

Queued, thanks.

Paolo



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux