Re: [PATCH kvm-unit-tests v2 1/2] svm: Add test cases around NMI injection

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

 



On 09/04/20 17:28, Cathy Avery wrote:
> This test checks for NMI delivery to L2 and
> intercepted NMI (VMEXIT_NMI) delivery to L1.
> 
> Signed-off-by: Cathy Avery <cavery@xxxxxxxxxx>
> ---
> v2: Remove redundant NMI_VECTOR
> ---
>  x86/svm_tests.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 82 insertions(+)
> 
> diff --git a/x86/svm_tests.c b/x86/svm_tests.c
> index 16b9dfd..b6c0106 100644
> --- a/x86/svm_tests.c
> +++ b/x86/svm_tests.c
> @@ -1340,6 +1340,85 @@ static bool interrupt_check(struct svm_test *test)
>      return get_test_stage(test) == 5;
>  }
>  
> +static volatile bool nmi_fired;
> +
> +static void nmi_handler(isr_regs_t *regs)
> +{
> +    nmi_fired = true;
> +    apic_write(APIC_EOI, 0);
> +}
> +
> +static void nmi_prepare(struct svm_test *test)
> +{
> +    default_prepare(test);
> +    nmi_fired = false;
> +    handle_irq(NMI_VECTOR, nmi_handler);
> +    set_test_stage(test, 0);
> +}
> +
> +static void nmi_test(struct svm_test *test)
> +{
> +    apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, 0);
> +
> +    report(nmi_fired, "direct NMI while running guest");
> +
> +    if (!nmi_fired)
> +        set_test_stage(test, -1);
> +
> +    vmmcall();
> +
> +    nmi_fired = false;
> +
> +    apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, 0);
> +
> +    if (!nmi_fired) {
> +        report(nmi_fired, "intercepted pending NMI not dispatched");
> +        set_test_stage(test, -1);
> +    }
> +
> +}
> +
> +static bool nmi_finished(struct svm_test *test)
> +{
> +    switch (get_test_stage(test)) {
> +    case 0:
> +        if (vmcb->control.exit_code != SVM_EXIT_VMMCALL) {
> +            report(false, "VMEXIT not due to vmmcall. Exit reason 0x%x",
> +                   vmcb->control.exit_code);
> +            return true;
> +        }
> +        vmcb->save.rip += 3;
> +
> +        vmcb->control.intercept |= (1ULL << INTERCEPT_NMI);
> +        break;
> +
> +    case 1:
> +        if (vmcb->control.exit_code != SVM_EXIT_NMI) {
> +            report(false, "VMEXIT not due to NMI intercept. Exit reason 0x%x",
> +                   vmcb->control.exit_code);
> +            return true;
> +        }
> +
> +        report(true, "NMI intercept while running guest");
> +        break;
> +
> +    case 2:
> +        break;
> +
> +    default:
> +        return true;
> +    }
> +
> +    inc_test_stage(test);
> +
> +    return get_test_stage(test) == 3;
> +}
> +
> +static bool nmi_check(struct svm_test *test)
> +{
> +    return get_test_stage(test) == 3;
> +}
> +
>  #define TEST(name) { #name, .v2 = name }
>  
>  /*
> @@ -1446,6 +1525,9 @@ struct svm_test svm_tests[] = {
>      { "interrupt", default_supported, interrupt_prepare,
>        default_prepare_gif_clear, interrupt_test,
>        interrupt_finished, interrupt_check },
> +    { "nmi", default_supported, nmi_prepare,
> +      default_prepare_gif_clear, nmi_test,
> +      nmi_finished, nmi_check },
>      TEST(svm_guest_state_test),
>      { NULL, NULL, NULL, NULL, NULL, NULL, NULL }
>  };
> 

Queued (both), 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