Re: [kvm-unit-tests PATCH 1/2] x86: Skip some VMX control field tests

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

 



Yes, that works for me. An alternative I've toyed with is modifying
nested_get_vmcs12_pages to generate a VM-exit for "illegal guest
state" rather than a VM-instruction failure for "VM entry with invalid
control field(s)" when kvm_vcpu_gpa_to_page(vcpu,
vmcs12->virtual_apic_page_addr) returns an error page. Still wrong,
but the kvm-unit-test isn't yet smart enough to notice the error.

On Fri, Sep 15, 2017 at 9:40 AM, Paolo Bonzini <pbonzini@xxxxxxxxxx> wrote:
> On 15/09/2017 01:31, Jim Mattson wrote:
>> When the APIC virtualization address references unbacked memory, kvm
>> incorrectly fails a VM-entry with "invalid control field(s)." Until
>> this can be fixed, just skip the VMX control field tests that populate
>> a VMCS field with a physical address that isn't backed.
>>
>> Tested: <multi line explanation of how the code was tested>
>>
>> Effort: <Your effort group>
>> Google-Bug-Id: <buganizer-id>
>> Change-Id: I624091cb5cd7cfaae887de8f017e18b5f95d8f61
>> Signed-off-by: Jim Mattson <jmattson@xxxxxxxxxx>
>> ---
>>  x86/vmx_tests.c | 6 ++++++
>>  1 file changed, 6 insertions(+)
>>
>> diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
>> index 088d32aaee0b..e82bc04d72e2 100644
>> --- a/x86/vmx_tests.c
>> +++ b/x86/vmx_tests.c
>> @@ -3359,6 +3359,12 @@ static void test_vmcs_page_addr(const char *name,
>>                               bool ignored,
>>                               u64 addr)
>>  {
>> +     /*
>> +      * Skip tests that reference unbacked memory for now, because
>> +      * kvm doesn't always handle this situation correctly.
>
> Since in practice it's only 16 tests that fail, it would be nice to only
> XFAIL those.  The following is a bit intrusive, but it works.  What do
> you think?
>
> diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
> index 729e85f..13b45dd 100644
> --- a/x86/vmx_tests.c
> +++ b/x86/vmx_tests.c
> @@ -3177,14 +3177,14 @@ success:
>  /*
>   * Try to launch the current VMCS.
>   */
> -static void test_vmx_controls(bool controls_valid)
> +static void test_vmx_controls(bool controls_valid, bool xfail)
>  {
>         bool success = vmlaunch_succeeds();
>         u32 vmx_inst_err;
>
> -       report("vmlaunch %s", success == controls_valid,
> -              controls_valid ? "succeeds" : "fails");
> -       if (!controls_valid) {
> +       report_xfail("vmlaunch %s", xfail, success == controls_valid,
> +                    controls_valid ? "succeeds" : "fails");
> +       if (!success) {
>                 vmx_inst_err = vmcs_read(VMX_INST_ERROR);
>                 report("VMX inst error is %d (actual %d)",
>                        vmx_inst_err == VMXERR_ENTRY_INVALID_CONTROL_FIELD,
> @@ -3226,7 +3226,7 @@ static void test_rsvd_ctl_bit_value(const char *name, union vmx_ctrl_msr msr,
>                 vmcs_write(encoding, msr.set & ~mask);
>                 expected = !(msr.set & mask);
>         }
> -       test_vmx_controls(expected);
> +       test_vmx_controls(expected, false);
>         vmcs_write(encoding, controls);
>         report_prefix_pop();
>  }
> @@ -3322,7 +3322,7 @@ static void try_cr3_target_count(unsigned i, unsigned max)
>  {
>         report_prefix_pushf("CR3 target count 0x%x", i);
>         vmcs_write(CR3_TARGET_COUNT, i);
> -       test_vmx_controls(i <= max);
> +       test_vmx_controls(i <= max, false);
>         report_prefix_pop();
>  }
>
> @@ -3357,13 +3357,21 @@ static void test_cr3_targets(void)
>  static void test_vmcs_page_addr(const char *name,
>                                 enum Encoding encoding,
>                                 bool ignored,
> +                               bool xfail_beyond_mapped_ram,
>                                 u64 addr)
>  {
> +       bool xfail =
> +               (xfail_beyond_mapped_ram &&
> +                addr > fwcfg_get_u64(FW_CFG_RAM_SIZE) - PAGE_SIZE &&
> +                addr < (1ul << cpuid_maxphyaddr()));
> +
>         report_prefix_pushf("%s = %lx", name, addr);
>         vmcs_write(encoding, addr);
>         test_vmx_controls(ignored || (IS_ALIGNED(addr, PAGE_SIZE) &&
> -                                 addr < (1ul << cpuid_maxphyaddr())));
> +                                 addr < (1ul << cpuid_maxphyaddr())),
> +                         xfail);
>         report_prefix_pop();
> +       xfail = false;
>  }
>
>  /*
> @@ -3371,19 +3379,26 @@ static void test_vmcs_page_addr(const char *name,
>   */
>  static void test_vmcs_page_values(const char *name,
>                                   enum Encoding encoding,
> -                                 bool ignored)
> +                                 bool ignored,
> +                                 bool xfail_beyond_mapped_ram)
>  {
>         unsigned i;
>         u64 orig_val = vmcs_read(encoding);
>
>         for (i = 0; i < 64; i++)
> -               test_vmcs_page_addr(name, encoding, ignored, 1ul << i);
> +               test_vmcs_page_addr(name, encoding, ignored,
> +                                   xfail_beyond_mapped_ram, 1ul << i);
>
> -       test_vmcs_page_addr(name, encoding, ignored, PAGE_SIZE - 1);
> -       test_vmcs_page_addr(name, encoding, ignored, PAGE_SIZE);
> +       test_vmcs_page_addr(name, encoding, ignored,
> +                           xfail_beyond_mapped_ram, PAGE_SIZE - 1);
> +       test_vmcs_page_addr(name, encoding, ignored,
> +                           xfail_beyond_mapped_ram, PAGE_SIZE);
>         test_vmcs_page_addr(name, encoding, ignored,
> +                           xfail_beyond_mapped_ram,
>                             (1ul << cpuid_maxphyaddr()) - PAGE_SIZE);
> -       test_vmcs_page_addr(name, encoding, ignored, -1ul);
> +       test_vmcs_page_addr(name, encoding, ignored,
> +                           xfail_beyond_mapped_ram,
> +                           -1ul);
>
>         vmcs_write(encoding, orig_val);
>  }
> @@ -3394,7 +3409,8 @@ static void test_vmcs_page_values(const char *name,
>   */
>  static void test_vmcs_page_reference(u32 control_bit, enum Encoding field,
>                                      const char *field_name,
> -                                    const char *control_name)
> +                                    const char *control_name,
> +                                    bool xfail_beyond_mapped_ram)
>  {
>         u32 primary = vmcs_read(CPU_EXEC_CTRL0);
>         u64 page_addr;
> @@ -3406,12 +3422,12 @@ static void test_vmcs_page_reference(u32 control_bit, enum Encoding field,
>
>         report_prefix_pushf("%s enabled", control_name);
>         vmcs_write(CPU_EXEC_CTRL0, primary | control_bit);
> -       test_vmcs_page_values(field_name, field, false);
> +       test_vmcs_page_values(field_name, field, false, xfail_beyond_mapped_ram);
>         report_prefix_pop();
>
>         report_prefix_pushf("%s disabled", control_name);
>         vmcs_write(CPU_EXEC_CTRL0, primary & ~control_bit);
> -       test_vmcs_page_values(field_name, field, true);
> +       test_vmcs_page_values(field_name, field, true, false);
>         report_prefix_pop();
>
>         vmcs_write(field, page_addr);
> @@ -3427,9 +3443,9 @@ static void test_vmcs_page_reference(u32 control_bit, enum Encoding field,
>  static void test_io_bitmaps(void)
>  {
>         test_vmcs_page_reference(CPU_IO_BITMAP, IO_BITMAP_A,
> -                                "I/O bitmap A", "Use I/O bitmaps");
> +                                "I/O bitmap A", "Use I/O bitmaps", false);
>         test_vmcs_page_reference(CPU_IO_BITMAP, IO_BITMAP_B,
> -                                "I/O bitmap B", "Use I/O bitmaps");
> +                                "I/O bitmap B", "Use I/O bitmaps", false);
>  }
>
>  /*
> @@ -3441,7 +3457,7 @@ static void test_io_bitmaps(void)
>  static void test_msr_bitmap(void)
>  {
>         test_vmcs_page_reference(CPU_MSR_BITMAP, MSR_BITMAP,
> -                                "MSR bitmap", "Use MSR bitmaps");
> +                                "MSR bitmap", "Use MSR bitmaps", false);
>  }
>
>  /*
> @@ -3455,7 +3471,7 @@ static void test_msr_bitmap(void)
>  static void test_apic_virt_addr(void)
>  {
>         test_vmcs_page_reference(CPU_TPR_SHADOW, APIC_VIRT_ADDR,
> -                                "virtual-APIC address", "Use TPR shadow");
> +                                "virtual-APIC address", "Use TPR shadow", true);
>  }
>
>  static void try_tpr_threshold(unsigned val)
> @@ -3468,7 +3484,7 @@ static void try_tpr_threshold(unsigned val)
>                 valid = !(val >> 4);
>         report_prefix_pushf("TPR threshold 0x%x", val);
>         vmcs_write(TPR_THRESHOLD, val);
> -       test_vmx_controls(valid);
> +       test_vmx_controls(valid, false);
>         report_prefix_pop();
>  }
>
>
> 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