kvm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH][kvm-unit-tests] VMX preemption timer: Make test case more robust
@ 2013-10-23 14:21 Jan Kiszka
  2013-10-28 13:10 ` Paolo Bonzini
  0 siblings, 1 reply; 2+ messages in thread
From: Jan Kiszka @ 2013-10-23 14:21 UTC (permalink / raw)
  To: Gleb Natapov, Paolo Bonzini
  Cc: kvm, "李春奇 <Arthur Chunqi Li>"

If we both print from L2 and, on timer expiry, from L1, we risk a
deadlock in L1 on the printf lock that is held by L2 then. Avoid this
by only printing from L1.

Furthermore, if the timer fails to fire in time, disable it before
continuing to avoid that it fire later on in different contexts.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 x86/vmx_tests.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 8d47bcd..7893a6c 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -128,6 +128,9 @@ void preemption_timer_init()
 	preempt_val = 10000000;
 	vmcs_write(PREEMPT_TIMER_VALUE, preempt_val);
 	preempt_scale = rdmsr(MSR_IA32_VMX_MISC) & 0x1F;
+
+	if (!(ctrl_exit_rev.clr & EXI_SAVE_PREEMPT))
+		printf("\tSave preemption value is not supported\n");
 }
 
 void preemption_timer_main()
@@ -137,9 +140,7 @@ void preemption_timer_main()
 		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 {
+	if (ctrl_exit_rev.clr & EXI_SAVE_PREEMPT) {
 		set_stage(0);
 		vmcall();
 		if (get_stage() == 1)
@@ -148,8 +149,8 @@ void preemption_timer_main()
 	while (1) {
 		if (((rdtsc() - tsc_val) >> preempt_scale)
 				> 10 * preempt_val) {
-			report("Preemption timer", 0);
-			break;
+			set_stage(2);
+			vmcall();
 		}
 	}
 }
@@ -170,7 +171,7 @@ int preemption_timer_exit_handler()
 			report("Preemption timer", 0);
 		else
 			report("Preemption timer", 1);
-		return VMX_TEST_VMEXIT;
+		break;
 	case VMX_VMCALL:
 		switch (get_stage()) {
 		case 0:
@@ -182,24 +183,29 @@ int preemption_timer_exit_handler()
 					EXI_SAVE_PREEMPT) & ctrl_exit_rev.clr;
 				vmcs_write(EXI_CONTROLS, ctrl_exit);
 			}
-			break;
+			vmcs_write(GUEST_RIP, guest_rip + insn_len);
+			return VMX_TEST_RESUME;
 		case 1:
 			if (vmcs_read(PREEMPT_TIMER_VALUE) >= preempt_val)
 				report("Save preemption value", 0);
 			else
 				report("Save preemption value", 1);
+			vmcs_write(GUEST_RIP, guest_rip + insn_len);
+			return VMX_TEST_RESUME;
+		case 2:
+			report("Preemption timer", 0);
 			break;
 		default:
 			printf("Invalid stage.\n");
 			print_vmexit_info();
-			return VMX_TEST_VMEXIT;
+			break;
 		}
-		vmcs_write(GUEST_RIP, guest_rip + insn_len);
-		return VMX_TEST_RESUME;
+		break;
 	default:
 		printf("Unknown exit reason, %d\n", reason);
 		print_vmexit_info();
 	}
+	vmcs_write(PIN_CONTROLS, vmcs_read(PIN_CONTROLS) & ~PIN_PREEMPT);
 	return VMX_TEST_VMEXIT;
 }
 
-- 
1.8.1.1.298.ge7eed54

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH][kvm-unit-tests] VMX preemption timer: Make test case more robust
  2013-10-23 14:21 [PATCH][kvm-unit-tests] VMX preemption timer: Make test case more robust Jan Kiszka
@ 2013-10-28 13:10 ` Paolo Bonzini
  0 siblings, 0 replies; 2+ messages in thread
From: Paolo Bonzini @ 2013-10-28 13:10 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Gleb Natapov, kvm,
	"李春奇 <Arthur Chunqi Li>"

Il 23/10/2013 16:21, Jan Kiszka ha scritto:
> If we both print from L2 and, on timer expiry, from L1, we risk a
> deadlock in L1 on the printf lock that is held by L2 then. Avoid this
> by only printing from L1.
> 
> Furthermore, if the timer fails to fire in time, disable it before
> continuing to avoid that it fire later on in different contexts.
> 
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
>  x86/vmx_tests.c | 26 ++++++++++++++++----------
>  1 file changed, 16 insertions(+), 10 deletions(-)
> 
> diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
> index 8d47bcd..7893a6c 100644
> --- a/x86/vmx_tests.c
> +++ b/x86/vmx_tests.c
> @@ -128,6 +128,9 @@ void preemption_timer_init()
>  	preempt_val = 10000000;
>  	vmcs_write(PREEMPT_TIMER_VALUE, preempt_val);
>  	preempt_scale = rdmsr(MSR_IA32_VMX_MISC) & 0x1F;
> +
> +	if (!(ctrl_exit_rev.clr & EXI_SAVE_PREEMPT))
> +		printf("\tSave preemption value is not supported\n");
>  }
>  
>  void preemption_timer_main()
> @@ -137,9 +140,7 @@ void preemption_timer_main()
>  		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 {
> +	if (ctrl_exit_rev.clr & EXI_SAVE_PREEMPT) {
>  		set_stage(0);
>  		vmcall();
>  		if (get_stage() == 1)
> @@ -148,8 +149,8 @@ void preemption_timer_main()
>  	while (1) {
>  		if (((rdtsc() - tsc_val) >> preempt_scale)
>  				> 10 * preempt_val) {
> -			report("Preemption timer", 0);
> -			break;
> +			set_stage(2);
> +			vmcall();
>  		}
>  	}
>  }
> @@ -170,7 +171,7 @@ int preemption_timer_exit_handler()
>  			report("Preemption timer", 0);
>  		else
>  			report("Preemption timer", 1);
> -		return VMX_TEST_VMEXIT;
> +		break;
>  	case VMX_VMCALL:
>  		switch (get_stage()) {
>  		case 0:
> @@ -182,24 +183,29 @@ int preemption_timer_exit_handler()
>  					EXI_SAVE_PREEMPT) & ctrl_exit_rev.clr;
>  				vmcs_write(EXI_CONTROLS, ctrl_exit);
>  			}
> -			break;
> +			vmcs_write(GUEST_RIP, guest_rip + insn_len);
> +			return VMX_TEST_RESUME;
>  		case 1:
>  			if (vmcs_read(PREEMPT_TIMER_VALUE) >= preempt_val)
>  				report("Save preemption value", 0);
>  			else
>  				report("Save preemption value", 1);
> +			vmcs_write(GUEST_RIP, guest_rip + insn_len);
> +			return VMX_TEST_RESUME;
> +		case 2:
> +			report("Preemption timer", 0);
>  			break;
>  		default:
>  			printf("Invalid stage.\n");
>  			print_vmexit_info();
> -			return VMX_TEST_VMEXIT;
> +			break;
>  		}
> -		vmcs_write(GUEST_RIP, guest_rip + insn_len);
> -		return VMX_TEST_RESUME;
> +		break;
>  	default:
>  		printf("Unknown exit reason, %d\n", reason);
>  		print_vmexit_info();
>  	}
> +	vmcs_write(PIN_CONTROLS, vmcs_read(PIN_CONTROLS) & ~PIN_PREEMPT);
>  	return VMX_TEST_VMEXIT;
>  }
>  
> 

Applied to kvm-unit-tests.git vmx.

Paolo

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2013-10-28 13:10 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-23 14:21 [PATCH][kvm-unit-tests] VMX preemption timer: Make test case more robust Jan Kiszka
2013-10-28 13:10 ` Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).