On Fri, 13 Mar 2020 16:50:08 +0200
Liran Alon <liran.a...@oracle.com> wrote:

> Microsoft introduced this ACPI table to avoid Windows guests performing
> various workarounds for device erratas. As the virtual device emulated
> by VMM may not have the errata.
> 
> Currently, WAET allows hypervisor to inform guest about two
> specific behaviors: One for RTC and the other for ACPI PM timer.
> 
> Support for WAET have been introduced since Windows Vista. This ACPI
> table is also exposed by other common hypervisors by default, including:
> VMware, GCP and AWS.
> 
> This patch adds WAET ACPI Table to QEMU.
> 
> We set "ACPI PM timer good" bit in "Emualted Device Flags" field to
> indicate that the ACPI PM timer has been enhanced to not require
> multiple reads to obtain a reliable value.
> This results in improving the performance of Windows guests that use
> ACPI PM timer by avoiding unnecessary VMExits caused by these multiple
> reads.
> 
> Co-developed-by: Elad Gabay <elad.ga...@oracle.com>
> Signed-off-by: Liran Alon <liran.a...@oracle.com>

Reviewed-by: Igor Mammedov <imamm...@redhat.com>

> ---
>  hw/i386/acpi-build.c | 31 +++++++++++++++++++++++++++++++
>  1 file changed, 31 insertions(+)
> 
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 9c4e46fa7466..1c3a2e8fcb3c 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -2512,6 +2512,34 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker)
>      build_header(linker, table_data, (void *)(table_data->data + dmar_start),
>                   "DMAR", table_data->len - dmar_start, 1, NULL, NULL);
>  }
> +
> +/*
> + * Windows ACPI Emulated Devices Table
> + * (Version 1.0 - April 6, 2009)
> + * Spec: 
> http://download.microsoft.com/download/7/E/7/7E7662CF-CBEA-470B-A97E-CE7CE0D98DC2/WAET.docx
> + *
> + * Helpful to speedup Windows guests and ignored by others.
> + */
> +static void
> +build_waet(GArray *table_data, BIOSLinker *linker)
> +{
> +    int waet_start = table_data->len;
> +
> +    /* WAET header */
> +    acpi_data_push(table_data, sizeof(AcpiTableHeader));
> +    /*
> +     * Set "ACPI PM timer good" flag.
> +     *
> +     * Tells Windows guests that our ACPI PM timer is reliable in the
> +     * sense that guest can read it only once to obtain a reliable value.
> +     * Which avoids costly VMExits caused by guest re-reading it 
> unnecessarily.
> +     */
> +    build_append_int_noprefix(table_data, 1 << 1 /* ACPI PM timer good */, 
> 4);
this should work but, I'd use (1UL << 1) if you'll need to respin


> +
> +    build_header(linker, table_data, (void *)(table_data->data + waet_start),
> +                 "WAET", table_data->len - waet_start, 1, NULL, NULL);
> +}
> +
>  /*
>   *   IVRS table as specified in AMD IOMMU Specification v2.62, Section 5.2
>   *   accessible here http://support.amd.com/TechDocs/48882_IOMMU.pdf
> @@ -2859,6 +2887,9 @@ void acpi_build(AcpiBuildTables *tables, MachineState 
> *machine)
>                            machine->nvdimms_state, machine->ram_slots);
>      }
>  
> +    acpi_add_table(table_offsets, tables_blob);
> +    build_waet(tables_blob, tables->linker);
> +
>      /* Add tables supplied by user (if any) */
>      for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
>          unsigned len = acpi_table_len(u);


Reply via email to