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 <[email protected]>
> ---
>  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
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to