Re: [PATCH] kvm-unit-tests: VMX: Test suite for preemption timer

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

 



Il 04/09/2013 17:26, Arthur Chunqi Li ha scritto:
> Test cases for preemption timer in nested VMX. Two aspects are tested:
> 1. Save preemption timer on VMEXIT if relevant bit set in EXIT_CONTROL
> 2. Test a relevant bug of KVM. The bug will not save preemption timer
> value if exit L2->L0 for some reason and enter L0->L2. Thus preemption
> timer will never trigger if the value is large enough.
> 
> Signed-off-by: Arthur Chunqi Li <yzt356@xxxxxxxxx>
> ---
>  x86/vmx.h       |    3 ++
>  x86/vmx_tests.c |  117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 120 insertions(+)

Please rebase your other four patches on top of this one, since this one
is good to go!

Reviewed-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>

Paolo

> +void preemption_timer_init()
> +{
> +	u32 ctrl_pin;
> +
> +	ctrl_pin = vmcs_read(PIN_CONTROLS) | PIN_PREEMPT;
> +	ctrl_pin &= ctrl_pin_rev.clr;
> +	vmcs_write(PIN_CONTROLS, ctrl_pin);
> +	preempt_val = 10000000;
> +	vmcs_write(PREEMPT_TIMER_VALUE, preempt_val);
> +	preempt_scale = rdmsr(MSR_IA32_VMX_MISC) & 0x1F;
> +}
> +
> +void preemption_timer_main()
> +{
> +	tsc_val = rdtsc();
> +	if (!(ctrl_pin_rev.clr & PIN_PREEMPT)) {
> +		printf("\tPreemption timer is not supported\n");
> +		return;
> +	}
> +	if (!(ctrl_exit_rev.clr & EXI_SAVE_PREEMPT))
> +		printf("\tSave preemption value is not supported\n");
> +	else {
> +		set_stage(0);
> +		vmcall();
> +		if (get_stage() == 1)
> +			vmcall();
> +	}
> +	while (1) {
> +		if (((rdtsc() - tsc_val) >> preempt_scale)
> +				> 10 * preempt_val) {
> +			report("Preemption timer", 0);
> +			break;
> +		}
> +	}
> +}
> +
> +int preemption_timer_exit_handler()
> +{
> +	u64 guest_rip;
> +	ulong reason;
> +	u32 insn_len;
> +	u32 ctrl_exit;
> +
> +	guest_rip = vmcs_read(GUEST_RIP);
> +	reason = vmcs_read(EXI_REASON) & 0xff;
> +	insn_len = vmcs_read(EXI_INST_LEN);
> +	switch (reason) {
> +	case VMX_PREEMPT:
> +		if (((rdtsc() - tsc_val) >> preempt_scale) < preempt_val)
> +			report("Preemption timer", 0);
> +		else
> +			report("Preemption timer", 1);
> +		return VMX_TEST_VMEXIT;
> +	case VMX_VMCALL:
> +		switch (get_stage()) {
> +		case 0:
> +			if (vmcs_read(PREEMPT_TIMER_VALUE) != preempt_val)
> +				report("Save preemption value", 0);
> +			else {
> +				set_stage(get_stage() + 1);
> +				ctrl_exit = (vmcs_read(EXI_CONTROLS) |
> +					EXI_SAVE_PREEMPT) & ctrl_exit_rev.clr;
> +				vmcs_write(EXI_CONTROLS, ctrl_exit);
> +			}
> +			break;
> +		case 1:
> +			if (vmcs_read(PREEMPT_TIMER_VALUE) >= preempt_val)
> +				report("Save preemption value", 0);
> +			else
> +				report("Save preemption value", 1);
> +			break;
> +		default:
> +			printf("Invalid stage.\n");
> +			print_vmexit_info();
> +			return VMX_TEST_VMEXIT;
> +		}
> +		vmcs_write(GUEST_RIP, guest_rip + insn_len);
> +		return VMX_TEST_RESUME;
> +	default:
> +		printf("Unknown exit reason, %d\n", reason);
> +		print_vmexit_info();
> +	}
> +	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 +198,7 @@ struct vmx_test vmx_tests[] = {
>  		basic_syscall_handler, {0} },
>  	{ "vmenter", basic_init, vmenter_main, vmenter_exit_handler,
>  		basic_syscall_handler, {0} },
> +	{ "preemption timer", preemption_timer_init, preemption_timer_main,
> +		preemption_timer_exit_handler, basic_syscall_handler, {0} },
>  	{ NULL, NULL, NULL, NULL, NULL, {0} },
>  };
> 

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[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