diff mbox series

[kvm-unit-tests] svm: run tests with host IF=1

Message ID 1573660209-26331-1-git-send-email-pbonzini@redhat.com (mailing list archive)
State New, archived
Headers show
Series [kvm-unit-tests] svm: run tests with host IF=1 | expand

Commit Message

Paolo Bonzini Nov. 13, 2019, 3:50 p.m. UTC
Tests should in general call VMRUN with EFLAGS.IF=1 (if there are
exceptions in the future we can add a cmp/jz in test_run).  This is
because currently interrupts are masked during all of VMRUN, while
we usually want interrupts during a test to cause a vmexit.
This is similar to how PIN_EXTINT and PIN_NMI are included by
default in the VMCS used by vmx.flat.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 x86/svm.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

Comments

Cathy Avery Nov. 13, 2019, 3:55 p.m. UTC | #1
On 11/13/19 10:50 AM, Paolo Bonzini wrote:
> Tests should in general call VMRUN with EFLAGS.IF=1 (if there are
> exceptions in the future we can add a cmp/jz in test_run).  This is
> because currently interrupts are masked during all of VMRUN, while
> we usually want interrupts during a test to cause a vmexit.
> This is similar to how PIN_EXTINT and PIN_NMI are included by
> default in the VMCS used by vmx.flat.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   x86/svm.c | 5 ++++-
>   1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/x86/svm.c b/x86/svm.c
> index 4ddfaa4..097a296 100644
> --- a/x86/svm.c
> +++ b/x86/svm.c
> @@ -254,6 +254,7 @@ static void test_run(struct test *test, struct vmcb *vmcb)
>       u64 vmcb_phys = virt_to_phys(vmcb);
>       u64 guest_stack[10000];
>   
> +    irq_disable();
>       test->vmcb = vmcb;
>       test->prepare(test);
>       vmcb->save.rip = (ulong)test_thunk;
> @@ -269,7 +270,9 @@ static void test_run(struct test *test, struct vmcb *vmcb)
>               "mov regs, %%r15\n\t"       // rax
>               "mov %%r15, 0x1f8(%0)\n\t"
>               LOAD_GPR_C
> +            "sti \n\t"		// only used if V_INTR_MASKING=1

I thought sti was going to be conditional

// entered with IF=0
     clgi
     cmp    $0, test_host_if
     jz    1f
     sti

>               "vmrun \n\t"
> +            "cli \n\t"
>               SAVE_GPR_C
>               "mov 0x170(%0), %%r15\n\t"  // rflags
>               "mov %%r15, regs+0x80\n\t"
> @@ -284,6 +287,7 @@ static void test_run(struct test *test, struct vmcb *vmcb)
>   	tsc_end = rdtsc();
>           ++test->exits;
>       } while (!test->finished(test));
> +    irq_enable();
>   
>       report("%s", test->succeeded(test), test->name);
>   }
> @@ -301,7 +305,6 @@ static bool default_supported(void)
>   static void default_prepare(struct test *test)
>   {
>       vmcb_ident(test->vmcb);
> -    cli();
>   }
>   
>   static bool default_finished(struct test *test)
Cathy Avery Nov. 13, 2019, 3:57 p.m. UTC | #2
On 11/13/19 10:55 AM, Cathy Avery wrote:
> On 11/13/19 10:50 AM, Paolo Bonzini wrote:
>> Tests should in general call VMRUN with EFLAGS.IF=1 (if there are
>> exceptions in the future we can add a cmp/jz in test_run).  This is
>> because currently interrupts are masked during all of VMRUN, while
>> we usually want interrupts during a test to cause a vmexit.
>> This is similar to how PIN_EXTINT and PIN_NMI are included by
>> default in the VMCS used by vmx.flat.
>>
>> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
>> ---
>>   x86/svm.c | 5 ++++-
>>   1 file changed, 4 insertions(+), 1 deletion(-)
>>
>> diff --git a/x86/svm.c b/x86/svm.c
>> index 4ddfaa4..097a296 100644
>> --- a/x86/svm.c
>> +++ b/x86/svm.c
>> @@ -254,6 +254,7 @@ static void test_run(struct test *test, struct 
>> vmcb *vmcb)
>>       u64 vmcb_phys = virt_to_phys(vmcb);
>>       u64 guest_stack[10000];
>>   +    irq_disable();
>>       test->vmcb = vmcb;
>>       test->prepare(test);
>>       vmcb->save.rip = (ulong)test_thunk;
>> @@ -269,7 +270,9 @@ static void test_run(struct test *test, struct 
>> vmcb *vmcb)
>>               "mov regs, %%r15\n\t"       // rax
>>               "mov %%r15, 0x1f8(%0)\n\t"
>>               LOAD_GPR_C
>> +            "sti \n\t"        // only used if V_INTR_MASKING=1
>
> I thought sti was going to be conditional
>
> // entered with IF=0
>     clgi
>     cmp    $0, test_host_if
>     jz    1f
>     sti
OK missed the comment above.
>
>>               "vmrun \n\t"
>> +            "cli \n\t"
>>               SAVE_GPR_C
>>               "mov 0x170(%0), %%r15\n\t"  // rflags
>>               "mov %%r15, regs+0x80\n\t"
>> @@ -284,6 +287,7 @@ static void test_run(struct test *test, struct 
>> vmcb *vmcb)
>>       tsc_end = rdtsc();
>>           ++test->exits;
>>       } while (!test->finished(test));
>> +    irq_enable();
>>         report("%s", test->succeeded(test), test->name);
>>   }
>> @@ -301,7 +305,6 @@ static bool default_supported(void)
>>   static void default_prepare(struct test *test)
>>   {
>>       vmcb_ident(test->vmcb);
>> -    cli();
>>   }
>>     static bool default_finished(struct test *test)
>
>
Cathy Avery Nov. 13, 2019, 4:12 p.m. UTC | #3
On 11/13/19 10:50 AM, Paolo Bonzini wrote:
> Tests should in general call VMRUN with EFLAGS.IF=1 (if there are
> exceptions in the future we can add a cmp/jz in test_run).  This is
> because currently interrupts are masked during all of VMRUN, while
> we usually want interrupts during a test to cause a vmexit.
> This is similar to how PIN_EXTINT and PIN_NMI are included by
> default in the VMCS used by vmx.flat.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   x86/svm.c | 5 ++++-
>   1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/x86/svm.c b/x86/svm.c
> index 4ddfaa4..097a296 100644
> --- a/x86/svm.c
> +++ b/x86/svm.c
> @@ -254,6 +254,7 @@ static void test_run(struct test *test, struct vmcb *vmcb)
>       u64 vmcb_phys = virt_to_phys(vmcb);
>       u64 guest_stack[10000];
>   
> +    irq_disable();
>       test->vmcb = vmcb;
>       test->prepare(test);
>       vmcb->save.rip = (ulong)test_thunk;
> @@ -269,7 +270,9 @@ static void test_run(struct test *test, struct vmcb *vmcb)
>               "mov regs, %%r15\n\t"       // rax
>               "mov %%r15, 0x1f8(%0)\n\t"
>               LOAD_GPR_C
> +            "sti \n\t"		// only used if V_INTR_MASKING=1
>               "vmrun \n\t"
> +            "cli \n\t"
>               SAVE_GPR_C
>               "mov 0x170(%0), %%r15\n\t"  // rflags
>               "mov %%r15, regs+0x80\n\t"
> @@ -284,6 +287,7 @@ static void test_run(struct test *test, struct vmcb *vmcb)
>   	tsc_end = rdtsc();
>           ++test->exits;
>       } while (!test->finished(test));
> +    irq_enable();
>   
>       report("%s", test->succeeded(test), test->name);
>   }
> @@ -301,7 +305,6 @@ static bool default_supported(void)
>   static void default_prepare(struct test *test)
>   {
>       vmcb_ident(test->vmcb);
> -    cli();
>   }
>   
>   static bool default_finished(struct test *test)

Reviewed-by: Cathy Avery <cavery@redhat.com>
diff mbox series

Patch

diff --git a/x86/svm.c b/x86/svm.c
index 4ddfaa4..097a296 100644
--- a/x86/svm.c
+++ b/x86/svm.c
@@ -254,6 +254,7 @@  static void test_run(struct test *test, struct vmcb *vmcb)
     u64 vmcb_phys = virt_to_phys(vmcb);
     u64 guest_stack[10000];
 
+    irq_disable();
     test->vmcb = vmcb;
     test->prepare(test);
     vmcb->save.rip = (ulong)test_thunk;
@@ -269,7 +270,9 @@  static void test_run(struct test *test, struct vmcb *vmcb)
             "mov regs, %%r15\n\t"       // rax
             "mov %%r15, 0x1f8(%0)\n\t"
             LOAD_GPR_C
+            "sti \n\t"		// only used if V_INTR_MASKING=1
             "vmrun \n\t"
+            "cli \n\t"
             SAVE_GPR_C
             "mov 0x170(%0), %%r15\n\t"  // rflags
             "mov %%r15, regs+0x80\n\t"
@@ -284,6 +287,7 @@  static void test_run(struct test *test, struct vmcb *vmcb)
 	tsc_end = rdtsc();
         ++test->exits;
     } while (!test->finished(test));
+    irq_enable();
 
     report("%s", test->succeeded(test), test->name);
 }
@@ -301,7 +305,6 @@  static bool default_supported(void)
 static void default_prepare(struct test *test)
 {
     vmcb_ident(test->vmcb);
-    cli();
 }
 
 static bool default_finished(struct test *test)