diff mbox series

[v8,07/10] ACPI ERST: create ACPI ERST table for pc/x86 machines

Message ID 1634324580-27120-8-git-send-email-eric.devolder@oracle.com
State New
Headers show
Series acpi: Error Record Serialization Table, ERST, support for QEMU | expand

Commit Message

Eric DeVolder Oct. 15, 2021, 7:02 p.m. UTC
This change exposes ACPI ERST support for x86 guests.

Signed-off-by: Eric DeVolder <eric.devolder@oracle.com>
---
 hw/i386/acpi-build.c   | 9 +++++++++
 hw/i386/acpi-microvm.c | 9 +++++++++
 include/hw/acpi/erst.h | 5 +++++
 3 files changed, 23 insertions(+)

Comments

Ani Sinha Oct. 22, 2021, 10:18 a.m. UTC | #1
On Fri, 15 Oct 2021, Eric DeVolder wrote:

> This change exposes ACPI ERST support for x86 guests.
>
> Signed-off-by: Eric DeVolder <eric.devolder@oracle.com>
> ---
>  hw/i386/acpi-build.c   | 9 +++++++++
>  hw/i386/acpi-microvm.c | 9 +++++++++
>  include/hw/acpi/erst.h | 5 +++++
>  3 files changed, 23 insertions(+)
>
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 81418b7..9c2f9d9 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -43,6 +43,7 @@
>  #include "sysemu/tpm.h"
>  #include "hw/acpi/tpm.h"
>  #include "hw/acpi/vmgenid.h"
> +#include "hw/acpi/erst.h"
>  #include "sysemu/tpm_backend.h"
>  #include "hw/rtc/mc146818rtc_regs.h"
>  #include "migration/vmstate.h"
> @@ -2499,6 +2500,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
>      GArray *tables_blob = tables->table_data;
>      AcpiSlicOem slic_oem = { .id = NULL, .table_id = NULL };
>      Object *vmgenid_dev;
> +    Object *erst_dev;
>      char *oem_id;
>      char *oem_table_id;
>
> @@ -2560,6 +2562,13 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
>                      ACPI_DEVICE_IF(x86ms->acpi_dev), x86ms->oem_id,
>                      x86ms->oem_table_id);
>
> +    erst_dev = find_erst_dev();
> +    if (erst_dev) {
> +        acpi_add_table(table_offsets, tables_blob);
> +        build_erst(tables_blob, tables->linker, erst_dev,
> +                   x86ms->oem_id, x86ms->oem_table_id);
> +    }
> +

This needs to be ifdef'd between CONFIG_ERST.


>      vmgenid_dev = find_vmgenid_dev();
>      if (vmgenid_dev) {
>          acpi_add_table(table_offsets, tables_blob);
> diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c

I do not think we need to include this for microvm machines. They are
supposed to have minimal ACPUI support. So lets not bloat it unless there
is a specific requirement to support ERST on microvms as well.


> index 196d318..662c8ad 100644
> --- a/hw/i386/acpi-microvm.c
> +++ b/hw/i386/acpi-microvm.c
> @@ -30,6 +30,7 @@
>  #include "hw/acpi/bios-linker-loader.h"
>  #include "hw/acpi/generic_event_device.h"
>  #include "hw/acpi/utils.h"
> +#include "hw/acpi/erst.h"
>  #include "hw/i386/fw_cfg.h"
>  #include "hw/i386/microvm.h"
>  #include "hw/pci/pci.h"
> @@ -158,6 +159,7 @@ static void acpi_build_microvm(AcpiBuildTables *tables,
>      X86MachineState *x86ms = X86_MACHINE(mms);
>      GArray *table_offsets;
>      GArray *tables_blob = tables->table_data;
> +    Object *erst_dev;
>      unsigned dsdt, xsdt;
>      AcpiFadtData pmfadt = {
>          /* ACPI 5.0: 4.1 Hardware-Reduced ACPI */
> @@ -207,6 +209,13 @@ static void acpi_build_microvm(AcpiBuildTables *tables,
>                      ACPI_DEVICE_IF(x86ms->acpi_dev), x86ms->oem_id,
>                      x86ms->oem_table_id);
>
> +    erst_dev = find_erst_dev();
> +    if (erst_dev) {
> +        acpi_add_table(table_offsets, tables_blob);
> +        build_erst(tables_blob, tables->linker, erst_dev,
> +                   x86ms->oem_id, x86ms->oem_table_id);
> +    }
> +



>      xsdt = tables_blob->len;
>      build_xsdt(tables_blob, tables->linker, table_offsets, x86ms->oem_id,
>                 x86ms->oem_table_id);
> diff --git a/include/hw/acpi/erst.h b/include/hw/acpi/erst.h
> index 9d63717..b747fe7 100644
> --- a/include/hw/acpi/erst.h
> +++ b/include/hw/acpi/erst.h
> @@ -16,4 +16,9 @@ void build_erst(GArray *table_data, BIOSLinker *linker, Object *erst_dev,
>
>  #define TYPE_ACPI_ERST "acpi-erst"
>
> +/* returns NULL unless there is exactly one device */
> +static inline Object *find_erst_dev(void)
> +{
> +    return object_resolve_path_type("", TYPE_ACPI_ERST, NULL);
> +}
>  #endif
> --
> 1.8.3.1
>
>
Eric DeVolder Oct. 22, 2021, 6:21 p.m. UTC | #2
Ani, inline below.
eric

On 10/22/21 05:18, Ani Sinha wrote:
> 
> 
> On Fri, 15 Oct 2021, Eric DeVolder wrote:
> 
>> This change exposes ACPI ERST support for x86 guests.
>>
>> Signed-off-by: Eric DeVolder <eric.devolder@oracle.com>
>> ---
>>   hw/i386/acpi-build.c   | 9 +++++++++
>>   hw/i386/acpi-microvm.c | 9 +++++++++
>>   include/hw/acpi/erst.h | 5 +++++
>>   3 files changed, 23 insertions(+)
>>
>> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
>> index 81418b7..9c2f9d9 100644
>> --- a/hw/i386/acpi-build.c
>> +++ b/hw/i386/acpi-build.c
>> @@ -43,6 +43,7 @@
>>   #include "sysemu/tpm.h"
>>   #include "hw/acpi/tpm.h"
>>   #include "hw/acpi/vmgenid.h"
>> +#include "hw/acpi/erst.h"
>>   #include "sysemu/tpm_backend.h"
>>   #include "hw/rtc/mc146818rtc_regs.h"
>>   #include "migration/vmstate.h"
>> @@ -2499,6 +2500,7 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
>>       GArray *tables_blob = tables->table_data;
>>       AcpiSlicOem slic_oem = { .id = NULL, .table_id = NULL };
>>       Object *vmgenid_dev;
>> +    Object *erst_dev;
>>       char *oem_id;
>>       char *oem_table_id;
>>
>> @@ -2560,6 +2562,13 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
>>                       ACPI_DEVICE_IF(x86ms->acpi_dev), x86ms->oem_id,
>>                       x86ms->oem_table_id);
>>
>> +    erst_dev = find_erst_dev();
>> +    if (erst_dev) {
>> +        acpi_add_table(table_offsets, tables_blob);
>> +        build_erst(tables_blob, tables->linker, erst_dev,
>> +                   x86ms->oem_id, x86ms->oem_table_id);
>> +    }
>> +
> 
> This needs to be ifdef'd between CONFIG_ERST.
ok

> 
> 
>>       vmgenid_dev = find_vmgenid_dev();
>>       if (vmgenid_dev) {
>>           acpi_add_table(table_offsets, tables_blob);
>> diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c
> 
> I do not think we need to include this for microvm machines. They are
> supposed to have minimal ACPUI support. So lets not bloat it unless there
> is a specific requirement to support ERST on microvms as well.
Would it be ok if I ifdef this on CONFIG_ERST also?

> 
> 
>> index 196d318..662c8ad 100644
>> --- a/hw/i386/acpi-microvm.c
>> +++ b/hw/i386/acpi-microvm.c
>> @@ -30,6 +30,7 @@
>>   #include "hw/acpi/bios-linker-loader.h"
>>   #include "hw/acpi/generic_event_device.h"
>>   #include "hw/acpi/utils.h"
>> +#include "hw/acpi/erst.h"
>>   #include "hw/i386/fw_cfg.h"
>>   #include "hw/i386/microvm.h"
>>   #include "hw/pci/pci.h"
>> @@ -158,6 +159,7 @@ static void acpi_build_microvm(AcpiBuildTables *tables,
>>       X86MachineState *x86ms = X86_MACHINE(mms);
>>       GArray *table_offsets;
>>       GArray *tables_blob = tables->table_data;
>> +    Object *erst_dev;
>>       unsigned dsdt, xsdt;
>>       AcpiFadtData pmfadt = {
>>           /* ACPI 5.0: 4.1 Hardware-Reduced ACPI */
>> @@ -207,6 +209,13 @@ static void acpi_build_microvm(AcpiBuildTables *tables,
>>                       ACPI_DEVICE_IF(x86ms->acpi_dev), x86ms->oem_id,
>>                       x86ms->oem_table_id);
>>
>> +    erst_dev = find_erst_dev();
>> +    if (erst_dev) {
>> +        acpi_add_table(table_offsets, tables_blob);
>> +        build_erst(tables_blob, tables->linker, erst_dev,
>> +                   x86ms->oem_id, x86ms->oem_table_id);
>> +    }
>> +
> 
> 
> 
>>       xsdt = tables_blob->len;
>>       build_xsdt(tables_blob, tables->linker, table_offsets, x86ms->oem_id,
>>                  x86ms->oem_table_id);
>> diff --git a/include/hw/acpi/erst.h b/include/hw/acpi/erst.h
>> index 9d63717..b747fe7 100644
>> --- a/include/hw/acpi/erst.h
>> +++ b/include/hw/acpi/erst.h
>> @@ -16,4 +16,9 @@ void build_erst(GArray *table_data, BIOSLinker *linker, Object *erst_dev,
>>
>>   #define TYPE_ACPI_ERST "acpi-erst"
>>
>> +/* returns NULL unless there is exactly one device */
>> +static inline Object *find_erst_dev(void)
>> +{
>> +    return object_resolve_path_type("", TYPE_ACPI_ERST, NULL);
>> +}
>>   #endif
>> --
>> 1.8.3.1
>>
>>
Ani Sinha Oct. 23, 2021, 2:22 a.m. UTC | #3
On Fri, 22 Oct 2021, Eric DeVolder wrote:

> Ani, inline below.
> eric
>
> On 10/22/21 05:18, Ani Sinha wrote:
> >
> >
> > On Fri, 15 Oct 2021, Eric DeVolder wrote:
> >
> > > This change exposes ACPI ERST support for x86 guests.
> > >
> > > Signed-off-by: Eric DeVolder <eric.devolder@oracle.com>
> > > ---
> > >   hw/i386/acpi-build.c   | 9 +++++++++
> > >   hw/i386/acpi-microvm.c | 9 +++++++++
> > >   include/hw/acpi/erst.h | 5 +++++
> > >   3 files changed, 23 insertions(+)
> > >
> > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > index 81418b7..9c2f9d9 100644
> > > --- a/hw/i386/acpi-build.c
> > > +++ b/hw/i386/acpi-build.c
> > > @@ -43,6 +43,7 @@
> > >   #include "sysemu/tpm.h"
> > >   #include "hw/acpi/tpm.h"
> > >   #include "hw/acpi/vmgenid.h"
> > > +#include "hw/acpi/erst.h"
> > >   #include "sysemu/tpm_backend.h"
> > >   #include "hw/rtc/mc146818rtc_regs.h"
> > >   #include "migration/vmstate.h"
> > > @@ -2499,6 +2500,7 @@ void acpi_build(AcpiBuildTables *tables,
> > > MachineState *machine)
> > >       GArray *tables_blob = tables->table_data;
> > >       AcpiSlicOem slic_oem = { .id = NULL, .table_id = NULL };
> > >       Object *vmgenid_dev;
> > > +    Object *erst_dev;
> > >       char *oem_id;
> > >       char *oem_table_id;
> > >
> > > @@ -2560,6 +2562,13 @@ void acpi_build(AcpiBuildTables *tables,
> > > MachineState *machine)
> > >                       ACPI_DEVICE_IF(x86ms->acpi_dev), x86ms->oem_id,
> > >                       x86ms->oem_table_id);
> > >
> > > +    erst_dev = find_erst_dev();
> > > +    if (erst_dev) {
> > > +        acpi_add_table(table_offsets, tables_blob);
> > > +        build_erst(tables_blob, tables->linker, erst_dev,
> > > +                   x86ms->oem_id, x86ms->oem_table_id);
> > > +    }
> > > +
> >
> > This needs to be ifdef'd between CONFIG_ERST.
> ok
>
> >
> >
> > >       vmgenid_dev = find_vmgenid_dev();
> > >       if (vmgenid_dev) {
> > >           acpi_add_table(table_offsets, tables_blob);
> > > diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c
> >
> > I do not think we need to include this for microvm machines. They are
> > supposed to have minimal ACPUI support. So lets not bloat it unless there
> > is a specific requirement to support ERST on microvms as well.
> Would it be ok if I ifdef this on CONFIG_ERST also?

I think we should not touch microvm machine unless you can justify why you
need ERST support there.

>
> >
> >
> > > index 196d318..662c8ad 100644
> > > --- a/hw/i386/acpi-microvm.c
> > > +++ b/hw/i386/acpi-microvm.c
> > > @@ -30,6 +30,7 @@
> > >   #include "hw/acpi/bios-linker-loader.h"
> > >   #include "hw/acpi/generic_event_device.h"
> > >   #include "hw/acpi/utils.h"
> > > +#include "hw/acpi/erst.h"
> > >   #include "hw/i386/fw_cfg.h"
> > >   #include "hw/i386/microvm.h"
> > >   #include "hw/pci/pci.h"
> > > @@ -158,6 +159,7 @@ static void acpi_build_microvm(AcpiBuildTables
> > > *tables,
> > >       X86MachineState *x86ms = X86_MACHINE(mms);
> > >       GArray *table_offsets;
> > >       GArray *tables_blob = tables->table_data;
> > > +    Object *erst_dev;
> > >       unsigned dsdt, xsdt;
> > >       AcpiFadtData pmfadt = {
> > >           /* ACPI 5.0: 4.1 Hardware-Reduced ACPI */
> > > @@ -207,6 +209,13 @@ static void acpi_build_microvm(AcpiBuildTables
> > > *tables,
> > >                       ACPI_DEVICE_IF(x86ms->acpi_dev), x86ms->oem_id,
> > >                       x86ms->oem_table_id);
> > >
> > > +    erst_dev = find_erst_dev();
> > > +    if (erst_dev) {
> > > +        acpi_add_table(table_offsets, tables_blob);
> > > +        build_erst(tables_blob, tables->linker, erst_dev,
> > > +                   x86ms->oem_id, x86ms->oem_table_id);
> > > +    }
> > > +
> >
> >
> >
> > >       xsdt = tables_blob->len;
> > >       build_xsdt(tables_blob, tables->linker, table_offsets,
> > > x86ms->oem_id,
> > >                  x86ms->oem_table_id);
> > > diff --git a/include/hw/acpi/erst.h b/include/hw/acpi/erst.h
> > > index 9d63717..b747fe7 100644
> > > --- a/include/hw/acpi/erst.h
> > > +++ b/include/hw/acpi/erst.h
> > > @@ -16,4 +16,9 @@ void build_erst(GArray *table_data, BIOSLinker *linker,
> > > Object *erst_dev,
> > >
> > >   #define TYPE_ACPI_ERST "acpi-erst"
> > >
> > > +/* returns NULL unless there is exactly one device */
> > > +static inline Object *find_erst_dev(void)
> > > +{
> > > +    return object_resolve_path_type("", TYPE_ACPI_ERST, NULL);
> > > +}
> > >   #endif
> > > --
> > > 1.8.3.1
> > >
> > >
>
Michael S. Tsirkin Oct. 23, 2021, 8:14 p.m. UTC | #4
On Sat, Oct 23, 2021 at 07:52:21AM +0530, Ani Sinha wrote:
> 
> 
> On Fri, 22 Oct 2021, Eric DeVolder wrote:
> 
> > Ani, inline below.
> > eric
> >
> > On 10/22/21 05:18, Ani Sinha wrote:
> > >
> > >
> > > On Fri, 15 Oct 2021, Eric DeVolder wrote:
> > >
> > > > This change exposes ACPI ERST support for x86 guests.
> > > >
> > > > Signed-off-by: Eric DeVolder <eric.devolder@oracle.com>
> > > > ---
> > > >   hw/i386/acpi-build.c   | 9 +++++++++
> > > >   hw/i386/acpi-microvm.c | 9 +++++++++
> > > >   include/hw/acpi/erst.h | 5 +++++
> > > >   3 files changed, 23 insertions(+)
> > > >
> > > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > > index 81418b7..9c2f9d9 100644
> > > > --- a/hw/i386/acpi-build.c
> > > > +++ b/hw/i386/acpi-build.c
> > > > @@ -43,6 +43,7 @@
> > > >   #include "sysemu/tpm.h"
> > > >   #include "hw/acpi/tpm.h"
> > > >   #include "hw/acpi/vmgenid.h"
> > > > +#include "hw/acpi/erst.h"
> > > >   #include "sysemu/tpm_backend.h"
> > > >   #include "hw/rtc/mc146818rtc_regs.h"
> > > >   #include "migration/vmstate.h"
> > > > @@ -2499,6 +2500,7 @@ void acpi_build(AcpiBuildTables *tables,
> > > > MachineState *machine)
> > > >       GArray *tables_blob = tables->table_data;
> > > >       AcpiSlicOem slic_oem = { .id = NULL, .table_id = NULL };
> > > >       Object *vmgenid_dev;
> > > > +    Object *erst_dev;
> > > >       char *oem_id;
> > > >       char *oem_table_id;
> > > >
> > > > @@ -2560,6 +2562,13 @@ void acpi_build(AcpiBuildTables *tables,
> > > > MachineState *machine)
> > > >                       ACPI_DEVICE_IF(x86ms->acpi_dev), x86ms->oem_id,
> > > >                       x86ms->oem_table_id);
> > > >
> > > > +    erst_dev = find_erst_dev();
> > > > +    if (erst_dev) {
> > > > +        acpi_add_table(table_offsets, tables_blob);
> > > > +        build_erst(tables_blob, tables->linker, erst_dev,
> > > > +                   x86ms->oem_id, x86ms->oem_table_id);
> > > > +    }
> > > > +
> > >
> > > This needs to be ifdef'd between CONFIG_ERST.
> > ok
> >
> > >
> > >
> > > >       vmgenid_dev = find_vmgenid_dev();
> > > >       if (vmgenid_dev) {
> > > >           acpi_add_table(table_offsets, tables_blob);
> > > > diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c
> > >
> > > I do not think we need to include this for microvm machines. They are
> > > supposed to have minimal ACPUI support. So lets not bloat it unless there
> > > is a specific requirement to support ERST on microvms as well.
> > Would it be ok if I ifdef this on CONFIG_ERST also?
> 
> I think we should not touch microvm machine unless you can justify why you
> need ERST support there.

OTOH why not? No idea... CC microvm maintainers and let them decide.

> >
> > >
> > >
> > > > index 196d318..662c8ad 100644
> > > > --- a/hw/i386/acpi-microvm.c
> > > > +++ b/hw/i386/acpi-microvm.c
> > > > @@ -30,6 +30,7 @@
> > > >   #include "hw/acpi/bios-linker-loader.h"
> > > >   #include "hw/acpi/generic_event_device.h"
> > > >   #include "hw/acpi/utils.h"
> > > > +#include "hw/acpi/erst.h"
> > > >   #include "hw/i386/fw_cfg.h"
> > > >   #include "hw/i386/microvm.h"
> > > >   #include "hw/pci/pci.h"
> > > > @@ -158,6 +159,7 @@ static void acpi_build_microvm(AcpiBuildTables
> > > > *tables,
> > > >       X86MachineState *x86ms = X86_MACHINE(mms);
> > > >       GArray *table_offsets;
> > > >       GArray *tables_blob = tables->table_data;
> > > > +    Object *erst_dev;
> > > >       unsigned dsdt, xsdt;
> > > >       AcpiFadtData pmfadt = {
> > > >           /* ACPI 5.0: 4.1 Hardware-Reduced ACPI */
> > > > @@ -207,6 +209,13 @@ static void acpi_build_microvm(AcpiBuildTables
> > > > *tables,
> > > >                       ACPI_DEVICE_IF(x86ms->acpi_dev), x86ms->oem_id,
> > > >                       x86ms->oem_table_id);
> > > >
> > > > +    erst_dev = find_erst_dev();
> > > > +    if (erst_dev) {
> > > > +        acpi_add_table(table_offsets, tables_blob);
> > > > +        build_erst(tables_blob, tables->linker, erst_dev,
> > > > +                   x86ms->oem_id, x86ms->oem_table_id);
> > > > +    }
> > > > +
> > >
> > >
> > >
> > > >       xsdt = tables_blob->len;
> > > >       build_xsdt(tables_blob, tables->linker, table_offsets,
> > > > x86ms->oem_id,
> > > >                  x86ms->oem_table_id);
> > > > diff --git a/include/hw/acpi/erst.h b/include/hw/acpi/erst.h
> > > > index 9d63717..b747fe7 100644
> > > > --- a/include/hw/acpi/erst.h
> > > > +++ b/include/hw/acpi/erst.h
> > > > @@ -16,4 +16,9 @@ void build_erst(GArray *table_data, BIOSLinker *linker,
> > > > Object *erst_dev,
> > > >
> > > >   #define TYPE_ACPI_ERST "acpi-erst"
> > > >
> > > > +/* returns NULL unless there is exactly one device */
> > > > +static inline Object *find_erst_dev(void)
> > > > +{
> > > > +    return object_resolve_path_type("", TYPE_ACPI_ERST, NULL);
> > > > +}
> > > >   #endif
> > > > --
> > > > 1.8.3.1
> > > >
> > > >
> >
Boris Ostrovsky Oct. 24, 2021, 1:13 a.m. UTC | #5
On 10/23/21 4:14 PM, Michael S. Tsirkin wrote:
> On Sat, Oct 23, 2021 at 07:52:21AM +0530, Ani Sinha wrote:
>>
>> On Fri, 22 Oct 2021, Eric DeVolder wrote:
>>
>>> Ani, inline below.
>>> eric
>>>
>>> On 10/22/21 05:18, Ani Sinha wrote:
>>>>
>>>> On Fri, 15 Oct 2021, Eric DeVolder wrote:
>>>>
>>>>
>>>>> diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c
>>>> I do not think we need to include this for microvm machines. They are
>>>> supposed to have minimal ACPUI support. So lets not bloat it unless there
>>>> is a specific requirement to support ERST on microvms as well.
>>> Would it be ok if I ifdef this on CONFIG_ERST also?
>> I think we should not touch microvm machine unless you can justify why you
>> need ERST support there.
> OTOH why not? No idea... CC microvm maintainers and let them decide.


I would argue that ERST support for microvm is in fact more useful than for "regular" VMs: those VMs can use EFI storage for pstore while microvms won't have that option.


-boris
diff mbox series

Patch

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 81418b7..9c2f9d9 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -43,6 +43,7 @@ 
 #include "sysemu/tpm.h"
 #include "hw/acpi/tpm.h"
 #include "hw/acpi/vmgenid.h"
+#include "hw/acpi/erst.h"
 #include "sysemu/tpm_backend.h"
 #include "hw/rtc/mc146818rtc_regs.h"
 #include "migration/vmstate.h"
@@ -2499,6 +2500,7 @@  void acpi_build(AcpiBuildTables *tables, MachineState *machine)
     GArray *tables_blob = tables->table_data;
     AcpiSlicOem slic_oem = { .id = NULL, .table_id = NULL };
     Object *vmgenid_dev;
+    Object *erst_dev;
     char *oem_id;
     char *oem_table_id;
 
@@ -2560,6 +2562,13 @@  void acpi_build(AcpiBuildTables *tables, MachineState *machine)
                     ACPI_DEVICE_IF(x86ms->acpi_dev), x86ms->oem_id,
                     x86ms->oem_table_id);
 
+    erst_dev = find_erst_dev();
+    if (erst_dev) {
+        acpi_add_table(table_offsets, tables_blob);
+        build_erst(tables_blob, tables->linker, erst_dev,
+                   x86ms->oem_id, x86ms->oem_table_id);
+    }
+
     vmgenid_dev = find_vmgenid_dev();
     if (vmgenid_dev) {
         acpi_add_table(table_offsets, tables_blob);
diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c
index 196d318..662c8ad 100644
--- a/hw/i386/acpi-microvm.c
+++ b/hw/i386/acpi-microvm.c
@@ -30,6 +30,7 @@ 
 #include "hw/acpi/bios-linker-loader.h"
 #include "hw/acpi/generic_event_device.h"
 #include "hw/acpi/utils.h"
+#include "hw/acpi/erst.h"
 #include "hw/i386/fw_cfg.h"
 #include "hw/i386/microvm.h"
 #include "hw/pci/pci.h"
@@ -158,6 +159,7 @@  static void acpi_build_microvm(AcpiBuildTables *tables,
     X86MachineState *x86ms = X86_MACHINE(mms);
     GArray *table_offsets;
     GArray *tables_blob = tables->table_data;
+    Object *erst_dev;
     unsigned dsdt, xsdt;
     AcpiFadtData pmfadt = {
         /* ACPI 5.0: 4.1 Hardware-Reduced ACPI */
@@ -207,6 +209,13 @@  static void acpi_build_microvm(AcpiBuildTables *tables,
                     ACPI_DEVICE_IF(x86ms->acpi_dev), x86ms->oem_id,
                     x86ms->oem_table_id);
 
+    erst_dev = find_erst_dev();
+    if (erst_dev) {
+        acpi_add_table(table_offsets, tables_blob);
+        build_erst(tables_blob, tables->linker, erst_dev,
+                   x86ms->oem_id, x86ms->oem_table_id);
+    }
+
     xsdt = tables_blob->len;
     build_xsdt(tables_blob, tables->linker, table_offsets, x86ms->oem_id,
                x86ms->oem_table_id);
diff --git a/include/hw/acpi/erst.h b/include/hw/acpi/erst.h
index 9d63717..b747fe7 100644
--- a/include/hw/acpi/erst.h
+++ b/include/hw/acpi/erst.h
@@ -16,4 +16,9 @@  void build_erst(GArray *table_data, BIOSLinker *linker, Object *erst_dev,
 
 #define TYPE_ACPI_ERST "acpi-erst"
 
+/* returns NULL unless there is exactly one device */
+static inline Object *find_erst_dev(void)
+{
+    return object_resolve_path_type("", TYPE_ACPI_ERST, NULL);
+}
 #endif