Re: [PATCH v2 5/5] hw/pci: ensure PCIE devices are plugged into only slot 0 of PCIE port

2023-06-23 Thread Julia Suvorova
On Thu, Jun 22, 2023 at 7:48 PM Michael S. Tsirkin  wrote:
>
> On Thu, Jun 22, 2023 at 05:46:40PM +0200, Julia Suvorova wrote:
> > On Thu, Jun 22, 2023 at 12:34 PM Ani Sinha  wrote:
> > >
> > > PCI Express ports only have one slot, so PCI Express devices can only be
> > > plugged into slot 0 on a PCIE port. Enforce it.
> > >
> > > CC: jus...@redhat.com
> > > CC: imamm...@redhat.com
> > > Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2128929
> > > Signed-off-by: Ani Sinha 
> > > ---
> > >  hw/pci/pci.c | 6 ++
> > >  1 file changed, 6 insertions(+)
> > >
> > > diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> > > index bf38905b7d..5f25ab9f5e 100644
> > > --- a/hw/pci/pci.c
> > > +++ b/hw/pci/pci.c
> > > @@ -64,6 +64,7 @@ bool pci_available = true;
> > >  static char *pcibus_get_dev_path(DeviceState *dev);
> > >  static char *pcibus_get_fw_dev_path(DeviceState *dev);
> > >  static void pcibus_reset(BusState *qbus);
> > > +static bool pcie_has_upstream_port(PCIDevice *dev);
> > >
> > >  static Property pci_props[] = {
> > >  DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
> > > @@ -1189,6 +1190,11 @@ static PCIDevice *do_pci_register_device(PCIDevice 
> > > *pci_dev,
> > > name);
> > >
> > > return NULL;
> > > +} else if (pcie_has_upstream_port(pci_dev) && PCI_SLOT(devfn)) {
> > > +error_setg(errp, "PCI: slot %d is not valid for %s,"
> > > +   " PCI express devices can only be plugged into slot 
> > > 0.",
> >
> > This is not technically correct, because downstream ports and root
> > ports are also PCIe devices, and they can have different slots under
> > upstream ports and RC. But this error will never be shown for them, so
> > it seems fine.
>
> Hmm. Confusing users is not nice ... I agree this might
> make people think they can not use root ports in slot !=0 either.
>
> Would you add "with an upstream port"?
> E.g. "PCI Express devices with an upstream port" ?

This whole upstream port conditioning is quite confusing.
How about "%parent device% only allows plugging into slot 0"?

Best regards, Julia Suvorova.

> >
> > Reviewed-by: Julia Suvorova 
> >
> >
> >
> >
> > > +   PCI_SLOT(devfn), name);
> > > +return NULL;
> > >  }
> > >
> > >  pci_dev->devfn = devfn;
> > > --
> > > 2.39.1
> > >
>




Re: [PATCH v1 02/23] pc/q35: Apply PCI bus BSEL property for Xen PCI device hotplug

2023-06-22 Thread Julia Suvorova
On Thu, Jun 22, 2023 at 9:36 AM Igor Mammedov  wrote:
>
> On Wed, 21 Jun 2023 13:24:42 -0400
> Joel Upham  wrote:
>
> > On Wed, Jun 21, 2023 at 7:28 AM Igor Mammedov  wrote:
> >
> > > On Tue, 20 Jun 2023 13:24:36 -0400
> > > Joel Upham  wrote:
> > >
> > > > On Q35 we still need to assign BSEL property to bus(es) for PCI device
> > > > add/hotplug to work.
> > > > Extend acpi_set_pci_info() function to support Q35 as well. This patch
> > > adds new (trivial)
> > > > function find_q35() which returns root PCIBus object on Q35, in a way
> > > > similar to what find_i440fx does.
> > >
> > > I think patch is mostly obsolete, q35 ACPI PCI hotplug is supported in
> > > upstream QEMU.
> > >
> > > Also see comment below.
> > >
> > > I make use of the find_q35() function in later patches, but I agree now a
> > majority of this patch is a bit different.
>
> There is likely an existing alternative already. (probably introduced by ACPI 
> PIC hotplug for q35)

There is a similar function acpi_get_i386_pci_host() in hw/i386/acpi-build.c

Best regards, Julia Suvorova.

> >
> > > >
> > > > Signed-off-by: Alexey Gerasimenko 
> > > > Signed-off-by: Joel Upham 
> > > > ---
> > > >  hw/acpi/pcihp.c  | 4 +++-
> > > >  hw/pci-host/q35.c| 9 +
> > > >  include/hw/i386/pc.h | 3 +++
> > > >  3 files changed, 15 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
> > > > index cdd6f775a1..f4e39d7a9c 100644
> > > > --- a/hw/acpi/pcihp.c
> > > > +++ b/hw/acpi/pcihp.c
> > > > @@ -40,6 +40,7 @@
> > > >  #include "qapi/error.h"
> > > >  #include "qom/qom-qobject.h"
> > > >  #include "trace.h"
> > > > +#include "sysemu/xen.h"
> > > >
> > > >  #define ACPI_PCIHP_SIZE 0x0018
> > > >  #define PCI_UP_BASE 0x
> > > > @@ -84,7 +85,8 @@ static void *acpi_set_bsel(PCIBus *bus, void *opaque)
> > > >  bool is_bridge = IS_PCI_BRIDGE(br);
> > > >
> > > >  /* hotplugged bridges can't be described in ACPI ignore them */
> > > > -if (qbus_is_hotpluggable(BUS(bus))) {
> > >
> > > > +/* Xen requires hotplugging to the root device, even on the Q35
> > > chipset */
> > > pls explain what 'root device' is.
> > > Why can't you use root-ports for hotplug?
> > >
> > > Wording may have been incorrect.  Root port is correct. This may not be
> > needed anymore,
> > and may have been left over for when I was debugging PCIe hotplugging
> > problems.
> > I will retest and fix patch once I know more. Xen expects the PCIe device
> > to be on the root port.
> >
> > I can move the function to a different patch that uses it.
> >
> > > > +if (qbus_is_hotpluggable(BUS(bus)) || xen_enabled()) {
> > > >  if (!is_bridge || (!br->hotplugged &&
> > > info->has_bridge_hotplug)) {
> > > >  bus_bsel = g_malloc(sizeof *bus_bsel);
> > > >
> > > > diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
> > > > index fd18920e7f..fe5fc0f47c 100644
> > > > --- a/hw/pci-host/q35.c
> > > > +++ b/hw/pci-host/q35.c
> > > > @@ -259,6 +259,15 @@ static void q35_host_initfn(Object *obj)
> > > >   qdev_prop_allow_set_link_before_realize,
> > > 0);
> > > >  }
> > > >
> > > > +PCIBus *find_q35(void)
> > > > +{
> > > > +PCIHostState *s = OBJECT_CHECK(PCIHostState,
> > > > +   object_resolve_path("/machine/q35",
> > > NULL),
> > > > +   TYPE_PCI_HOST_BRIDGE);
> > > > +return s ? s->bus : NULL;
> > > > +}
> > > > +
> > > > +
> > > >  static const TypeInfo q35_host_info = {
> > > >  .name   = TYPE_Q35_HOST_DEVICE,
> > > >  .parent = TYPE_PCIE_HOST_BRIDGE,
> > > > diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> > > > index c661e9cc80..550f8fa221 100644
> > > > --- a/include/hw/i386/pc.h
> > > > +++ b/include/hw/i386/pc.h
> > > > @@ -196,6 +196,9 @@ void pc_madt_cpu_entry(int uid, const CPUArchIdList
> > > *apic_ids,
> > > >  /* sgx.c */
> > > >  void pc_machine_init_sgx_epc(PCMachineState *pcms);
> > > >
> > > > +/* q35.c */
> > > > +PCIBus *find_q35(void);
> > > > +
> > > >  extern GlobalProperty pc_compat_8_0[];
> > > >  extern const size_t pc_compat_8_0_len;
> > > >
> > >
> > >
>
>




Re: [PATCH v2 5/5] hw/pci: ensure PCIE devices are plugged into only slot 0 of PCIE port

2023-06-22 Thread Julia Suvorova
On Thu, Jun 22, 2023 at 12:34 PM Ani Sinha  wrote:
>
> PCI Express ports only have one slot, so PCI Express devices can only be
> plugged into slot 0 on a PCIE port. Enforce it.
>
> CC: jus...@redhat.com
> CC: imamm...@redhat.com
> Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2128929
> Signed-off-by: Ani Sinha 
> ---
>  hw/pci/pci.c | 6 ++
>  1 file changed, 6 insertions(+)
>
> diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> index bf38905b7d..5f25ab9f5e 100644
> --- a/hw/pci/pci.c
> +++ b/hw/pci/pci.c
> @@ -64,6 +64,7 @@ bool pci_available = true;
>  static char *pcibus_get_dev_path(DeviceState *dev);
>  static char *pcibus_get_fw_dev_path(DeviceState *dev);
>  static void pcibus_reset(BusState *qbus);
> +static bool pcie_has_upstream_port(PCIDevice *dev);
>
>  static Property pci_props[] = {
>  DEFINE_PROP_PCI_DEVFN("addr", PCIDevice, devfn, -1),
> @@ -1189,6 +1190,11 @@ static PCIDevice *do_pci_register_device(PCIDevice 
> *pci_dev,
> name);
>
> return NULL;
> +} else if (pcie_has_upstream_port(pci_dev) && PCI_SLOT(devfn)) {
> +error_setg(errp, "PCI: slot %d is not valid for %s,"
> +   " PCI express devices can only be plugged into slot 0.",

This is not technically correct, because downstream ports and root
ports are also PCIe devices, and they can have different slots under
upstream ports and RC. But this error will never be shown for them, so
it seems fine.

Reviewed-by: Julia Suvorova 




> +   PCI_SLOT(devfn), name);
> +return NULL;
>  }
>
>  pci_dev->devfn = devfn;
> --
> 2.39.1
>




[PATCH v2] hw/smbios: fix field corruption in type 4 table

2023-02-23 Thread Julia Suvorova
Since table type 4 of SMBIOS version 2.6 is shorter than 3.0, the
strings which follow immediately after the struct fields have been
overwritten by unconditional filling of later fields such as core_count2.
Make these fields dependent on the SMBIOS version.

Fixes: 05e27d74c7 ("hw/smbios: add core_count2 to smbios table type 4")
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2169904

Signed-off-by: Julia Suvorova 
---
v2:
* add fixes tag
* check tbl_len instead of ep_type

 hw/smbios/smbios.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 4869566cf5..d2007e70fb 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -750,14 +750,16 @@ static void smbios_build_type_4_table(MachineState *ms, 
unsigned instance)
 t->core_count = (ms->smp.cores > 255) ? 0xFF : ms->smp.cores;
 t->core_enabled = t->core_count;
 
-t->core_count2 = t->core_enabled2 = cpu_to_le16(ms->smp.cores);
-
 t->thread_count = (ms->smp.threads > 255) ? 0xFF : ms->smp.threads;
-t->thread_count2 = cpu_to_le16(ms->smp.threads);
 
 t->processor_characteristics = cpu_to_le16(0x02); /* Unknown */
 t->processor_family2 = cpu_to_le16(0x01); /* Other */
 
+if (tbl_len == SMBIOS_TYPE_4_LEN_V30) {
+t->core_count2 = t->core_enabled2 = cpu_to_le16(ms->smp.cores);
+t->thread_count2 = cpu_to_le16(ms->smp.threads);
+}
+
 SMBIOS_BUILD_TABLE_POST;
 smbios_type4_count++;
 }
-- 
2.38.1




[PATCH] hw/smbios: fix field corruption in type 4 table

2023-02-22 Thread Julia Suvorova
Since table type 4 of SMBIOS version 2.6 is shorter than 3.0, the
strings which follow immediately after the struct fields have been
overwritten by unconditional filling of later fields such as core_count2.
Make these fields dependent on the SMBIOS version.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2169904

Signed-off-by: Julia Suvorova 
---
 hw/smbios/smbios.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index b4243de735..903fd22350 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -749,14 +749,16 @@ static void smbios_build_type_4_table(MachineState *ms, 
unsigned instance)
 t->core_count = (ms->smp.cores > 255) ? 0xFF : ms->smp.cores;
 t->core_enabled = t->core_count;
 
-t->core_count2 = t->core_enabled2 = cpu_to_le16(ms->smp.cores);
-
 t->thread_count = (ms->smp.threads > 255) ? 0xFF : ms->smp.threads;
-t->thread_count2 = cpu_to_le16(ms->smp.threads);
 
 t->processor_characteristics = cpu_to_le16(0x02); /* Unknown */
 t->processor_family2 = cpu_to_le16(0x01); /* Other */
 
+if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_64) {
+t->core_count2 = t->core_enabled2 = cpu_to_le16(ms->smp.cores);
+t->thread_count2 = cpu_to_le16(ms->smp.threads);
+}
+
 SMBIOS_BUILD_TABLE_POST;
 smbios_type4_count++;
 }
-- 
2.38.1




[PATCH v2] hw/mem/nvdimm: fix error message for 'unarmed' flag

2022-10-23 Thread Julia Suvorova
In the ACPI specification [1], the 'unarmed' bit is set when a device
cannot accept a persistent write. This means that when a memdev is
read-only, the 'unarmed' flag must be turned on. The logic is correct,
just changing the error message.

[1] ACPI NFIT NVDIMM Region Mapping Structure "NVDIMM State Flags" Bit 3

Fixes: dbd730e859 ("nvdimm: check -object memory-backend-file, readonly=on 
option")
Signed-off-by: Julia Suvorova 
Reviewed-by: Stefan Hajnoczi 
Reviewed-by: Pankaj Gupta 
Reviewed-by: Philippe Mathieu-Daudé 
Acked-by: David Hildenbrand 
---
v2:
* enquote 'on' [Philippe]

 hw/mem/nvdimm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c
index 7c7d81..31080c22c9 100644
--- a/hw/mem/nvdimm.c
+++ b/hw/mem/nvdimm.c
@@ -149,7 +149,7 @@ static void nvdimm_prepare_memory_region(NVDIMMDevice 
*nvdimm, Error **errp)
 if (!nvdimm->unarmed && memory_region_is_rom(mr)) {
 HostMemoryBackend *hostmem = dimm->hostmem;
 
-error_setg(errp, "'unarmed' property must be off since memdev %s "
+error_setg(errp, "'unarmed' property must be 'on' since memdev %s "
"is read-only",
object_get_canonical_path_component(OBJECT(hostmem)));
 return;
-- 
2.37.3




Re: [RESEND PATCH] hw/mem/nvdimm: fix error message for 'unarmed' flag

2022-10-19 Thread Julia Suvorova
On Tue, Oct 18, 2022 at 6:49 PM Michael S. Tsirkin  wrote:
>
> On Tue, Oct 18, 2022 at 06:17:55PM +0200, Philippe Mathieu-Daudé wrote:
> > On 18/10/22 17:25, Julia Suvorova wrote:
> > > In the ACPI specification [1], the 'unarmed' bit is set when a device
> > > cannot accept a persistent write. This means that when a memdev is
> > > read-only, the 'unarmed' flag must be turned on. The logic is correct,
> > > just changing the error message.
> > >
> > > [1] ACPI NFIT NVDIMM Region Mapping Structure "NVDIMM State Flags" Bit 3
> > >
> >
> > Fixes: dbd730e859 ("nvdimm: check -object memory-backend-file, readonly=on
> > option")
> >
> > The documentation in 'docs/nvdimm.txt' is correct :)
> >
> > > Signed-off-by: Julia Suvorova 
> > > Reviewed-by: Stefan Hajnoczi 
> > > ---
> > >   hw/mem/nvdimm.c | 2 +-
> > >   1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c
> > > index 7c7d81..bfb76818c1 100644
> > > --- a/hw/mem/nvdimm.c
> > > +++ b/hw/mem/nvdimm.c
> > > @@ -149,7 +149,7 @@ static void nvdimm_prepare_memory_region(NVDIMMDevice 
> > > *nvdimm, Error **errp)
> > >   if (!nvdimm->unarmed && memory_region_is_rom(mr)) {
> > >   HostMemoryBackend *hostmem = dimm->hostmem;
> > > -error_setg(errp, "'unarmed' property must be off since memdev %s 
> > > "
> > > +error_setg(errp, "'unarmed' property must be on since memdev %s "
> >
> > If you ever respin please quote 'on' for readability.
>
>
> Yes make sense. Julia could you change this pls?

Sure, will do.

> > >  "is read-only",
> > >  
> > > object_get_canonical_path_component(OBJECT(hostmem)));
> > >   return;
> >
> > Reviewed-by: Philippe Mathieu-Daudé 
>




[RESEND PATCH] hw/mem/nvdimm: fix error message for 'unarmed' flag

2022-10-18 Thread Julia Suvorova
In the ACPI specification [1], the 'unarmed' bit is set when a device
cannot accept a persistent write. This means that when a memdev is
read-only, the 'unarmed' flag must be turned on. The logic is correct,
just changing the error message.

[1] ACPI NFIT NVDIMM Region Mapping Structure "NVDIMM State Flags" Bit 3

Signed-off-by: Julia Suvorova 
Reviewed-by: Stefan Hajnoczi 
---
 hw/mem/nvdimm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c
index 7c7d81..bfb76818c1 100644
--- a/hw/mem/nvdimm.c
+++ b/hw/mem/nvdimm.c
@@ -149,7 +149,7 @@ static void nvdimm_prepare_memory_region(NVDIMMDevice 
*nvdimm, Error **errp)
 if (!nvdimm->unarmed && memory_region_is_rom(mr)) {
 HostMemoryBackend *hostmem = dimm->hostmem;
 
-error_setg(errp, "'unarmed' property must be off since memdev %s "
+error_setg(errp, "'unarmed' property must be on since memdev %s "
"is read-only",
object_get_canonical_path_component(OBJECT(hostmem)));
 return;
-- 
2.37.3




[PATCH v3 0/5] hw/smbios: add core_count2 to smbios table type 4

2022-10-11 Thread Julia Suvorova
The SMBIOS 3.0 specification provides the ability to reflect over
255 cores. The 64-bit entry point has been used for a while, but
structure type 4 has not been updated before, so the dmidecode output
looked like this (-smp 280):

Handle 0x0400, DMI type 4, 42 bytes
Processor Information
...
Core Count: 24
Core Enabled: 24
Thread Count: 1
...

Big update in the bios-tables-test as it couldn't work with SMBIOS 3.0.

v3:
* rebase on fresh master
* crop lines to 80 characters [Igor]
* add conditions for cc2 field check in the test [Igor]

v2:
* generate tables type 4 of different sizes based on the
  selected smbios version
* use SmbiosEntryPoint* types instead of creating new constants
* refactor smbios_cpu_test [Igor, Ani]
* clarify signature check [Igor]
* add comments with specifications and clarification of the structure loop 
[Ani]


Julia Suvorova (5):
  hw/smbios: add core_count2 to smbios table type 4
  bios-tables-test: teach test to use smbios 3.0 tables
  tests/acpi: allow changes for core_count2 test
  bios-tables-test: add test for number of cores > 255
  tests/acpi: update tables for new core count test

 hw/smbios/smbios.c   |  19 +++-
 hw/smbios/smbios_build.h |   9 +-
 include/hw/firmware/smbios.h |  12 ++
 tests/data/acpi/q35/APIC.core-count2 | Bin 0 -> 2478 bytes
 tests/data/acpi/q35/DSDT.core-count2 | Bin 0 -> 32414 bytes
 tests/data/acpi/q35/FACP.core-count2 | Bin 0 -> 244 bytes
 tests/qtest/bios-tables-test.c   | 158 ---
 7 files changed, 156 insertions(+), 42 deletions(-)
 create mode 100644 tests/data/acpi/q35/APIC.core-count2
 create mode 100644 tests/data/acpi/q35/DSDT.core-count2
 create mode 100644 tests/data/acpi/q35/FACP.core-count2

-- 
2.37.3




[PATCH v3 4/5] bios-tables-test: add test for number of cores > 255

2022-10-11 Thread Julia Suvorova
The new test is run with a large number of cpus and checks if the
core_count field in smbios_cpu_test (structure type 4) is correct.

Choose q35 as it allows to run with -smp > 255.

Signed-off-by: Julia Suvorova 
Message-Id: <20220731162141.178443-5-jus...@redhat.com>
---
 tests/qtest/bios-tables-test.c | 58 ++
 1 file changed, 45 insertions(+), 13 deletions(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index f5fffdc348..4a76befc93 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -92,6 +92,8 @@ typedef struct {
 SmbiosEntryPoint smbios_ep_table;
 uint16_t smbios_cpu_max_speed;
 uint16_t smbios_cpu_curr_speed;
+uint8_t smbios_core_count;
+uint16_t smbios_core_count2;
 uint8_t *required_struct_types;
 int required_struct_types_len;
 QTestState *qts;
@@ -631,29 +633,42 @@ static inline bool smbios_single_instance(uint8_t type)
 }
 }
 
-static bool smbios_cpu_test(test_data *data, uint32_t addr)
+static void smbios_cpu_test(test_data *data, uint32_t addr,
+SmbiosEntryPointType ep_type)
 {
-uint16_t expect_speed[2];
-uint16_t real;
+uint8_t core_count, expected_core_count = data->smbios_core_count;
+uint16_t speed, expected_speed[2];
+uint16_t core_count2, expected_core_count2 = data->smbios_core_count2;
 int offset[2];
 int i;
 
 /* Check CPU speed for backward compatibility */
 offset[0] = offsetof(struct smbios_type_4, max_speed);
 offset[1] = offsetof(struct smbios_type_4, current_speed);
-expect_speed[0] = data->smbios_cpu_max_speed ? : 2000;
-expect_speed[1] = data->smbios_cpu_curr_speed ? : 2000;
+expected_speed[0] = data->smbios_cpu_max_speed ? : 2000;
+expected_speed[1] = data->smbios_cpu_curr_speed ? : 2000;
 
 for (i = 0; i < 2; i++) {
-real = qtest_readw(data->qts, addr + offset[i]);
-if (real != expect_speed[i]) {
-fprintf(stderr, "Unexpected SMBIOS CPU speed: real %u expect %u\n",
-real, expect_speed[i]);
-return false;
-}
+speed = qtest_readw(data->qts, addr + offset[i]);
+g_assert_cmpuint(speed, ==, expected_speed[i]);
 }
 
-return true;
+core_count = qtest_readb(data->qts,
+addr + offsetof(struct smbios_type_4, core_count));
+
+if (expected_core_count) {
+g_assert_cmpuint(core_count, ==, expected_core_count);
+}
+
+if (ep_type == SMBIOS_ENTRY_POINT_TYPE_64) {
+core_count2 = qtest_readw(data->qts,
+  addr + offsetof(struct smbios_type_4, core_count2));
+
+/* Core Count has reached its limit, checking Core Count 2 */
+if (expected_core_count == 0xFF && expected_core_count2) {
+g_assert_cmpuint(core_count2, ==, expected_core_count2);
+}
+}
 }
 
 static void test_smbios_structs(test_data *data, SmbiosEntryPointType ep_type)
@@ -686,7 +701,7 @@ static void test_smbios_structs(test_data *data, 
SmbiosEntryPointType ep_type)
 set_bit(type, struct_bitmap);
 
 if (type == 4) {
-g_assert(smbios_cpu_test(data, addr));
+smbios_cpu_test(data, addr, ep_type);
 }
 
 /* seek to end of unformatted string area of this struct ("\0\0") */
@@ -908,6 +923,21 @@ static void test_acpi_q35_tcg(void)
 free_test_data();
 }
 
+static void test_acpi_q35_tcg_core_count2(void)
+{
+test_data data = {
+.machine = MACHINE_Q35,
+.variant = ".core-count2",
+.required_struct_types = base_required_struct_types,
+.required_struct_types_len = ARRAY_SIZE(base_required_struct_types),
+.smbios_core_count = 0xFF,
+.smbios_core_count2 = 275,
+};
+
+test_acpi_one("-machine smbios-entry-point-type=64 -smp 275", );
+free_test_data();
+}
+
 static void test_acpi_q35_tcg_bridge(void)
 {
 test_data data;
@@ -1859,6 +1889,8 @@ int main(int argc, char *argv[])
 qtest_add_func("acpi/q35/tpm12-tis",
test_acpi_q35_tcg_tpm12_tis);
 }
+qtest_add_func("acpi/q35/core-count2",
+   test_acpi_q35_tcg_core_count2);
 qtest_add_func("acpi/q35/bridge", test_acpi_q35_tcg_bridge);
 qtest_add_func("acpi/q35/multif-bridge",
test_acpi_q35_multif_bridge);
-- 
2.37.3




[PATCH v3 2/5] bios-tables-test: teach test to use smbios 3.0 tables

2022-10-11 Thread Julia Suvorova
Introduce the 64-bit entry point. Since we no longer have a total
number of structures, stop checking for the new ones at the EOF
structure (type 127).

Signed-off-by: Julia Suvorova 
Reviewed-by: Igor Mammedov 
Message-Id: <20220731162141.178443-3-jus...@redhat.com>
---
 tests/qtest/bios-tables-test.c | 100 +
 1 file changed, 76 insertions(+), 24 deletions(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 2ebeb530b2..f5fffdc348 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -88,8 +88,8 @@ typedef struct {
 uint64_t rsdp_addr;
 uint8_t rsdp_table[36 /* ACPI 2.0+ RSDP size */];
 GArray *tables;
-uint32_t smbios_ep_addr;
-struct smbios_21_entry_point smbios_ep_table;
+uint64_t smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE__MAX];
+SmbiosEntryPoint smbios_ep_table;
 uint16_t smbios_cpu_max_speed;
 uint16_t smbios_cpu_curr_speed;
 uint8_t *required_struct_types;
@@ -533,10 +533,9 @@ static void test_acpi_asl(test_data *data)
 free_test_data(_data);
 }
 
-static bool smbios_ep_table_ok(test_data *data)
+static bool smbios_ep2_table_ok(test_data *data, uint32_t addr)
 {
-struct smbios_21_entry_point *ep_table = >smbios_ep_table;
-uint32_t addr = data->smbios_ep_addr;
+struct smbios_21_entry_point *ep_table = >smbios_ep_table.ep21;
 
 qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table));
 if (memcmp(ep_table->anchor_string, "_SM_", 4)) {
@@ -559,13 +558,29 @@ static bool smbios_ep_table_ok(test_data *data)
 return true;
 }
 
-static void test_smbios_entry_point(test_data *data)
+static bool smbios_ep3_table_ok(test_data *data, uint64_t addr)
+{
+struct smbios_30_entry_point *ep_table = >smbios_ep_table.ep30;
+
+qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table));
+if (memcmp(ep_table->anchor_string, "_SM3_", 5)) {
+return false;
+}
+
+if (acpi_calc_checksum((uint8_t *)ep_table, sizeof *ep_table)) {
+return false;
+}
+
+return true;
+}
+
+static SmbiosEntryPointType test_smbios_entry_point(test_data *data)
 {
 uint32_t off;
 
 /* find smbios entry point structure */
 for (off = 0xf; off < 0x10; off += 0x10) {
-uint8_t sig[] = "_SM_";
+uint8_t sig[] = "_SM_", sig3[] = "_SM3_";
 int i;
 
 for (i = 0; i < sizeof sig - 1; ++i) {
@@ -574,14 +589,30 @@ static void test_smbios_entry_point(test_data *data)
 
 if (!memcmp(sig, "_SM_", sizeof sig)) {
 /* signature match, but is this a valid entry point? */
-data->smbios_ep_addr = off;
-if (smbios_ep_table_ok(data)) {
+if (smbios_ep2_table_ok(data, off)) {
+data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_32] = off;
+}
+}
+
+for (i = 0; i < sizeof sig3 - 1; ++i) {
+sig3[i] = qtest_readb(data->qts, off + i);
+}
+
+if (!memcmp(sig3, "_SM3_", sizeof sig3)) {
+if (smbios_ep3_table_ok(data, off)) {
+data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64] = off;
+/* found 64-bit entry point, no need to look for 32-bit one */
 break;
 }
 }
 }
 
-g_assert_cmphex(off, <, 0x10);
+/* found at least one entry point */
+g_assert_true(data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_32] ||
+  data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64]);
+
+return data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64] ?
+   SMBIOS_ENTRY_POINT_TYPE_64 : SMBIOS_ENTRY_POINT_TYPE_32;
 }
 
 static inline bool smbios_single_instance(uint8_t type)
@@ -625,16 +656,23 @@ static bool smbios_cpu_test(test_data *data, uint32_t 
addr)
 return true;
 }
 
-static void test_smbios_structs(test_data *data)
+static void test_smbios_structs(test_data *data, SmbiosEntryPointType ep_type)
 {
 DECLARE_BITMAP(struct_bitmap, SMBIOS_MAX_TYPE+1) = { 0 };
-struct smbios_21_entry_point *ep_table = >smbios_ep_table;
-uint32_t addr = le32_to_cpu(ep_table->structure_table_address);
-int i, len, max_len = 0;
+
+SmbiosEntryPoint *ep_table = >smbios_ep_table;
+int i = 0, len, max_len = 0;
 uint8_t type, prv, crt;
+uint64_t addr;
+
+if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32) {
+addr = le32_to_cpu(ep_table->ep21.structure_table_address);
+} else {
+addr = le64_to_cpu(ep_table->ep30.structure_table_address);
+}
 
 /* walk the smbios tables */
-for (i = 0; i < le16_to_cpu(ep_table->number_of_structures); i++) {
+do {
 
 /* grab type and formatted area length from struct header */
 type = qtest_readb(data->qts, addr);
@@ -660,19 +698,33 @@ static void test_smbios_structs(test_data *data)

[PATCH v3 5/5] tests/acpi: update tables for new core count test

2022-10-11 Thread Julia Suvorova
Changes in the tables (for 275 cores):
FACP:
+ Use APIC Cluster Model (V4) : 1

APIC:
+[02Ch 0044   1]Subtable Type : 00 [Processor Local APIC]
+[02Dh 0045   1]   Length : 08
+[02Eh 0046   1] Processor ID : 00
+[02Fh 0047   1]Local Apic ID : 00
+[030h 0048   4]Flags (decoded below) : 0001
+   Processor Enabled : 1
...
+
+[81Ch 2076   1]Subtable Type : 00 [Processor Local APIC]
+[81Dh 2077   1]   Length : 08
+[81Eh 2078   1] Processor ID : FE
+[81Fh 2079   1]Local Apic ID : FE
+[820h 2080   4]Flags (decoded below) : 0001
+   Processor Enabled : 1
+  Runtime Online Capable : 0
+
+[824h 2084   1]Subtable Type : 09 [Processor Local x2APIC]
+[825h 2085   1]   Length : 10
+[826h 2086   2] Reserved : 
+[828h 2088   4]  Processor x2Apic ID : 00FF
+[82Ch 2092   4]Flags (decoded below) : 0001
+   Processor Enabled : 1
+[830h 2096   4]Processor UID : 00FF
...

DSDT:
+Processor (C001, 0x01, 0x, 0x00)
+{
+Method (_STA, 0, Serialized)  // _STA: Status
+{
+Return (CSTA (One))
+}
+
+Name (_MAT, Buffer (0x08)  // _MAT: Multiple APIC Table Entry
+{
+ 0x00, 0x08, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00   // 

+})
+Method (_EJ0, 1, NotSerialized)  // _EJx: Eject Device, x=0-9
+{
+CEJ0 (One)
+}
+
+Method (_OST, 3, Serialized)  // _OST: OSPM Status Indication
+{
+COST (One, Arg0, Arg1, Arg2)
+}
+}
...
+Processor (C0FE, 0xFE, 0x, 0x00)
+{
+Method (_STA, 0, Serialized)  // _STA: Status
+{
+Return (CSTA (0xFE))
+}
+
+Name (_MAT, Buffer (0x08)  // _MAT: Multiple APIC Table Entry
+{
+ 0x00, 0x08, 0xFE, 0xFE, 0x01, 0x00, 0x00, 0x00   // 

+})
+Method (_EJ0, 1, NotSerialized)  // _EJx: Eject Device, x=0-9
+{
+CEJ0 (0xFE)
+}
+
+Method (_OST, 3, Serialized)  // _OST: OSPM Status Indication
+{
+COST (0xFE, Arg0, Arg1, Arg2)
+}
+}
+
+Device (C0FF)
+{
+Name (_HID, "ACPI0007" /* Processor Device */)  // _HID: 
Hardware ID
+Name (_UID, 0xFF)  // _UID: Unique ID
+Method (_STA, 0, Serialized)  // _STA: Status
+{
+Return (CSTA (0xFF))
+}
+
+Name (_MAT, Buffer (0x10)  // _MAT: Multiple APIC Table Entry
+{
+/*  */  0x09, 0x10, 0x00, 0x00, 0xFF, 0x00, 0x00, 
0x00,  // 
+/* 0008 */  0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 
  // 
+})
+Method (_EJ0, 1, NotSerialized)  // _EJx: Eject Device, x=0-9
+{
+CEJ0 (0xFF)
+}
+
+Method (_OST, 3, Serialized)  // _OST: OSPM Status Indication
+{
+COST (0xFF, Arg0, Arg1, Arg2)
+}
+}
+
...

Signed-off-by: Julia Suvorova 
Message-Id: <20220731162141.178443-6-jus...@redhat.com>
---
 tests/data/acpi/q35/APIC.core-count2| Bin 0 -> 2478 bytes
 tests/data/acpi/q35/DSDT.core-count2| Bin 0 -> 32414 bytes
 tests/data/acpi/q35/FACP.core-count2| Bin 0 -> 244 bytes
 tests/qtest/bios-tables-test-allowed-diff.h |   3 ---
 4 files changed, 3 deletions(-)

diff --git a/tests/data/acpi/q35/APIC.core-count2 
b/tests/data/acpi/q35/APIC.core-count2
index 
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a255082ef5bc39f0d92d3e372b91f09dd6d0d9a1
 100644
GIT binary patch
literal 2478
zcmXZeWl$AS7=Youz=a#M-K}6ZwgLuNAQ;$~*xjvQcY@uCVs{~Sf`WpLVt2Rbe!ORA
z_B`J^b9R56*=M2p(=#;b`y@>U1KQZ2
ztu5Nwq0xx;_UPb%CKH;?XtAKxijI!xf-7uzGc@Q3Gq%
z#9Fnmc5SRv2fe+~#|M4+PE2*{()H?L{rcFT0s8r?h>aRyuWjcwXs+qT%Q9ky?e9Xepgju;w>ojPIX)|3
zcI}GYx?%V37#4;-dSK6<*sB-z?u~u=VBfyjuOIgBj{^qaz=1eu5Dp%ULx$kcp*U<9
z4j+yqM*9*twh;MlP^ZXAvuj}s=~#ECd*5{8FkL5Yu4b}wYY8_u3wKEHsHpMxM>q^-i%we;MT3UZ5u{MiV+Y2>;Le@6
zYZva`jeGXs-o3bQAMW3e2M*xDgLvo=9zKjmj^NRwcZnq0$#t4H*R2JA|@r_&6{}Z
z7A7ZSN($b-jd$+g-Me`29^Su?4<6vdhnSj*j~?OU$C#FePoCh@r}*p{K7WocUf|1@
z`05qDevNP5;M=$O?j62=j~_nZ$B+2w6Mp`TU%ueiulVg7e*ca?e`0E$`{*8bB
z;NQQPo-UeQHSM3S%%ZeJ#vXl>ElNA8

[PATCH v3 3/5] tests/acpi: allow changes for core_count2 test

2022-10-11 Thread Julia Suvorova
Signed-off-by: Julia Suvorova 
Message-Id: <20220731162141.178443-4-jus...@redhat.com>
---
 tests/data/acpi/q35/APIC.core-count2| 0
 tests/data/acpi/q35/DSDT.core-count2| 0
 tests/data/acpi/q35/FACP.core-count2| 0
 tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
 4 files changed, 3 insertions(+)
 create mode 100644 tests/data/acpi/q35/APIC.core-count2
 create mode 100644 tests/data/acpi/q35/DSDT.core-count2
 create mode 100644 tests/data/acpi/q35/FACP.core-count2

diff --git a/tests/data/acpi/q35/APIC.core-count2 
b/tests/data/acpi/q35/APIC.core-count2
new file mode 100644
index 00..e69de29bb2
diff --git a/tests/data/acpi/q35/DSDT.core-count2 
b/tests/data/acpi/q35/DSDT.core-count2
new file mode 100644
index 00..e69de29bb2
diff --git a/tests/data/acpi/q35/FACP.core-count2 
b/tests/data/acpi/q35/FACP.core-count2
new file mode 100644
index 00..e69de29bb2
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..e81dc67a2e 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,4 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/APIC.core-count2",
+"tests/data/acpi/q35/DSDT.core-count2",
+"tests/data/acpi/q35/FACP.core-count2",
-- 
2.37.3




[PATCH v3 1/5] hw/smbios: add core_count2 to smbios table type 4

2022-10-11 Thread Julia Suvorova
In order to use the increased number of cpus, we need to bring smbios
tables in line with the SMBIOS 3.0 specification. This allows us to
introduce core_count2 which acts as a duplicate of core_count if we have
fewer cores than 256, and contains the actual core number per socket if
we have more.

core_enabled2 and thread_count2 fields work the same way.

Signed-off-by: Julia Suvorova 
Reviewed-by: Igor Mammedov 
Message-Id: <20220731162141.178443-2-jus...@redhat.com>
---
 hw/smbios/smbios.c   | 19 ---
 hw/smbios/smbios_build.h |  9 +++--
 include/hw/firmware/smbios.h | 12 
 3 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 4c9f664830..591481d449 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -681,8 +681,14 @@ static void smbios_build_type_3_table(void)
 static void smbios_build_type_4_table(MachineState *ms, unsigned instance)
 {
 char sock_str[128];
+size_t tbl_len = SMBIOS_TYPE_4_LEN_V28;
 
-SMBIOS_BUILD_TABLE_PRE(4, T4_BASE + instance, true); /* required */
+if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_64) {
+tbl_len = SMBIOS_TYPE_4_LEN_V30;
+}
+
+SMBIOS_BUILD_TABLE_PRE_SIZE(4, T4_BASE + instance,
+true, tbl_len); /* required */
 
 snprintf(sock_str, sizeof(sock_str), "%s%2x", type4.sock_pfx, instance);
 SMBIOS_TABLE_SET_STR(4, socket_designation_str, sock_str);
@@ -709,8 +715,15 @@ static void smbios_build_type_4_table(MachineState *ms, 
unsigned instance)
 SMBIOS_TABLE_SET_STR(4, serial_number_str, type4.serial);
 SMBIOS_TABLE_SET_STR(4, asset_tag_number_str, type4.asset);
 SMBIOS_TABLE_SET_STR(4, part_number_str, type4.part);
-t->core_count = t->core_enabled = ms->smp.cores;
-t->thread_count = ms->smp.threads;
+
+t->core_count = (ms->smp.cores > 255) ? 0xFF : ms->smp.cores;
+t->core_enabled = t->core_count;
+
+t->core_count2 = t->core_enabled2 = cpu_to_le16(ms->smp.cores);
+
+t->thread_count = (ms->smp.threads > 255) ? 0xFF : ms->smp.threads;
+t->thread_count2 = cpu_to_le16(ms->smp.threads);
+
 t->processor_characteristics = cpu_to_le16(0x02); /* Unknown */
 t->processor_family2 = cpu_to_le16(0x01); /* Other */
 
diff --git a/hw/smbios/smbios_build.h b/hw/smbios/smbios_build.h
index 56b5a1e3f3..351660024e 100644
--- a/hw/smbios/smbios_build.h
+++ b/hw/smbios/smbios_build.h
@@ -27,6 +27,11 @@ extern unsigned smbios_table_max;
 extern unsigned smbios_table_cnt;
 
 #define SMBIOS_BUILD_TABLE_PRE(tbl_type, tbl_handle, tbl_required)\
+SMBIOS_BUILD_TABLE_PRE_SIZE(tbl_type, tbl_handle, tbl_required,   \
+sizeof(struct smbios_type_##tbl_type))\
+
+#define SMBIOS_BUILD_TABLE_PRE_SIZE(tbl_type, tbl_handle, \
+tbl_required, tbl_len)\
 struct smbios_type_##tbl_type *t; \
 size_t t_off; /* table offset into smbios_tables */   \
 int str_index = 0;\
@@ -39,12 +44,12 @@ extern unsigned smbios_table_cnt;
 /* use offset of table t within smbios_tables */  \
 /* (pointer must be updated after each realloc) */\
 t_off = smbios_tables_len;\
-smbios_tables_len += sizeof(*t);  \
+smbios_tables_len += tbl_len; \
 smbios_tables = g_realloc(smbios_tables, smbios_tables_len);  \
 t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off); \
   \
 t->header.type = tbl_type;\
-t->header.length = sizeof(*t);\
+t->header.length = tbl_len;   \
 t->header.handle = cpu_to_le16(tbl_handle);   \
 } while (0)
 
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 4b7ad77a44..9615446f5d 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -18,6 +18,8 @@
 
 
 #define SMBIOS_MAX_TYPE 127
+#define offsetofend(TYPE, MEMBER) \
+   (offsetof(TYPE, MEMBER) + sizeof_field(TYPE, MEMBER))
 
 /* memory area description, used by type 19 table */
 struct smbios_phys_mem_area {
@@ -187,8 +189,18 @@ struct smbios_type_4 {
 uint8_t thread_count;
 uint16_t processor_characteristics;
 uint16_t processor_family2;
+/* SMBIOS spec 3.0.0, Table 21 */
+uint16_t core_count2;
+uint16_t core_enabled2;
+uint16_t thread_count2;
 } QEMU_PACKED;
 
+type

[PATCH v2 3/5] tests/acpi: allow changes for core_count2 test

2022-07-31 Thread Julia Suvorova
Signed-off-by: Julia Suvorova 
---
 tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
 tests/data/acpi/q35/APIC.core-count2| 0
 tests/data/acpi/q35/DSDT.core-count2| 0
 tests/data/acpi/q35/FACP.core-count2| 0
 4 files changed, 3 insertions(+)
 create mode 100644 tests/data/acpi/q35/APIC.core-count2
 create mode 100644 tests/data/acpi/q35/DSDT.core-count2
 create mode 100644 tests/data/acpi/q35/FACP.core-count2

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..e81dc67a2e 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,4 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/APIC.core-count2",
+"tests/data/acpi/q35/DSDT.core-count2",
+"tests/data/acpi/q35/FACP.core-count2",
diff --git a/tests/data/acpi/q35/APIC.core-count2 
b/tests/data/acpi/q35/APIC.core-count2
new file mode 100644
index 00..e69de29bb2
diff --git a/tests/data/acpi/q35/DSDT.core-count2 
b/tests/data/acpi/q35/DSDT.core-count2
new file mode 100644
index 00..e69de29bb2
diff --git a/tests/data/acpi/q35/FACP.core-count2 
b/tests/data/acpi/q35/FACP.core-count2
new file mode 100644
index 00..e69de29bb2
-- 
2.35.3




[PATCH v2 2/5] bios-tables-test: teach test to use smbios 3.0 tables

2022-07-31 Thread Julia Suvorova
Introduce the 64-bit entry point. Since we no longer have a total
number of structures, stop checking for the new ones at the EOF
structure (type 127).

Signed-off-by: Julia Suvorova 
---
 tests/qtest/bios-tables-test.c | 95 +-
 1 file changed, 71 insertions(+), 24 deletions(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 359916c228..e352d5249f 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -88,8 +88,8 @@ typedef struct {
 uint64_t rsdp_addr;
 uint8_t rsdp_table[36 /* ACPI 2.0+ RSDP size */];
 GArray *tables;
-uint32_t smbios_ep_addr;
-struct smbios_21_entry_point smbios_ep_table;
+uint64_t smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE__MAX];
+SmbiosEntryPoint smbios_ep_table;
 uint16_t smbios_cpu_max_speed;
 uint16_t smbios_cpu_curr_speed;
 uint8_t *required_struct_types;
@@ -533,10 +533,9 @@ static void test_acpi_asl(test_data *data)
 free_test_data(_data);
 }
 
-static bool smbios_ep_table_ok(test_data *data)
+static bool smbios_ep2_table_ok(test_data *data, uint32_t addr)
 {
-struct smbios_21_entry_point *ep_table = >smbios_ep_table;
-uint32_t addr = data->smbios_ep_addr;
+struct smbios_21_entry_point *ep_table = >smbios_ep_table.ep21;
 
 qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table));
 if (memcmp(ep_table->anchor_string, "_SM_", 4)) {
@@ -559,13 +558,29 @@ static bool smbios_ep_table_ok(test_data *data)
 return true;
 }
 
-static void test_smbios_entry_point(test_data *data)
+static bool smbios_ep3_table_ok(test_data *data, uint64_t addr)
+{
+struct smbios_30_entry_point *ep_table = >smbios_ep_table.ep30;
+
+qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table));
+if (memcmp(ep_table->anchor_string, "_SM3_", 5)) {
+return false;
+}
+
+if (acpi_calc_checksum((uint8_t *)ep_table, sizeof *ep_table)) {
+return false;
+}
+
+return true;
+}
+
+static SmbiosEntryPointType test_smbios_entry_point(test_data *data)
 {
 uint32_t off;
 
 /* find smbios entry point structure */
 for (off = 0xf; off < 0x10; off += 0x10) {
-uint8_t sig[] = "_SM_";
+uint8_t sig[] = "_SM_", sig3[] = "_SM3_";
 int i;
 
 for (i = 0; i < sizeof sig - 1; ++i) {
@@ -574,14 +589,30 @@ static void test_smbios_entry_point(test_data *data)
 
 if (!memcmp(sig, "_SM_", sizeof sig)) {
 /* signature match, but is this a valid entry point? */
-data->smbios_ep_addr = off;
-if (smbios_ep_table_ok(data)) {
+if (smbios_ep2_table_ok(data, off)) {
+data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_32] = off;
+}
+}
+
+for (i = 0; i < sizeof sig3 - 1; ++i) {
+sig3[i] = qtest_readb(data->qts, off + i);
+}
+
+if (!memcmp(sig3, "_SM3_", sizeof sig3)) {
+if (smbios_ep3_table_ok(data, off)) {
+data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64] = off;
+/* found 64-bit entry point, no need to look for 32-bit one */
 break;
 }
 }
 }
 
-g_assert_cmphex(off, <, 0x10);
+/* found at least one entry point */
+g_assert_true(data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_32] ||
+  data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64]);
+
+return data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64] ?
+   SMBIOS_ENTRY_POINT_TYPE_64 : SMBIOS_ENTRY_POINT_TYPE_32;
 }
 
 static inline bool smbios_single_instance(uint8_t type)
@@ -625,16 +656,23 @@ static bool smbios_cpu_test(test_data *data, uint32_t 
addr)
 return true;
 }
 
-static void test_smbios_structs(test_data *data)
+static void test_smbios_structs(test_data *data, SmbiosEntryPointType ep_type)
 {
 DECLARE_BITMAP(struct_bitmap, SMBIOS_MAX_TYPE+1) = { 0 };
-struct smbios_21_entry_point *ep_table = >smbios_ep_table;
-uint32_t addr = le32_to_cpu(ep_table->structure_table_address);
-int i, len, max_len = 0;
+
+SmbiosEntryPoint *ep_table = >smbios_ep_table;
+int i = 0, len, max_len = 0;
 uint8_t type, prv, crt;
+uint64_t addr;
+
+if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32) {
+addr = le32_to_cpu(ep_table->ep21.structure_table_address);
+} else {
+addr = le64_to_cpu(ep_table->ep30.structure_table_address);
+}
 
 /* walk the smbios tables */
-for (i = 0; i < le16_to_cpu(ep_table->number_of_structures); i++) {
+do {
 
 /* grab type and formatted area length from struct header */
 type = qtest_readb(data->qts, addr);
@@ -660,19 +698,28 @@ static void test_smbios_structs(test_data *data)
 }
 
 /* keep track of max. struct size */
-if (max_len < len

[PATCH v2 4/5] bios-tables-test: add test for number of cores > 255

2022-07-31 Thread Julia Suvorova
The new test is run with a large number of cpus and checks if the
core_count field in smbios_cpu_test (structure type 4) is correct.

Choose q35 as it allows to run with -smp > 255.

Signed-off-by: Julia Suvorova 
---
 tests/qtest/bios-tables-test.c | 53 +-
 1 file changed, 40 insertions(+), 13 deletions(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index e352d5249f..cebfa430ac 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -92,6 +92,8 @@ typedef struct {
 SmbiosEntryPoint smbios_ep_table;
 uint16_t smbios_cpu_max_speed;
 uint16_t smbios_cpu_curr_speed;
+uint8_t smbios_core_count;
+uint16_t smbios_core_count2;
 uint8_t *required_struct_types;
 int required_struct_types_len;
 QTestState *qts;
@@ -631,29 +633,38 @@ static inline bool smbios_single_instance(uint8_t type)
 }
 }
 
-static bool smbios_cpu_test(test_data *data, uint32_t addr)
+static void smbios_cpu_test(test_data *data, uint32_t addr)
 {
-uint16_t expect_speed[2];
-uint16_t real;
+uint8_t core_count, expected_core_count = data->smbios_core_count;
+uint16_t speed, core_count2, expected_core_count2 = 
data->smbios_core_count2;
+uint16_t expected_speed[2];
 int offset[2];
 int i;
 
 /* Check CPU speed for backward compatibility */
 offset[0] = offsetof(struct smbios_type_4, max_speed);
 offset[1] = offsetof(struct smbios_type_4, current_speed);
-expect_speed[0] = data->smbios_cpu_max_speed ? : 2000;
-expect_speed[1] = data->smbios_cpu_curr_speed ? : 2000;
+expected_speed[0] = data->smbios_cpu_max_speed ? : 2000;
+expected_speed[1] = data->smbios_cpu_curr_speed ? : 2000;
 
 for (i = 0; i < 2; i++) {
-real = qtest_readw(data->qts, addr + offset[i]);
-if (real != expect_speed[i]) {
-fprintf(stderr, "Unexpected SMBIOS CPU speed: real %u expect %u\n",
-real, expect_speed[i]);
-return false;
-}
+speed = qtest_readw(data->qts, addr + offset[i]);
+g_assert_cmpuint(speed, ==, expected_speed[i]);
 }
 
-return true;
+core_count = qtest_readb(data->qts,
+ addr + offsetof(struct smbios_type_4, 
core_count));
+core_count2 = qtest_readw(data->qts,
+  addr + offsetof(struct smbios_type_4, 
core_count2));
+
+if (expected_core_count) {
+g_assert_cmpuint(core_count, ==, expected_core_count);
+}
+
+/* Core Count has reached its limit, checking Core Count 2 */
+if (expected_core_count == 0xFF && expected_core_count2) {
+g_assert_cmpuint(core_count2, ==, expected_core_count2);
+}
 }
 
 static void test_smbios_structs(test_data *data, SmbiosEntryPointType ep_type)
@@ -686,7 +697,7 @@ static void test_smbios_structs(test_data *data, 
SmbiosEntryPointType ep_type)
 set_bit(type, struct_bitmap);
 
 if (type == 4) {
-g_assert(smbios_cpu_test(data, addr));
+smbios_cpu_test(data, addr);
 }
 
 /* seek to end of unformatted string area of this struct ("\0\0") */
@@ -903,6 +914,21 @@ static void test_acpi_q35_tcg(void)
 free_test_data();
 }
 
+static void test_acpi_q35_tcg_core_count2(void)
+{
+test_data data = {
+.machine = MACHINE_Q35,
+.variant = ".core-count2",
+.required_struct_types = base_required_struct_types,
+.required_struct_types_len = ARRAY_SIZE(base_required_struct_types),
+.smbios_core_count = 0xFF,
+.smbios_core_count2 = 275,
+};
+
+test_acpi_one("-machine smbios-entry-point-type=64 -smp 275", );
+free_test_data();
+}
+
 static void test_acpi_q35_tcg_bridge(void)
 {
 test_data data;
@@ -1822,6 +1848,7 @@ int main(int argc, char *argv[])
 qtest_add_func("acpi/piix4/pci-hotplug/off",
test_acpi_piix4_no_acpi_pci_hotplug);
 qtest_add_func("acpi/q35", test_acpi_q35_tcg);
+qtest_add_func("acpi/q35/core-count2", test_acpi_q35_tcg_core_count2);
 qtest_add_func("acpi/q35/bridge", test_acpi_q35_tcg_bridge);
 qtest_add_func("acpi/q35/multif-bridge", test_acpi_q35_multif_bridge);
 qtest_add_func("acpi/q35/mmio64", test_acpi_q35_tcg_mmio64);
-- 
2.35.3




[PATCH v2 5/5] tests/acpi: update tables for new core count test

2022-07-31 Thread Julia Suvorova
Changes in the tables (for 275 cores):
FACP:
+ Use APIC Cluster Model (V4) : 1

APIC:
+[02Ch 0044   1]Subtable Type : 00 [Processor Local APIC]
+[02Dh 0045   1]   Length : 08
+[02Eh 0046   1] Processor ID : 00
+[02Fh 0047   1]Local Apic ID : 00
+[030h 0048   4]Flags (decoded below) : 0001
+   Processor Enabled : 1
...
+
+[81Ch 2076   1]Subtable Type : 00 [Processor Local APIC]
+[81Dh 2077   1]   Length : 08
+[81Eh 2078   1] Processor ID : FE
+[81Fh 2079   1]Local Apic ID : FE
+[820h 2080   4]Flags (decoded below) : 0001
+   Processor Enabled : 1
+  Runtime Online Capable : 0
+
+[824h 2084   1]Subtable Type : 09 [Processor Local x2APIC]
+[825h 2085   1]   Length : 10
+[826h 2086   2] Reserved : 
+[828h 2088   4]  Processor x2Apic ID : 00FF
+[82Ch 2092   4]Flags (decoded below) : 0001
+   Processor Enabled : 1
+[830h 2096   4]Processor UID : 00FF
...

DSDT:
+Processor (C001, 0x01, 0x, 0x00)
+{
+Method (_STA, 0, Serialized)  // _STA: Status
+{
+Return (CSTA (One))
+}
+
+Name (_MAT, Buffer (0x08)  // _MAT: Multiple APIC Table Entry
+{
+ 0x00, 0x08, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00   // 

+})
+Method (_EJ0, 1, NotSerialized)  // _EJx: Eject Device, x=0-9
+{
+CEJ0 (One)
+}
+
+Method (_OST, 3, Serialized)  // _OST: OSPM Status Indication
+{
+COST (One, Arg0, Arg1, Arg2)
+}
+}
...
+Processor (C0FE, 0xFE, 0x, 0x00)
+{
+Method (_STA, 0, Serialized)  // _STA: Status
+{
+Return (CSTA (0xFE))
+}
+
+Name (_MAT, Buffer (0x08)  // _MAT: Multiple APIC Table Entry
+{
+ 0x00, 0x08, 0xFE, 0xFE, 0x01, 0x00, 0x00, 0x00   // 

+})
+Method (_EJ0, 1, NotSerialized)  // _EJx: Eject Device, x=0-9
+{
+CEJ0 (0xFE)
+}
+
+Method (_OST, 3, Serialized)  // _OST: OSPM Status Indication
+{
+COST (0xFE, Arg0, Arg1, Arg2)
+}
+}
+
+Device (C0FF)
+{
+Name (_HID, "ACPI0007" /* Processor Device */)  // _HID: 
Hardware ID
+Name (_UID, 0xFF)  // _UID: Unique ID
+Method (_STA, 0, Serialized)  // _STA: Status
+{
+Return (CSTA (0xFF))
+}
+
+Name (_MAT, Buffer (0x10)  // _MAT: Multiple APIC Table Entry
+{
+/*  */  0x09, 0x10, 0x00, 0x00, 0xFF, 0x00, 0x00, 
0x00,  // 
+/* 0008 */  0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 
  // 
+})
+Method (_EJ0, 1, NotSerialized)  // _EJx: Eject Device, x=0-9
+{
+CEJ0 (0xFF)
+}
+
+Method (_OST, 3, Serialized)  // _OST: OSPM Status Indication
+{
+COST (0xFF, Arg0, Arg1, Arg2)
+}
+}
+
...

Signed-off-by: Julia Suvorova 
---
 tests/qtest/bios-tables-test-allowed-diff.h |   3 ---
 tests/data/acpi/q35/APIC.core-count2| Bin 0 -> 2478 bytes
 tests/data/acpi/q35/DSDT.core-count2| Bin 0 -> 32414 bytes
 tests/data/acpi/q35/FACP.core-count2| Bin 0 -> 244 bytes
 4 files changed, 3 deletions(-)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index e81dc67a2e..dfb8523c8b 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,4 +1 @@
 /* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/q35/APIC.core-count2",
-"tests/data/acpi/q35/DSDT.core-count2",
-"tests/data/acpi/q35/FACP.core-count2",
diff --git a/tests/data/acpi/q35/APIC.core-count2 
b/tests/data/acpi/q35/APIC.core-count2
index 
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a255082ef5bc39f0d92d3e372b91f09dd6d0d9a1
 100644
GIT binary patch
literal 2478
zcmXZeWl$AS7=Youz=a#M-K}6ZwgLuNAQ;$~*xjvQcY@uCVs{~Sf`WpLVt2Rbe!ORA
z_B`J^b9R56*=M2p(=#;b`y@>U1KQZ2
ztu5Nwq0xx;_UPb%CKH;?XtAKxijI!xf-7uzGc@Q3Gq%
z#9Fnmc5SRv2fe+~#|M4+PE2*{()H?L{rcFT0s8r?h>aRyuWjcwXs+qT%Q9ky?e9Xepgju;w>ojPIX)|3
zcI}GYx?

[PATCH v2 0/5] hw/smbios: add core_count2 to smbios table type 4

2022-07-31 Thread Julia Suvorova
The SMBIOS 3.0 specification provides the ability to reflect over
255 cores. The 64-bit entry point has been used for a while, but
structure type 4 has not been updated before, so the dmidecode output
looked like this (-smp 280):

Handle 0x0400, DMI type 4, 42 bytes
Processor Information
...
Core Count: 24
Core Enabled: 24
Thread Count: 1
...

Big update in the bios-tables-test as it couldn't work with SMBIOS 3.0.

v2:
* generate tables type 4 of different sizes based on the
  selected smbios version
* use SmbiosEntryPoint* types instead of creating new constants
* refactor smbios_cpu_test [Igor, Ani]
* clarify signature check [Igor]
* add comments with specifications and clarification of the structure loop 
[Ani]

Julia Suvorova (5):
  hw/smbios: add core_count2 to smbios table type 4
  bios-tables-test: teach test to use smbios 3.0 tables
  tests/acpi: allow changes for core_count2 test
  bios-tables-test: add test for number of cores > 255
  tests/acpi: update tables for new core count test

 hw/smbios/smbios_build.h |   9 +-
 include/hw/firmware/smbios.h |  11 ++
 hw/smbios/smbios.c   |  18 +++-
 tests/qtest/bios-tables-test.c   | 148 ---
 tests/data/acpi/q35/APIC.core-count2 | Bin 0 -> 2478 bytes
 tests/data/acpi/q35/DSDT.core-count2 | Bin 0 -> 32414 bytes
 tests/data/acpi/q35/FACP.core-count2 | Bin 0 -> 244 bytes
 7 files changed, 144 insertions(+), 42 deletions(-)
 create mode 100644 tests/data/acpi/q35/APIC.core-count2
 create mode 100644 tests/data/acpi/q35/DSDT.core-count2
 create mode 100644 tests/data/acpi/q35/FACP.core-count2

-- 
2.35.3




[PATCH v2 1/5] hw/smbios: add core_count2 to smbios table type 4

2022-07-31 Thread Julia Suvorova
In order to use the increased number of cpus, we need to bring smbios
tables in line with the SMBIOS 3.0 specification. This allows us to
introduce core_count2 which acts as a duplicate of core_count if we have
fewer cores than 256, and contains the actual core number per socket if
we have more.

core_enabled2 and thread_count2 fields work the same way.

Signed-off-by: Julia Suvorova 
---
 hw/smbios/smbios_build.h |  9 +++--
 include/hw/firmware/smbios.h | 11 +++
 hw/smbios/smbios.c   | 18 +++---
 3 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/hw/smbios/smbios_build.h b/hw/smbios/smbios_build.h
index 56b5a1e3f3..351660024e 100644
--- a/hw/smbios/smbios_build.h
+++ b/hw/smbios/smbios_build.h
@@ -27,6 +27,11 @@ extern unsigned smbios_table_max;
 extern unsigned smbios_table_cnt;
 
 #define SMBIOS_BUILD_TABLE_PRE(tbl_type, tbl_handle, tbl_required)\
+SMBIOS_BUILD_TABLE_PRE_SIZE(tbl_type, tbl_handle, tbl_required,   \
+sizeof(struct smbios_type_##tbl_type))\
+
+#define SMBIOS_BUILD_TABLE_PRE_SIZE(tbl_type, tbl_handle, \
+tbl_required, tbl_len)\
 struct smbios_type_##tbl_type *t; \
 size_t t_off; /* table offset into smbios_tables */   \
 int str_index = 0;\
@@ -39,12 +44,12 @@ extern unsigned smbios_table_cnt;
 /* use offset of table t within smbios_tables */  \
 /* (pointer must be updated after each realloc) */\
 t_off = smbios_tables_len;\
-smbios_tables_len += sizeof(*t);  \
+smbios_tables_len += tbl_len; \
 smbios_tables = g_realloc(smbios_tables, smbios_tables_len);  \
 t = (struct smbios_type_##tbl_type *)(smbios_tables + t_off); \
   \
 t->header.type = tbl_type;\
-t->header.length = sizeof(*t);\
+t->header.length = tbl_len;   \
 t->header.handle = cpu_to_le16(tbl_handle);   \
 } while (0)
 
diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 4b7ad77a44..56f7bf0fea 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -18,6 +18,8 @@
 
 
 #define SMBIOS_MAX_TYPE 127
+#define offsetofend(TYPE, MEMBER) \
+   (offsetof(TYPE, MEMBER) + sizeof_field(TYPE, MEMBER))
 
 /* memory area description, used by type 19 table */
 struct smbios_phys_mem_area {
@@ -187,8 +189,17 @@ struct smbios_type_4 {
 uint8_t thread_count;
 uint16_t processor_characteristics;
 uint16_t processor_family2;
+/* SMBIOS spec 3.0.0, Table 21 */
+uint16_t core_count2;
+uint16_t core_enabled2;
+uint16_t thread_count2;
 } QEMU_PACKED;
 
+typedef enum smbios_type_4_len_ver {
+SMBIOS_TYPE_4_LEN_V28 = offsetofend(struct smbios_type_4, 
processor_family2),
+SMBIOS_TYPE_4_LEN_V30 = offsetofend(struct smbios_type_4, thread_count2),
+} smbios_type_4_len_ver;
+
 /* SMBIOS type 11 - OEM strings */
 struct smbios_type_11 {
 struct smbios_structure_header header;
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 60349ee402..657093e5f6 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -681,8 +681,13 @@ static void smbios_build_type_3_table(void)
 static void smbios_build_type_4_table(MachineState *ms, unsigned instance)
 {
 char sock_str[128];
+size_t tbl_len = SMBIOS_TYPE_4_LEN_V28;
 
-SMBIOS_BUILD_TABLE_PRE(4, T4_BASE + instance, true); /* required */
+if (smbios_ep_type == SMBIOS_ENTRY_POINT_TYPE_64) {
+tbl_len = SMBIOS_TYPE_4_LEN_V30;
+}
+
+SMBIOS_BUILD_TABLE_PRE_SIZE(4, T4_BASE + instance, true, tbl_len); /* 
required */
 
 snprintf(sock_str, sizeof(sock_str), "%s%2x", type4.sock_pfx, instance);
 SMBIOS_TABLE_SET_STR(4, socket_designation_str, sock_str);
@@ -709,8 +714,15 @@ static void smbios_build_type_4_table(MachineState *ms, 
unsigned instance)
 SMBIOS_TABLE_SET_STR(4, serial_number_str, type4.serial);
 SMBIOS_TABLE_SET_STR(4, asset_tag_number_str, type4.asset);
 SMBIOS_TABLE_SET_STR(4, part_number_str, type4.part);
-t->core_count = t->core_enabled = ms->smp.cores;
-t->thread_count = ms->smp.threads;
+
+t->core_count = (ms->smp.cores > 255) ? 0xFF : ms->smp.cores;
+t->core_enabled = t->core_count;
+
+t->core_count2 = t->core_enabled2 = cpu_to_le16(ms->smp.cores);
+
+t->thread_count = (ms->smp.threads > 255) ? 0xFF : ms->smp.threads;
+t->thread_count2 = 

Re: [PATCH] hw/mem/nvdimm: fix error message for 'unarmed' flag

2022-06-14 Thread Julia Suvorova
On Tue, Jun 14, 2022 at 11:50 AM David Hildenbrand  wrote:
>
> On 14.06.22 10:54, Igor Mammedov wrote:
> > On Mon, 13 Jun 2022 16:09:53 +0100
> > Stefan Hajnoczi  wrote:
> >
> >> On Mon, Jun 13, 2022 at 05:01:10PM +0200, Julia Suvorova wrote:
> >>> On Tue, May 31, 2022 at 5:32 PM Stefan Hajnoczi  
> >>> wrote:
> >>>>
> >>>> On Tue, May 31, 2022 at 04:51:47PM +0200, Julia Suvorova wrote:
> >>>>> In the ACPI specification [1], the 'unarmed' bit is set when a device
> >>>>> cannot accept a persistent write. This means that when a memdev is
> >>>>> read-only, the 'unarmed' flag must be turned on. The logic is correct,
> >>>>> just changing the error message.
> >>>>>
> >>>>> [1] ACPI NFIT NVDIMM Region Mapping Structure "NVDIMM State Flags" Bit 3
> >>>>>
> >>>>> Signed-off-by: Julia Suvorova 
> >>>>> ---
> >>>>>  hw/mem/nvdimm.c | 2 +-
> >>>>>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>>>
> >>>> Reviewed-by: Stefan Hajnoczi 
> >>>
> >>> It seems like Xiao is not active, whose tree should this patch go to?
>
> Is that a temporary or a permanent thing? Do we know?

No idea. But his last signed-off was three years ago.

> >
> > Perhaps David can add himself as maintainer (i.e. put it
> > under memory mantanership umbrella) and merge it
>
> Maybe it makes sense to combine NVDIMM with pc-dimm.c and
> memory-device.c into a "MEMORY DEVICE" section. Then, remove "hw/mem/*"
> from "ACPI/SMBIOS".
>
> cxl_type3.c, npcm7xx_mc.c and sparse-mem.c in /hw/mem/ are a bit
> different. We could add cxl_type3.c to "Compute Express Link".
> npcm7xx_mc.c and sparse-mem.c should be already covered.
>
> --
> Thanks,
>
> David / dhildenb
>




Re: [PATCH] hw/mem/nvdimm: fix error message for 'unarmed' flag

2022-06-13 Thread Julia Suvorova
On Tue, May 31, 2022 at 5:32 PM Stefan Hajnoczi  wrote:
>
> On Tue, May 31, 2022 at 04:51:47PM +0200, Julia Suvorova wrote:
> > In the ACPI specification [1], the 'unarmed' bit is set when a device
> > cannot accept a persistent write. This means that when a memdev is
> > read-only, the 'unarmed' flag must be turned on. The logic is correct,
> > just changing the error message.
> >
> > [1] ACPI NFIT NVDIMM Region Mapping Structure "NVDIMM State Flags" Bit 3
> >
> > Signed-off-by: Julia Suvorova 
> > ---
> >  hw/mem/nvdimm.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
>
> Reviewed-by: Stefan Hajnoczi 

It seems like Xiao is not active, whose tree should this patch go to?

Best regards, Julia Suvorova.




Re: [PATCH 4/5] bios-tables-test: add test for number of cores > 255

2022-06-06 Thread Julia Suvorova
On Thu, Jun 2, 2022 at 5:20 PM Igor Mammedov  wrote:
>
> On Fri, 27 May 2022 18:56:50 +0200
> Julia Suvorova  wrote:
>
> > The new test is run with a large number of cpus and checks if the
> > core_count field in smbios_cpu_test (structure type 4) is correct.
> >
> > Choose q35 as it allows to run with -smp > 255.
> >
> > Signed-off-by: Julia Suvorova 
> > ---
> >  tests/qtest/bios-tables-test.c | 35 +-
> >  1 file changed, 34 insertions(+), 1 deletion(-)
> >
> > diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
> > index 0ba9d749a5..f2464adaa0 100644
> > --- a/tests/qtest/bios-tables-test.c
> > +++ b/tests/qtest/bios-tables-test.c
> > @@ -100,6 +100,8 @@ typedef struct {
> >  smbios_entry_point smbios_ep_table;
> >  uint16_t smbios_cpu_max_speed;
> >  uint16_t smbios_cpu_curr_speed;
> > +uint8_t smbios_core_count;
> > +uint16_t smbios_core_count2;
> >  uint8_t *required_struct_types;
> >  int required_struct_types_len;
> >  QTestState *qts;
> > @@ -640,8 +642,9 @@ static inline bool smbios_single_instance(uint8_t type)
> >
> >  static bool smbios_cpu_test(test_data *data, uint32_t addr)
> >  {
> > +uint8_t real_cc, expect_cc = data->smbios_core_count;
>
> %s/expect/expected/
> also I'd s/real_cc/core_count/
>
> > +uint16_t real, real_cc2, expect_cc2 = data->smbios_core_count2;
> ditto
>
> >  uint16_t expect_speed[2];
> > -uint16_t real;
> >  int offset[2];
> >  int i;
> >
> > @@ -660,6 +663,20 @@ static bool smbios_cpu_test(test_data *data, uint32_t 
> > addr)
> >  }
> >  }
> >
> > +real_cc = qtest_readb(data->qts, addr + offsetof(struct smbios_type_4, 
> > core_count));
> > +real_cc2 = qtest_readw(data->qts, addr + offsetof(struct 
> > smbios_type_4, core_count2));
> > +
> > +if (expect_cc && (real_cc != expect_cc)) {
> > +fprintf(stderr, "Unexpected SMBIOS CPU count: real %u expect %u\n",
> > +real_cc, expect_cc);
> > +return false;
>
> since you are rewriting it anyways, how about
> if (expect_cc) {
>   g_assert_cmpuint(...)
> }
>
> instead of printing/propagating error

That works. But I still need to return something, unless you want to
change the original code too.

Best regards, Julia Suvorova.

> > +}
> > +if ((expect_cc == 0xFF) && (real_cc2 != expect_cc2)) {
> > +fprintf(stderr, "Unexpected SMBIOS CPU count2: real %u expect 
> > %u\n",
> > +real_cc2, expect_cc2);
> > +return false;
> > +}
> > +
> >  return true;
> >  }
> >
> > @@ -905,6 +922,21 @@ static void test_acpi_q35_tcg(void)
> >  free_test_data();
> >  }
> >
> > +static void test_acpi_q35_tcg_core_count2(void)
> > +{
> > +test_data data = {
> > +.machine = MACHINE_Q35,
> > +.variant = ".core-count2",
> > +.required_struct_types = base_required_struct_types,
> > +.required_struct_types_len = 
> > ARRAY_SIZE(base_required_struct_types),
> > +.smbios_core_count = 0xFF,
> > +.smbios_core_count2 = 275,
> > +};
> > +
> > +test_acpi_one("-machine smbios-entry-point-type=64 -smp 275", );
> > +free_test_data();
> > +}
> > +
> >  static void test_acpi_q35_tcg_bridge(void)
> >  {
> >  test_data data;
> > @@ -1787,6 +1819,7 @@ int main(int argc, char *argv[])
> >  qtest_add_func("acpi/piix4/pci-hotplug/off",
> > test_acpi_piix4_no_acpi_pci_hotplug);
> >  qtest_add_func("acpi/q35", test_acpi_q35_tcg);
> > +qtest_add_func("acpi/q35/core-count2", 
> > test_acpi_q35_tcg_core_count2);
> >  qtest_add_func("acpi/q35/bridge", test_acpi_q35_tcg_bridge);
> >  qtest_add_func("acpi/q35/multif-bridge", 
> > test_acpi_q35_multif_bridge);
> >  qtest_add_func("acpi/q35/mmio64", test_acpi_q35_tcg_mmio64);
>




Re: [PATCH 1/5] hw/smbios: add core_count2 to smbios table type 4

2022-06-06 Thread Julia Suvorova
On Thu, Jun 2, 2022 at 4:35 PM Igor Mammedov  wrote:
>
> On Thu, 2 Jun 2022 16:31:25 +0200
> Igor Mammedov  wrote:
>
> > On Tue, 31 May 2022 14:40:15 +0200
> > Julia Suvorova  wrote:
> >
> > > On Sat, May 28, 2022 at 6:34 AM Ani Sinha  wrote:
> > > >
> > > >
> > > >
> > > > On Fri, 27 May 2022, Julia Suvorova wrote:
> > > >
> > > > > In order to use the increased number of cpus, we need to bring smbios
> > > > > tables in line with the SMBIOS 3.0 specification. This allows us to
> > > > > introduce core_count2 which acts as a duplicate of core_count if we 
> > > > > have
> > > > > fewer cores than 256, and contains the actual core number per socket 
> > > > > if
> > > > > we have more.
> > > > >
> > > > > core_enabled2 and thread_count2 fields work the same way.
> > > > >
> > > > > Signed-off-by: Julia Suvorova 
> > > >
> > > > Other than the comment below,
> > > > Reviewed-by: Ani Sinha 
> > > >
> > > > > ---
> > > > >  include/hw/firmware/smbios.h |  3 +++
> > > > >  hw/smbios/smbios.c   | 11 +--
> > > > >  2 files changed, 12 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git a/include/hw/firmware/smbios.h 
> > > > > b/include/hw/firmware/smbios.h
> > > > > index 4b7ad77a44..c427ae5558 100644
> > > > > --- a/include/hw/firmware/smbios.h
> > > > > +++ b/include/hw/firmware/smbios.h
> > > > > @@ -187,6 +187,9 @@ struct smbios_type_4 {
> > > > >  uint8_t thread_count;
> > > > >  uint16_t processor_characteristics;
> > > > >  uint16_t processor_family2;
> > > > > +uint16_t core_count2;
> > > > > +uint16_t core_enabled2;
> > > > > +    uint16_t thread_count2;
>
> on the other hand,
> is it ok unconditionally extend type 4 and use v3 structure
> if qemu was started with v2 smbios?

We have a flag for the entry point type, not the smbios version per
se. Additional fields added to structures were not previously tracked
(for instance, processor_family2 is v2.6 and status is v2.0). AFAIU it
can affect only the total table length and the maximum structure size
(word). But if you like, I can raise an error (warning) if someone
tries to start a vm with cpus > 255 and smbios v2.

Best regards, Julia Suvorova.

> > > >
> > > > I would add a comment along the lines of
> > > > /* section 7.5, table 21 smbios spec version 3.0.0 */
> > >
> > > Ok
> >
> > With Ani's comment fixed
> >
> > Reviewed-by: Igor Mammedov 
> >
> > >
> > > > >  } QEMU_PACKED;
> > > > >
> > > > >  /* SMBIOS type 11 - OEM strings */
> > > > > diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> > > > > index 60349ee402..45d7be6b30 100644
> > > > > --- a/hw/smbios/smbios.c
> > > > > +++ b/hw/smbios/smbios.c
> > > > > @@ -709,8 +709,15 @@ static void 
> > > > > smbios_build_type_4_table(MachineState *ms, unsigned instance)
> > > > >  SMBIOS_TABLE_SET_STR(4, serial_number_str, type4.serial);
> > > > >  SMBIOS_TABLE_SET_STR(4, asset_tag_number_str, type4.asset);
> > > > >  SMBIOS_TABLE_SET_STR(4, part_number_str, type4.part);
> > > > > -t->core_count = t->core_enabled = ms->smp.cores;
> > > > > -t->thread_count = ms->smp.threads;
> > > > > +
> > > > > +t->core_count = (ms->smp.cores > 255) ? 0xFF : ms->smp.cores;
> > > > > +t->core_enabled = t->core_count;
> > > > > +
> > > > > +t->core_count2 = t->core_enabled2 = cpu_to_le16(ms->smp.cores);
> > > > > +
> > > > > +t->thread_count = (ms->smp.threads > 255) ? 0xFF : 
> > > > > ms->smp.threads;
> > > > > +t->thread_count2 = cpu_to_le16(ms->smp.threads);
> > > > > +
> > > > >  t->processor_characteristics = cpu_to_le16(0x02); /* Unknown */
> > > > >  t->processor_family2 = cpu_to_le16(0x01); /* Other */
> > > > >
> > > > > --
> > > > > 2.35.1
> > > > >
> > > > >
> > > >
> > >
> >
>




Re: [PATCH 2/5] bios-tables-test: teach test to use smbios 3.0 tables

2022-06-06 Thread Julia Suvorova
On Thu, Jun 2, 2022 at 5:04 PM Igor Mammedov  wrote:
>
> On Fri, 27 May 2022 18:56:48 +0200
> Julia Suvorova  wrote:
>
> > Introduce the 64-bit entry point. Since we no longer have a total
> > number of structures, stop checking for the new ones at the EOF
> > structure (type 127).
> >
> > Signed-off-by: Julia Suvorova 
> > ---
> >  tests/qtest/bios-tables-test.c | 101 -
> >  1 file changed, 75 insertions(+), 26 deletions(-)
> >
> > diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
> > index a4a46e97f0..0ba9d749a5 100644
> > --- a/tests/qtest/bios-tables-test.c
> > +++ b/tests/qtest/bios-tables-test.c
> > @@ -75,6 +75,14 @@
> >  #define OEM_TEST_ARGS  "-machine x-oem-id=" OEM_ID ",x-oem-table-id=" \
> > OEM_TABLE_ID
> >
> > +#define SMBIOS_VER21 0
> > +#define SMBIOS_VER30 1
> > +
> > +typedef struct {
> > +struct smbios_21_entry_point ep21;
> > +struct smbios_30_entry_point ep30;
> > +} smbios_entry_point;
> > +
> >  typedef struct {
> >  bool tcg_only;
> >  const char *machine;
> > @@ -88,8 +96,8 @@ typedef struct {
> >  uint64_t rsdp_addr;
> >  uint8_t rsdp_table[36 /* ACPI 2.0+ RSDP size */];
> >  GArray *tables;
> > -uint32_t smbios_ep_addr;
> > -struct smbios_21_entry_point smbios_ep_table;
> > +uint64_t smbios_ep_addr[2];
> > +smbios_entry_point smbios_ep_table;
> >  uint16_t smbios_cpu_max_speed;
> >  uint16_t smbios_cpu_curr_speed;
> >  uint8_t *required_struct_types;
> > @@ -533,10 +541,10 @@ static void test_acpi_asl(test_data *data)
> >  free_test_data(_data);
> >  }
> >
> > -static bool smbios_ep_table_ok(test_data *data)
> > +static bool smbios_ep2_table_ok(test_data *data)
> >  {
> > -struct smbios_21_entry_point *ep_table = >smbios_ep_table;
> > -uint32_t addr = data->smbios_ep_addr;
> > +struct smbios_21_entry_point *ep_table = >smbios_ep_table.ep21;
> > +uint32_t addr = data->smbios_ep_addr[SMBIOS_VER21];
> >
> >  qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table));
> >  if (memcmp(ep_table->anchor_string, "_SM_", 4)) {
> > @@ -559,29 +567,59 @@ static bool smbios_ep_table_ok(test_data *data)
> >  return true;
> >  }
> >
> > -static void test_smbios_entry_point(test_data *data)
> > +static bool smbios_ep3_table_ok(test_data *data)
> > +{
> > +struct smbios_30_entry_point *ep_table = >smbios_ep_table.ep30;
> > +uint64_t addr = data->smbios_ep_addr[SMBIOS_VER30];
> > +
> > +qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table));
> > +if (memcmp(ep_table->anchor_string, "_SM3_", 5)) {
> > +return false;
> > +}
> > +
> > +if (acpi_calc_checksum((uint8_t *)ep_table, sizeof *ep_table)) {
> > +return false;
> > +}
> > +
> > +return true;
> > +}
> > +
> > +static int test_smbios_entry_point(test_data *data)
> >  {
> >  uint32_t off;
> > +bool found_ep2 = false, found_ep3 = false;
> >
> >  /* find smbios entry point structure */
> >  for (off = 0xf; off < 0x10; off += 0x10) {
> > -uint8_t sig[] = "_SM_";
> > +uint8_t sig[] = "_SM3_";
>
> well I'd just add a separate sig3

Ok

> >  int i;
> >
> >  for (i = 0; i < sizeof sig - 1; ++i) {
> >  sig[i] = qtest_readb(data->qts, off + i);
> >  }
> >
> > -if (!memcmp(sig, "_SM_", sizeof sig)) {
> > +if (!found_ep2 && !memcmp(sig, "_SM_", sizeof sig - 2)) {
>
> keep original v2 code and just add similar chunk for v3,
> drop found_foo locals,
> that should make it easier to read/follow
> (i.e. less conditions to think about and no magic fiddling with the length of 
> signature)

The idea was to reuse existing code, but since it doesn't improve
things much, it makes sense to repeat it.

> >  /* signature match, but is this a valid entry point? */
> > -data->smbios_ep_addr = off;
> > -if (smbios_ep_table_ok(data)) {
> > -break;
> > +data->smbios_ep_addr[SMBIOS_VER21] = off;
> > +if (smbios_ep2_table_ok(data)) {
> > +found_ep2 = true;
> > +}
> > +} else if (

Re: [PATCH 4/5] bios-tables-test: add test for number of cores > 255

2022-05-31 Thread Julia Suvorova
On Tue, May 31, 2022 at 3:14 PM Ani Sinha  wrote:
>
> On Tue, May 31, 2022 at 5:53 PM Julia Suvorova  wrote:
> >
> > On Sat, May 28, 2022 at 7:22 AM Ani Sinha  wrote:
> > >
> > >
> > >
> > > On Fri, 27 May 2022, Julia Suvorova wrote:
> > >
> > > > The new test is run with a large number of cpus and checks if the
> > > > core_count field in smbios_cpu_test (structure type 4) is correct.
> > > >
> > > > Choose q35 as it allows to run with -smp > 255.
> > > >
> > > > Signed-off-by: Julia Suvorova 
> > > > ---
> > > >  tests/qtest/bios-tables-test.c | 35 +-
> > > >  1 file changed, 34 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/tests/qtest/bios-tables-test.c 
> > > > b/tests/qtest/bios-tables-test.c
> > > > index 0ba9d749a5..f2464adaa0 100644
> > > > --- a/tests/qtest/bios-tables-test.c
> > > > +++ b/tests/qtest/bios-tables-test.c
> > > > @@ -100,6 +100,8 @@ typedef struct {
> > > >  smbios_entry_point smbios_ep_table;
> > > >  uint16_t smbios_cpu_max_speed;
> > > >  uint16_t smbios_cpu_curr_speed;
> > > > +uint8_t smbios_core_count;
> > > > +uint16_t smbios_core_count2;
> > > >  uint8_t *required_struct_types;
> > > >  int required_struct_types_len;
> > > >  QTestState *qts;
> > > > @@ -640,8 +642,9 @@ static inline bool smbios_single_instance(uint8_t 
> > > > type)
> > > >
> > > >  static bool smbios_cpu_test(test_data *data, uint32_t addr)
> > > >  {
> > > > +uint8_t real_cc, expect_cc = data->smbios_core_count;
> > > > +uint16_t real, real_cc2, expect_cc2 = data->smbios_core_count2;
> > > >  uint16_t expect_speed[2];
> > > > -uint16_t real;
> > >
> > > while you are at it, I suggest renaming this to real_speed or some such so
> > > that its better redeable.
> >
> > Ok
> >
> > > >  int offset[2];
> > > >  int i;
> > > >
> > > > @@ -660,6 +663,20 @@ static bool smbios_cpu_test(test_data *data, 
> > > > uint32_t addr)
> > > >  }
> > > >  }
> > > >
> > > > +real_cc = qtest_readb(data->qts, addr + offsetof(struct 
> > > > smbios_type_4, core_count));
> > > > +real_cc2 = qtest_readw(data->qts, addr + offsetof(struct 
> > > > smbios_type_4, core_count2));
> > > > +
> > > > +if (expect_cc && (real_cc != expect_cc)) {
> > >
> > > I think better to say if ((expect_cc < 256) && (real_cc != expect_cc))
> >
> > The check is not whether it fits into the field, but whether the field
> > is initialized.
>
> yes so the real_cc will contain the actual value of core count only
> when the core count value is less than 256. This value should be the
> same as the expect_cc (the cc value we pass). Is this not what is
> being tested?

The real_cc should always be equal to expect_cc (which is 0xFF with
-smp 275). So if the core count is less than 256, this checks for the
actual core counter, and if it's over, it checks if real_cc is equal
to 0xFF, which eliminates several unnecessary comparisons. If we
didn't initialize expect_cc in the test, the value is undefined, and
we shouldn't check anything.

Best regards, Julia Suvorova.

> >
> > > > +fprintf(stderr, "Unexpected SMBIOS CPU count: real %u expect 
> > > > %u\n",
> > > > +real_cc, expect_cc);
> > > > +return false;
> > > > +}
> > > > +if ((expect_cc == 0xFF) && (real_cc2 != expect_cc2)) {
> > > > +fprintf(stderr, "Unexpected SMBIOS CPU count2: real %u expect 
> > > > %u\n",
> > > > +real_cc2, expect_cc2);
> > > > +return false;
> > > > +}
> > > > +
> > > >  return true;
> > > >  }
> > > >
> > > > @@ -905,6 +922,21 @@ static void test_acpi_q35_tcg(void)
> > > >  free_test_data();
> > > >  }
> > > >
> > > > +static void test_acpi_q35_tcg_core_count2(void)
> > > > +{
> > > > +test_data data = {
> > > > +.machine = MACHINE_Q35,
> > > > +.variant = ".core-count2"

[PATCH] hw/mem/nvdimm: fix error message for 'unarmed' flag

2022-05-31 Thread Julia Suvorova
In the ACPI specification [1], the 'unarmed' bit is set when a device
cannot accept a persistent write. This means that when a memdev is
read-only, the 'unarmed' flag must be turned on. The logic is correct,
just changing the error message.

[1] ACPI NFIT NVDIMM Region Mapping Structure "NVDIMM State Flags" Bit 3

Signed-off-by: Julia Suvorova 
---
 hw/mem/nvdimm.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c
index 7c7d81..bfb76818c1 100644
--- a/hw/mem/nvdimm.c
+++ b/hw/mem/nvdimm.c
@@ -149,7 +149,7 @@ static void nvdimm_prepare_memory_region(NVDIMMDevice 
*nvdimm, Error **errp)
 if (!nvdimm->unarmed && memory_region_is_rom(mr)) {
 HostMemoryBackend *hostmem = dimm->hostmem;
 
-error_setg(errp, "'unarmed' property must be off since memdev %s "
+error_setg(errp, "'unarmed' property must be on since memdev %s "
"is read-only",
object_get_canonical_path_component(OBJECT(hostmem)));
 return;
-- 
2.35.1




Re: [PATCH 1/5] hw/smbios: add core_count2 to smbios table type 4

2022-05-31 Thread Julia Suvorova
On Sat, May 28, 2022 at 6:34 AM Ani Sinha  wrote:
>
>
>
> On Fri, 27 May 2022, Julia Suvorova wrote:
>
> > In order to use the increased number of cpus, we need to bring smbios
> > tables in line with the SMBIOS 3.0 specification. This allows us to
> > introduce core_count2 which acts as a duplicate of core_count if we have
> > fewer cores than 256, and contains the actual core number per socket if
> > we have more.
> >
> > core_enabled2 and thread_count2 fields work the same way.
> >
> > Signed-off-by: Julia Suvorova 
>
> Other than the comment below,
> Reviewed-by: Ani Sinha 
>
> > ---
> >  include/hw/firmware/smbios.h |  3 +++
> >  hw/smbios/smbios.c   | 11 +--
> >  2 files changed, 12 insertions(+), 2 deletions(-)
> >
> > diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
> > index 4b7ad77a44..c427ae5558 100644
> > --- a/include/hw/firmware/smbios.h
> > +++ b/include/hw/firmware/smbios.h
> > @@ -187,6 +187,9 @@ struct smbios_type_4 {
> >  uint8_t thread_count;
> >  uint16_t processor_characteristics;
> >  uint16_t processor_family2;
> > +uint16_t core_count2;
> > +uint16_t core_enabled2;
> > +uint16_t thread_count2;
>
> I would add a comment along the lines of
> /* section 7.5, table 21 smbios spec version 3.0.0 */

Ok

> >  } QEMU_PACKED;
> >
> >  /* SMBIOS type 11 - OEM strings */
> > diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
> > index 60349ee402..45d7be6b30 100644
> > --- a/hw/smbios/smbios.c
> > +++ b/hw/smbios/smbios.c
> > @@ -709,8 +709,15 @@ static void smbios_build_type_4_table(MachineState 
> > *ms, unsigned instance)
> >  SMBIOS_TABLE_SET_STR(4, serial_number_str, type4.serial);
> >  SMBIOS_TABLE_SET_STR(4, asset_tag_number_str, type4.asset);
> >  SMBIOS_TABLE_SET_STR(4, part_number_str, type4.part);
> > -t->core_count = t->core_enabled = ms->smp.cores;
> > -t->thread_count = ms->smp.threads;
> > +
> > +t->core_count = (ms->smp.cores > 255) ? 0xFF : ms->smp.cores;
> > +t->core_enabled = t->core_count;
> > +
> > +t->core_count2 = t->core_enabled2 = cpu_to_le16(ms->smp.cores);
> > +
> > +t->thread_count = (ms->smp.threads > 255) ? 0xFF : ms->smp.threads;
> > +t->thread_count2 = cpu_to_le16(ms->smp.threads);
> > +
> >  t->processor_characteristics = cpu_to_le16(0x02); /* Unknown */
> >  t->processor_family2 = cpu_to_le16(0x01); /* Other */
> >
> > --
> > 2.35.1
> >
> >
>




Re: [PATCH 4/5] bios-tables-test: add test for number of cores > 255

2022-05-31 Thread Julia Suvorova
On Sat, May 28, 2022 at 7:22 AM Ani Sinha  wrote:
>
>
>
> On Fri, 27 May 2022, Julia Suvorova wrote:
>
> > The new test is run with a large number of cpus and checks if the
> > core_count field in smbios_cpu_test (structure type 4) is correct.
> >
> > Choose q35 as it allows to run with -smp > 255.
> >
> > Signed-off-by: Julia Suvorova 
> > ---
> >  tests/qtest/bios-tables-test.c | 35 +-
> >  1 file changed, 34 insertions(+), 1 deletion(-)
> >
> > diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
> > index 0ba9d749a5..f2464adaa0 100644
> > --- a/tests/qtest/bios-tables-test.c
> > +++ b/tests/qtest/bios-tables-test.c
> > @@ -100,6 +100,8 @@ typedef struct {
> >  smbios_entry_point smbios_ep_table;
> >  uint16_t smbios_cpu_max_speed;
> >  uint16_t smbios_cpu_curr_speed;
> > +uint8_t smbios_core_count;
> > +uint16_t smbios_core_count2;
> >  uint8_t *required_struct_types;
> >  int required_struct_types_len;
> >  QTestState *qts;
> > @@ -640,8 +642,9 @@ static inline bool smbios_single_instance(uint8_t type)
> >
> >  static bool smbios_cpu_test(test_data *data, uint32_t addr)
> >  {
> > +uint8_t real_cc, expect_cc = data->smbios_core_count;
> > +uint16_t real, real_cc2, expect_cc2 = data->smbios_core_count2;
> >  uint16_t expect_speed[2];
> > -uint16_t real;
>
> while you are at it, I suggest renaming this to real_speed or some such so
> that its better redeable.

Ok

> >  int offset[2];
> >  int i;
> >
> > @@ -660,6 +663,20 @@ static bool smbios_cpu_test(test_data *data, uint32_t 
> > addr)
> >  }
> >  }
> >
> > +real_cc = qtest_readb(data->qts, addr + offsetof(struct smbios_type_4, 
> > core_count));
> > +real_cc2 = qtest_readw(data->qts, addr + offsetof(struct 
> > smbios_type_4, core_count2));
> > +
> > +if (expect_cc && (real_cc != expect_cc)) {
>
> I think better to say if ((expect_cc < 256) && (real_cc != expect_cc))

The check is not whether it fits into the field, but whether the field
is initialized.

> > +fprintf(stderr, "Unexpected SMBIOS CPU count: real %u expect %u\n",
> > +real_cc, expect_cc);
> > +return false;
> > +}
> > +if ((expect_cc == 0xFF) && (real_cc2 != expect_cc2)) {
> > +fprintf(stderr, "Unexpected SMBIOS CPU count2: real %u expect 
> > %u\n",
> > +real_cc2, expect_cc2);
> > +return false;
> > +}
> > +
> >  return true;
> >  }
> >
> > @@ -905,6 +922,21 @@ static void test_acpi_q35_tcg(void)
> >  free_test_data();
> >  }
> >
> > +static void test_acpi_q35_tcg_core_count2(void)
> > +{
> > +test_data data = {
> > +.machine = MACHINE_Q35,
> > +.variant = ".core-count2",
> > +.required_struct_types = base_required_struct_types,
> > +.required_struct_types_len = 
> > ARRAY_SIZE(base_required_struct_types),
> > +.smbios_core_count = 0xFF,
> > +.smbios_core_count2 = 275,
> > +};
> > +
> > +test_acpi_one("-machine smbios-entry-point-type=64 -smp 275", );
> > +free_test_data();
> > +}
> > +
> >  static void test_acpi_q35_tcg_bridge(void)
> >  {
> >  test_data data;
> > @@ -1787,6 +1819,7 @@ int main(int argc, char *argv[])
> >  qtest_add_func("acpi/piix4/pci-hotplug/off",
> > test_acpi_piix4_no_acpi_pci_hotplug);
> >  qtest_add_func("acpi/q35", test_acpi_q35_tcg);
> > +qtest_add_func("acpi/q35/core-count2", 
> > test_acpi_q35_tcg_core_count2);
>
> How about checking thread count as well in the same test or in a
> different test?

Maybe a different test.

Best regards, Julia Suvorova.

> >  qtest_add_func("acpi/q35/bridge", test_acpi_q35_tcg_bridge);
> >  qtest_add_func("acpi/q35/multif-bridge", 
> > test_acpi_q35_multif_bridge);
> >  qtest_add_func("acpi/q35/mmio64", test_acpi_q35_tcg_mmio64);
> > --
> > 2.35.1
> >
> >
>




Re: [PATCH 2/5] bios-tables-test: teach test to use smbios 3.0 tables

2022-05-31 Thread Julia Suvorova
On Mon, May 30, 2022 at 8:11 AM Ani Sinha  wrote:
>
> On Fri, May 27, 2022 at 10:27 PM Julia Suvorova  wrote:
> >
> > Introduce the 64-bit entry point. Since we no longer have a total
> > number of structures, stop checking for the new ones at the EOF
> > structure (type 127).
> >
> > Signed-off-by: Julia Suvorova 
> > ---
> >  tests/qtest/bios-tables-test.c | 101 -
> >  1 file changed, 75 insertions(+), 26 deletions(-)
> >
> > diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
> > index a4a46e97f0..0ba9d749a5 100644
> > --- a/tests/qtest/bios-tables-test.c
> > +++ b/tests/qtest/bios-tables-test.c
> > @@ -75,6 +75,14 @@
> >  #define OEM_TEST_ARGS  "-machine x-oem-id=" OEM_ID ",x-oem-table-id=" \
> > OEM_TABLE_ID
> >
> > +#define SMBIOS_VER21 0
> > +#define SMBIOS_VER30 1
> > +
> > +typedef struct {
> > +struct smbios_21_entry_point ep21;
> > +struct smbios_30_entry_point ep30;
> > +} smbios_entry_point;
> > +
> >  typedef struct {
> >  bool tcg_only;
> >  const char *machine;
> > @@ -88,8 +96,8 @@ typedef struct {
> >  uint64_t rsdp_addr;
> >  uint8_t rsdp_table[36 /* ACPI 2.0+ RSDP size */];
> >  GArray *tables;
> > -uint32_t smbios_ep_addr;
> > -struct smbios_21_entry_point smbios_ep_table;
> > +uint64_t smbios_ep_addr[2];
> > +smbios_entry_point smbios_ep_table;
> >  uint16_t smbios_cpu_max_speed;
> >  uint16_t smbios_cpu_curr_speed;
> >  uint8_t *required_struct_types;
> > @@ -533,10 +541,10 @@ static void test_acpi_asl(test_data *data)
> >  free_test_data(_data);
> >  }
> >
> > -static bool smbios_ep_table_ok(test_data *data)
> > +static bool smbios_ep2_table_ok(test_data *data)
> >  {
> > -struct smbios_21_entry_point *ep_table = >smbios_ep_table;
> > -uint32_t addr = data->smbios_ep_addr;
> > +struct smbios_21_entry_point *ep_table = >smbios_ep_table.ep21;
> > +uint32_t addr = data->smbios_ep_addr[SMBIOS_VER21];
> >
> >  qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table));
> >  if (memcmp(ep_table->anchor_string, "_SM_", 4)) {
> > @@ -559,29 +567,59 @@ static bool smbios_ep_table_ok(test_data *data)
> >  return true;
> >  }
> >
> > -static void test_smbios_entry_point(test_data *data)
> > +static bool smbios_ep3_table_ok(test_data *data)
> > +{
> > +struct smbios_30_entry_point *ep_table = >smbios_ep_table.ep30;
> > +uint64_t addr = data->smbios_ep_addr[SMBIOS_VER30];
> > +
> > +qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table));
> > +if (memcmp(ep_table->anchor_string, "_SM3_", 5)) {
> > +return false;
> > +}
> > +
> > +if (acpi_calc_checksum((uint8_t *)ep_table, sizeof *ep_table)) {
> > +return false;
> > +}
> > +
> > +return true;
> > +}
> > +
> > +static int test_smbios_entry_point(test_data *data)
> >  {
> >  uint32_t off;
> > +bool found_ep2 = false, found_ep3 = false;
> >
> >  /* find smbios entry point structure */
> >  for (off = 0xf; off < 0x10; off += 0x10) {
> > -uint8_t sig[] = "_SM_";
> > +uint8_t sig[] = "_SM3_";
> >  int i;
> >
> >  for (i = 0; i < sizeof sig - 1; ++i) {
> >  sig[i] = qtest_readb(data->qts, off + i);
> >  }
> >
> > -if (!memcmp(sig, "_SM_", sizeof sig)) {
> > +if (!found_ep2 && !memcmp(sig, "_SM_", sizeof sig - 2)) {
> >  /* signature match, but is this a valid entry point? */
> > -data->smbios_ep_addr = off;
> > -if (smbios_ep_table_ok(data)) {
> > -break;
> > +data->smbios_ep_addr[SMBIOS_VER21] = off;
> > +if (smbios_ep2_table_ok(data)) {
> > +found_ep2 = true;
> > +}
> > +} else if (!found_ep3 && !memcmp(sig, "_SM3_", sizeof sig - 1)) {
> > +data->smbios_ep_addr[SMBIOS_VER30] = off;
> > +if (smbios_ep3_table_ok(data)) {
> > +found_ep3 = true;
> >  }
> >  }
> > +
> > +if (found_ep2 || found_ep3) {
> > +break;
> > +}
> &

[PATCH 4/5] bios-tables-test: add test for number of cores > 255

2022-05-27 Thread Julia Suvorova
The new test is run with a large number of cpus and checks if the
core_count field in smbios_cpu_test (structure type 4) is correct.

Choose q35 as it allows to run with -smp > 255.

Signed-off-by: Julia Suvorova 
---
 tests/qtest/bios-tables-test.c | 35 +-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 0ba9d749a5..f2464adaa0 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -100,6 +100,8 @@ typedef struct {
 smbios_entry_point smbios_ep_table;
 uint16_t smbios_cpu_max_speed;
 uint16_t smbios_cpu_curr_speed;
+uint8_t smbios_core_count;
+uint16_t smbios_core_count2;
 uint8_t *required_struct_types;
 int required_struct_types_len;
 QTestState *qts;
@@ -640,8 +642,9 @@ static inline bool smbios_single_instance(uint8_t type)
 
 static bool smbios_cpu_test(test_data *data, uint32_t addr)
 {
+uint8_t real_cc, expect_cc = data->smbios_core_count;
+uint16_t real, real_cc2, expect_cc2 = data->smbios_core_count2;
 uint16_t expect_speed[2];
-uint16_t real;
 int offset[2];
 int i;
 
@@ -660,6 +663,20 @@ static bool smbios_cpu_test(test_data *data, uint32_t addr)
 }
 }
 
+real_cc = qtest_readb(data->qts, addr + offsetof(struct smbios_type_4, 
core_count));
+real_cc2 = qtest_readw(data->qts, addr + offsetof(struct smbios_type_4, 
core_count2));
+
+if (expect_cc && (real_cc != expect_cc)) {
+fprintf(stderr, "Unexpected SMBIOS CPU count: real %u expect %u\n",
+real_cc, expect_cc);
+return false;
+}
+if ((expect_cc == 0xFF) && (real_cc2 != expect_cc2)) {
+fprintf(stderr, "Unexpected SMBIOS CPU count2: real %u expect %u\n",
+real_cc2, expect_cc2);
+return false;
+}
+
 return true;
 }
 
@@ -905,6 +922,21 @@ static void test_acpi_q35_tcg(void)
 free_test_data();
 }
 
+static void test_acpi_q35_tcg_core_count2(void)
+{
+test_data data = {
+.machine = MACHINE_Q35,
+.variant = ".core-count2",
+.required_struct_types = base_required_struct_types,
+.required_struct_types_len = ARRAY_SIZE(base_required_struct_types),
+.smbios_core_count = 0xFF,
+.smbios_core_count2 = 275,
+};
+
+test_acpi_one("-machine smbios-entry-point-type=64 -smp 275", );
+free_test_data();
+}
+
 static void test_acpi_q35_tcg_bridge(void)
 {
 test_data data;
@@ -1787,6 +1819,7 @@ int main(int argc, char *argv[])
 qtest_add_func("acpi/piix4/pci-hotplug/off",
test_acpi_piix4_no_acpi_pci_hotplug);
 qtest_add_func("acpi/q35", test_acpi_q35_tcg);
+qtest_add_func("acpi/q35/core-count2", test_acpi_q35_tcg_core_count2);
 qtest_add_func("acpi/q35/bridge", test_acpi_q35_tcg_bridge);
 qtest_add_func("acpi/q35/multif-bridge", test_acpi_q35_multif_bridge);
 qtest_add_func("acpi/q35/mmio64", test_acpi_q35_tcg_mmio64);
-- 
2.35.1




[PATCH 3/5] tests/acpi: allow changes for core_count2 test

2022-05-27 Thread Julia Suvorova
Signed-off-by: Julia Suvorova 
---
 tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
 tests/data/acpi/q35/APIC.core-count2| 0
 tests/data/acpi/q35/DSDT.core-count2| 0
 tests/data/acpi/q35/FACP.core-count2| 0
 4 files changed, 3 insertions(+)
 create mode 100644 tests/data/acpi/q35/APIC.core-count2
 create mode 100644 tests/data/acpi/q35/DSDT.core-count2
 create mode 100644 tests/data/acpi/q35/FACP.core-count2

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..e81dc67a2e 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,4 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/APIC.core-count2",
+"tests/data/acpi/q35/DSDT.core-count2",
+"tests/data/acpi/q35/FACP.core-count2",
diff --git a/tests/data/acpi/q35/APIC.core-count2 
b/tests/data/acpi/q35/APIC.core-count2
new file mode 100644
index 00..e69de29bb2
diff --git a/tests/data/acpi/q35/DSDT.core-count2 
b/tests/data/acpi/q35/DSDT.core-count2
new file mode 100644
index 00..e69de29bb2
diff --git a/tests/data/acpi/q35/FACP.core-count2 
b/tests/data/acpi/q35/FACP.core-count2
new file mode 100644
index 00..e69de29bb2
-- 
2.35.1




[PATCH 2/5] bios-tables-test: teach test to use smbios 3.0 tables

2022-05-27 Thread Julia Suvorova
Introduce the 64-bit entry point. Since we no longer have a total
number of structures, stop checking for the new ones at the EOF
structure (type 127).

Signed-off-by: Julia Suvorova 
---
 tests/qtest/bios-tables-test.c | 101 -
 1 file changed, 75 insertions(+), 26 deletions(-)

diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index a4a46e97f0..0ba9d749a5 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -75,6 +75,14 @@
 #define OEM_TEST_ARGS  "-machine x-oem-id=" OEM_ID ",x-oem-table-id=" \
OEM_TABLE_ID
 
+#define SMBIOS_VER21 0
+#define SMBIOS_VER30 1
+
+typedef struct {
+struct smbios_21_entry_point ep21;
+struct smbios_30_entry_point ep30;
+} smbios_entry_point;
+
 typedef struct {
 bool tcg_only;
 const char *machine;
@@ -88,8 +96,8 @@ typedef struct {
 uint64_t rsdp_addr;
 uint8_t rsdp_table[36 /* ACPI 2.0+ RSDP size */];
 GArray *tables;
-uint32_t smbios_ep_addr;
-struct smbios_21_entry_point smbios_ep_table;
+uint64_t smbios_ep_addr[2];
+smbios_entry_point smbios_ep_table;
 uint16_t smbios_cpu_max_speed;
 uint16_t smbios_cpu_curr_speed;
 uint8_t *required_struct_types;
@@ -533,10 +541,10 @@ static void test_acpi_asl(test_data *data)
 free_test_data(_data);
 }
 
-static bool smbios_ep_table_ok(test_data *data)
+static bool smbios_ep2_table_ok(test_data *data)
 {
-struct smbios_21_entry_point *ep_table = >smbios_ep_table;
-uint32_t addr = data->smbios_ep_addr;
+struct smbios_21_entry_point *ep_table = >smbios_ep_table.ep21;
+uint32_t addr = data->smbios_ep_addr[SMBIOS_VER21];
 
 qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table));
 if (memcmp(ep_table->anchor_string, "_SM_", 4)) {
@@ -559,29 +567,59 @@ static bool smbios_ep_table_ok(test_data *data)
 return true;
 }
 
-static void test_smbios_entry_point(test_data *data)
+static bool smbios_ep3_table_ok(test_data *data)
+{
+struct smbios_30_entry_point *ep_table = >smbios_ep_table.ep30;
+uint64_t addr = data->smbios_ep_addr[SMBIOS_VER30];
+
+qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table));
+if (memcmp(ep_table->anchor_string, "_SM3_", 5)) {
+return false;
+}
+
+if (acpi_calc_checksum((uint8_t *)ep_table, sizeof *ep_table)) {
+return false;
+}
+
+return true;
+}
+
+static int test_smbios_entry_point(test_data *data)
 {
 uint32_t off;
+bool found_ep2 = false, found_ep3 = false;
 
 /* find smbios entry point structure */
 for (off = 0xf; off < 0x10; off += 0x10) {
-uint8_t sig[] = "_SM_";
+uint8_t sig[] = "_SM3_";
 int i;
 
 for (i = 0; i < sizeof sig - 1; ++i) {
 sig[i] = qtest_readb(data->qts, off + i);
 }
 
-if (!memcmp(sig, "_SM_", sizeof sig)) {
+if (!found_ep2 && !memcmp(sig, "_SM_", sizeof sig - 2)) {
 /* signature match, but is this a valid entry point? */
-data->smbios_ep_addr = off;
-if (smbios_ep_table_ok(data)) {
-break;
+data->smbios_ep_addr[SMBIOS_VER21] = off;
+if (smbios_ep2_table_ok(data)) {
+found_ep2 = true;
+}
+} else if (!found_ep3 && !memcmp(sig, "_SM3_", sizeof sig - 1)) {
+data->smbios_ep_addr[SMBIOS_VER30] = off;
+if (smbios_ep3_table_ok(data)) {
+found_ep3 = true;
 }
 }
+
+if (found_ep2 || found_ep3) {
+break;
+}
 }
 
-g_assert_cmphex(off, <, 0x10);
+g_assert_cmphex(data->smbios_ep_addr[SMBIOS_VER21], <, 0x10);
+g_assert_cmphex(data->smbios_ep_addr[SMBIOS_VER30], <, 0x10);
+
+return found_ep3 ? SMBIOS_VER30 : SMBIOS_VER21;
 }
 
 static inline bool smbios_single_instance(uint8_t type)
@@ -625,16 +663,23 @@ static bool smbios_cpu_test(test_data *data, uint32_t 
addr)
 return true;
 }
 
-static void test_smbios_structs(test_data *data)
+static void test_smbios_structs(test_data *data, int ver)
 {
 DECLARE_BITMAP(struct_bitmap, SMBIOS_MAX_TYPE+1) = { 0 };
-struct smbios_21_entry_point *ep_table = >smbios_ep_table;
-uint32_t addr = le32_to_cpu(ep_table->structure_table_address);
-int i, len, max_len = 0;
+
+smbios_entry_point *ep_table = >smbios_ep_table;
+int i = 0, len, max_len = 0;
 uint8_t type, prv, crt;
+uint64_t addr;
+
+if (ver == SMBIOS_VER21) {
+addr = le32_to_cpu(ep_table->ep21.structure_table_address);
+} else {
+addr = le64_to_cpu(ep_table->ep30.structure_table_address);
+}
 
 /* walk the smbios tables */
-for (i = 0; i < le16_to_cpu(ep_table->number_of_structures)

[PATCH 0/5] hw/smbios: add core_count2 to smbios table type 4

2022-05-27 Thread Julia Suvorova
The SMBIOS 3.0 specification provides the ability to reflect over
255 cores. The 64-bit entry point has been used for a while, but
structure type 4 has not been updated before, so the dmidecode output
looked like this (-smp 280):

Handle 0x0400, DMI type 4, 42 bytes
Processor Information
...
Core Count: 24
Core Enabled: 24
Thread Count: 1
...

Big update in the bios-tables-test as it couldn't work with SMBIOS 3.0.

Julia Suvorova (5):
  hw/smbios: add core_count2 to smbios table type 4
  bios-tables-test: teach test to use smbios 3.0 tables
  tests/acpi: allow changes for core_count2 test
  bios-tables-test: add test for number of cores > 255
  tests/acpi: update tables for new core count test

 include/hw/firmware/smbios.h |   3 +
 hw/smbios/smbios.c   |  11 ++-
 tests/qtest/bios-tables-test.c   | 136 +--
 tests/data/acpi/q35/APIC.core-count2 | Bin 0 -> 2478 bytes
 tests/data/acpi/q35/DSDT.core-count2 | Bin 0 -> 32429 bytes
 tests/data/acpi/q35/FACP.core-count2 | Bin 0 -> 244 bytes
 6 files changed, 121 insertions(+), 29 deletions(-)
 create mode 100644 tests/data/acpi/q35/APIC.core-count2
 create mode 100644 tests/data/acpi/q35/DSDT.core-count2
 create mode 100644 tests/data/acpi/q35/FACP.core-count2

-- 
2.35.1




[PATCH 1/5] hw/smbios: add core_count2 to smbios table type 4

2022-05-27 Thread Julia Suvorova
In order to use the increased number of cpus, we need to bring smbios
tables in line with the SMBIOS 3.0 specification. This allows us to
introduce core_count2 which acts as a duplicate of core_count if we have
fewer cores than 256, and contains the actual core number per socket if
we have more.

core_enabled2 and thread_count2 fields work the same way.

Signed-off-by: Julia Suvorova 
---
 include/hw/firmware/smbios.h |  3 +++
 hw/smbios/smbios.c   | 11 +--
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/include/hw/firmware/smbios.h b/include/hw/firmware/smbios.h
index 4b7ad77a44..c427ae5558 100644
--- a/include/hw/firmware/smbios.h
+++ b/include/hw/firmware/smbios.h
@@ -187,6 +187,9 @@ struct smbios_type_4 {
 uint8_t thread_count;
 uint16_t processor_characteristics;
 uint16_t processor_family2;
+uint16_t core_count2;
+uint16_t core_enabled2;
+uint16_t thread_count2;
 } QEMU_PACKED;
 
 /* SMBIOS type 11 - OEM strings */
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 60349ee402..45d7be6b30 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -709,8 +709,15 @@ static void smbios_build_type_4_table(MachineState *ms, 
unsigned instance)
 SMBIOS_TABLE_SET_STR(4, serial_number_str, type4.serial);
 SMBIOS_TABLE_SET_STR(4, asset_tag_number_str, type4.asset);
 SMBIOS_TABLE_SET_STR(4, part_number_str, type4.part);
-t->core_count = t->core_enabled = ms->smp.cores;
-t->thread_count = ms->smp.threads;
+
+t->core_count = (ms->smp.cores > 255) ? 0xFF : ms->smp.cores;
+t->core_enabled = t->core_count;
+
+t->core_count2 = t->core_enabled2 = cpu_to_le16(ms->smp.cores);
+
+t->thread_count = (ms->smp.threads > 255) ? 0xFF : ms->smp.threads;
+t->thread_count2 = cpu_to_le16(ms->smp.threads);
+
 t->processor_characteristics = cpu_to_le16(0x02); /* Unknown */
 t->processor_family2 = cpu_to_le16(0x01); /* Other */
 
-- 
2.35.1




[PATCH 5/5] tests/acpi: update tables for new core count test

2022-05-27 Thread Julia Suvorova
Changes in the tables (for 275 cores):
FACP:
+ Use APIC Cluster Model (V4) : 1

APIC:
+[02Ch 0044   1]Subtable Type : 00 [Processor Local APIC]
+[02Dh 0045   1]   Length : 08
+[02Eh 0046   1] Processor ID : 00
+[02Fh 0047   1]Local Apic ID : 00
+[030h 0048   4]Flags (decoded below) : 0001
+   Processor Enabled : 1
...
+
+[81Ch 2076   1]Subtable Type : 00 [Processor Local APIC]
+[81Dh 2077   1]   Length : 08
+[81Eh 2078   1] Processor ID : FE
+[81Fh 2079   1]Local Apic ID : FE
+[820h 2080   4]Flags (decoded below) : 0001
+   Processor Enabled : 1
+  Runtime Online Capable : 0
+
+[824h 2084   1]Subtable Type : 09 [Processor Local x2APIC]
+[825h 2085   1]   Length : 10
+[826h 2086   2] Reserved : 
+[828h 2088   4]  Processor x2Apic ID : 00FF
+[82Ch 2092   4]Flags (decoded below) : 0001
+   Processor Enabled : 1
+[830h 2096   4]Processor UID : 00FF
...

DSDT:
+Processor (C000, 0x00, 0x, 0x00)
+{
+Method (_STA, 0, Serialized)  // _STA: Status
+{
+Return (CSTA (Zero))
+}
+
+Name (_MAT, Buffer (0x08)  // _MAT: Multiple APIC Table Entry
+{
+ 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00   // 

+})
+Method (_OST, 3, Serialized)  // _OST: OSPM Status Indication
+{
+COST (Zero, Arg0, Arg1, Arg2)
+}
+}
...
+Processor (C0FE, 0xFE, 0x, 0x00)
+{
+Method (_STA, 0, Serialized)  // _STA: Status
+{
+Return (CSTA (0xFE))
+}
+
+Name (_MAT, Buffer (0x08)  // _MAT: Multiple APIC Table Entry
+{
+ 0x00, 0x08, 0xFE, 0xFE, 0x01, 0x00, 0x00, 0x00   // 

+})
+Method (_EJ0, 1, NotSerialized)  // _EJx: Eject Device, x=0-9
+{
+CEJ0 (0xFE)
+}
+
+Method (_OST, 3, Serialized)  // _OST: OSPM Status Indication
+{
+COST (0xFE, Arg0, Arg1, Arg2)
+}
+}
+
+Device (C0FF)
+{
+Name (_HID, "ACPI0007" /* Processor Device */)  // _HID: 
Hardware ID
+Name (_UID, 0xFF)  // _UID: Unique ID
+Method (_STA, 0, Serialized)  // _STA: Status
+{
+Return (CSTA (0xFF))
+}
+
+Name (_MAT, Buffer (0x10)  // _MAT: Multiple APIC Table Entry
+{
+/*  */  0x09, 0x10, 0x00, 0x00, 0xFF, 0x00, 0x00, 
0x00,  // 
+/* 0008 */  0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 
  // 
+})
+Method (_EJ0, 1, NotSerialized)  // _EJx: Eject Device, x=0-9
+{
+CEJ0 (0xFF)
+}
+
+Method (_OST, 3, Serialized)  // _OST: OSPM Status Indication
+{
+   COST (0x0101, Arg0, Arg1, Arg2)
+}
+}
...

Signed-off-by: Julia Suvorova 
---
 tests/qtest/bios-tables-test-allowed-diff.h |   3 ---
 tests/data/acpi/q35/APIC.core-count2| Bin 0 -> 2478 bytes
 tests/data/acpi/q35/DSDT.core-count2| Bin 0 -> 32429 bytes
 tests/data/acpi/q35/FACP.core-count2| Bin 0 -> 244 bytes
 4 files changed, 3 deletions(-)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index e81dc67a2e..dfb8523c8b 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,4 +1 @@
 /* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/q35/APIC.core-count2",
-"tests/data/acpi/q35/DSDT.core-count2",
-"tests/data/acpi/q35/FACP.core-count2",
diff --git a/tests/data/acpi/q35/APIC.core-count2 
b/tests/data/acpi/q35/APIC.core-count2
index 
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a255082ef5bc39f0d92d3e372b91f09dd6d0d9a1
 100644
GIT binary patch
literal 2478
zcmXZeWl$AS7=Youz=a#M-K}6ZwgLuNAQ;$~*xjvQcY@uCVs{~Sf`WpLVt2Rbe!ORA
z_B`J^b9R56*=M2p(=#;b`y@>U1KQZ2
ztu5Nwq0xx;_UPb%CKH;?XtAKxijI!xf-7uzGc@Q3Gq%
z#9Fnmc5SRv2fe+~#|M4+PE2*{()H?L{rcFT0s8r?h>aRyuWjcwXs+qT%Q9ky?e9Xepgju;w>ojPIX)|3
zcI}GYx?%V37#4;-dSK6<*sB-z?u~u=VBfyjuOIgBj{^qaz=1eu5Dp%ULx$kcp*U<9
z4j+yqM*9*twh;MlP^ZXAvuj}s=~#ECd*5{8FkL5Yu4b}wYY8_u3wKEHsHpMxM>q^-i%we;MT3UZ5u{MiV+Y2

Re: [PATCH] pc: q35: Bump max_cpus to 512

2022-05-19 Thread Julia Suvorova
On Tue, May 10, 2022 at 1:38 PM Igor Mammedov  wrote:
>
> On Tue, 10 May 2022 09:14:19 +0100
> Daniel P. Berrangé  wrote:
>
> > On Tue, May 10, 2022 at 09:03:25AM +0200, Igor Mammedov wrote:
> > > On Mon, 9 May 2022 13:03:38 +0100
> > > Daniel P. Berrangé  wrote:
> > >
> > > > On Mon, May 09, 2022 at 09:12:49AM +0200, Igor Mammedov wrote:
> > > > > On Wed, 4 May 2022 08:16:39 -0500
> > > > > Suravee Suthikulpanit  wrote:
> > > > >
> > > > > > This is the maximum number of vCPU supported by
> > > > > > the AMD x2APIC virtualization.
> > > > > >
> > > > > > Signed-off-by: Suravee Suthikulpanit 
> > > > > > ---
> > > > > >  hw/i386/pc_q35.c | 2 +-
> > > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > > >
> > > > > > diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
> > > > > > index 302288342a..e82b1c690d 100644
> > > > > > --- a/hw/i386/pc_q35.c
> > > > > > +++ b/hw/i386/pc_q35.c
> > > > > > @@ -357,7 +357,7 @@ static void pc_q35_machine_options(MachineClass 
> > > > > > *m)
> > > > > >  machine_class_allow_dynamic_sysbus_dev(m, 
> > > > > > TYPE_INTEL_IOMMU_DEVICE);
> > > > > >  machine_class_allow_dynamic_sysbus_dev(m, TYPE_RAMFB_DEVICE);
> > > > > >  machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
> > > > > > -m->max_cpus = 288;
> > > > > > +m->max_cpus = 512;
> > > > >
> > > > > Maybe we should bump it to KVM VCPU maximum,
> > > > > and make sure we error out if asked for combination of
> > > > > hardware/irqchip is not usable.
> > > >
> > > > In RHEL downstream we currently bump this to 710 CPUs, because you
> > > > overflow the SMBIOS 2.1 tables at approx 720 CPUs (give/take a little
> > > > depending on other config options).
> > >
> > > Also there were some testing done with 1024,
> > > but my main reason for matching KVM's limit is unblock upstream
> > > testing so it would be easier to push limits for others.
> > > Downstream can clamp that value down to whatever it deems as supported.
> > >
> > > > Going beyond 710 CPUs value requires using the SMBIOS 3 entry point.
> > > >
> > > > AFAIK, the x86 machine types still default to SMBIOS 2.1, so that
> > > > would need changing too.
> > >
> > > Yep, we can change default to SMBIOS 3 starting with new machine type 
> > > (7.1?)
> > > or conditionally depending on requested number of CPUs,
> > > though I'd prefer machine type approach.
> >
> > Agree, machine type is better IMHO, a it gives us a consistent guest
> > ABI regardless of CPU count.
> >
> > > As for SMBIOS 3, we still have to update CPU structures to support more 
> > > than
> > > 255 vcpus (Julia was working on it). It's long standing bug, but that 
> > > doesn't
> > > seem to be critical, as guest boots fine with old structures.
> >
> > What's the impact of SMBIOS 3 being limited to 255 ?  That's lower than
> > the current max CPUs of 288 in upstream / 710 in downstream.
>
> possibly users that look into SMBIOS for licensing purposes and/or inventory
> Julia told me that dmidecode somehow figures out correct number of total 
> vcpus.
>
> CCing Julia for patches ETA.

Should be this week.

Best regards, Julia Suvorova.

>
> >
> >
> > With regards,
> > Daniel
>




Re: [PATCH 4/5] hw/i386/acpi-build: Deny control on PCIe Native Hot-plug in _OSC

2021-11-10 Thread Julia Suvorova
On Wed, Nov 10, 2021 at 2:58 PM Igor Mammedov  wrote:
>
> On Wed, 10 Nov 2021 02:21:34 -0500
> "Michael S. Tsirkin"  wrote:
>
> > On Wed, Nov 10, 2021 at 06:30:13AM +0100, Julia Suvorova wrote:
> > > There are two ways to enable ACPI PCI Hot-plug:
> > >
> > > * Disable the Hot-plug Capable bit on PCIe slots.
> > >
> > > This was the first approach which led to regression [1-2], as
> > > I/O space for a port is allocated only when it is hot-pluggable,
> > > which is determined by HPC bit.
> > >
> > > * Leave the HPC bit on and disable PCIe Native Hot-plug in _OSC
> > >   method.
> > >
> > > This removes the (future) ability of hot-plugging switches with PCIe
> > > Native hotplug since ACPI PCI Hot-plug only works with cold-plugged
> > > bridges. If the user wants to explicitely use this feature, they can
> > > disable ACPI PCI Hot-plug with:
> > > --global ICH9-LPC.acpi-pci-hotplug-with-bridge-support=off
> > >
> > > Change the bit in _OSC method so that the OS selects ACPI PCI Hot-plug
> > > instead of PCIe Native.
> > >
> > > [1] https://gitlab.com/qemu-project/qemu/-/issues/641
> > > [2] https://bugzilla.redhat.com/show_bug.cgi?id=2006409
> > >
> > > Signed-off-by: Julia Suvorova 
> > > ---
> > >  hw/i386/acpi-build.c | 12 
> > >  1 file changed, 8 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > index a3ad6abd33..a2f92ab32b 100644
> > > --- a/hw/i386/acpi-build.c
> > > +++ b/hw/i386/acpi-build.c
> > > @@ -1337,7 +1337,7 @@ static void build_x86_acpi_pci_hotplug(Aml *table, 
> > > uint64_t pcihp_addr)
> > >  aml_append(table, scope);
> > >  }
> > >
> > > -static Aml *build_q35_osc_method(void)
> > > +static Aml *build_q35_osc_method(bool acpi_pcihp)
> > >  {
> > >  Aml *if_ctx;
> > >  Aml *if_ctx2;
> > > @@ -1345,6 +1345,7 @@ static Aml *build_q35_osc_method(void)
> > >  Aml *method;
> > >  Aml *a_cwd1 = aml_name("CDW1");
> > >  Aml *a_ctrl = aml_local(0);
> > > +const uint64_t hotplug = acpi_pcihp ? 0x1E : 0x1F;
> >
> > drop this variable and open-code at use point below.
> > As it is the comment is misplaced.
> > Also a slightly better way to write this:
> > 0x1E | (acpi_pcihp ? 0x0 : 0x1)
> >
> >
> >
> > >
> > >  method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
> > >  aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), 
> > > "CDW1"));
> >
> > So what acpi_pcihp does is enable/disable native pcie hotplug.
> > How about we call the option exactly that?
> >
> >
> > > @@ -1359,8 +1360,9 @@ static Aml *build_q35_osc_method(void)
> > >  /*
> > >   * Always allow native PME, AER (no dependencies)
> > >   * Allow SHPC (PCI bridges can have SHPC controller)
> > > + * Disable PCIe Native Hot-plug if ACPI PCI Hot-plug is enabled.
> > >   */
> > > -aml_append(if_ctx, aml_and(a_ctrl, aml_int(0x1F), a_ctrl));
> > > +aml_append(if_ctx, aml_and(a_ctrl, aml_int(hotplug), a_ctrl));
> > >
> >
> > using the variable hotplug just made things confusing,
> > open-coding will be clearer.
> >
> >
> > >  if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1;
> > >  /* Unknown revision */
> > > @@ -1449,7 +1451,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
> > >  aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
> > >  aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
> > >  aml_append(dev, aml_name_decl("_UID", 
> > > aml_int(pcmc->pci_root_uid)));
> > > -aml_append(dev, build_q35_osc_method());
> > > +aml_append(dev, build_q35_osc_method(pm->pcihp_bridge_en));
> > >  aml_append(sb_scope, dev);
> > >  if (mcfg_valid) {
> > >  aml_append(sb_scope, build_q35_dram_controller());
> >
> > One of the complaints of libvirt people was that the
> > name is confusing. It seems to say whether to describe bridges
> > in ACPI but it also disables native hotplug, but only for PCIe.
> >
> > Maybe we should address this with flags saying whether to enable each o

[PATCH 4/5] hw/i386/acpi-build: Deny control on PCIe Native Hot-plug in _OSC

2021-11-09 Thread Julia Suvorova
There are two ways to enable ACPI PCI Hot-plug:

* Disable the Hot-plug Capable bit on PCIe slots.

This was the first approach which led to regression [1-2], as
I/O space for a port is allocated only when it is hot-pluggable,
which is determined by HPC bit.

* Leave the HPC bit on and disable PCIe Native Hot-plug in _OSC
  method.

This removes the (future) ability of hot-plugging switches with PCIe
Native hotplug since ACPI PCI Hot-plug only works with cold-plugged
bridges. If the user wants to explicitely use this feature, they can
disable ACPI PCI Hot-plug with:
--global ICH9-LPC.acpi-pci-hotplug-with-bridge-support=off

Change the bit in _OSC method so that the OS selects ACPI PCI Hot-plug
instead of PCIe Native.

[1] https://gitlab.com/qemu-project/qemu/-/issues/641
[2] https://bugzilla.redhat.com/show_bug.cgi?id=2006409

Signed-off-by: Julia Suvorova 
---
 hw/i386/acpi-build.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index a3ad6abd33..a2f92ab32b 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1337,7 +1337,7 @@ static void build_x86_acpi_pci_hotplug(Aml *table, 
uint64_t pcihp_addr)
 aml_append(table, scope);
 }
 
-static Aml *build_q35_osc_method(void)
+static Aml *build_q35_osc_method(bool acpi_pcihp)
 {
 Aml *if_ctx;
 Aml *if_ctx2;
@@ -1345,6 +1345,7 @@ static Aml *build_q35_osc_method(void)
 Aml *method;
 Aml *a_cwd1 = aml_name("CDW1");
 Aml *a_ctrl = aml_local(0);
+const uint64_t hotplug = acpi_pcihp ? 0x1E : 0x1F;
 
 method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
 aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
@@ -1359,8 +1360,9 @@ static Aml *build_q35_osc_method(void)
 /*
  * Always allow native PME, AER (no dependencies)
  * Allow SHPC (PCI bridges can have SHPC controller)
+ * Disable PCIe Native Hot-plug if ACPI PCI Hot-plug is enabled.
  */
-aml_append(if_ctx, aml_and(a_ctrl, aml_int(0x1F), a_ctrl));
+aml_append(if_ctx, aml_and(a_ctrl, aml_int(hotplug), a_ctrl));
 
 if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1;
 /* Unknown revision */
@@ -1449,7 +1451,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
 aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
 aml_append(dev, aml_name_decl("_UID", aml_int(pcmc->pci_root_uid)));
-aml_append(dev, build_q35_osc_method());
+aml_append(dev, build_q35_osc_method(pm->pcihp_bridge_en));
 aml_append(sb_scope, dev);
 if (mcfg_valid) {
 aml_append(sb_scope, build_q35_dram_controller());
@@ -1565,7 +1567,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
 if (pci_bus_is_express(bus)) {
 aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
 aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
-aml_append(dev, build_q35_osc_method());
+
+/* Expander bridges do not have ACPI PCI Hot-plug enabled */
+aml_append(dev, build_q35_osc_method(false));
 } else {
 aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03")));
 }
-- 
2.31.1




[PATCH 3/5] bios-tables-test: Allow changes in DSDT ACPI tables

2021-11-09 Thread Julia Suvorova
Prepare for changing the _OSC method in q35 DSDT.

Signed-off-by: Julia Suvorova 
---
 tests/qtest/bios-tables-test-allowed-diff.h | 16 
 1 file changed, 16 insertions(+)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..48e5634d4b 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,17 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/DSDT",
+"tests/data/acpi/q35/DSDT.tis",
+"tests/data/acpi/q35/DSDT.bridge",
+"tests/data/acpi/q35/DSDT.mmio64",
+"tests/data/acpi/q35/DSDT.ipmibt",
+"tests/data/acpi/q35/DSDT.cphp",
+"tests/data/acpi/q35/DSDT.memhp",
+"tests/data/acpi/q35/DSDT.acpihmat",
+"tests/data/acpi/q35/DSDT.numamem",
+"tests/data/acpi/q35/DSDT.dimmpxm",
+"tests/data/acpi/q35/DSDT.nohpet",
+"tests/data/acpi/q35/DSDT.tis.tpm2",
+"tests/data/acpi/q35/DSDT.tis.tpm12",
+"tests/data/acpi/q35/DSDT.multi-bridge",
+"tests/data/acpi/q35/DSDT.ivrs",
+"tests/data/acpi/q35/DSDT.xapic",
-- 
2.31.1




[PATCH 1/5] hw/pci/pcie_port: Rename 'native-hotplug' to 'native-hpc-bit'

2021-11-09 Thread Julia Suvorova
Rename the option to better represent its function - toggle Hot-Plug
Capable bit in the PCIe Slot Capability.

Signed-off-by: Julia Suvorova 
---
 include/hw/pci/pcie_port.h | 2 +-
 hw/i386/pc_q35.c   | 2 +-
 hw/pci-bridge/gen_pcie_root_port.c | 6 +-
 hw/pci/pcie.c  | 2 +-
 hw/pci/pcie_port.c | 2 +-
 5 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h
index e25b289ce8..0da6d66c95 100644
--- a/include/hw/pci/pcie_port.h
+++ b/include/hw/pci/pcie_port.h
@@ -60,7 +60,7 @@ struct PCIESlot {
 /* Indicates whether any type of hot-plug is allowed on the slot */
 boolhotplug;
 
-boolnative_hotplug;
+boolnative_hpc_bit;
 
 QLIST_ENTRY(PCIESlot) next;
 };
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 797e09500b..ded61f8ef7 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -243,7 +243,7 @@ static void pc_q35_init(MachineState *machine)
   NULL);
 
 if (acpi_pcihp) {
-object_register_sugar_prop(TYPE_PCIE_SLOT, "native-hotplug",
+object_register_sugar_prop(TYPE_PCIE_SLOT, "native-hpc-bit",
"false", true);
 }
 
diff --git a/hw/pci-bridge/gen_pcie_root_port.c 
b/hw/pci-bridge/gen_pcie_root_port.c
index 20099a8ae3..ed079d72b3 100644
--- a/hw/pci-bridge/gen_pcie_root_port.c
+++ b/hw/pci-bridge/gen_pcie_root_port.c
@@ -87,7 +87,11 @@ static void gen_rp_realize(DeviceState *dev, Error **errp)
 return;
 }
 
-if (grp->res_reserve.io == -1 && s->hotplug && !s->native_hotplug) {
+/*
+ * Make sure that IO is assigned in case the slot is hot-pluggable
+ * but it is not visible through the PCIe Slot Capabilities
+ */
+if (grp->res_reserve.io == -1 && s->hotplug && !s->native_hpc_bit) {
 grp->res_reserve.io = GEN_PCIE_ROOT_DEFAULT_IO_RANGE;
 }
 int rc = pci_bridge_qemu_reserve_cap_init(d, 0,
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 914a9bf3d1..ebe002831e 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -535,7 +535,7 @@ void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s)
  * hot-plug is disabled on the slot.
  */
 if (s->hotplug &&
-(s->native_hotplug || DEVICE(dev)->hotplugged)) {
+(s->native_hpc_bit || DEVICE(dev)->hotplugged)) {
 pci_long_test_and_set_mask(dev->config + pos + PCI_EXP_SLTCAP,
PCI_EXP_SLTCAP_HPS |
PCI_EXP_SLTCAP_HPC);
diff --git a/hw/pci/pcie_port.c b/hw/pci/pcie_port.c
index da850e8dde..eae06d10e2 100644
--- a/hw/pci/pcie_port.c
+++ b/hw/pci/pcie_port.c
@@ -148,7 +148,7 @@ static Property pcie_slot_props[] = {
 DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
 DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
 DEFINE_PROP_BOOL("hotplug", PCIESlot, hotplug, true),
-DEFINE_PROP_BOOL("native-hotplug", PCIESlot, native_hotplug, true),
+DEFINE_PROP_BOOL("native-hpc-bit", PCIESlot, native_hpc_bit, true),
 DEFINE_PROP_END_OF_LIST()
 };
 
-- 
2.31.1




[PATCH 5/5] bios-tables-test: Update golden binaries

2021-11-09 Thread Julia Suvorova
The changes are the result of
'hw/i386/acpi-build: Deny control on PCIe Native Hot-Plug in _OSC'
and listed here:

Method (_OSC, 4, NotSerialized)  // _OSC: Operating System Capabilities
 {
 CreateDWordField (Arg3, Zero, CDW1)
 If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") 
/* PCI Host Bridge Device */))
 {
 CreateDWordField (Arg3, 0x04, CDW2)
 CreateDWordField (Arg3, 0x08, CDW3)
 Local0 = CDW3 /* \_SB_.PCI0._OSC.CDW3 */
-Local0 &= 0x1F
+Local0 &= 0x1E

Signed-off-by: Julia Suvorova 
---
 tests/qtest/bios-tables-test-allowed-diff.h |  16 
 tests/data/acpi/q35/DSDT| Bin 8289 -> 8289 bytes
 tests/data/acpi/q35/DSDT.acpihmat   | Bin 9614 -> 9614 bytes
 tests/data/acpi/q35/DSDT.bridge | Bin 11003 -> 11003 bytes
 tests/data/acpi/q35/DSDT.cphp   | Bin 8753 -> 8753 bytes
 tests/data/acpi/q35/DSDT.dimmpxm| Bin 9943 -> 9943 bytes
 tests/data/acpi/q35/DSDT.dmar   | Bin 0 -> 8289 bytes
 tests/data/acpi/q35/DSDT.ipmibt | Bin 8364 -> 8364 bytes
 tests/data/acpi/q35/DSDT.ivrs   | Bin 8306 -> 8306 bytes
 tests/data/acpi/q35/DSDT.memhp  | Bin 9648 -> 9648 bytes
 tests/data/acpi/q35/DSDT.mmio64 | Bin 9419 -> 9419 bytes
 tests/data/acpi/q35/DSDT.multi-bridge   | Bin 8583 -> 8583 bytes
 tests/data/acpi/q35/DSDT.nohpet | Bin 8147 -> 8147 bytes
 tests/data/acpi/q35/DSDT.nosmm  | Bin 0 -> 8289 bytes
 tests/data/acpi/q35/DSDT.numamem| Bin 8295 -> 8295 bytes
 tests/data/acpi/q35/DSDT.smm-compat | Bin 0 -> 8289 bytes
 tests/data/acpi/q35/DSDT.smm-compat-nosmm   | Bin 0 -> 8289 bytes
 tests/data/acpi/q35/DSDT.tis.tpm12  | Bin 8894 -> 8894 bytes
 tests/data/acpi/q35/DSDT.tis.tpm2   | Bin 8894 -> 8894 bytes
 tests/data/acpi/q35/DSDT.xapic  | Bin 35652 -> 35652 bytes
 20 files changed, 16 deletions(-)
 create mode 100644 tests/data/acpi/q35/DSDT.dmar
 create mode 100644 tests/data/acpi/q35/DSDT.nosmm
 create mode 100644 tests/data/acpi/q35/DSDT.smm-compat
 create mode 100644 tests/data/acpi/q35/DSDT.smm-compat-nosmm

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index 48e5634d4b..dfb8523c8b 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,17 +1 @@
 /* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/q35/DSDT",
-"tests/data/acpi/q35/DSDT.tis",
-"tests/data/acpi/q35/DSDT.bridge",
-"tests/data/acpi/q35/DSDT.mmio64",
-"tests/data/acpi/q35/DSDT.ipmibt",
-"tests/data/acpi/q35/DSDT.cphp",
-"tests/data/acpi/q35/DSDT.memhp",
-"tests/data/acpi/q35/DSDT.acpihmat",
-"tests/data/acpi/q35/DSDT.numamem",
-"tests/data/acpi/q35/DSDT.dimmpxm",
-"tests/data/acpi/q35/DSDT.nohpet",
-"tests/data/acpi/q35/DSDT.tis.tpm2",
-"tests/data/acpi/q35/DSDT.tis.tpm12",
-"tests/data/acpi/q35/DSDT.multi-bridge",
-"tests/data/acpi/q35/DSDT.ivrs",
-"tests/data/acpi/q35/DSDT.xapic",
diff --git a/tests/data/acpi/q35/DSDT b/tests/data/acpi/q35/DSDT
index 
281fc82c03b2562d2e6b7caec0d817b034a47138..c1965f6051ef2af81dd8412abe169d87845bb033
 100644
GIT binary patch
delta 24
gcmaFp@X&$FCDET<0BnZ{w*UYD

delta 24
gcmaFp@X&$FCDET<0BnK?w*UYD

diff --git a/tests/data/acpi/q35/DSDT.acpihmat 
b/tests/data/acpi/q35/DSDT.acpihmat
index 
8c1e05a11a328ec1cc6f86e36e52c28f41f9744e..f24d4874bff8d327a165ed7c36de507aea114edd
 100644
GIT binary patch
delta 24
fcmeD4?(^ny33dtTQ)OUa+&+=(3ZvY{`|DKzU@Hhn

delta 24
fcmeD4?(^ny33dtTQ)OUa+%}Qx3ZwkS`|DKzU?vDi

diff --git a/tests/data/acpi/q35/DSDT.bridge b/tests/data/acpi/q35/DSDT.bridge
index 
6f1464b6c712d7f33cb4b891b7ce76fe228f44c9..424d51bd1cb39ea73501ef7d0044ee52cec5bdac
 100644
GIT binary patch
delta 24
gcmewz`a6`%CDF$oF>WH)6-K#@_k$DxTWtqt

delta 24
fcmdn!veAXhCDF$oF?J%?6-N1u_k$DxTWAMo

diff --git a/tests/data/acpi/q35/DSDT.dimmpxm b/tests/data/acpi/q35/DSDT.dimmpxm
index 
fe5820d93d057ef09a001662369b15afbc5b87e2..76e451e829ec4c245315f7eed8731aa1be45a747
 100644
GIT binary patch
delta 24
gcmccad)=4ICDU+JE-@
z{(rvNo&8obUf^~51;{egaP$<9Ry9N9V#u%N`U#F3{%(}Z?xz;n%v4qjRo#y8_
zl+FB)z4BJg`29}!c^JO+QE2odcI6A_vn&1RgFE3BMxa|)BFmx^r?Sus%DwKMYx!=Y
zX!hz2`W%Ota^Tv$)wSd2MF)wi+JGug~>10ylB@26MejtHV}uu#;V~oNn`<=e{|8
z@)w_9daHE*=l}TS-5XW{fV22(;_tbL4)V>pAN1W?-QM0TOBTaI^dT@n?qNk
zkXr89qKQ(i?%(L{z38<|F7IQ;Z}~;HxQc$c?I3{DEGV>S{r)r>js7A|nez^F
znx;@$G3$P%BUKvEMyk5Ib-(OIO|wMzwnOpK%axW_@Y`Omkbk}xbV@9umN25G
z{=1>+!-Y=2-W`>w_s*}CJ%GhMilg`Fl`M1ATCN!(

[PATCH 2/5] hw/acpi/ich9: Add compatibility option for 'native-hpc-bit'

2021-11-09 Thread Julia Suvorova
To solve issues [1-2] the Hot Plug Capable bit in PCIe Slots will be
turned on, while the switch to ACPI Hot-plug will be done in the
DSDT table.

Introducing 'x-keep-native-hpc' option disables the HPC bit only
in 6.1 and as a result keeps the forced 'reserve-io' on
pcie-root-ports in 6.1 too.

[1] https://gitlab.com/qemu-project/qemu/-/issues/641
[2] https://bugzilla.redhat.com/show_bug.cgi?id=2006409

Signed-off-by: Julia Suvorova 
---
 include/hw/acpi/ich9.h |  1 +
 hw/acpi/ich9.c | 18 ++
 hw/i386/pc.c   |  2 ++
 hw/i386/pc_q35.c   |  7 ++-
 4 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index f04f1791bd..7ca92843c6 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -56,6 +56,7 @@ typedef struct ICH9LPCPMRegs {
 AcpiCpuHotplug gpe_cpu;
 CPUHotplugState cpuhp_state;
 
+bool keep_pci_slot_hpc;
 bool use_acpi_hotplug_bridge;
 AcpiPciHpState acpi_pci_hotplug;
 MemHotplugState acpi_memory_hotplug;
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 1ee2ba2c50..ebe08ed831 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -419,6 +419,20 @@ static void ich9_pm_set_acpi_pci_hotplug(Object *obj, bool 
value, Error **errp)
 s->pm.use_acpi_hotplug_bridge = value;
 }
 
+static bool ich9_pm_get_keep_pci_slot_hpc(Object *obj, Error **errp)
+{
+ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
+
+return s->pm.keep_pci_slot_hpc;
+}
+
+static void ich9_pm_set_keep_pci_slot_hpc(Object *obj, bool value, Error 
**errp)
+{
+ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
+
+s->pm.keep_pci_slot_hpc = value;
+}
+
 void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 {
 static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN;
@@ -428,6 +442,7 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 pm->disable_s4 = 0;
 pm->s4_val = 2;
 pm->use_acpi_hotplug_bridge = true;
+pm->keep_pci_slot_hpc = true;
 
 object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
>pm_io_base, OBJ_PROP_FLAG_READ);
@@ -454,6 +469,9 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 object_property_add_bool(obj, ACPI_PM_PROP_ACPI_PCIHP_BRIDGE,
  ich9_pm_get_acpi_pci_hotplug,
  ich9_pm_set_acpi_pci_hotplug);
+object_property_add_bool(obj, "x-keep-pci-slot-hpc",
+ ich9_pm_get_keep_pci_slot_hpc,
+ ich9_pm_set_keep_pci_slot_hpc);
 }
 
 void ich9_pm_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 2592a82148..a2ef40ecbc 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -98,6 +98,7 @@ GlobalProperty pc_compat_6_1[] = {
 { TYPE_X86_CPU, "hv-version-id-build", "0x1bbc" },
 { TYPE_X86_CPU, "hv-version-id-major", "0x0006" },
 { TYPE_X86_CPU, "hv-version-id-minor", "0x0001" },
+{ "ICH9-LPC", "x-keep-pci-slot-hpc", "false" },
 };
 const size_t pc_compat_6_1_len = G_N_ELEMENTS(pc_compat_6_1);
 
@@ -107,6 +108,7 @@ GlobalProperty pc_compat_6_0[] = {
 { "qemu64" "-" TYPE_X86_CPU, "stepping", "3" },
 { TYPE_X86_CPU, "x-vendor-cpuid-only", "off" },
 { "ICH9-LPC", ACPI_PM_PROP_ACPI_PCIHP_BRIDGE, "off" },
+{ "ICH9-LPC", "x-keep-pci-slot-hpc", "true" },
 };
 const size_t pc_compat_6_0_len = G_N_ELEMENTS(pc_compat_6_0);
 
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index ded61f8ef7..06f09dfcc6 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -137,6 +137,7 @@ static void pc_q35_init(MachineState *machine)
 DriveInfo *hd[MAX_SATA_PORTS];
 MachineClass *mc = MACHINE_GET_CLASS(machine);
 bool acpi_pcihp;
+bool keep_pci_slot_hpc;
 
 /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory
  * and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping
@@ -242,7 +243,11 @@ static void pc_q35_init(MachineState *machine)
   ACPI_PM_PROP_ACPI_PCIHP_BRIDGE,
   NULL);
 
-if (acpi_pcihp) {
+keep_pci_slot_hpc = object_property_get_bool(OBJECT(lpc),
+ "x-keep-pci-slot-hpc",
+ NULL);
+
+if (!keep_pci_slot_hpc && acpi_pcihp) {
 object_register_sugar_prop(TYPE_PCIE_SLOT, "native-hpc-bit",
"false", true);
 }
-- 
2.31.1




[PATCH 0/5] Fix Q35 ACPI PCI Hot-plug I/O issues

2021-11-09 Thread Julia Suvorova
Attempt [1] to fix I/O allocation with the 'reserve-io' hint on each
pcie-root-port resulted in regression [2-3]. This patchset aims to fix
it by addressing the root cause of the problem - the disabled PCIe
Slot HPC bit.

[1] 'hw/pcie-root-port: Fix hotplug for PCI devices requiring IO'
[2] https://gitlab.com/qemu-project/qemu/-/issues/641
[3] https://bugzilla.redhat.com/show_bug.cgi?id=2006409

Julia Suvorova (5):
  hw/pci/pcie_port: Rename 'native-hotplug' to 'native-hpc-bit'
  hw/acpi/ich9: Add compatibility option for 'native-hpc-bit'
  bios-tables-test: Allow changes in DSDT ACPI tables
  hw/i386/acpi-build: Deny control on PCIe Native Hot-plug in _OSC
  bios-tables-test: Update golden binaries

 include/hw/acpi/ich9.h|   1 +
 include/hw/pci/pcie_port.h|   2 +-
 hw/acpi/ich9.c|  18 ++
 hw/i386/acpi-build.c  |  12 
 hw/i386/pc.c  |   2 ++
 hw/i386/pc_q35.c  |   9 +++--
 hw/pci-bridge/gen_pcie_root_port.c|   6 +-
 hw/pci/pcie.c |   2 +-
 hw/pci/pcie_port.c|   2 +-
 tests/data/acpi/q35/DSDT  | Bin 8289 -> 8289 bytes
 tests/data/acpi/q35/DSDT.acpihmat | Bin 9614 -> 9614 bytes
 tests/data/acpi/q35/DSDT.bridge   | Bin 11003 -> 11003 bytes
 tests/data/acpi/q35/DSDT.cphp | Bin 8753 -> 8753 bytes
 tests/data/acpi/q35/DSDT.dimmpxm  | Bin 9943 -> 9943 bytes
 tests/data/acpi/q35/DSDT.dmar | Bin 0 -> 8289 bytes
 tests/data/acpi/q35/DSDT.ipmibt   | Bin 8364 -> 8364 bytes
 tests/data/acpi/q35/DSDT.ivrs | Bin 8306 -> 8306 bytes
 tests/data/acpi/q35/DSDT.memhp| Bin 9648 -> 9648 bytes
 tests/data/acpi/q35/DSDT.mmio64   | Bin 9419 -> 9419 bytes
 tests/data/acpi/q35/DSDT.multi-bridge | Bin 8583 -> 8583 bytes
 tests/data/acpi/q35/DSDT.nohpet   | Bin 8147 -> 8147 bytes
 tests/data/acpi/q35/DSDT.nosmm| Bin 0 -> 8289 bytes
 tests/data/acpi/q35/DSDT.numamem  | Bin 8295 -> 8295 bytes
 tests/data/acpi/q35/DSDT.smm-compat   | Bin 0 -> 8289 bytes
 tests/data/acpi/q35/DSDT.smm-compat-nosmm | Bin 0 -> 8289 bytes
 tests/data/acpi/q35/DSDT.tis.tpm12| Bin 8894 -> 8894 bytes
 tests/data/acpi/q35/DSDT.tis.tpm2 | Bin 8894 -> 8894 bytes
 tests/data/acpi/q35/DSDT.xapic| Bin 35652 -> 35652 bytes
 28 files changed, 44 insertions(+), 10 deletions(-)
 create mode 100644 tests/data/acpi/q35/DSDT.dmar
 create mode 100644 tests/data/acpi/q35/DSDT.nosmm
 create mode 100644 tests/data/acpi/q35/DSDT.smm-compat
 create mode 100644 tests/data/acpi/q35/DSDT.smm-compat-nosmm

-- 
2.31.1




Re: [PULL 1/5] hw/pcie-root-port: Fix hotplug for PCI devices requiring IO

2021-11-02 Thread Julia Suvorova
On Tue, Nov 2, 2021 at 10:26 AM Daniel P. Berrangé  wrote:
>
> On Mon, Sep 27, 2021 at 05:49:15AM -0400, Michael S. Tsirkin wrote:
> > On Mon, Sep 27, 2021 at 10:33:42AM +0100, Daniel P. Berrangé wrote:
> > > On Tue, Aug 03, 2021 at 04:52:03PM -0400, Michael S. Tsirkin wrote:
> > > > From: Marcel Apfelbaum 
> > > >
> > > > Q35 has now ACPI hotplug enabled by default for PCI(e) devices.
> > > > As opposed to native PCIe hotplug, guests like Fedora 34
> > > > will not assign IO range to pcie-root-ports not supporting
> > > > native hotplug, resulting into a regression.
> > > >
> > > > Reproduce by:
> > > > qemu-bin -M q35 -device pcie-root-port,id=p1 -monitor stdio
> > > > device_add e1000,bus=p1
> > > > In the Guest OS the respective pcie-root-port will have the IO range
> > > > disabled.
> > > >
> > > > Fix it by setting the "reserve-io" hint capability of the
> > > > pcie-root-ports so the firmware will allocate the IO range instead.
> > > >
> > > > Acked-by: Igor Mammedov 
> > > > Signed-off-by: Marcel Apfelbaum 
> > > > Message-Id: <20210802090057.1709775-1-mar...@redhat.com>
> > > > Reviewed-by: Michael S. Tsirkin 
> > > > Signed-off-by: Michael S. Tsirkin 
> > > > ---
> > > >  hw/pci-bridge/gen_pcie_root_port.c | 5 +
> > > >  1 file changed, 5 insertions(+)
> > >
> > > This change, when combined with the switch to ACPI based hotplug by
> > > default, is responsible for a significant regression in QEMU 6.1.0
> > >
> > > It is no longer possible to have more than 15 pcie-root-port devices
> > > added to a q35 VM in 6.1.0.  Before this I've had as many as 80+ devices
> > > present before I stopped trying to add more.
> > >
> > >   https://gitlab.com/qemu-project/qemu/-/issues/641
> > >
> > > This regression is significant, because it has broken the out of the
> > > box default configuration that OpenStack uses for booting all VMs.
> > > They add 16 pcie-root-ports by defalt to allow empty slots for device
> > > hotplug under q35 [1].
> >
> >
> > Indeed, oops. Thanks for the report!
>
> We're at soft freeze now and this is still broken in git master.
> I don't recall seeing a fix for this problem on list and no one has
> commented on the bug report.
>
> Is anyone actively working on a fix for this release ?

Yes, I'm working on a fix, going to send it soon.

Best regards, Julia Suvorova.

> If not, I'm going to post a patch to revert to PCI native
> hotplug, because this was a significant regression in 6.1 that
> breaks openstack out of the box and we can't leave it broken
> again for 6.2.
>
> Regards,
> Daniel
> --
> |: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org -o-https://fstop138.berrange.com :|
> |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|
>
>




Re: [PATCH 2/3] hw/i386/acpi: fix conflicting IO address range for acpi pci hotplug in q35

2021-09-16 Thread Julia Suvorova
On Tue, Sep 14, 2021 at 6:54 AM Ani Sinha  wrote:
>
> Change caf108bc58790 ("hw/i386/acpi-build: Add ACPI PCI hot-plug methods to 
> Q35")
> selects an IO address range for acpi based PCI hotplug for q35 arbitrarily. It
> starts at address 0x0cc4 and ends at 0x0cdb. At the time when the patch was
> written but the final version of the patch was not yet pushed upstream, this
> address range was free and did not conflict with any other IO address ranges.
> However, with the following change, this address range was no
> longer conflict free as in this change, the IO address range
> (value of ACPI_PCIHP_SIZE) was incremented by four bytes:
>
> b32bd763a1ca92 ("pci: introduce acpi-index property for PCI device")
>
> This can be seen from the output of QMP command 'info mtree' :
>
> 0600-0603 (prio 0, i/o): acpi-evt
> 0604-0605 (prio 0, i/o): acpi-cnt
> 0608-060b (prio 0, i/o): acpi-tmr
> 0620-062f (prio 0, i/o): acpi-gpe0
> 0630-0637 (prio 0, i/o): acpi-smi
> 0cc4-0cdb (prio 0, i/o): acpi-pci-hotplug
> 0cd8-0ce3 (prio 0, i/o): acpi-cpu-hotplug
>
> It shows that there is a region of conflict between IO regions of acpi
> pci hotplug and acpi cpu hotplug.
>
> Unfortunately, the change caf108bc58790 did not update the IO address range
> appropriately before it was pushed upstream to accomodate

s/accomodate/accommodate

> the increased
> length of the IO address space introduced in change b32bd763a1ca92.
>
> Due to this bug, windows guests complain 'This device cannot find
> enough free resources it can use' in the device manager panel for extended
> IO buses. This issue also breaks the correct functioning of pci hotplug as the
> following shows that the IO space for pci hotplug has been truncated:
>
> (qemu) info mtree -f
> FlatView #0
>  AS "I/O", root: io
>  Root memory region: io
>   0cc4-0cd7 (prio 0, i/o): acpi-pci-hotplug
>   0cd8-0cf7 (prio 0, i/o): acpi-cpu-hotplug
>
> Therefore, in this fix, we adjust the IO address range for the acpi pci
> hotplug so that it does not conflict with cpu hotplug and there is no
> truncation of IO spaces. The starting IO address of PCI hotplug region
> has been decremented by four bytes in order to accomodate

same

> four byte
> increment in the IO address space introduced by change
> b32bd763a1ca92 ("pci: introduce acpi-index property for PCI device")
>
> After fixing, the following are the corrected IO ranges:
>
> 0600-0603 (prio 0, i/o): acpi-evt
> 0604-0605 (prio 0, i/o): acpi-cnt
> 0608-060b (prio 0, i/o): acpi-tmr
> 0620-062f (prio 0, i/o): acpi-gpe0
> 0630-0637 (prio 0, i/o): acpi-smi
> 0cc0-0cd7 (prio 0, i/o): acpi-pci-hotplug
> 0cd8-0ce3 (prio 0, i/o): acpi-cpu-hotplug
>
> This change has been tested using a Windows Server 2019 guest VM. Windows
> no longer complains after this change.
>
> Fixes: caf108bc58790 ("hw/i386/acpi-build: Add ACPI PCI hot-plug methods to 
> Q35")
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/561
>
> Signed-off-by: Ani Sinha 

On the code itself:
Reviewed-by: Julia Suvorova 


> ---
>  include/hw/acpi/ich9.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
> index a329ce43ab..f04f1791bd 100644
> --- a/include/hw/acpi/ich9.h
> +++ b/include/hw/acpi/ich9.h
> @@ -29,7 +29,7 @@
>  #include "hw/acpi/acpi_dev_interface.h"
>  #include "hw/acpi/tco.h"
>
> -#define ACPI_PCIHP_ADDR_ICH9 0x0cc4
> +#define ACPI_PCIHP_ADDR_ICH9 0x0cc0
>
>  typedef struct ICH9LPCPMRegs {
>  /*
> --
> 2.25.1
>




[PATCH v6 5/6] hw/acpi/ich9: Set ACPI PCI hot-plug as default on Q35

2021-07-12 Thread Julia Suvorova
Q35 has three different types of PCI devices hot-plug: PCIe Native,
SHPC Native and ACPI hot-plug. This patch changes the default choice
for cold-plugged bridges from PCIe Native to ACPI Hot-plug with
ability to use SHPC and PCIe Native for hot-plugged bridges.

This is a list of the PCIe Native hot-plug issues that led to this
change:
* no racy behavior during boot (see 110c477c2ed)
* no delay during deleting - after the actual power off software
  must wait at least 1 second before indicating about it. This case
  is quite important for users, it even has its own bug:
  https://bugzilla.redhat.com/show_bug.cgi?id=1594168
* no timer-based behavior - in addition to the previous example,
  the attention button has a 5-second waiting period, during which
  the operation can be canceled with a second press. While this
  looks fine for manual button control, automation will result in
  the need to queue or drop events, and the software receiving
  events in all sort of unspecified combinations of attention/power
  indicator states, which is racy and uppredictable.
* fixes:
* https://bugzilla.redhat.com/show_bug.cgi?id=1752465
* https://bugzilla.redhat.com/show_bug.cgi?id=1690256

To return to PCIe Native hot-plug:
-global ICH9-LPC.acpi-pci-hotplug-with-bridge-support=off

Signed-off-by: Julia Suvorova 
Reviewed-by: Igor Mammedov 
---
 hw/acpi/ich9.c | 2 +-
 hw/i386/pc.c   | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 2f4eb453ac..778e27b659 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -427,7 +427,7 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 pm->disable_s3 = 0;
 pm->disable_s4 = 0;
 pm->s4_val = 2;
-pm->use_acpi_hotplug_bridge = false;
+pm->use_acpi_hotplug_bridge = true;
 
 object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
>pm_io_base, OBJ_PROP_FLAG_READ);
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 8e1220db72..7e03848792 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -98,6 +98,7 @@ GlobalProperty pc_compat_6_0[] = {
 { "qemu64" "-" TYPE_X86_CPU, "family", "6" },
 { "qemu64" "-" TYPE_X86_CPU, "model", "6" },
 { "qemu64" "-" TYPE_X86_CPU, "stepping", "3" },
+{ "ICH9-LPC", "acpi-pci-hotplug-with-bridge-support", "off" },
 };
 const size_t pc_compat_6_0_len = G_N_ELEMENTS(pc_compat_6_0);
 
-- 
2.30.2




[PATCH v6 6/6] bios-tables-test: Update golden binaries

2021-07-12 Thread Julia Suvorova
Add ACPI hot-plug registers to DSDT Q35 tables.
Changes in the tables:

+Scope (_SB.PCI0)
+{
+OperationRegion (PCST, SystemIO, 0x0CC4, 0x08)
+Field (PCST, DWordAcc, NoLock, WriteAsZeros)
+{
+PCIU,   32,
+PCID,   32
+}
+
+OperationRegion (SEJ, SystemIO, 0x0CCC, 0x04)
+Field (SEJ, DWordAcc, NoLock, WriteAsZeros)
+{
+B0EJ,   32
+}
+
+OperationRegion (BNMR, SystemIO, 0x0CD4, 0x08)
+Field (BNMR, DWordAcc, NoLock, WriteAsZeros)
+{
+BNUM,   32,
+PIDX,   32
+}
+
+Mutex (BLCK, 0x00)
+Method (PCEJ, 2, NotSerialized)
+{
+Acquire (BLCK, 0x)
+BNUM = Arg0
+B0EJ = (One << Arg1)
+Release (BLCK)
+Return (Zero)
+}
+
+Method (AIDX, 2, NotSerialized)
+{
+Acquire (BLCK, 0x)
+BNUM = Arg0
+PIDX = (One << Arg1)
+Local0 = PIDX /* \_SB_.PCI0.PIDX */
+Release (BLCK)
+Return (Local0)
+}
+
+Method (PDSM, 6, Serialized)
+{
+If ((Arg0 == ToUUID ("e5c937d0-3553-4d7a-9117-ea4d19c3434d") /* 
Device Labeling Interface */))
+{
+Local0 = AIDX (Arg4, Arg5)
+If ((Arg2 == Zero))
+{
+If ((Arg1 == 0x02))
+{
+If (!((Local0 == Zero) | (Local0 == 0x)))
+{
+Return (Buffer (One)
+{
+ 0x81  
   // .
+})
+}
+}
+
+Return (Buffer (One)
+{
+ 0x00 // .
+})
+}
+ElseIf ((Arg2 == 0x07))
+{
+Local1 = Package (0x02)
+{
+Zero,
+""
+}
+Local1 [Zero] = Local0
+Return (Local1)
+}
+}
+}
+}
+
...

 Scope (_GPE)
 {
 Name (_HID, "ACPI0006" /* GPE Block Device */)  // _HID: Hardware ID
+Method (_E01, 0, NotSerialized)  // _Exx: Edge-Triggered GPE, 
xx=0x00-0xFF
+{
+Acquire (\_SB.PCI0.BLCK, 0x)
+\_SB.PCI0.PCNT ()
+Release (\_SB.PCI0.BLCK)
+}
...

+
+Device (PHPR)
+{
+Name (_HID, "PNP0A06" /* Generic Container Device */)  // _HID: 
Hardware ID
+Name (_UID, "PCI Hotplug resources")  // _UID: Unique ID
+Name (_STA, 0x0B)  // _STA: Status
+Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
+{
+IO (Decode16,
+0x0CC4, // Range Minimum
+0x0CC4, // Range Maximum
+0x01,   // Alignment
+0x18,   // Length
+)
+})
+}
 }
...

And if there is a port in configuration:

 Device (S10)
 {
 Name (_ADR, 0x0002)  // _ADR: Address
+Name (BSEL, Zero)
+Device (S00)
+{
+Name (_SUN, Zero)  // _SUN: Slot User Number
+Name (_ADR, Zero)  // _ADR: Address
+Method (_EJ0, 1, NotSerialized)  // _EJx: Eject Device, 
x=0-9
+{
+PCEJ (BSEL, _SUN)
+}
+
+Method (_DSM, 4, Serialized)  // _DSM: Device-Specific 
Method
+{
+Return (PDSM (Arg0, Arg1, Arg2, Arg3, BSEL, _SUN))
+}
+}
+
...

+Method (DVNT, 2, NotSerialized)
+{
+If ((Arg0 & One))
+{
+Notify (S00, Arg1)
+}
...

Signed-off-by: Julia Suvorova 
---
 tests/qtest/bios-tables-test-allowed-diff.h |  11 ---
 tests/data/acpi/q35/DSDT| Bin 7859 -> 8289 bytes
 tests/data/acpi/q35/DSDT.acpihmat   | Bin 9184 -> 9614 bytes
 tests/data/acpi/q35/DSDT.bridge | Bin 7877 -> 11003 bytes
 tests/data/acpi/q35/DSDT.cphp   | Bin 8323 -> 8753 bytes
 tests/data/acpi/q35/DSDT.dimmpxm| Bin 9513 -> 9943 bytes
 tests/data/acpi/q35/DSDT.ipmibt | Bin 7934 -> 8364 bytes
 tests/data/acpi/q35/DSDT.memhp  | Bin 9218 -> 9648 bytes

[PATCH v6 1/6] hw/i386/acpi-build: Add ACPI PCI hot-plug methods to Q35

2021-07-12 Thread Julia Suvorova
Implement notifications and gpe to support q35 ACPI PCI hot-plug.
Use 0xcc4 - 0xcd7 range for 'acpi-pci-hotplug' io ports.

Signed-off-by: Julia Suvorova 
Reviewed-by: Igor Mammedov 
Reviewed-by: Marcel Apfelbaum 
---
 hw/i386/acpi-build.h|  4 
 include/hw/acpi/ich9.h  |  2 ++
 include/hw/acpi/pcihp.h |  3 ++-
 hw/acpi/pcihp.c |  6 +++---
 hw/acpi/piix4.c |  4 +++-
 hw/i386/acpi-build.c| 30 +++---
 6 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
index 74df5fc612..487ec7710f 100644
--- a/hw/i386/acpi-build.h
+++ b/hw/i386/acpi-build.h
@@ -5,6 +5,10 @@
 
 extern const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio;
 
+/* PCI Hot-plug registers bases. See docs/spec/acpi_pci_hotplug.txt */
+#define ACPI_PCIHP_SEJ_BASE 0x8
+#define ACPI_PCIHP_BNMR_BASE 0x10
+
 void acpi_setup(void);
 
 #endif
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index df519e40b5..596120d97f 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -28,6 +28,8 @@
 #include "hw/acpi/acpi_dev_interface.h"
 #include "hw/acpi/tco.h"
 
+#define ACPI_PCIHP_ADDR_ICH9 0x0cc4
+
 typedef struct ICH9LPCPMRegs {
 /*
  * In ich9 spec says that pm1_cnt register is 32bit width and
diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
index 2dd90aea30..af1a169fc3 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -55,7 +55,8 @@ typedef struct AcpiPciHpState {
 } AcpiPciHpState;
 
 void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root,
- MemoryRegion *address_space_io, bool bridges_enabled);
+ MemoryRegion *address_space_io, bool bridges_enabled,
+ uint16_t io_base);
 
 void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp);
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 4999277d57..d98a284b7a 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -37,7 +37,6 @@
 #include "qom/qom-qobject.h"
 #include "trace.h"
 
-#define ACPI_PCIHP_ADDR 0xae00
 #define ACPI_PCIHP_SIZE 0x0018
 #define PCI_UP_BASE 0x
 #define PCI_DOWN_BASE 0x0004
@@ -488,10 +487,11 @@ static const MemoryRegionOps acpi_pcihp_io_ops = {
 };
 
 void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
- MemoryRegion *address_space_io, bool bridges_enabled)
+ MemoryRegion *address_space_io, bool bridges_enabled,
+ uint16_t io_base)
 {
 s->io_len = ACPI_PCIHP_SIZE;
-s->io_base = ACPI_PCIHP_ADDR;
+s->io_base = io_base;
 
 s->root = root_bus;
 s->legacy_piix = !bridges_enabled;
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 0bd23d74e2..48f7a1edbc 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -49,6 +49,8 @@
 #define GPE_BASE 0xafe0
 #define GPE_LEN 4
 
+#define ACPI_PCIHP_ADDR_PIIX4 0xae00
+
 struct pci_status {
 uint32_t up; /* deprecated, maintained for migration compatibility */
 uint32_t down;
@@ -607,7 +609,7 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
*parent,
 
 if (s->use_acpi_hotplug_bridge || s->use_acpi_root_pci_hotplug) {
 acpi_pcihp_init(OBJECT(s), >acpi_pci_hotplug, bus, parent,
-s->use_acpi_hotplug_bridge);
+s->use_acpi_hotplug_bridge, ACPI_PCIHP_ADDR_PIIX4);
 }
 
 s->cpu_hotplug_legacy = true;
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 357437ff1d..e1c246d6e8 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -219,10 +219,6 @@ static void acpi_get_pm_info(MachineState *machine, 
AcpiPmInfo *pm)
 /* w2k requires FADT(rev1) or it won't boot, keep PC compatible */
 pm->fadt.rev = 1;
 pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE;
-pm->pcihp_io_base =
-object_property_get_uint(obj, ACPI_PCIHP_IO_BASE_PROP, NULL);
-pm->pcihp_io_len =
-object_property_get_uint(obj, ACPI_PCIHP_IO_LEN_PROP, NULL);
 }
 if (lpc) {
 uint64_t smi_features = object_property_get_uint(lpc,
@@ -238,6 +234,10 @@ static void acpi_get_pm_info(MachineState *machine, 
AcpiPmInfo *pm)
 pm->smi_on_cpu_unplug =
 !!(smi_features & BIT_ULL(ICH9_LPC_SMI_F_CPU_HOT_UNPLUG_BIT));
 }
+pm->pcihp_io_base =
+object_property_get_uint(obj, ACPI_PCIHP_IO_BASE_PROP, NULL);
+pm->pcihp_io_len =
+object_property_get_uint(obj, ACPI_PCIHP_IO_LEN_PROP, NULL);
 
 /* The above need not be conditional on machine type because the reset port
  * happens to be the same on PIIX (pc) and ICH9 (q35). */
@@ -392,6 +392,9 @@ static void build_append_pci_bus_devices(Aml *parent_scope, 
PCIBus *bus,
 
 if (!pdev) {
 if (bsel) { /* add

[PATCH v6 3/6] hw/pci/pcie: Do not set HPC flag if acpihp is used

2021-07-12 Thread Julia Suvorova
Instead of changing the hot-plug type in _OSC register, do not
set the 'Hot-Plug Capable' flag. This way guest will choose ACPI
hot-plug if it is preferred and leave the option to use SHPC with
pcie-pci-bridge.

The ability to control hot-plug for each downstream port is retained,
while 'hotplug=off' on the port means all hot-plug types are disabled.

Signed-off-by: Julia Suvorova 
Reviewed-by: Igor Mammedov 
Reviewed-by: Marcel Apfelbaum 
Reviewed-by: David Gibson 
---
 include/hw/pci/pcie_port.h |  5 -
 hw/acpi/pcihp.c|  8 
 hw/core/machine.c  |  1 -
 hw/i386/pc_q35.c   | 11 +++
 hw/pci/pcie.c  |  8 +++-
 hw/pci/pcie_port.c |  1 +
 6 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h
index bea8ecad0f..e25b289ce8 100644
--- a/include/hw/pci/pcie_port.h
+++ b/include/hw/pci/pcie_port.h
@@ -57,8 +57,11 @@ struct PCIESlot {
 /* Disable ACS (really for a pcie_root_port) */
 booldisable_acs;
 
-/* Indicates whether hot-plug is enabled on the slot */
+/* Indicates whether any type of hot-plug is allowed on the slot */
 boolhotplug;
+
+boolnative_hotplug;
+
 QLIST_ENTRY(PCIESlot) next;
 };
 
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 9fdc6342b0..f4d706e47d 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -31,6 +31,7 @@
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_bridge.h"
 #include "hw/pci/pci_host.h"
+#include "hw/pci/pcie_port.h"
 #include "hw/i386/acpi-build.h"
 #include "hw/acpi/acpi.h"
 #include "hw/pci/pci_bus.h"
@@ -336,6 +337,13 @@ void acpi_pcihp_device_plug_cb(HotplugHandler 
*hotplug_dev, AcpiPciHpState *s,
 object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) {
 PCIBus *sec = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
 
+/* Remove all hot-plug handlers if hot-plug is disabled on slot */
+if (object_dynamic_cast(OBJECT(dev), TYPE_PCIE_SLOT) &&
+!PCIE_SLOT(pdev)->hotplug) {
+qbus_set_hotplug_handler(BUS(sec), NULL);
+return;
+}
+
 qbus_set_hotplug_handler(BUS(sec), OBJECT(hotplug_dev));
 /* We don't have to overwrite any other hotplug handler yet */
 assert(QLIST_EMPTY(>child));
diff --git a/hw/core/machine.c b/hw/core/machine.c
index ca69f0343a..339031219d 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -583,7 +583,6 @@ static void machine_set_memdev(Object *obj, const char 
*value, Error **errp)
 ms->ram_memdev_id = g_strdup(value);
 }
 
-
 static void machine_init_notify(Notifier *notifier, void *data)
 {
 MachineState *machine = MACHINE(qdev_get_machine());
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 46a0f196f4..04b4a4788d 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -37,6 +37,7 @@
 #include "sysemu/kvm.h"
 #include "hw/kvm/clock.h"
 #include "hw/pci-host/q35.h"
+#include "hw/pci/pcie_port.h"
 #include "hw/qdev-properties.h"
 #include "hw/i386/x86.h"
 #include "hw/i386/pc.h"
@@ -136,6 +137,7 @@ static void pc_q35_init(MachineState *machine)
 ram_addr_t lowmem;
 DriveInfo *hd[MAX_SATA_PORTS];
 MachineClass *mc = MACHINE_GET_CLASS(machine);
+bool acpi_pcihp;
 
 /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory
  * and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping
@@ -236,6 +238,15 @@ static void pc_q35_init(MachineState *machine)
 object_property_set_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP,
  OBJECT(lpc), _abort);
 
+acpi_pcihp = object_property_get_bool(OBJECT(lpc),
+  
"acpi-pci-hotplug-with-bridge-support",
+  NULL);
+
+if (acpi_pcihp) {
+object_register_sugar_prop(TYPE_PCIE_SLOT, "native-hotplug",
+   "false", true);
+}
+
 /* irq lines */
 gsi_state = pc_gsi_create(>gsi, pcmc->pci_enabled);
 
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index fd0fa157e8..6e95d82903 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -529,7 +529,13 @@ void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s)
PCI_EXP_SLTCAP_PIP |
PCI_EXP_SLTCAP_AIP |
PCI_EXP_SLTCAP_ABP);
-if (s->hotplug) {
+
+/*
+ * Enable native hot-plug on all hot-plugged bridges unless
+ * hot-plug is disabled on the slot.
+ */
+if (s->hotplug &&
+(s->native_hotplug || DEVICE(dev)->hotplugged)) {
 pci_long_test_and_set_mask(dev->config + pos + PCI_EXP_SLTCAP,

[PATCH v6 4/6] bios-tables-test: Allow changes in DSDT ACPI tables

2021-07-12 Thread Julia Suvorova
All DSDT Q35 tables will be modified because ACPI hot-plug is enabled
by default.

Signed-off-by: Julia Suvorova 
Reviewed-by: Igor Mammedov 
Reviewed-by: Marcel Apfelbaum 
---
 tests/qtest/bios-tables-test-allowed-diff.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..c5167f48af 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,12 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/DSDT",
+"tests/data/acpi/q35/DSDT.tis",
+"tests/data/acpi/q35/DSDT.bridge",
+"tests/data/acpi/q35/DSDT.mmio64",
+"tests/data/acpi/q35/DSDT.ipmibt",
+"tests/data/acpi/q35/DSDT.cphp",
+"tests/data/acpi/q35/DSDT.memhp",
+"tests/data/acpi/q35/DSDT.acpihmat",
+"tests/data/acpi/q35/DSDT.numamem",
+"tests/data/acpi/q35/DSDT.dimmpxm",
+"tests/data/acpi/q35/DSDT.nohpet",
-- 
2.30.2




[PATCH v6 2/6] hw/acpi/ich9: Enable ACPI PCI hot-plug

2021-07-12 Thread Julia Suvorova
Add acpi_pcihp to ich9_pm as part of
'acpi-pci-hotplug-with-bridge-support' option. Set default to false.

Signed-off-by: Julia Suvorova 
Signed-off-by: Marcel Apfelbaum 
Reviewed-by: Igor Mammedov 
---
 hw/i386/acpi-build.h|  1 +
 include/hw/acpi/ich9.h  |  3 ++
 hw/acpi/acpi-x86-stub.c |  6 
 hw/acpi/ich9.c  | 70 +
 hw/acpi/pcihp.c | 12 +--
 hw/i386/acpi-build.c| 14 ++---
 6 files changed, 100 insertions(+), 6 deletions(-)

diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
index 487ec7710f..0dce155c8c 100644
--- a/hw/i386/acpi-build.h
+++ b/hw/i386/acpi-build.h
@@ -10,5 +10,6 @@ extern const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio;
 #define ACPI_PCIHP_BNMR_BASE 0x10
 
 void acpi_setup(void);
+Object *acpi_get_i386_pci_host(void);
 
 #endif
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 596120d97f..a329ce43ab 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -24,6 +24,7 @@
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/cpu_hotplug.h"
 #include "hw/acpi/cpu.h"
+#include "hw/acpi/pcihp.h"
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/acpi_dev_interface.h"
 #include "hw/acpi/tco.h"
@@ -55,6 +56,8 @@ typedef struct ICH9LPCPMRegs {
 AcpiCpuHotplug gpe_cpu;
 CPUHotplugState cpuhp_state;
 
+bool use_acpi_hotplug_bridge;
+AcpiPciHpState acpi_pci_hotplug;
 MemHotplugState acpi_memory_hotplug;
 
 uint8_t disable_s3;
diff --git a/hw/acpi/acpi-x86-stub.c b/hw/acpi/acpi-x86-stub.c
index f88d6a090b..e9e46c5c5f 100644
--- a/hw/acpi/acpi-x86-stub.c
+++ b/hw/acpi/acpi-x86-stub.c
@@ -1,7 +1,13 @@
 #include "qemu/osdep.h"
 #include "hw/i386/pc.h"
+#include "hw/i386/acpi-build.h"
 
 void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
const CPUArchIdList *apic_ids, GArray *entry)
 {
 }
+
+Object *acpi_get_i386_pci_host(void)
+{
+   return NULL;
+}
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 4daa79ec8d..2f4eb453ac 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -217,6 +217,26 @@ static const VMStateDescription vmstate_cpuhp_state = {
 }
 };
 
+static bool vmstate_test_use_pcihp(void *opaque)
+{
+ICH9LPCPMRegs *s = opaque;
+
+return s->use_acpi_hotplug_bridge;
+}
+
+static const VMStateDescription vmstate_pcihp_state = {
+.name = "ich9_pm/pcihp",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = vmstate_test_use_pcihp,
+.fields  = (VMStateField[]) {
+VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug,
+ICH9LPCPMRegs,
+NULL, NULL),
+VMSTATE_END_OF_LIST()
+}
+};
+
 const VMStateDescription vmstate_ich9_pm = {
 .name = "ich9_pm",
 .version_id = 1,
@@ -238,6 +258,7 @@ const VMStateDescription vmstate_ich9_pm = {
 _memhp_state,
 _tco_io_state,
 _cpuhp_state,
+_pcihp_state,
 NULL
 }
 };
@@ -259,6 +280,10 @@ static void pm_reset(void *opaque)
 }
 pm->smi_en_wmask = ~0;
 
+if (pm->use_acpi_hotplug_bridge) {
+acpi_pcihp_reset(>acpi_pci_hotplug, true);
+}
+
 acpi_update_sci(>acpi_regs, pm->irq);
 }
 
@@ -297,6 +322,18 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 pm->enable_tco = true;
 acpi_pm_tco_init(>tco_regs, >io);
 
+if (pm->use_acpi_hotplug_bridge) {
+acpi_pcihp_init(OBJECT(lpc_pci),
+>acpi_pci_hotplug,
+pci_get_bus(lpc_pci),
+pci_address_space_io(lpc_pci),
+true,
+ACPI_PCIHP_ADDR_ICH9);
+
+qbus_set_hotplug_handler(BUS(pci_get_bus(lpc_pci)),
+ OBJECT(lpc_pci));
+}
+
 pm->irq = sci_irq;
 qemu_register_reset(pm_reset, pm);
 pm->powerdown_notifier.notify = pm_powerdown_req;
@@ -368,6 +405,20 @@ static void ich9_pm_set_enable_tco(Object *obj, bool 
value, Error **errp)
 s->pm.enable_tco = value;
 }
 
+static bool ich9_pm_get_acpi_pci_hotplug(Object *obj, Error **errp)
+{
+ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
+
+return s->pm.use_acpi_hotplug_bridge;
+}
+
+static void ich9_pm_set_acpi_pci_hotplug(Object *obj, bool value, Error **errp)
+{
+ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
+
+s->pm.use_acpi_hotplug_bridge = value;
+}
+
 void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 {
 static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN;
@@ -376,6 +427,7 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 pm->disable_s3 = 0;
 pm->disable_s4 = 0;
 pm->s4_val = 2;
+pm->use_acpi_hotplug_bridge = false;
 
 object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
 

[PATCH v6 0/6] Use ACPI PCI hot-plug for Q35

2021-07-12 Thread Julia Suvorova
The patch set consists of two parts:
patches 1-3: introduce new feature
 'acpi-pci-hotplug-with-bridge-support' on Q35
patches 4-6: make the feature default along with changes in ACPI tables

With the feature disabled Q35 falls back to the native hot-plug.

Pros
* no racy behavior during boot (see 110c477c2ed)
* eject is possible - according to PCIe spec, attention button
  press should lead to power off, and then the adapter should be
  removed manually. As there is no power down state exists in QEMU,
  we cannot distinguish between an eject and a power down
  request.
* no delay during deleting - after the actual power off software
  must wait at least 1 second before indicating about it. This case
  is quite important for users, it even has its own bug:
  https://bugzilla.redhat.com/show_bug.cgi?id=1594168
* no timer-based behavior - in addition to the previous example,
  the attention button has a 5-second waiting period, during which
  the operation can be canceled with a second press. While this
  looks fine for manual button control, automation will result in
  the need to queue or drop events, and the software receiving
  events in all sort of unspecified combinations of attention/power
  indicator states, which is racy and uppredictable.
* fixes or reduces the likelihood of the bugs:
* https://bugzilla.redhat.com/show_bug.cgi?id=1833187
* https://bugzilla.redhat.com/show_bug.cgi?id=1657077
* https://bugzilla.redhat.com/show_bug.cgi?id=1669931
* https://bugzilla.redhat.com/show_bug.cgi?id=1678290

Cons:
* no access to possible features presented in slot capabilities
  (this is only surprise removal AFAIK)

v6:
* move acpi_pcihp_disable_root_bus() changes into "Enable ACPI
  PCI hot-plug" patch
* fix mips compilation [Michael, Marcel]
* additional check in pm_reset() [David]
* rename property to "native-hotplug" [Igor]

v5:
* make sugar property on TYPE_PCIE_SLOT
  instead of old TYPE_MACHINE property [Igor]
* minor style changes
v4:
* regain per-port control over hot-plug
* rebased over acpi-index changes
* set property on machine type to
  make pci code more generic [Igor, Michael]

v3:
* drop change of _OSC to allow SHPC on hotplugged bridges
* use 'acpi-root-pci-hotplug'
* add migration states [Igor]
* minor style changes

v2:
* new ioport range for acpiphp [Gerd]
* drop find_pci_host() [Igor]
* explain magic numbers in _OSC [Igor]
* drop build_q35_pci_hotplug() wrapper [Igor]

Julia Suvorova (6):
  hw/i386/acpi-build: Add ACPI PCI hot-plug methods to Q35
  hw/acpi/ich9: Enable ACPI PCI hot-plug
  hw/pci/pcie: Do not set HPC flag if acpihp is used
  bios-tables-test: Allow changes in DSDT ACPI tables
  hw/acpi/ich9: Set ACPI PCI hot-plug as default on Q35
  bios-tables-test: Update golden binaries

 hw/i386/acpi-build.h  |   5 +++
 include/hw/acpi/ich9.h|   5 +++
 include/hw/acpi/pcihp.h   |   3 +-
 include/hw/pci/pcie_port.h|   5 ++-
 hw/acpi/acpi-x86-stub.c   |   6 +++
 hw/acpi/ich9.c|  70 ++
 hw/acpi/pcihp.c   |  26 ---
 hw/acpi/piix4.c   |   4 +-
 hw/core/machine.c |   1 -
 hw/i386/acpi-build.c  |  44 ---
 hw/i386/pc.c  |   1 +
 hw/i386/pc_q35.c  |  11 +
 hw/pci/pcie.c |   8 +++-
 hw/pci/pcie_port.c|   1 +
 tests/data/acpi/q35/DSDT  | Bin 7859 -> 8289 bytes
 tests/data/acpi/q35/DSDT.acpihmat | Bin 9184 -> 9614 bytes
 tests/data/acpi/q35/DSDT.bridge   | Bin 7877 -> 11003 bytes
 tests/data/acpi/q35/DSDT.cphp | Bin 8323 -> 8753 bytes
 tests/data/acpi/q35/DSDT.dimmpxm  | Bin 9513 -> 9943 bytes
 tests/data/acpi/q35/DSDT.ipmibt   | Bin 7934 -> 8364 bytes
 tests/data/acpi/q35/DSDT.memhp| Bin 9218 -> 9648 bytes
 tests/data/acpi/q35/DSDT.mmio64   | Bin 8990 -> 9419 bytes
 tests/data/acpi/q35/DSDT.nohpet   | Bin 7717 -> 8147 bytes
 tests/data/acpi/q35/DSDT.numamem  | Bin 7865 -> 8295 bytes
 tests/data/acpi/q35/DSDT.tis  | Bin 8465 -> 8894 bytes
 25 files changed, 165 insertions(+), 25 deletions(-)

-- 
2.30.2




Re: [PATCH v5 3/7] hw/acpi/ich9: Enable ACPI PCI hot-plug

2021-07-02 Thread Julia Suvorova
On Thu, Jul 1, 2021 at 6:59 AM David Gibson  wrote:
>
> On Thu, Jun 17, 2021 at 09:07:35PM +0200, Julia Suvorova wrote:
> > Add acpi_pcihp to ich9_pm as part of
> > 'acpi-pci-hotplug-with-bridge-support' option. Set default to false.
> >
> > Signed-off-by: Julia Suvorova 
> > Reviewed-by: Igor Mammedov 
> > Reviewed-by: Marcel Apfelbaum 
> > ---
> >  hw/i386/acpi-build.h   |  1 +
> >  include/hw/acpi/ich9.h |  3 ++
> >  hw/acpi/ich9.c | 67 ++
> >  hw/acpi/pcihp.c|  5 +++-
> >  hw/i386/acpi-build.c   |  2 +-
> >  5 files changed, 76 insertions(+), 2 deletions(-)
> >
> > diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
> > index 487ec7710f..0dce155c8c 100644
> > --- a/hw/i386/acpi-build.h
> > +++ b/hw/i386/acpi-build.h
> > @@ -10,5 +10,6 @@ extern const struct AcpiGenericAddress 
> > x86_nvdimm_acpi_dsmio;
> >  #define ACPI_PCIHP_BNMR_BASE 0x10
> >
> >  void acpi_setup(void);
> > +Object *acpi_get_i386_pci_host(void);
> >
> >  #endif
> > diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
> > index 596120d97f..a329ce43ab 100644
> > --- a/include/hw/acpi/ich9.h
> > +++ b/include/hw/acpi/ich9.h
> > @@ -24,6 +24,7 @@
> >  #include "hw/acpi/acpi.h"
> >  #include "hw/acpi/cpu_hotplug.h"
> >  #include "hw/acpi/cpu.h"
> > +#include "hw/acpi/pcihp.h"
> >  #include "hw/acpi/memory_hotplug.h"
> >  #include "hw/acpi/acpi_dev_interface.h"
> >  #include "hw/acpi/tco.h"
> > @@ -55,6 +56,8 @@ typedef struct ICH9LPCPMRegs {
> >  AcpiCpuHotplug gpe_cpu;
> >  CPUHotplugState cpuhp_state;
> >
> > +bool use_acpi_hotplug_bridge;
> > +AcpiPciHpState acpi_pci_hotplug;
> >  MemHotplugState acpi_memory_hotplug;
> >
> >  uint8_t disable_s3;
> > diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> > index 4daa79ec8d..bcbd567cb0 100644
> > --- a/hw/acpi/ich9.c
> > +++ b/hw/acpi/ich9.c
> > @@ -217,6 +217,26 @@ static const VMStateDescription vmstate_cpuhp_state = {
> >  }
> >  };
> >
> > +static bool vmstate_test_use_pcihp(void *opaque)
> > +{
> > +ICH9LPCPMRegs *s = opaque;
> > +
> > +return s->use_acpi_hotplug_bridge;
> > +}
> > +
> > +static const VMStateDescription vmstate_pcihp_state = {
> > +.name = "ich9_pm/pcihp",
> > +.version_id = 1,
> > +.minimum_version_id = 1,
> > +.needed = vmstate_test_use_pcihp,
> > +.fields  = (VMStateField[]) {
> > +VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug,
> > +ICH9LPCPMRegs,
> > +NULL, NULL),
> > +VMSTATE_END_OF_LIST()
> > +}
> > +};
> > +
> >  const VMStateDescription vmstate_ich9_pm = {
> >  .name = "ich9_pm",
> >  .version_id = 1,
> > @@ -238,6 +258,7 @@ const VMStateDescription vmstate_ich9_pm = {
> >  _memhp_state,
> >  _tco_io_state,
> >  _cpuhp_state,
> > +_pcihp_state,
> >  NULL
> >  }
> >  };
> > @@ -259,6 +280,7 @@ static void pm_reset(void *opaque)
> >  }
> >  pm->smi_en_wmask = ~0;
> >
> > +acpi_pcihp_reset(>acpi_pci_hotplug, true);
>
> Doesn't this need to be protected by if (pm->use_acpi_hotplug_bridge)
> ? Otherwise pm->acpi_pci_hotplug won't be initialized.

Yes, you're right. Although it doesn't affect anything now, it should
be fixed. I'll send a patch on top.

> >  acpi_update_sci(>acpi_regs, pm->irq);
> >  }
> >
> > @@ -297,6 +319,18 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs 
> > *pm,
> >  pm->enable_tco = true;
> >  acpi_pm_tco_init(>tco_regs, >io);
> >
> > +if (pm->use_acpi_hotplug_bridge) {
> > +acpi_pcihp_init(OBJECT(lpc_pci),
> > +>acpi_pci_hotplug,
> > +pci_get_bus(lpc_pci),
> > +pci_address_space_io(lpc_pci),
> > +true,
> > +ACPI_PCIHP_ADDR_ICH9);
> > +
> > +qbus_set_hotplug_handler(BUS(pci_get_bus(lpc_pci)),
> > + OBJECT(lpc_pci));
> > +}
> > +
> >  pm->irq = sci_irq;
> >  qemu_register_reset(pm_reset, pm);
> >  pm->powerdown_notifier.notify = pm_powerdown_req;
> > @@ -368,6 +402,20

[PATCH] hw/pci/pcie_port: Rename "enable-native-hotplug" property

2021-06-23 Thread Julia Suvorova
PCIE_SLOT property renamed to "native-hotplug" to be more concise
and consistent with other properties.

Signed-off-by: Julia Suvorova 
---
 hw/i386/pc_q35.c   | 4 ++--
 hw/pci/pcie_port.c | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index a0ec7964cc..04b4a4788d 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -243,8 +243,8 @@ static void pc_q35_init(MachineState *machine)
   NULL);
 
 if (acpi_pcihp) {
-object_register_sugar_prop(TYPE_PCIE_SLOT, "enable-native-hotplug",
-  "false", true);
+object_register_sugar_prop(TYPE_PCIE_SLOT, "native-hotplug",
+   "false", true);
 }
 
 /* irq lines */
diff --git a/hw/pci/pcie_port.c b/hw/pci/pcie_port.c
index a410111825..da850e8dde 100644
--- a/hw/pci/pcie_port.c
+++ b/hw/pci/pcie_port.c
@@ -148,7 +148,7 @@ static Property pcie_slot_props[] = {
 DEFINE_PROP_UINT8("chassis", PCIESlot, chassis, 0),
 DEFINE_PROP_UINT16("slot", PCIESlot, slot, 0),
 DEFINE_PROP_BOOL("hotplug", PCIESlot, hotplug, true),
-DEFINE_PROP_BOOL("enable-native-hotplug", PCIESlot, native_hotplug, true),
+DEFINE_PROP_BOOL("native-hotplug", PCIESlot, native_hotplug, true),
 DEFINE_PROP_END_OF_LIST()
 };
 
-- 
2.30.2




[PATCH v5 7/7] bios-tables-test: Update golden binaries

2021-06-17 Thread Julia Suvorova
Add ACPI hot-plug registers to DSDT Q35 tables.
Changes in the tables:

+Scope (_SB.PCI0)
+{
+OperationRegion (PCST, SystemIO, 0x0CC4, 0x08)
+Field (PCST, DWordAcc, NoLock, WriteAsZeros)
+{
+PCIU,   32,
+PCID,   32
+}
+
+OperationRegion (SEJ, SystemIO, 0x0CCC, 0x04)
+Field (SEJ, DWordAcc, NoLock, WriteAsZeros)
+{
+B0EJ,   32
+}
+
+OperationRegion (BNMR, SystemIO, 0x0CD4, 0x08)
+Field (BNMR, DWordAcc, NoLock, WriteAsZeros)
+{
+BNUM,   32,
+PIDX,   32
+}
+
+Mutex (BLCK, 0x00)
+Method (PCEJ, 2, NotSerialized)
+{
+Acquire (BLCK, 0x)
+BNUM = Arg0
+B0EJ = (One << Arg1)
+Release (BLCK)
+Return (Zero)
+}
+
+Method (AIDX, 2, NotSerialized)
+{
+Acquire (BLCK, 0x)
+BNUM = Arg0
+PIDX = (One << Arg1)
+Local0 = PIDX /* \_SB_.PCI0.PIDX */
+Release (BLCK)
+Return (Local0)
+}
+
+Method (PDSM, 6, Serialized)
+{
+If ((Arg0 == ToUUID ("e5c937d0-3553-4d7a-9117-ea4d19c3434d") /* 
Device Labeling Interface */))
+{
+Local0 = AIDX (Arg4, Arg5)
+If ((Arg2 == Zero))
+{
+If ((Arg1 == 0x02))
+{
+If (!((Local0 == Zero) | (Local0 == 0x)))
+{
+Return (Buffer (One)
+{
+ 0x81  
   // .
+})
+}
+}
+
+Return (Buffer (One)
+{
+ 0x00 // .
+})
+}
+ElseIf ((Arg2 == 0x07))
+{
+Local1 = Package (0x02)
+{
+Zero,
+""
+}
+Local1 [Zero] = Local0
+Return (Local1)
+}
+}
+}
+}
+
...

 Scope (_GPE)
 {
 Name (_HID, "ACPI0006" /* GPE Block Device */)  // _HID: Hardware ID
+Method (_E01, 0, NotSerialized)  // _Exx: Edge-Triggered GPE, 
xx=0x00-0xFF
+{
+Acquire (\_SB.PCI0.BLCK, 0x)
+\_SB.PCI0.PCNT ()
+Release (\_SB.PCI0.BLCK)
+}
...

+
+Device (PHPR)
+{
+Name (_HID, "PNP0A06" /* Generic Container Device */)  // _HID: 
Hardware ID
+Name (_UID, "PCI Hotplug resources")  // _UID: Unique ID
+Name (_STA, 0x0B)  // _STA: Status
+Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
+{
+IO (Decode16,
+0x0CC4, // Range Minimum
+0x0CC4, // Range Maximum
+0x01,   // Alignment
+0x18,   // Length
+)
+})
+}
 }
...

And if there is a port in configuration:

 Device (S10)
 {
 Name (_ADR, 0x0002)  // _ADR: Address
+Name (BSEL, Zero)
+Device (S00)
+{
+Name (_SUN, Zero)  // _SUN: Slot User Number
+Name (_ADR, Zero)  // _ADR: Address
+Method (_EJ0, 1, NotSerialized)  // _EJx: Eject Device, 
x=0-9
+{
+PCEJ (BSEL, _SUN)
+}
+
+Method (_DSM, 4, Serialized)  // _DSM: Device-Specific 
Method
+{
+Return (PDSM (Arg0, Arg1, Arg2, Arg3, BSEL, _SUN))
+}
+}
+
...

+Method (DVNT, 2, NotSerialized)
+{
+If ((Arg0 & One))
+{
+Notify (S00, Arg1)
+}
...

Signed-off-by: Julia Suvorova 
---
 tests/qtest/bios-tables-test-allowed-diff.h |  11 ---
 tests/data/acpi/q35/DSDT| Bin 7859 -> 8289 bytes
 tests/data/acpi/q35/DSDT.acpihmat   | Bin 9184 -> 9614 bytes
 tests/data/acpi/q35/DSDT.bridge | Bin 7877 -> 11003 bytes
 tests/data/acpi/q35/DSDT.cphp   | Bin 8323 -> 8753 bytes
 tests/data/acpi/q35/DSDT.dimmpxm| Bin 9513 -> 9943 bytes
 tests/data/acpi/q35/DSDT.ipmibt | Bin 7934 -> 8364 bytes
 tests/data/acpi/q35/DSDT.memhp  | Bin 9218 -> 9648 bytes

[PATCH v5 4/7] hw/pci/pcie: Do not set HPC flag if acpihp is used

2021-06-17 Thread Julia Suvorova
Instead of changing the hot-plug type in _OSC register, do not
set the 'Hot-Plug Capable' flag. This way guest will choose ACPI
hot-plug if it is preferred and leave the option to use SHPC with
pcie-pci-bridge.

The ability to control hot-plug for each downstream port is retained,
while 'hotplug=off' on the port means all hot-plug types are disabled.

Signed-off-by: Julia Suvorova 
---
 include/hw/pci/pcie_port.h |  5 -
 hw/acpi/pcihp.c|  8 
 hw/core/machine.c  |  1 -
 hw/i386/pc_q35.c   | 11 +++
 hw/pci/pcie.c  |  8 +++-
 hw/pci/pcie_port.c |  1 +
 6 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h
index bea8ecad0f..e25b289ce8 100644
--- a/include/hw/pci/pcie_port.h
+++ b/include/hw/pci/pcie_port.h
@@ -57,8 +57,11 @@ struct PCIESlot {
 /* Disable ACS (really for a pcie_root_port) */
 booldisable_acs;
 
-/* Indicates whether hot-plug is enabled on the slot */
+/* Indicates whether any type of hot-plug is allowed on the slot */
 boolhotplug;
+
+boolnative_hotplug;
+
 QLIST_ENTRY(PCIESlot) next;
 };
 
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 5355618608..7a6bc1b31e 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -31,6 +31,7 @@
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_bridge.h"
 #include "hw/pci/pci_host.h"
+#include "hw/pci/pcie_port.h"
 #include "hw/i386/acpi-build.h"
 #include "hw/acpi/acpi.h"
 #include "hw/pci/pci_bus.h"
@@ -332,6 +333,13 @@ void acpi_pcihp_device_plug_cb(HotplugHandler 
*hotplug_dev, AcpiPciHpState *s,
 object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) {
 PCIBus *sec = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
 
+/* Remove all hot-plug handlers if hot-plug is disabled on slot */
+if (object_dynamic_cast(OBJECT(dev), TYPE_PCIE_SLOT) &&
+!PCIE_SLOT(pdev)->hotplug) {
+qbus_set_hotplug_handler(BUS(sec), NULL);
+return;
+}
+
 qbus_set_hotplug_handler(BUS(sec), OBJECT(hotplug_dev));
 /* We don't have to overwrite any other hotplug handler yet */
 assert(QLIST_EMPTY(>child));
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 55b9bc7817..6ed0575d81 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -582,7 +582,6 @@ static void machine_set_memdev(Object *obj, const char 
*value, Error **errp)
 ms->ram_memdev_id = g_strdup(value);
 }
 
-
 static void machine_init_notify(Notifier *notifier, void *data)
 {
 MachineState *machine = MACHINE(qdev_get_machine());
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 46a0f196f4..a0ec7964cc 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -37,6 +37,7 @@
 #include "sysemu/kvm.h"
 #include "hw/kvm/clock.h"
 #include "hw/pci-host/q35.h"
+#include "hw/pci/pcie_port.h"
 #include "hw/qdev-properties.h"
 #include "hw/i386/x86.h"
 #include "hw/i386/pc.h"
@@ -136,6 +137,7 @@ static void pc_q35_init(MachineState *machine)
 ram_addr_t lowmem;
 DriveInfo *hd[MAX_SATA_PORTS];
 MachineClass *mc = MACHINE_GET_CLASS(machine);
+bool acpi_pcihp;
 
 /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory
  * and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping
@@ -236,6 +238,15 @@ static void pc_q35_init(MachineState *machine)
 object_property_set_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP,
  OBJECT(lpc), _abort);
 
+acpi_pcihp = object_property_get_bool(OBJECT(lpc),
+  
"acpi-pci-hotplug-with-bridge-support",
+  NULL);
+
+if (acpi_pcihp) {
+object_register_sugar_prop(TYPE_PCIE_SLOT, "enable-native-hotplug",
+  "false", true);
+}
+
 /* irq lines */
 gsi_state = pc_gsi_create(>gsi, pcmc->pci_enabled);
 
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index fd0fa157e8..6e95d82903 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -529,7 +529,13 @@ void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s)
PCI_EXP_SLTCAP_PIP |
PCI_EXP_SLTCAP_AIP |
PCI_EXP_SLTCAP_ABP);
-if (s->hotplug) {
+
+/*
+ * Enable native hot-plug on all hot-plugged bridges unless
+ * hot-plug is disabled on the slot.
+ */
+if (s->hotplug &&
+(s->native_hotplug || DEVICE(dev)->hotplugged)) {
 pci_long_test_and_set_mask(dev->config + pos + PCI_EXP_SLTCAP,
PCI_EXP_SLTCAP_HPS |
   

[PATCH v5 2/7] hw/i386/acpi-build: Add ACPI PCI hot-plug methods to Q35

2021-06-17 Thread Julia Suvorova
Implement notifications and gpe to support q35 ACPI PCI hot-plug.
Use 0xcc4 - 0xcd7 range for 'acpi-pci-hotplug' io ports.

Signed-off-by: Julia Suvorova 
Reviewed-by: Igor Mammedov 
---
 hw/i386/acpi-build.h|  4 
 include/hw/acpi/ich9.h  |  2 ++
 include/hw/acpi/pcihp.h |  3 ++-
 hw/acpi/pcihp.c |  6 +++---
 hw/acpi/piix4.c |  4 +++-
 hw/i386/acpi-build.c| 30 +++---
 6 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
index 74df5fc612..487ec7710f 100644
--- a/hw/i386/acpi-build.h
+++ b/hw/i386/acpi-build.h
@@ -5,6 +5,10 @@
 
 extern const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio;
 
+/* PCI Hot-plug registers bases. See docs/spec/acpi_pci_hotplug.txt */
+#define ACPI_PCIHP_SEJ_BASE 0x8
+#define ACPI_PCIHP_BNMR_BASE 0x10
+
 void acpi_setup(void);
 
 #endif
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index df519e40b5..596120d97f 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -28,6 +28,8 @@
 #include "hw/acpi/acpi_dev_interface.h"
 #include "hw/acpi/tco.h"
 
+#define ACPI_PCIHP_ADDR_ICH9 0x0cc4
+
 typedef struct ICH9LPCPMRegs {
 /*
  * In ich9 spec says that pm1_cnt register is 32bit width and
diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
index 2dd90aea30..af1a169fc3 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -55,7 +55,8 @@ typedef struct AcpiPciHpState {
 } AcpiPciHpState;
 
 void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root,
- MemoryRegion *address_space_io, bool bridges_enabled);
+ MemoryRegion *address_space_io, bool bridges_enabled,
+ uint16_t io_base);
 
 void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp);
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 09f531e941..a55992ed9f 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -37,7 +37,6 @@
 #include "qom/qom-qobject.h"
 #include "trace.h"
 
-#define ACPI_PCIHP_ADDR 0xae00
 #define ACPI_PCIHP_SIZE 0x0018
 #define PCI_UP_BASE 0x
 #define PCI_DOWN_BASE 0x0004
@@ -489,10 +488,11 @@ static const MemoryRegionOps acpi_pcihp_io_ops = {
 };
 
 void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
- MemoryRegion *address_space_io, bool bridges_enabled)
+ MemoryRegion *address_space_io, bool bridges_enabled,
+ uint16_t io_base)
 {
 s->io_len = ACPI_PCIHP_SIZE;
-s->io_base = ACPI_PCIHP_ADDR;
+s->io_base = io_base;
 
 s->root = root_bus;
 s->legacy_piix = !bridges_enabled;
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 0bd23d74e2..48f7a1edbc 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -49,6 +49,8 @@
 #define GPE_BASE 0xafe0
 #define GPE_LEN 4
 
+#define ACPI_PCIHP_ADDR_PIIX4 0xae00
+
 struct pci_status {
 uint32_t up; /* deprecated, maintained for migration compatibility */
 uint32_t down;
@@ -607,7 +609,7 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
*parent,
 
 if (s->use_acpi_hotplug_bridge || s->use_acpi_root_pci_hotplug) {
 acpi_pcihp_init(OBJECT(s), >acpi_pci_hotplug, bus, parent,
-s->use_acpi_hotplug_bridge);
+s->use_acpi_hotplug_bridge, ACPI_PCIHP_ADDR_PIIX4);
 }
 
 s->cpu_hotplug_legacy = true;
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 796ffc6f5c..67753638e4 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -219,10 +219,6 @@ static void acpi_get_pm_info(MachineState *machine, 
AcpiPmInfo *pm)
 /* w2k requires FADT(rev1) or it won't boot, keep PC compatible */
 pm->fadt.rev = 1;
 pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE;
-pm->pcihp_io_base =
-object_property_get_uint(obj, ACPI_PCIHP_IO_BASE_PROP, NULL);
-pm->pcihp_io_len =
-object_property_get_uint(obj, ACPI_PCIHP_IO_LEN_PROP, NULL);
 }
 if (lpc) {
 uint64_t smi_features = object_property_get_uint(lpc,
@@ -238,6 +234,10 @@ static void acpi_get_pm_info(MachineState *machine, 
AcpiPmInfo *pm)
 pm->smi_on_cpu_unplug =
 !!(smi_features & BIT_ULL(ICH9_LPC_SMI_F_CPU_HOT_UNPLUG_BIT));
 }
+pm->pcihp_io_base =
+object_property_get_uint(obj, ACPI_PCIHP_IO_BASE_PROP, NULL);
+pm->pcihp_io_len =
+object_property_get_uint(obj, ACPI_PCIHP_IO_LEN_PROP, NULL);
 
 /* The above need not be conditional on machine type because the reset port
  * happens to be the same on PIIX (pc) and ICH9 (q35). */
@@ -392,6 +392,9 @@ static void build_append_pci_bus_devices(Aml *parent_scope, 
PCIBus *bus,
 
 if (!pdev) {
 if (bsel) { /* add hotplug slots for non present

[PATCH v5 6/7] hw/acpi/ich9: Set ACPI PCI hot-plug as default on Q35

2021-06-17 Thread Julia Suvorova
Q35 has three different types of PCI devices hot-plug: PCIe Native,
SHPC Native and ACPI hot-plug. This patch changes the default choice
for cold-plugged bridges from PCIe Native to ACPI Hot-plug with
ability to use SHPC and PCIe Native for hot-plugged bridges.

This is a list of the PCIe Native hot-plug issues that led to this
change:
* no racy behavior during boot (see 110c477c2ed)
* no delay during deleting - after the actual power off software
  must wait at least 1 second before indicating about it. This case
  is quite important for users, it even has its own bug:
  https://bugzilla.redhat.com/show_bug.cgi?id=1594168
* no timer-based behavior - in addition to the previous example,
  the attention button has a 5-second waiting period, during which
  the operation can be canceled with a second press. While this
  looks fine for manual button control, automation will result in
  the need to queue or drop events, and the software receiving
  events in all sort of unspecified combinations of attention/power
  indicator states, which is racy and uppredictable.
* fixes:
* https://bugzilla.redhat.com/show_bug.cgi?id=1752465
* https://bugzilla.redhat.com/show_bug.cgi?id=1690256

To return to PCIe Native hot-plug:
-global ICH9-LPC.acpi-pci-hotplug-with-bridge-support=off

Signed-off-by: Julia Suvorova 
Reviewed-by: Igor Mammedov 
---
 hw/acpi/ich9.c | 2 +-
 hw/i386/pc.c   | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index bcbd567cb0..daa3cd44b1 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -424,7 +424,7 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 pm->disable_s3 = 0;
 pm->disable_s4 = 0;
 pm->s4_val = 2;
-pm->use_acpi_hotplug_bridge = false;
+pm->use_acpi_hotplug_bridge = true;
 
 object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
>pm_io_base, OBJ_PROP_FLAG_READ);
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index c6d8d0d84d..cc10589552 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -98,6 +98,7 @@ GlobalProperty pc_compat_6_0[] = {
 { "qemu64" "-" TYPE_X86_CPU, "family", "6" },
 { "qemu64" "-" TYPE_X86_CPU, "model", "6" },
 { "qemu64" "-" TYPE_X86_CPU, "stepping", "3" },
+{ "ICH9-LPC", "acpi-pci-hotplug-with-bridge-support", "off" },
 };
 const size_t pc_compat_6_0_len = G_N_ELEMENTS(pc_compat_6_0);
 
-- 
2.30.2




[PATCH v5 5/7] bios-tables-test: Allow changes in DSDT ACPI tables

2021-06-17 Thread Julia Suvorova
All DSDT Q35 tables will be modified because ACPI hot-plug is enabled
by default.

Signed-off-by: Julia Suvorova 
Reviewed-by: Igor Mammedov 
---
 tests/qtest/bios-tables-test-allowed-diff.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..c5167f48af 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,12 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/DSDT",
+"tests/data/acpi/q35/DSDT.tis",
+"tests/data/acpi/q35/DSDT.bridge",
+"tests/data/acpi/q35/DSDT.mmio64",
+"tests/data/acpi/q35/DSDT.ipmibt",
+"tests/data/acpi/q35/DSDT.cphp",
+"tests/data/acpi/q35/DSDT.memhp",
+"tests/data/acpi/q35/DSDT.acpihmat",
+"tests/data/acpi/q35/DSDT.numamem",
+"tests/data/acpi/q35/DSDT.dimmpxm",
+"tests/data/acpi/q35/DSDT.nohpet",
-- 
2.30.2




[PATCH v5 3/7] hw/acpi/ich9: Enable ACPI PCI hot-plug

2021-06-17 Thread Julia Suvorova
Add acpi_pcihp to ich9_pm as part of
'acpi-pci-hotplug-with-bridge-support' option. Set default to false.

Signed-off-by: Julia Suvorova 
Reviewed-by: Igor Mammedov 
---
 hw/i386/acpi-build.h   |  1 +
 include/hw/acpi/ich9.h |  3 ++
 hw/acpi/ich9.c | 67 ++
 hw/acpi/pcihp.c|  5 +++-
 hw/i386/acpi-build.c   |  2 +-
 5 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
index 487ec7710f..0dce155c8c 100644
--- a/hw/i386/acpi-build.h
+++ b/hw/i386/acpi-build.h
@@ -10,5 +10,6 @@ extern const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio;
 #define ACPI_PCIHP_BNMR_BASE 0x10
 
 void acpi_setup(void);
+Object *acpi_get_i386_pci_host(void);
 
 #endif
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 596120d97f..a329ce43ab 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -24,6 +24,7 @@
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/cpu_hotplug.h"
 #include "hw/acpi/cpu.h"
+#include "hw/acpi/pcihp.h"
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/acpi_dev_interface.h"
 #include "hw/acpi/tco.h"
@@ -55,6 +56,8 @@ typedef struct ICH9LPCPMRegs {
 AcpiCpuHotplug gpe_cpu;
 CPUHotplugState cpuhp_state;
 
+bool use_acpi_hotplug_bridge;
+AcpiPciHpState acpi_pci_hotplug;
 MemHotplugState acpi_memory_hotplug;
 
 uint8_t disable_s3;
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 4daa79ec8d..bcbd567cb0 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -217,6 +217,26 @@ static const VMStateDescription vmstate_cpuhp_state = {
 }
 };
 
+static bool vmstate_test_use_pcihp(void *opaque)
+{
+ICH9LPCPMRegs *s = opaque;
+
+return s->use_acpi_hotplug_bridge;
+}
+
+static const VMStateDescription vmstate_pcihp_state = {
+.name = "ich9_pm/pcihp",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = vmstate_test_use_pcihp,
+.fields  = (VMStateField[]) {
+VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug,
+ICH9LPCPMRegs,
+NULL, NULL),
+VMSTATE_END_OF_LIST()
+}
+};
+
 const VMStateDescription vmstate_ich9_pm = {
 .name = "ich9_pm",
 .version_id = 1,
@@ -238,6 +258,7 @@ const VMStateDescription vmstate_ich9_pm = {
 _memhp_state,
 _tco_io_state,
 _cpuhp_state,
+_pcihp_state,
 NULL
 }
 };
@@ -259,6 +280,7 @@ static void pm_reset(void *opaque)
 }
 pm->smi_en_wmask = ~0;
 
+acpi_pcihp_reset(>acpi_pci_hotplug, true);
 acpi_update_sci(>acpi_regs, pm->irq);
 }
 
@@ -297,6 +319,18 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 pm->enable_tco = true;
 acpi_pm_tco_init(>tco_regs, >io);
 
+if (pm->use_acpi_hotplug_bridge) {
+acpi_pcihp_init(OBJECT(lpc_pci),
+>acpi_pci_hotplug,
+pci_get_bus(lpc_pci),
+pci_address_space_io(lpc_pci),
+true,
+ACPI_PCIHP_ADDR_ICH9);
+
+qbus_set_hotplug_handler(BUS(pci_get_bus(lpc_pci)),
+ OBJECT(lpc_pci));
+}
+
 pm->irq = sci_irq;
 qemu_register_reset(pm_reset, pm);
 pm->powerdown_notifier.notify = pm_powerdown_req;
@@ -368,6 +402,20 @@ static void ich9_pm_set_enable_tco(Object *obj, bool 
value, Error **errp)
 s->pm.enable_tco = value;
 }
 
+static bool ich9_pm_get_acpi_pci_hotplug(Object *obj, Error **errp)
+{
+ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
+
+return s->pm.use_acpi_hotplug_bridge;
+}
+
+static void ich9_pm_set_acpi_pci_hotplug(Object *obj, bool value, Error **errp)
+{
+ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
+
+s->pm.use_acpi_hotplug_bridge = value;
+}
+
 void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 {
 static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN;
@@ -376,6 +424,7 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 pm->disable_s3 = 0;
 pm->disable_s4 = 0;
 pm->s4_val = 2;
+pm->use_acpi_hotplug_bridge = false;
 
 object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
>pm_io_base, OBJ_PROP_FLAG_READ);
@@ -399,6 +448,9 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 object_property_add_bool(obj, ACPI_PM_PROP_TCO_ENABLED,
  ich9_pm_get_enable_tco,
  ich9_pm_set_enable_tco);
+object_property_add_bool(obj, "acpi-pci-hotplug-with-bridge-support",
+ ich9_pm_get_acpi_pci_hotplug,
+ ich9_pm_set_acpi_pci_hotplug);
 }
 
 void ich9_pm_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
@@ -406,6 +458,11 @@ void ich9_pm_device_pre_plug_cb(Hotpl

[PATCH v5 0/7] Use ACPI PCI hot-plug for Q35

2021-06-17 Thread Julia Suvorova
The patch set consists of two parts:
patches 1-4: introduce new feature
 'acpi-pci-hotplug-with-bridge-support' on Q35
patches 5-7: make the feature default along with changes in ACPI tables

With the feature disabled Q35 falls back to the native hot-plug.

Pros
* no racy behavior during boot (see 110c477c2ed)
* eject is possible - according to PCIe spec, attention button
  press should lead to power off, and then the adapter should be
  removed manually. As there is no power down state exists in QEMU,
  we cannot distinguish between an eject and a power down
  request.
* no delay during deleting - after the actual power off software
  must wait at least 1 second before indicating about it. This case
  is quite important for users, it even has its own bug:
  https://bugzilla.redhat.com/show_bug.cgi?id=1594168
* no timer-based behavior - in addition to the previous example,
  the attention button has a 5-second waiting period, during which
  the operation can be canceled with a second press. While this
  looks fine for manual button control, automation will result in
  the need to queue or drop events, and the software receiving
  events in all sort of unspecified combinations of attention/power
  indicator states, which is racy and uppredictable.
* fixes or reduces the likelihood of the bugs:
* https://bugzilla.redhat.com/show_bug.cgi?id=1833187
* https://bugzilla.redhat.com/show_bug.cgi?id=1657077
* https://bugzilla.redhat.com/show_bug.cgi?id=1669931
* https://bugzilla.redhat.com/show_bug.cgi?id=1678290

Cons:
* no access to possible features presented in slot capabilities
  (this is only surprise removal AFAIK)

v5:
* make sugar property on TYPE_PCIE_SLOT
  instead of old TYPE_MACHINE property [Igor]
* minor style changes
v4:
* regain per-port control over hot-plug
* rebased over acpi-index changes
* set property on machine type to
  make pci code more generic [Igor, Michael]

v3:
* drop change of _OSC to allow SHPC on hotplugged bridges
* use 'acpi-root-pci-hotplug'
* add migration states [Igor]
* minor style changes

v2:
* new ioport range for acpiphp [Gerd]
* drop find_pci_host() [Igor]
* explain magic numbers in _OSC [Igor]
* drop build_q35_pci_hotplug() wrapper [Igor]

Julia Suvorova (7):
  hw/acpi/pcihp: Enhance acpi_pcihp_disable_root_bus() to support Q35
  hw/i386/acpi-build: Add ACPI PCI hot-plug methods to Q35
  hw/acpi/ich9: Enable ACPI PCI hot-plug
  hw/pci/pcie: Do not set HPC flag if acpihp is used
  bios-tables-test: Allow changes in DSDT ACPI tables
  hw/acpi/ich9: Set ACPI PCI hot-plug as default on Q35
  bios-tables-test: Update golden binaries

 hw/i386/acpi-build.h  |   5 +++
 include/hw/acpi/ich9.h|   5 +++
 include/hw/acpi/pcihp.h   |   3 +-
 include/hw/pci/pcie_port.h|   5 ++-
 hw/acpi/ich9.c|  67 ++
 hw/acpi/pcihp.c   |  22 +++---
 hw/acpi/piix4.c   |   4 +-
 hw/core/machine.c |   1 -
 hw/i386/acpi-build.c  |  32 --
 hw/i386/pc.c  |   1 +
 hw/i386/pc_q35.c  |  11 +
 hw/pci/pcie.c |   8 +++-
 hw/pci/pcie_port.c|   1 +
 tests/data/acpi/q35/DSDT  | Bin 7859 -> 8289 bytes
 tests/data/acpi/q35/DSDT.acpihmat | Bin 9184 -> 9614 bytes
 tests/data/acpi/q35/DSDT.bridge   | Bin 7877 -> 11003 bytes
 tests/data/acpi/q35/DSDT.cphp | Bin 8323 -> 8753 bytes
 tests/data/acpi/q35/DSDT.dimmpxm  | Bin 9513 -> 9943 bytes
 tests/data/acpi/q35/DSDT.ipmibt   | Bin 7934 -> 8364 bytes
 tests/data/acpi/q35/DSDT.memhp| Bin 9218 -> 9648 bytes
 tests/data/acpi/q35/DSDT.mmio64   | Bin 8990 -> 9419 bytes
 tests/data/acpi/q35/DSDT.nohpet   | Bin 7717 -> 8147 bytes
 tests/data/acpi/q35/DSDT.numamem  | Bin 7865 -> 8295 bytes
 tests/data/acpi/q35/DSDT.tis  | Bin 8465 -> 8894 bytes
 24 files changed, 143 insertions(+), 22 deletions(-)

-- 
2.30.2




[PATCH v5 1/7] hw/acpi/pcihp: Enhance acpi_pcihp_disable_root_bus() to support Q35

2021-06-17 Thread Julia Suvorova
PCI Express does not allow hot-plug on pcie.0. Check for Q35 in
acpi_pcihp_disable_root_bus() to be able to forbid hot-plug using the
'acpi-root-pci-hotplug' flag.

Signed-off-by: Julia Suvorova 
Reviewed-by: Igor Mammedov 
---
 hw/acpi/pcihp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 4999277d57..09f531e941 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -122,13 +122,14 @@ static void acpi_set_pci_info(void)
 static void acpi_pcihp_disable_root_bus(void)
 {
 static bool root_hp_disabled;
+Object *host = acpi_get_i386_pci_host();
 PCIBus *bus;
 
 if (root_hp_disabled) {
 return;
 }
 
-bus = find_i440fx();
+bus = PCI_HOST_BRIDGE(host)->bus;
 if (bus) {
 /* setting the hotplug handler to NULL makes the bus non-hotpluggable 
*/
 qbus_set_hotplug_handler(BUS(bus), NULL);
-- 
2.30.2




Re: [RFC PATCH v4 0/7] Use ACPI PCI hot-plug for Q35

2021-06-16 Thread Julia Suvorova
On Sun, May 23, 2021 at 10:26 AM Michael S. Tsirkin  wrote:
>
> On Thu, May 13, 2021 at 08:26:35AM +0200, Julia Suvorova wrote:
> > The patch set consists of two parts:
> > patches 1-4: introduce new feature
> >  'acpi-pci-hotplug-with-bridge-support' on Q35
> > patches 5-7: make the feature default along with changes in ACPI tables
> >
> > This way maintainers can decide which way to choose without breaking
> > the patch set.
> >
> > With the feature disabled Q35 falls back to the native hot-plug.
>
> Overall I think this version has addressed my concerns, good job!
> I see Igor has some suggestions on how to structure the code,
> they seem easy to address.
> Question: what makes this an RFC? Any known bugs/missing functionality?
> I don't see anything obvious - what did I miss?

No known issues, just indecisiveness about the default. The next
version will be non-RFC.

Best regards, Julia Suvorova.

> > Pros
> > * no racy behavior during boot (see 110c477c2ed)
> > * eject is possible - according to PCIe spec, attention button
> >   press should lead to power off, and then the adapter should be
> >   removed manually. As there is no power down state exists in QEMU,
> >   we cannot distinguish between an eject and a power down
> >   request.
> > * no delay during deleting - after the actual power off software
> >   must wait at least 1 second before indicating about it. This case
> >   is quite important for users, it even has its own bug:
> >   https://bugzilla.redhat.com/show_bug.cgi?id=1594168
> > * no timer-based behavior - in addition to the previous example,
> >   the attention button has a 5-second waiting period, during which
> >   the operation can be canceled with a second press. While this
> >   looks fine for manual button control, automation will result in
> >   the need to queue or drop events, and the software receiving
> >   events in all sort of unspecified combinations of attention/power
> >   indicator states, which is racy and uppredictable.
> > * fixes or reduces the likelihood of the bugs:
> > * https://bugzilla.redhat.com/show_bug.cgi?id=1833187
> > * https://bugzilla.redhat.com/show_bug.cgi?id=1657077
> > * https://bugzilla.redhat.com/show_bug.cgi?id=1669931
> > * https://bugzilla.redhat.com/show_bug.cgi?id=1678290
> >
> > Cons:
> > * no access to possible features presented in slot capabilities
> >   (this is only surprise removal AFAIK)
> >
> > v4:
> > * regain per-port control over hot-plug
> > * rebased over acpi-index changes
> > * set property on machine type to
> >   make pci code more generic [Igor, Michael]
> >
> > v3:
> > * drop change of _OSC to allow SHPC on hotplugged bridges
> > * use 'acpi-root-pci-hotplug'
> > * add migration states [Igor]
> > * minor style changes
> >
> > v2:
> > * new ioport range for acpiphp [Gerd]
> > * drop find_pci_host() [Igor]
> > * explain magic numbers in _OSC [Igor]
> > * drop build_q35_pci_hotplug() wrapper [Igor]
> >
> > Julia Suvorova (7):
> >   hw/acpi/pcihp: Enhance acpi_pcihp_disable_root_bus() to support Q35
> >   hw/i386/acpi-build: Add ACPI PCI hot-plug methods to Q35
> >   hw/acpi/ich9: Enable ACPI PCI hot-plug
> >   hw/pci/pcie: Do not set HPC flag if acpihp is used
> >   bios-tables-test: Allow changes in DSDT ACPI tables
> >   hw/acpi/ich9: Set ACPI PCI hot-plug as default on Q35
> >   bios-tables-test: Update golden binaries
> >
> >  hw/i386/acpi-build.h  |   5 +++
> >  include/hw/acpi/ich9.h|   5 +++
> >  include/hw/acpi/pcihp.h   |   3 +-
> >  include/hw/boards.h   |   1 +
> >  hw/acpi/ich9.c|  68 ++
> >  hw/acpi/pcihp.c   |  22 +++---
> >  hw/acpi/piix4.c   |   4 +-
> >  hw/core/machine.c |  19 +
> >  hw/i386/acpi-build.c  |  32 --
> >  hw/i386/pc.c  |   4 +-
> >  hw/i386/pc_q35.c  |   8 
> >  hw/pci/pcie.c |  11 -
> >  tests/data/acpi/q35/DSDT  | Bin 7859 -> 8289 bytes
> >  tests/data/acpi/q35/DSDT.acpihmat | Bin 9184 -> 9614 bytes
> >  tests/data/acpi/q35/DSDT.bridge   | Bin 7877 -> 11003 bytes
> >  tests/data/acpi/q35/DSDT.cphp | Bin 8323 -> 8753 bytes
> >  tests/data/acpi/q35/DSDT.dimmpxm  | Bin 9513 -> 9943 bytes
> >  tests/data/acpi/q35/DSDT.ipmibt   | Bin 7934 -> 8364 bytes
> >  tests/data/acpi/q35/DSDT.memhp| Bin 9218 -> 9648 bytes
> >  tests/data/acpi/q35/DSDT.mmio64   | Bin 8990 -> 9419 bytes
> >  tests/data/acpi/q35/DSDT.nohpet   | Bin 7717 -> 8147 bytes
> >  tests/data/acpi/q35/DSDT.numamem  | Bin 7865 -> 8295 bytes
> >  tests/data/acpi/q35/DSDT.tis  | Bin 8465 -> 8894 bytes
> >  23 files changed, 161 insertions(+), 21 deletions(-)
> >
> > --
> > 2.30.2
>




[RFC PATCH v4 1/7] hw/acpi/pcihp: Enhance acpi_pcihp_disable_root_bus() to support Q35

2021-05-13 Thread Julia Suvorova
PCI Express does not allow hot-plug on pcie.0. Check for Q35 in
acpi_pcihp_disable_root_bus() to be able to forbid hot-plug using the
'acpi-root-pci-hotplug' flag.

Signed-off-by: Julia Suvorova 
Reviewed-by: Igor Mammedov 
---
 hw/acpi/pcihp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 4999277d57..09f531e941 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -122,13 +122,14 @@ static void acpi_set_pci_info(void)
 static void acpi_pcihp_disable_root_bus(void)
 {
 static bool root_hp_disabled;
+Object *host = acpi_get_i386_pci_host();
 PCIBus *bus;
 
 if (root_hp_disabled) {
 return;
 }
 
-bus = find_i440fx();
+bus = PCI_HOST_BRIDGE(host)->bus;
 if (bus) {
 /* setting the hotplug handler to NULL makes the bus non-hotpluggable 
*/
 qbus_set_hotplug_handler(BUS(bus), NULL);
-- 
2.30.2




[RFC PATCH v4 7/7] bios-tables-test: Update golden binaries

2021-05-13 Thread Julia Suvorova
Add ACPI hot-plug registers to DSDT Q35 tables.
Changes in the tables:

+Scope (_SB.PCI0)
+{
+OperationRegion (PCST, SystemIO, 0x0CC4, 0x08)
+Field (PCST, DWordAcc, NoLock, WriteAsZeros)
+{
+PCIU,   32,
+PCID,   32
+}
+
+OperationRegion (SEJ, SystemIO, 0x0CCC, 0x04)
+Field (SEJ, DWordAcc, NoLock, WriteAsZeros)
+{
+B0EJ,   32
+}
+
+OperationRegion (BNMR, SystemIO, 0x0CD4, 0x08)
+Field (BNMR, DWordAcc, NoLock, WriteAsZeros)
+{
+BNUM,   32,
+PIDX,   32
+}
+
+Mutex (BLCK, 0x00)
+Method (PCEJ, 2, NotSerialized)
+{
+Acquire (BLCK, 0x)
+BNUM = Arg0
+B0EJ = (One << Arg1)
+Release (BLCK)
+Return (Zero)
+}
+
+Method (AIDX, 2, NotSerialized)
+{
+Acquire (BLCK, 0x)
+BNUM = Arg0
+PIDX = (One << Arg1)
+Local0 = PIDX /* \_SB_.PCI0.PIDX */
+Release (BLCK)
+Return (Local0)
+}
+
+Method (PDSM, 6, Serialized)
+{
+If ((Arg0 == ToUUID ("e5c937d0-3553-4d7a-9117-ea4d19c3434d") /* 
Device Labeling Interface */))
+{
+Local0 = AIDX (Arg4, Arg5)
+If ((Arg2 == Zero))
+{
+If ((Arg1 == 0x02))
+{
+If (!((Local0 == Zero) | (Local0 == 0x)))
+{
+Return (Buffer (One)
+{
+ 0x81  
   // .
+})
+}
+}
+
+Return (Buffer (One)
+{
+ 0x00 // .
+})
+}
+ElseIf ((Arg2 == 0x07))
+{
+Local1 = Package (0x02)
+{
+Zero,
+""
+}
+Local1 [Zero] = Local0
+Return (Local1)
+}
+}
+}
+}
+
...

 Scope (_GPE)
 {
 Name (_HID, "ACPI0006" /* GPE Block Device */)  // _HID: Hardware ID
+Method (_E01, 0, NotSerialized)  // _Exx: Edge-Triggered GPE, 
xx=0x00-0xFF
+{
+Acquire (\_SB.PCI0.BLCK, 0x)
+\_SB.PCI0.PCNT ()
+Release (\_SB.PCI0.BLCK)
+}
...

+
+Device (PHPR)
+{
+Name (_HID, "PNP0A06" /* Generic Container Device */)  // _HID: 
Hardware ID
+Name (_UID, "PCI Hotplug resources")  // _UID: Unique ID
+Name (_STA, 0x0B)  // _STA: Status
+Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
+{
+IO (Decode16,
+0x0CC4, // Range Minimum
+0x0CC4, // Range Maximum
+0x01,   // Alignment
+0x18,   // Length
+)
+})
+}
 }
...

And if there is a port in configuration:

 Device (S10)
 {
 Name (_ADR, 0x0002)  // _ADR: Address
+Name (BSEL, Zero)
+Device (S00)
+{
+Name (_SUN, Zero)  // _SUN: Slot User Number
+Name (_ADR, Zero)  // _ADR: Address
+Method (_EJ0, 1, NotSerialized)  // _EJx: Eject Device, 
x=0-9
+{
+PCEJ (BSEL, _SUN)
+}
+
+Method (_DSM, 4, Serialized)  // _DSM: Device-Specific 
Method
+{
+Return (PDSM (Arg0, Arg1, Arg2, Arg3, BSEL, _SUN))
+}
+}
+
...

+Method (DVNT, 2, NotSerialized)
+{
+If ((Arg0 & One))
+{
+Notify (S00, Arg1)
+}
...

Signed-off-by: Julia Suvorova 
---
 tests/qtest/bios-tables-test-allowed-diff.h |  11 ---
 tests/data/acpi/q35/DSDT| Bin 7859 -> 8289 bytes
 tests/data/acpi/q35/DSDT.acpihmat   | Bin 9184 -> 9614 bytes
 tests/data/acpi/q35/DSDT.bridge | Bin 7877 -> 11003 bytes
 tests/data/acpi/q35/DSDT.cphp   | Bin 8323 -> 8753 bytes
 tests/data/acpi/q35/DSDT.dimmpxm| Bin 9513 -> 9943 bytes
 tests/data/acpi/q35/DSDT.ipmibt | Bin 7934 -> 8364 bytes
 tests/data/acpi/q35/DSDT.memhp  | Bin 9218 -> 9648 bytes

[RFC PATCH v4 5/7] bios-tables-test: Allow changes in DSDT ACPI tables

2021-05-13 Thread Julia Suvorova
All DSDT Q35 tables will be modified because ACPI hot-plug is enabled
by default.

Signed-off-by: Julia Suvorova 
---
 tests/qtest/bios-tables-test-allowed-diff.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..c5167f48af 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,12 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/DSDT",
+"tests/data/acpi/q35/DSDT.tis",
+"tests/data/acpi/q35/DSDT.bridge",
+"tests/data/acpi/q35/DSDT.mmio64",
+"tests/data/acpi/q35/DSDT.ipmibt",
+"tests/data/acpi/q35/DSDT.cphp",
+"tests/data/acpi/q35/DSDT.memhp",
+"tests/data/acpi/q35/DSDT.acpihmat",
+"tests/data/acpi/q35/DSDT.numamem",
+"tests/data/acpi/q35/DSDT.dimmpxm",
+"tests/data/acpi/q35/DSDT.nohpet",
-- 
2.30.2




[RFC PATCH v4 6/7] hw/acpi/ich9: Set ACPI PCI hot-plug as default on Q35

2021-05-13 Thread Julia Suvorova
Q35 has three different types of PCI devices hot-plug: PCIe Native,
SHPC Native and ACPI hot-plug. This patch changes the default choice
for cold-plugged bridges from PCIe Native to ACPI Hot-plug with
ability to use SHPC and PCIe Native for hot-plugged bridges.

This is a list of the PCIe Native hot-plug issues that led to this
change:
* no racy behavior during boot (see 110c477c2ed)
* no delay during deleting - after the actual power off software
  must wait at least 1 second before indicating about it. This case
  is quite important for users, it even has its own bug:
  https://bugzilla.redhat.com/show_bug.cgi?id=1594168
* no timer-based behavior - in addition to the previous example,
  the attention button has a 5-second waiting period, during which
  the operation can be canceled with a second press. While this
  looks fine for manual button control, automation will result in
  the need to queue or drop events, and the software receiving
  events in all sort of unspecified combinations of attention/power
  indicator states, which is racy and uppredictable.
* fixes or reduces the likelihood of the bug:
* https://bugzilla.redhat.com/show_bug.cgi?id=1833187
* https://bugzilla.redhat.com/show_bug.cgi?id=1657077
* https://bugzilla.redhat.com/show_bug.cgi?id=1669931
* https://bugzilla.redhat.com/show_bug.cgi?id=1678290

To return to PCIe Native hot-plug:
-global ICH9-LPC.acpi-pci-hotplug-with-bridge-support=off

Signed-off-by: Julia Suvorova 
---
 hw/acpi/ich9.c | 2 +-
 hw/i386/pc.c   | 4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index f6819c4f2a..e7b2cd9719 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -425,7 +425,7 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 pm->disable_s3 = 0;
 pm->disable_s4 = 0;
 pm->s4_val = 2;
-pm->use_acpi_hotplug_bridge = false;
+pm->use_acpi_hotplug_bridge = true;
 
 object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
>pm_io_base, OBJ_PROP_FLAG_READ);
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 8cfaf216e7..5c2d3d11a2 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -94,7 +94,9 @@
 #include "trace.h"
 #include CONFIG_DEVICES
 
-GlobalProperty pc_compat_6_0[] = {};
+GlobalProperty pc_compat_6_0[] = {
+{ "ICH9-LPC", "acpi-pci-hotplug-with-bridge-support", "off" },
+};
 const size_t pc_compat_6_0_len = G_N_ELEMENTS(pc_compat_6_0);
 
 GlobalProperty pc_compat_5_2[] = {
-- 
2.30.2




[RFC PATCH v4 4/7] hw/pci/pcie: Do not set HPC flag if acpihp is used

2021-05-13 Thread Julia Suvorova
Instead of changing the hot-plug type in _OSC register, do not
set the 'Hot-Plug Capable' flag. This way guest will choose ACPI
hot-plug if it is preferred and leave the option to use SHPC with
pcie-pci-bridge.

The ability to control hot-plug for each downstream port is retained,
while 'hotplug=off' on the port means all hot-plug types are disabled.

Signed-off-by: Julia Suvorova 
---
 include/hw/boards.h |  1 +
 hw/acpi/pcihp.c |  8 
 hw/core/machine.c   | 19 +++
 hw/i386/pc_q35.c|  8 
 hw/pci/pcie.c   | 11 ++-
 5 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/include/hw/boards.h b/include/hw/boards.h
index 3d55d2bd62..a20ca5ab37 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -334,6 +334,7 @@ struct MachineState {
 CpuTopology smp;
 struct NVDIMMState *nvdimms_state;
 struct NumaState *numa_state;
+bool native_pci_hotplug;
 };
 
 #define DEFINE_MACHINE(namestr, machine_initfn) \
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 5355618608..7a6bc1b31e 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -31,6 +31,7 @@
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_bridge.h"
 #include "hw/pci/pci_host.h"
+#include "hw/pci/pcie_port.h"
 #include "hw/i386/acpi-build.h"
 #include "hw/acpi/acpi.h"
 #include "hw/pci/pci_bus.h"
@@ -332,6 +333,13 @@ void acpi_pcihp_device_plug_cb(HotplugHandler 
*hotplug_dev, AcpiPciHpState *s,
 object_dynamic_cast(OBJECT(dev), TYPE_PCI_BRIDGE)) {
 PCIBus *sec = pci_bridge_get_sec_bus(PCI_BRIDGE(pdev));
 
+/* Remove all hot-plug handlers if hot-plug is disabled on slot */
+if (object_dynamic_cast(OBJECT(dev), TYPE_PCIE_SLOT) &&
+!PCIE_SLOT(pdev)->hotplug) {
+qbus_set_hotplug_handler(BUS(sec), NULL);
+return;
+}
+
 qbus_set_hotplug_handler(BUS(sec), OBJECT(hotplug_dev));
 /* We don't have to overwrite any other hotplug handler yet */
 assert(QLIST_EMPTY(>child));
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 1bf0e687b9..a3411f0e04 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -581,6 +581,21 @@ static void machine_set_memdev(Object *obj, const char 
*value, Error **errp)
 ms->ram_memdev_id = g_strdup(value);
 }
 
+static void machine_set_native_pci_hotplug(Object *obj, bool value,
+   Error **errp)
+{
+MachineState *ms = MACHINE(obj);
+
+ms->native_pci_hotplug = value;
+}
+
+static bool machine_get_native_pci_hotplug(Object *obj, Error **errp)
+{
+MachineState *ms = MACHINE(obj);
+
+return ms->native_pci_hotplug;
+}
+
 
 static void machine_init_notify(Notifier *notifier, void *data)
 {
@@ -891,6 +906,10 @@ static void machine_class_init(ObjectClass *oc, void *data)
 object_class_property_set_description(oc, "confidential-guest-support",
   "Set confidential guest scheme to 
support");
 
+object_class_property_add_bool(oc, "x-native-pci-hotplug",
+   machine_get_native_pci_hotplug,
+   machine_set_native_pci_hotplug);
+
 /* For compatibility */
 object_class_property_add_str(oc, "memory-encryption",
 machine_get_memory_encryption, machine_set_memory_encryption);
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 46a0f196f4..1059ebfdc7 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -136,6 +136,7 @@ static void pc_q35_init(MachineState *machine)
 ram_addr_t lowmem;
 DriveInfo *hd[MAX_SATA_PORTS];
 MachineClass *mc = MACHINE_GET_CLASS(machine);
+bool acpi_pcihp;
 
 /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory
  * and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping
@@ -236,6 +237,13 @@ static void pc_q35_init(MachineState *machine)
 object_property_set_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP,
  OBJECT(lpc), _abort);
 
+acpi_pcihp = object_property_get_bool(OBJECT(lpc),
+  
"acpi-pci-hotplug-with-bridge-support",
+  NULL);
+
+object_property_set_bool(OBJECT(machine), "x-native-pci-hotplug",
+ !acpi_pcihp, NULL);
+
 /* irq lines */
 gsi_state = pc_gsi_create(>gsi, pcmc->pci_enabled);
 
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index fd0fa157e8..be331310c3 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -517,6 +517,9 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler 
*hotplug_dev,
 void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s)
 {
 uint32_t pos = dev->exp.exp_cap;
+bool native_pcihp_enabled = object_property_get_bool(qde

[RFC PATCH v4 0/7] Use ACPI PCI hot-plug for Q35

2021-05-13 Thread Julia Suvorova
The patch set consists of two parts:
patches 1-4: introduce new feature
 'acpi-pci-hotplug-with-bridge-support' on Q35
patches 5-7: make the feature default along with changes in ACPI tables

This way maintainers can decide which way to choose without breaking
the patch set.

With the feature disabled Q35 falls back to the native hot-plug.

Pros
* no racy behavior during boot (see 110c477c2ed)
* eject is possible - according to PCIe spec, attention button
  press should lead to power off, and then the adapter should be
  removed manually. As there is no power down state exists in QEMU,
  we cannot distinguish between an eject and a power down
  request.
* no delay during deleting - after the actual power off software
  must wait at least 1 second before indicating about it. This case
  is quite important for users, it even has its own bug:
  https://bugzilla.redhat.com/show_bug.cgi?id=1594168
* no timer-based behavior - in addition to the previous example,
  the attention button has a 5-second waiting period, during which
  the operation can be canceled with a second press. While this
  looks fine for manual button control, automation will result in
  the need to queue or drop events, and the software receiving
  events in all sort of unspecified combinations of attention/power
  indicator states, which is racy and uppredictable.
* fixes or reduces the likelihood of the bugs:
* https://bugzilla.redhat.com/show_bug.cgi?id=1833187
* https://bugzilla.redhat.com/show_bug.cgi?id=1657077
* https://bugzilla.redhat.com/show_bug.cgi?id=1669931
* https://bugzilla.redhat.com/show_bug.cgi?id=1678290

Cons:
* no access to possible features presented in slot capabilities
  (this is only surprise removal AFAIK)

v4:
* regain per-port control over hot-plug
* rebased over acpi-index changes
* set property on machine type to
  make pci code more generic [Igor, Michael]

v3:
* drop change of _OSC to allow SHPC on hotplugged bridges
* use 'acpi-root-pci-hotplug'
* add migration states [Igor]
* minor style changes

v2:
* new ioport range for acpiphp [Gerd]
* drop find_pci_host() [Igor]
* explain magic numbers in _OSC [Igor]
* drop build_q35_pci_hotplug() wrapper [Igor]

Julia Suvorova (7):
  hw/acpi/pcihp: Enhance acpi_pcihp_disable_root_bus() to support Q35
  hw/i386/acpi-build: Add ACPI PCI hot-plug methods to Q35
  hw/acpi/ich9: Enable ACPI PCI hot-plug
  hw/pci/pcie: Do not set HPC flag if acpihp is used
  bios-tables-test: Allow changes in DSDT ACPI tables
  hw/acpi/ich9: Set ACPI PCI hot-plug as default on Q35
  bios-tables-test: Update golden binaries

 hw/i386/acpi-build.h  |   5 +++
 include/hw/acpi/ich9.h|   5 +++
 include/hw/acpi/pcihp.h   |   3 +-
 include/hw/boards.h   |   1 +
 hw/acpi/ich9.c|  68 ++
 hw/acpi/pcihp.c   |  22 +++---
 hw/acpi/piix4.c   |   4 +-
 hw/core/machine.c |  19 +
 hw/i386/acpi-build.c  |  32 --
 hw/i386/pc.c  |   4 +-
 hw/i386/pc_q35.c  |   8 
 hw/pci/pcie.c |  11 -
 tests/data/acpi/q35/DSDT  | Bin 7859 -> 8289 bytes
 tests/data/acpi/q35/DSDT.acpihmat | Bin 9184 -> 9614 bytes
 tests/data/acpi/q35/DSDT.bridge   | Bin 7877 -> 11003 bytes
 tests/data/acpi/q35/DSDT.cphp | Bin 8323 -> 8753 bytes
 tests/data/acpi/q35/DSDT.dimmpxm  | Bin 9513 -> 9943 bytes
 tests/data/acpi/q35/DSDT.ipmibt   | Bin 7934 -> 8364 bytes
 tests/data/acpi/q35/DSDT.memhp| Bin 9218 -> 9648 bytes
 tests/data/acpi/q35/DSDT.mmio64   | Bin 8990 -> 9419 bytes
 tests/data/acpi/q35/DSDT.nohpet   | Bin 7717 -> 8147 bytes
 tests/data/acpi/q35/DSDT.numamem  | Bin 7865 -> 8295 bytes
 tests/data/acpi/q35/DSDT.tis  | Bin 8465 -> 8894 bytes
 23 files changed, 161 insertions(+), 21 deletions(-)

-- 
2.30.2




[RFC PATCH v4 2/7] hw/i386/acpi-build: Add ACPI PCI hot-plug methods to Q35

2021-05-13 Thread Julia Suvorova
Implement notifications and gpe to support q35 ACPI PCI hot-plug.
Use 0xcc4 - 0xcd7 range for 'acpi-pci-hotplug' io ports.

Signed-off-by: Julia Suvorova 
Reviewed-by: Igor Mammedov 
---
 hw/i386/acpi-build.h|  4 
 include/hw/acpi/ich9.h  |  2 ++
 include/hw/acpi/pcihp.h |  3 ++-
 hw/acpi/pcihp.c |  6 +++---
 hw/acpi/piix4.c |  4 +++-
 hw/i386/acpi-build.c| 30 +++---
 6 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
index 74df5fc612..487ec7710f 100644
--- a/hw/i386/acpi-build.h
+++ b/hw/i386/acpi-build.h
@@ -5,6 +5,10 @@
 
 extern const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio;
 
+/* PCI Hot-plug registers bases. See docs/spec/acpi_pci_hotplug.txt */
+#define ACPI_PCIHP_SEJ_BASE 0x8
+#define ACPI_PCIHP_BNMR_BASE 0x10
+
 void acpi_setup(void);
 
 #endif
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index df519e40b5..596120d97f 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -28,6 +28,8 @@
 #include "hw/acpi/acpi_dev_interface.h"
 #include "hw/acpi/tco.h"
 
+#define ACPI_PCIHP_ADDR_ICH9 0x0cc4
+
 typedef struct ICH9LPCPMRegs {
 /*
  * In ich9 spec says that pm1_cnt register is 32bit width and
diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
index 2dd90aea30..af1a169fc3 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -55,7 +55,8 @@ typedef struct AcpiPciHpState {
 } AcpiPciHpState;
 
 void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root,
- MemoryRegion *address_space_io, bool bridges_enabled);
+ MemoryRegion *address_space_io, bool bridges_enabled,
+ uint16_t io_base);
 
 void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp);
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 09f531e941..a55992ed9f 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -37,7 +37,6 @@
 #include "qom/qom-qobject.h"
 #include "trace.h"
 
-#define ACPI_PCIHP_ADDR 0xae00
 #define ACPI_PCIHP_SIZE 0x0018
 #define PCI_UP_BASE 0x
 #define PCI_DOWN_BASE 0x0004
@@ -489,10 +488,11 @@ static const MemoryRegionOps acpi_pcihp_io_ops = {
 };
 
 void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
- MemoryRegion *address_space_io, bool bridges_enabled)
+ MemoryRegion *address_space_io, bool bridges_enabled,
+ uint16_t io_base)
 {
 s->io_len = ACPI_PCIHP_SIZE;
-s->io_base = ACPI_PCIHP_ADDR;
+s->io_base = io_base;
 
 s->root = root_bus;
 s->legacy_piix = !bridges_enabled;
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 0bd23d74e2..48f7a1edbc 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -49,6 +49,8 @@
 #define GPE_BASE 0xafe0
 #define GPE_LEN 4
 
+#define ACPI_PCIHP_ADDR_PIIX4 0xae00
+
 struct pci_status {
 uint32_t up; /* deprecated, maintained for migration compatibility */
 uint32_t down;
@@ -607,7 +609,7 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
*parent,
 
 if (s->use_acpi_hotplug_bridge || s->use_acpi_root_pci_hotplug) {
 acpi_pcihp_init(OBJECT(s), >acpi_pci_hotplug, bus, parent,
-s->use_acpi_hotplug_bridge);
+s->use_acpi_hotplug_bridge, ACPI_PCIHP_ADDR_PIIX4);
 }
 
 s->cpu_hotplug_legacy = true;
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index bfecb0038c..1cc5c3b791 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -217,10 +217,6 @@ static void acpi_get_pm_info(MachineState *machine, 
AcpiPmInfo *pm)
 /* w2k requires FADT(rev1) or it won't boot, keep PC compatible */
 pm->fadt.rev = 1;
 pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE;
-pm->pcihp_io_base =
-object_property_get_uint(obj, ACPI_PCIHP_IO_BASE_PROP, NULL);
-pm->pcihp_io_len =
-object_property_get_uint(obj, ACPI_PCIHP_IO_LEN_PROP, NULL);
 }
 if (lpc) {
 uint64_t smi_features = object_property_get_uint(lpc,
@@ -236,6 +232,10 @@ static void acpi_get_pm_info(MachineState *machine, 
AcpiPmInfo *pm)
 pm->smi_on_cpu_unplug =
 !!(smi_features & BIT_ULL(ICH9_LPC_SMI_F_CPU_HOT_UNPLUG_BIT));
 }
+pm->pcihp_io_base =
+object_property_get_uint(obj, ACPI_PCIHP_IO_BASE_PROP, NULL);
+pm->pcihp_io_len =
+object_property_get_uint(obj, ACPI_PCIHP_IO_LEN_PROP, NULL);
 
 /* The above need not be conditional on machine type because the reset port
  * happens to be the same on PIIX (pc) and ICH9 (q35). */
@@ -388,6 +388,9 @@ static void build_append_pci_bus_devices(Aml *parent_scope, 
PCIBus *bus,
 
 if (!pdev) {
 if (bsel) { /* add hotplug slots for non present

[RFC PATCH v4 3/7] hw/acpi/ich9: Enable ACPI PCI hot-plug

2021-05-13 Thread Julia Suvorova
Add acpi_pcihp to ich9_pm as part of
'acpi-pci-hotplug-with-bridge-support' option. Set default to false.

Signed-off-by: Julia Suvorova 
---
 hw/i386/acpi-build.h   |  1 +
 include/hw/acpi/ich9.h |  3 ++
 hw/acpi/ich9.c | 68 ++
 hw/acpi/pcihp.c|  5 +++-
 hw/i386/acpi-build.c   |  2 +-
 5 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
index 487ec7710f..0dce155c8c 100644
--- a/hw/i386/acpi-build.h
+++ b/hw/i386/acpi-build.h
@@ -10,5 +10,6 @@ extern const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio;
 #define ACPI_PCIHP_BNMR_BASE 0x10
 
 void acpi_setup(void);
+Object *acpi_get_i386_pci_host(void);
 
 #endif
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 596120d97f..a329ce43ab 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -24,6 +24,7 @@
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/cpu_hotplug.h"
 #include "hw/acpi/cpu.h"
+#include "hw/acpi/pcihp.h"
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/acpi_dev_interface.h"
 #include "hw/acpi/tco.h"
@@ -55,6 +56,8 @@ typedef struct ICH9LPCPMRegs {
 AcpiCpuHotplug gpe_cpu;
 CPUHotplugState cpuhp_state;
 
+bool use_acpi_hotplug_bridge;
+AcpiPciHpState acpi_pci_hotplug;
 MemHotplugState acpi_memory_hotplug;
 
 uint8_t disable_s3;
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 4daa79ec8d..f6819c4f2a 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -217,6 +217,26 @@ static const VMStateDescription vmstate_cpuhp_state = {
 }
 };
 
+static bool vmstate_test_use_pcihp(void *opaque)
+{
+ICH9LPCPMRegs *s = opaque;
+
+return s->use_acpi_hotplug_bridge;
+}
+
+static const VMStateDescription vmstate_pcihp_state = {
+.name = "ich9_pm/pcihp",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = vmstate_test_use_pcihp,
+.fields  = (VMStateField[]) {
+VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug,
+ICH9LPCPMRegs,
+NULL, NULL),
+VMSTATE_END_OF_LIST()
+}
+};
+
 const VMStateDescription vmstate_ich9_pm = {
 .name = "ich9_pm",
 .version_id = 1,
@@ -238,6 +258,7 @@ const VMStateDescription vmstate_ich9_pm = {
 _memhp_state,
 _tco_io_state,
 _cpuhp_state,
+_pcihp_state,
 NULL
 }
 };
@@ -259,6 +280,7 @@ static void pm_reset(void *opaque)
 }
 pm->smi_en_wmask = ~0;
 
+acpi_pcihp_reset(>acpi_pci_hotplug, true);
 acpi_update_sci(>acpi_regs, pm->irq);
 }
 
@@ -297,6 +319,18 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 pm->enable_tco = true;
 acpi_pm_tco_init(>tco_regs, >io);
 
+if (pm->use_acpi_hotplug_bridge) {
+acpi_pcihp_init(OBJECT(lpc_pci),
+>acpi_pci_hotplug,
+pci_get_bus(lpc_pci),
+pci_address_space_io(lpc_pci),
+true,
+ACPI_PCIHP_ADDR_ICH9);
+
+qbus_set_hotplug_handler(BUS(pci_get_bus(lpc_pci)),
+ OBJECT(lpc_pci));
+}
+
 pm->irq = sci_irq;
 qemu_register_reset(pm_reset, pm);
 pm->powerdown_notifier.notify = pm_powerdown_req;
@@ -368,6 +402,21 @@ static void ich9_pm_set_enable_tco(Object *obj, bool 
value, Error **errp)
 s->pm.enable_tco = value;
 }
 
+static bool ich9_pm_get_acpi_pci_hotplug(Object *obj, Error **errp)
+{
+ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
+
+return s->pm.use_acpi_hotplug_bridge;
+}
+
+static void ich9_pm_set_acpi_pci_hotplug(Object *obj, bool value,
+   Error **errp)
+{
+ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
+
+s->pm.use_acpi_hotplug_bridge = value;
+}
+
 void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 {
 static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN;
@@ -376,6 +425,7 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 pm->disable_s3 = 0;
 pm->disable_s4 = 0;
 pm->s4_val = 2;
+pm->use_acpi_hotplug_bridge = false;
 
 object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
>pm_io_base, OBJ_PROP_FLAG_READ);
@@ -399,6 +449,9 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 object_property_add_bool(obj, ACPI_PM_PROP_TCO_ENABLED,
  ich9_pm_get_enable_tco,
  ich9_pm_set_enable_tco);
+object_property_add_bool(obj, "acpi-pci-hotplug-with-bridge-support",
+ ich9_pm_get_acpi_pci_hotplug,
+ ich9_pm_set_acpi_pci_hotplug);
 }
 
 void ich9_pm_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
@@ -406,6 +459,11 @@ void ich9_pm_device

Re: [PATCH] hw/pci-host/pam: Replace magic number by PAM_REGIONS_COUNT definition

2020-12-02 Thread Julia Suvorova
On Wed, Dec 2, 2020 at 2:24 PM Philippe Mathieu-Daudé  wrote:
>
> While this change helps triskaidekaphobic developers, it
> is a good practice to avoid magic values and using constant
> definitions instead.
>
> Introduce the PAM_REGIONS_COUNT and use it. No logical change.
>
> Signed-off-by: Philippe Mathieu-Daudé 
> ---
>  include/hw/pci-host/i440fx.h | 2 +-
>  include/hw/pci-host/pam.h| 2 ++
>  include/hw/pci-host/q35.h| 2 +-
>  hw/pci-host/pam.c| 2 +-
>  hw/pci-host/q35.c| 2 +-
>  5 files changed, 6 insertions(+), 4 deletions(-)

:D

Reviewed-by: Julia Suvorova 




Re: hw/i386/q35: Where go LPC irqs?

2020-11-11 Thread Julia Suvorova
On Sat, Nov 7, 2020 at 3:48 PM Philippe Mathieu-Daudé  wrote:
>
> Hi, I am confuse with the LPC/GSI code.
>
> In pc_q35_init() we connect the LPC outputs to
> GSI input:
>
> 116 static void pc_q35_init(MachineState *machine)
> 117 {
> ...
> 240 /* irq lines */
> 241 gsi_state = pc_gsi_create(>gsi, pcmc->pci_enabled);
> 242
> 243 ich9_lpc = ICH9_LPC_DEVICE(lpc);
> 244 lpc_dev = DEVICE(lpc);
> 245 for (i = 0; i < GSI_NUM_PINS; i++) {
> 246 qdev_connect_gpio_out_named(lpc_dev, ICH9_GPIO_GSI, i,
> x86ms->gsi[i]);
> 247 }
> ...
> 268 /* init basic PC hardware */
> 269 pc_basic_device_init(pcms, isa_bus, x86ms->gsi, _state,
> !mc->no_floppy,
> 270  0xff0104);
>
> But then we call pc_basic_device_init() which overwrite
> the GSI inputs with HPET outputs:
>
> 1118 void pc_basic_device_init(struct PCMachineState *pcms,
> 1119   ISABus *isa_bus, qemu_irq *gsi,
> 1120   ISADevice **rtc_state,
> 1121   bool create_fdctrl,
> 1122   uint32_t hpet_irqs)
> 1123 {
> ...
> 1139 /*
> 1140  * Check if an HPET shall be created.
> 1141  *
> 1142  * Without KVM_CAP_PIT_STATE2, we cannot switch off the
> in-kernel PIT
> 1143  * when the HPET wants to take over. Thus we have to disable
> the latter.
> 1144  */
> 1145 if (pcms->hpet_enabled && (!kvm_irqchip_in_kernel() ||
> 1146kvm_has_pit_state2())) {
> ...
> 1165 for (i = 0; i < GSI_NUM_PINS; i++) {
> 1166 sysbus_connect_irq(SYS_BUS_DEVICE(hpet), i, gsi[i]);
> 1167 }
>
> Are LPC IRQ still delivered?

>From what I got, LPC IRQs and HPET IRQs do not usually overlap (IRQ
0,2,8 for HPET, IRQ 3-7,9+ for all ICH9), which means that connecting
them together will not create an issue. I don't know what will happen
if higher IRQ is chosen for HPET, but according to ICH9 spec, it seems
to be aware of HPET interrupts.

> Peter commented here:
> https://www.mail-archive.com/qemu-devel@nongnu.org/msg758178.html
>
> "Connecting two qemu_irqs outputs directly
> to the same input is not valid as it produces subtly wrong behaviour
> (for instance if both the IRQ lines are high, and then one goes
> low, the PIC input will see this as a high-to-low transition
> even though the second IRQ line should still be holding it high)."
>
> Are this IRQ OR'ed to the GSI?
>
> Thanks,
>
> Phil.
>
>




Re: [PATCH v2] hw/pci/pci: Fix slot check for plugged devices

2020-10-07 Thread Julia Suvorova
On Wed, Oct 7, 2020 at 9:39 AM Stefano Garzarella  wrote:
>
> On Tue, Oct 06, 2020 at 02:59:08PM +0200, Julia Suvorova wrote:
> > If devfn is assigned automatically, 'else' clauses will never be
> > executed. And if it does not matter for the reserved and available
> > devfn, because we have already checked it, the check for function0
> > needs to be done again.
> >
> > Steps to reproduce:
> > 1. Run QEMU with:
> > -M q35 \
> > -device pcie-root-port,id=rp,.. \
> > -device pci-device,bus=rp
> > 2. Add a new device to the same port:
> > device_add pci-device,bus=rp
> >
> > The last command will add the device to slot 1 instead of
> > failing with "PCI: slot 0 function 0 already occupied..."
> >
> > Signed-off-by: Julia Suvorova 
> > ---
> > v2:
> > * add example to the commit message [Michael]
> >
> >  hw/pci/pci.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> > index de0fae10ab..ae132b0b52 100644
> > --- a/hw/pci/pci.c
> > +++ b/hw/pci/pci.c
> > @@ -1034,8 +1034,9 @@ static PCIDevice *do_pci_register_device(PCIDevice 
> > *pci_dev,
> > PCI_SLOT(devfn), PCI_FUNC(devfn), name,
> > bus->devices[devfn]->name);
> >  return NULL;
> > -} else if (dev->hotplugged &&
> > -   pci_get_function_0(pci_dev)) {
> > +};
> ^
> This semicolon seems unnecessary, can we take it out?

Oops, thanks for pointing out.




[PATCH] hw/pci: Fix typo in PCI hot-plug error message

2020-10-06 Thread Julia Suvorova
'occupied' is spelled like 'ocuppied' in the message.

Signed-off-by: Julia Suvorova 
---
 hw/pci/pci.c   | 2 +-
 hw/ppc/spapr_pci.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 3c8f10b461..100c9381c2 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1036,7 +1036,7 @@ static PCIDevice *do_pci_register_device(PCIDevice 
*pci_dev,
 return NULL;
 } else if (dev->hotplugged &&
pci_get_function_0(pci_dev)) {
-error_setg(errp, "PCI: slot %d function 0 already ocuppied by %s,"
+error_setg(errp, "PCI: slot %d function 0 already occupied by %s,"
" new func %s cannot be exposed to guest.",
PCI_SLOT(pci_get_function_0(pci_dev)->devfn),
pci_get_function_0(pci_dev)->name,
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 5db912b48c..68e2218fe0 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1572,7 +1572,7 @@ static void spapr_pci_plug(HotplugHandler *plug_handler,
  */
 if (plugged_dev->hotplugged && bus->devices[PCI_DEVFN(slotnr, 0)] &&
 PCI_FUNC(pdev->devfn) != 0) {
-error_setg(errp, "PCI: slot %d function 0 already ocuppied by %s,"
+error_setg(errp, "PCI: slot %d function 0 already occupied by %s,"
" additional functions can no longer be exposed to guest.",
slotnr, bus->devices[PCI_DEVFN(slotnr, 0)]->name);
 return;
-- 
2.25.4




[PATCH v2] hw/pci/pci: Fix slot check for plugged devices

2020-10-06 Thread Julia Suvorova
If devfn is assigned automatically, 'else' clauses will never be
executed. And if it does not matter for the reserved and available
devfn, because we have already checked it, the check for function0
needs to be done again.

Steps to reproduce:
1. Run QEMU with:
-M q35 \
-device pcie-root-port,id=rp,.. \
-device pci-device,bus=rp
2. Add a new device to the same port:
device_add pci-device,bus=rp

The last command will add the device to slot 1 instead of
failing with "PCI: slot 0 function 0 already occupied..."

Signed-off-by: Julia Suvorova 
---
v2:
* add example to the commit message [Michael]

 hw/pci/pci.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index de0fae10ab..ae132b0b52 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1034,8 +1034,9 @@ static PCIDevice *do_pci_register_device(PCIDevice 
*pci_dev,
PCI_SLOT(devfn), PCI_FUNC(devfn), name,
bus->devices[devfn]->name);
 return NULL;
-} else if (dev->hotplugged &&
-   pci_get_function_0(pci_dev)) {
+};
+
+if (dev->hotplugged && pci_get_function_0(pci_dev)) {
 error_setg(errp, "PCI: slot %d function 0 already ocuppied by %s,"
" new func %s cannot be exposed to guest.",
PCI_SLOT(pci_get_function_0(pci_dev)->devfn),
-- 
2.25.4




Re: [RFC PATCH v3 0/7] Use ACPI PCI hot-plug for Q35

2020-10-01 Thread Julia Suvorova
On Thu, Oct 1, 2020 at 1:40 PM Michael S. Tsirkin  wrote:
>
> On Thu, Oct 01, 2020 at 10:55:35AM +0200, Julia Suvorova wrote:
> > On Thu, Sep 24, 2020 at 11:20 AM Michael S. Tsirkin  wrote:
> > >
> > > On Thu, Sep 24, 2020 at 09:00:06AM +0200, Julia Suvorova wrote:
> > > > The patch set consists of two parts:
> > > > patches 1-4: introduce new feature
> > > >  'acpi-pci-hotplug-with-bridge-support' on Q35
> > > > patches 5-7: make the feature default along with changes in ACPI tables
> > > >
> > > > This way maintainers can decide which way to choose without breaking
> > > > the patch set.
> > > >
> > > > With the feature disabled Q35 falls back to the native hot-plug.
> > > >
> > > > Pros
> > > > * no racy behavior during boot (see 110c477c2ed)
> > > > * eject is possible - according to PCIe spec, attention button
> > > >   press should lead to power off, and then the adapter should be
> > > >   removed manually. As there is no power down state exists in QEMU,
> > > >   we cannot distinguish between an eject and a power down
> > > >   request.
> > > > * no delay during deleting - after the actual power off software
> > > >   must wait at least 1 second before indicating about it. This case
> > > >   is quite important for users, it even has its own bug:
> > > >   https://bugzilla.redhat.com/show_bug.cgi?id=1594168
> > > > * no timer-based behavior - in addition to the previous example,
> > > >   the attention button has a 5-second waiting period, during which
> > > >   the operation can be canceled with a second press. While this
> > > >   looks fine for manual button control, automation will result in
> > > >   the need to queue or drop events, and the software receiving
> > > >   events in all sort of unspecified combinations of attention/power
> > > >   indicator states, which is racy and uppredictable.
> > > > * fixes:
> > > > * https://bugzilla.redhat.com/show_bug.cgi?id=1752465
> > > > * https://bugzilla.redhat.com/show_bug.cgi?id=1690256
> > > >
> > > > Cons:
> > > > * lose per-port control over hot-plug (can be resolved)
> > > > * no access to possible features presented in slot capabilities
> > > >   (this is only surprise removal AFAIK)
> > >
> > > something I don't quite get is whether with this one can still add
> > > new pcie bridges and then hotplug into these with native
> > > hotplug.
> >
> > Right now I disable native if there is acpihp anywhere, but even if
> > you enable it for hotplugged devices, native hot-plug will not work.
>
> So that's a minor regression in functionality, right?
> Why is that the case? Because you disable it in ACPI?
> What if we don't?

I meant that I disable slot hotplug capabilities, nothing in ACPI
prevents native from working. Actually, I don't see if there's any
regression at all. Configurations like hot-plugging downstream port or
switch to another downstream port haven't worked before, and they
don't work now. I can enable native for hotplugged bridges, but that
doesn't make sense, because you won't be able to hot-plug anything to
it. It's not an issue of ACPI, it's PCIe behaviour. Also, native-acpi
combination may seem bizarre to os (slot enumeration is independent,
that's why I suggested disabling pcie slot flags).

> > > the challenge to answering this with certainty is that right now qemu
> > > does not allow hotplugging complex devices such as bridges at all,
> > > we only have a hack for multifunction devices.
> > > Maybe adding a bridge as function 1 on command line, then hotplugging 
> > > another device as
> > > function 0 will work to test this.
> > >
> > >
> > >
> > > > v3:
> > > > * drop change of _OSC to allow SHPC on hotplugged bridges
> > > > * use 'acpi-root-pci-hotplug'
> > > > * add migration states [Igor]
> > > > * minor style changes
> > > >
> > > > v2:
> > > > * new ioport range for acpiphp [Gerd]
> > > > * drop find_pci_host() [Igor]
> > > > * explain magic numbers in _OSC [Igor]
> > > > * drop build_q35_pci_hotplug() wrapper [Igor]
> > > >
> > > > Julia Suvorova (7):
> > > >   hw/acpi/pcihp: Enhance acpi_pcihp_dis

Re: [RFC PATCH v3 0/7] Use ACPI PCI hot-plug for Q35

2020-10-01 Thread Julia Suvorova
On Thu, Oct 1, 2020 at 3:02 PM Ani Sinha  wrote:
>
>
>
> On Thu, Oct 1, 2020 at 17:10 Michael S. Tsirkin  wrote:
>>
>> On Thu, Oct 01, 2020 at 10:55:35AM +0200, Julia Suvorova wrote:
>> > On Thu, Sep 24, 2020 at 11:20 AM Michael S. Tsirkin  
>> > wrote:
>> > >
>> > > On Thu, Sep 24, 2020 at 09:00:06AM +0200, Julia Suvorova wrote:
>> > > > The patch set consists of two parts:
>> > > > patches 1-4: introduce new feature
>> > > >  'acpi-pci-hotplug-with-bridge-support' on Q35
>> > > > patches 5-7: make the feature default along with changes in ACPI tables
>> > > >
>> > > > This way maintainers can decide which way to choose without breaking
>> > > > the patch set.
>> > > >
>> > > > With the feature disabled Q35 falls back to the native hot-plug.
>> > > >
>> > > > Pros
>> > > > * no racy behavior during boot (see 110c477c2ed)
>> > > > * eject is possible - according to PCIe spec, attention button
>> > > >   press should lead to power off, and then the adapter should be
>> > > >   removed manually. As there is no power down state exists in QEMU,
>> > > >   we cannot distinguish between an eject and a power down
>> > > >   request.
>> > > > * no delay during deleting - after the actual power off software
>> > > >   must wait at least 1 second before indicating about it. This case
>> > > >   is quite important for users, it even has its own bug:
>> > > >   https://bugzilla.redhat.com/show_bug.cgi?id=1594168
>> > > > * no timer-based behavior - in addition to the previous example,
>> > > >   the attention button has a 5-second waiting period, during which
>> > > >   the operation can be canceled with a second press. While this
>> > > >   looks fine for manual button control, automation will result in
>> > > >   the need to queue or drop events, and the software receiving
>> > > >   events in all sort of unspecified combinations of attention/power
>> > > >   indicator states, which is racy and uppredictable.
>> > > > * fixes:
>> > > > * https://bugzilla.redhat.com/show_bug.cgi?id=1752465
>> > > > * https://bugzilla.redhat.com/show_bug.cgi?id=1690256
>> > > >
>> > > > Cons:
>> > > > * lose per-port control over hot-plug (can be resolved)
>> > > > * no access to possible features presented in slot capabilities
>> > > >   (this is only surprise removal AFAIK)
>> > >
>> > > something I don't quite get is whether with this one can still add
>> > > new pcie bridges and then hotplug into these with native
>> > > hotplug.
>> >
>> > Right now I disable native if there is acpihp anywhere, but even if
>> > you enable it for hotplugged devices, native hot-plug will not work.
>>
>> So that's a minor regression in functionality, right?
>> Why is that the case? Because you disable it in ACPI?
>> What if we don't?
>
>
> Stupid question. If both native and acpi is enabled which one does OS chose? 
> Does this choice vary between OSes and different flavours of the same OS like 
> Windows?

It will always choose native.

>>
>>
>> > > the challenge to answering this with certainty is that right now qemu
>> > > does not allow hotplugging complex devices such as bridges at all,
>> > > we only have a hack for multifunction devices.
>> > > Maybe adding a bridge as function 1 on command line, then hotplugging 
>> > > another device as
>> > > function 0 will work to test this.
>> > >
>> > >
>> > >
>> > > > v3:
>> > > > * drop change of _OSC to allow SHPC on hotplugged bridges
>> > > > * use 'acpi-root-pci-hotplug'
>> > > > * add migration states [Igor]
>> > > > * minor style changes
>> > > >
>> > > > v2:
>> > > > * new ioport range for acpiphp [Gerd]
>> > > > * drop find_pci_host() [Igor]
>> > > > * explain magic numbers in _OSC [Igor]
>> > > > * drop build_q35_pci_hotplug() wrapper [Igor]
>> > > >
>> > > > Julia Suvorova (7):
>> > > >   hw/acpi/pcihp: Enhanc

Re: [RFC PATCH v3 0/7] Use ACPI PCI hot-plug for Q35

2020-10-01 Thread Julia Suvorova
On Thu, Sep 24, 2020 at 11:20 AM Michael S. Tsirkin  wrote:
>
> On Thu, Sep 24, 2020 at 09:00:06AM +0200, Julia Suvorova wrote:
> > The patch set consists of two parts:
> > patches 1-4: introduce new feature
> >  'acpi-pci-hotplug-with-bridge-support' on Q35
> > patches 5-7: make the feature default along with changes in ACPI tables
> >
> > This way maintainers can decide which way to choose without breaking
> > the patch set.
> >
> > With the feature disabled Q35 falls back to the native hot-plug.
> >
> > Pros
> > * no racy behavior during boot (see 110c477c2ed)
> > * eject is possible - according to PCIe spec, attention button
> >   press should lead to power off, and then the adapter should be
> >   removed manually. As there is no power down state exists in QEMU,
> >   we cannot distinguish between an eject and a power down
> >   request.
> > * no delay during deleting - after the actual power off software
> >   must wait at least 1 second before indicating about it. This case
> >   is quite important for users, it even has its own bug:
> >   https://bugzilla.redhat.com/show_bug.cgi?id=1594168
> > * no timer-based behavior - in addition to the previous example,
> >   the attention button has a 5-second waiting period, during which
> >   the operation can be canceled with a second press. While this
> >   looks fine for manual button control, automation will result in
> >   the need to queue or drop events, and the software receiving
> >   events in all sort of unspecified combinations of attention/power
> >   indicator states, which is racy and uppredictable.
> > * fixes:
> > * https://bugzilla.redhat.com/show_bug.cgi?id=1752465
> > * https://bugzilla.redhat.com/show_bug.cgi?id=1690256
> >
> > Cons:
> > * lose per-port control over hot-plug (can be resolved)
> > * no access to possible features presented in slot capabilities
> >   (this is only surprise removal AFAIK)
>
> something I don't quite get is whether with this one can still add
> new pcie bridges and then hotplug into these with native
> hotplug.

Right now I disable native if there is acpihp anywhere, but even if
you enable it for hotplugged devices, native hot-plug will not work.

> the challenge to answering this with certainty is that right now qemu
> does not allow hotplugging complex devices such as bridges at all,
> we only have a hack for multifunction devices.
> Maybe adding a bridge as function 1 on command line, then hotplugging another 
> device as
> function 0 will work to test this.
>
>
>
> > v3:
> > * drop change of _OSC to allow SHPC on hotplugged bridges
> > * use 'acpi-root-pci-hotplug'
> > * add migration states [Igor]
> > * minor style changes
> >
> > v2:
> > * new ioport range for acpiphp [Gerd]
> > * drop find_pci_host() [Igor]
> > * explain magic numbers in _OSC [Igor]
> > * drop build_q35_pci_hotplug() wrapper [Igor]
> >
> > Julia Suvorova (7):
> >   hw/acpi/pcihp: Enhance acpi_pcihp_disable_root_bus() to support Q35
> >   hw/i386/acpi-build: Add ACPI PCI hot-plug methods to Q35
> >   hw/pci/pcie: Do not initialize slot capability if acpihp is used
> >   hw/acpi/ich9: Enable ACPI PCI hot-plug
> >   bios-tables-test: Allow changes in DSDT ACPI tables
> >   hw/acpi/ich9: Set ACPI PCI hot-plug as default
> >   bios-tables-test: Update golden binaries
> >
> >  hw/i386/acpi-build.h  |   7 
> >  include/hw/acpi/ich9.h|   5 +++
> >  include/hw/acpi/pcihp.h   |   3 +-
> >  hw/acpi/ich9.c|  67 ++
> >  hw/acpi/pcihp.c   |  16 ---
> >  hw/acpi/piix4.c   |   4 +-
> >  hw/i386/acpi-build.c  |  31 --
> >  hw/i386/pc.c  |   1 +
> >  hw/pci/pcie.c |  16 +++
> >  tests/data/acpi/q35/DSDT  | Bin 7678 -> 7950 bytes
> >  tests/data/acpi/q35/DSDT.acpihmat | Bin 9002 -> 9274 bytes
> >  tests/data/acpi/q35/DSDT.bridge   | Bin 7695 -> 9865 bytes
> >  tests/data/acpi/q35/DSDT.cphp | Bin 8141 -> 8413 bytes
> >  tests/data/acpi/q35/DSDT.dimmpxm  | Bin 9331 -> 9603 bytes
> >  tests/data/acpi/q35/DSDT.ipmibt   | Bin 7753 -> 8025 bytes
> >  tests/data/acpi/q35/DSDT.memhp| Bin 9037 -> 9309 bytes
> >  tests/data/acpi/q35/DSDT.mmio64   | Bin 8808 -> 9080 bytes
> >  tests/data/acpi/q35/DSDT.numamem  | Bin 7684 -> 7956 bytes
> >  tests/data/acpi/q35/DSDT.tis  | Bin 8283 -> 8555 bytes
> >  19 files changed, 129 insertions(+), 21 deletions(-)
> >
> > --
> > 2.25.4
>




Re: [PATCH] docs: add 'io_uring' option to 'aio' param in qemu-options.hx

2020-09-24 Thread Julia Suvorova
On Thu, Sep 24, 2020 at 5:15 PM Stefano Garzarella  wrote:
>
> When we added io_uring AIO engine, we forgot to update qemu-options.hx,
> so qemu(1) man page and qemu help were outdated.
>
> Signed-off-by: Stefano Garzarella 

Reviewed-by: Julia Suvorova 

> ---
>  qemu-options.hx | 10 ++
>  1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 47f64be0c0..5b098577fe 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1053,7 +1053,8 @@ SRST
>  The path to the image file in the local filesystem
>
>  ``aio``
> -Specifies the AIO backend (threads/native, default: threads)
> +Specifies the AIO backend (threads/native/io_uring,
> +default: threads)
>
>  ``locking``
>  Specifies whether the image file is protected with Linux OFD
> @@ -1175,7 +1176,8 @@ DEF("drive", HAS_ARG, QEMU_OPTION_drive,
>  "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
>  "   
> [,cache=writethrough|writeback|none|directsync|unsafe][,format=f]\n"
>  "   [,snapshot=on|off][,rerror=ignore|stop|report]\n"
> -"   
> [,werror=ignore|stop|report|enospc][,id=name][,aio=threads|native]\n"
> +"   [,werror=ignore|stop|report|enospc][,id=name]\n"
> +"   [,aio=threads|native|io_uring]\n"
>  "   [,readonly=on|off][,copy-on-read=on|off]\n"
>  "   [,discard=ignore|unmap][,detect-zeroes=on|off|unmap]\n"
>  "   [[,bps=b]|[[,bps_rd=r][,bps_wr=w]]]\n"
> @@ -1247,8 +1249,8 @@ SRST
>  The default mode is ``cache=writeback``.
>
>  ``aio=aio``
> -aio is "threads", or "native" and selects between pthread based
> -disk I/O and native Linux AIO.
> +aio is "threads", "native", or "io_uring" and selects between pthread
> +based disk I/O, native Linux AIO, or Linux io_uring API.
>
>  ``format=format``
>  Specify which disk format will be used rather than detecting the
> --
> 2.26.2
>




Re: [RFC PATCH v3 4/7] hw/acpi/ich9: Enable ACPI PCI hot-plug

2020-09-24 Thread Julia Suvorova
On Thu, Sep 24, 2020 at 1:28 PM Ani Sinha  wrote:
>
>
>
> On Thu, 24 Sep 2020, Julia Suvorova wrote:
>
> > Add acpi_pcihp to ich9_pm as part of
> > 'acpi-pci-hotplug-with-bridge-support' option. Set default to false.
> >
> > Signed-off-by: Julia Suvorova 
> > ---
> > hw/i386/acpi-build.h   |  1 +
> > include/hw/acpi/ich9.h |  3 ++
> > hw/acpi/ich9.c | 67 ++
> > hw/acpi/pcihp.c|  5 +++-
> > hw/i386/acpi-build.c   |  2 +-
> > 5 files changed, 76 insertions(+), 2 deletions(-)
> >
> > diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
> > index 4c5bfb3d0b..39f143830a 100644
> > --- a/hw/i386/acpi-build.h
> > +++ b/hw/i386/acpi-build.h
> > @@ -10,6 +10,7 @@ extern const struct AcpiGenericAddress 
> > x86_nvdimm_acpi_dsmio;
> > #define ACPI_PCIHP_BNMR_BASE 0x10
> >
> > void acpi_setup(void);
> > +Object *acpi_get_i386_pci_host(void);
> >
> > Object *object_resolve_type_unambiguous(const char *typename);
> >
> > diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
> > index 4d19571ed7..833e62fefe 100644
> > --- a/include/hw/acpi/ich9.h
> > +++ b/include/hw/acpi/ich9.h
> > @@ -24,6 +24,7 @@
> > #include "hw/acpi/acpi.h"
> > #include "hw/acpi/cpu_hotplug.h"
> > #include "hw/acpi/cpu.h"
> > +#include "hw/acpi/pcihp.h"
> > #include "hw/acpi/memory_hotplug.h"
> > #include "hw/acpi/acpi_dev_interface.h"
> > #include "hw/acpi/tco.h"
> > @@ -55,6 +56,8 @@ typedef struct ICH9LPCPMRegs {
> > AcpiCpuHotplug gpe_cpu;
> > CPUHotplugState cpuhp_state;
> >
> > +bool use_acpi_hotplug_bridge;
> > +AcpiPciHpState acpi_pci_hotplug;
> > MemHotplugState acpi_memory_hotplug;
> >
> > uint8_t disable_s3;
> > diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> > index 6a19070cec..987f23e388 100644
> > --- a/hw/acpi/ich9.c
> > +++ b/hw/acpi/ich9.c
> > @@ -218,6 +218,26 @@ static const VMStateDescription vmstate_cpuhp_state = {
> > }
> > };
> >
> > +static bool vmstate_test_use_pcihp(void *opaque)
> > +{
> > +ICH9LPCPMRegs *s = opaque;
> > +
> > +return s->use_acpi_hotplug_bridge;
> > +}
> > +
> > +static const VMStateDescription vmstate_pcihp_state = {
> > +.name = "ich9_pm/pcihp",
> > +.version_id = 1,
> > +.minimum_version_id = 1,
> > +.needed = vmstate_test_use_pcihp,
> > +.fields  = (VMStateField[]) {
> > +VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug,
> > +ICH9LPCPMRegs,
> > +NULL),
> > +VMSTATE_END_OF_LIST()
> > +}
> > +};
> > +
> > const VMStateDescription vmstate_ich9_pm = {
> > .name = "ich9_pm",
> > .version_id = 1,
> > @@ -239,6 +259,7 @@ const VMStateDescription vmstate_ich9_pm = {
> > _memhp_state,
> > _tco_io_state,
> > _cpuhp_state,
> > +_pcihp_state,
> > NULL
> > }
> > };
> > @@ -260,6 +281,7 @@ static void pm_reset(void *opaque)
> > }
> > pm->smi_en_wmask = ~0;
> >
> > +acpi_pcihp_reset(>acpi_pci_hotplug, true);
>
> Maybe add a comment here that acpi based hotplug is disabled both for
> PCIE.0 and for the bridges.
>
>
> > acpi_update_sci(>acpi_regs, pm->irq);
> > }
> >
> > @@ -298,6 +320,18 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs 
> > *pm,
> > pm->enable_tco = true;
> > acpi_pm_tco_init(>tco_regs, >io);
> >
> > +if (pm->use_acpi_hotplug_bridge) {
> > +acpi_pcihp_init(OBJECT(lpc_pci),
> > +>acpi_pci_hotplug,
> > +pci_get_bus(lpc_pci),
> > +pci_address_space_io(lpc_pci),
> > +true,
> > +ACPI_PCIHP_ADDR_ICH9);
> > +
> > +qbus_set_hotplug_handler(BUS(pci_get_bus(lpc_pci)),
> > + OBJECT(lpc_pci));
> > +}
> > +
> > pm->irq = sci_irq;
> > qemu_register_reset(pm_reset, pm);
> > pm->powerdown_notifier.notify = pm_powerdown_req;
> > @@ -369,6 +403,20 @@ static void ich9_pm_set_enable_tco(Object *obj, bool 
> > value, Error **errp)
> > s->pm.enable_tco = value;
> > }
> >
> > +static bool ich9_pm_get_acpi_pci

Re: [RFC PATCH v3 6/7] hw/acpi/ich9: Set ACPI PCI hot-plug as default

2020-09-24 Thread Julia Suvorova
On Thu, Sep 24, 2020 at 12:36 PM Daniel P. Berrangé  wrote:
>
> On Thu, Sep 24, 2020 at 09:00:12AM +0200, Julia Suvorova wrote:
>
> There needs to be a commit message to explain / justify why this change
> is a benefit. You have a nice list of pros/cons in the cover letter
> which could serve as a good commit message here.
>
> The cover letter gets discarded, only the commit message is in git
> history, so its beneficial to capture that info here.

Sure, I'll add it.

> > Signed-off-by: Julia Suvorova 
> > ---
> >  hw/acpi/ich9.c | 2 +-
> >  hw/i386/pc.c   | 1 +
> >  2 files changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> > index 987f23e388..c67c20de4e 100644
> > --- a/hw/acpi/ich9.c
> > +++ b/hw/acpi/ich9.c
> > @@ -425,7 +425,7 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs 
> > *pm)
> >  pm->disable_s3 = 0;
> >  pm->disable_s4 = 0;
> >  pm->s4_val = 2;
> > -pm->use_acpi_hotplug_bridge = false;
> > +pm->use_acpi_hotplug_bridge = true;
> >
> >  object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
> > >pm_io_base, OBJ_PROP_FLAG_READ);
> > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > index b55369357e..5de4475570 100644
> > --- a/hw/i386/pc.c
> > +++ b/hw/i386/pc.c
> > @@ -101,6 +101,7 @@ GlobalProperty pc_compat_5_1[] = {};
> >  const size_t pc_compat_5_1_len = G_N_ELEMENTS(pc_compat_5_1);
> >
> >  GlobalProperty pc_compat_5_0[] = {
> > +{ "ICH9-LPC", "acpi-pci-hotplug-with-bridge-support", "off" },
> >  };
> >  const size_t pc_compat_5_0_len = G_N_ELEMENTS(pc_compat_5_0);
> >
> > --
> > 2.25.4
> >
> >
>
> Regards,
> Daniel
> --
> |: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org -o-https://fstop138.berrange.com :|
> |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|
>




Re: [RFC PATCH v3 2/7] hw/i386/acpi-build: Add ACPI PCI hot-plug methods to Q35

2020-09-24 Thread Julia Suvorova
On Thu, Sep 24, 2020 at 3:15 PM Ani Sinha  wrote:
>
>
>
> On Thu, 24 Sep 2020, Julia Suvorova wrote:
>
> > Implement notifications and gpe to support q35 ACPI PCI hot-plug.
> > Use 0xcc4 - 0xcd7 range for 'acpi-pci-hotplug' io ports.
> >
>
> For this patch, I would suggest maybe you can also add a diff of the
> disassembly of the DSDT table so that we know what changes exactly we
> shall see in the table as a result of this patch.
> Add the diff to this commit message as it will be helpful for anyone
> to take a look at it when they look at this patch.

There is no difference in golden DSDT, because this is an option,
which is disabled by default.
The diff is placed in the patch where it actually makes a difference.
But I agree that a list of changed registers would be a nice addition
to the commit message.

> > Signed-off-by: Julia Suvorova 
> > ---
> > hw/i386/acpi-build.h|  4 
> > include/hw/acpi/ich9.h  |  2 ++
> > include/hw/acpi/pcihp.h |  3 ++-
> > hw/acpi/pcihp.c |  8 
> > hw/acpi/piix4.c |  4 +++-
> > hw/i386/acpi-build.c| 27 ---
> > 6 files changed, 31 insertions(+), 17 deletions(-)
> >
> > diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
> > index 74df5fc612..487ec7710f 100644
> > --- a/hw/i386/acpi-build.h
> > +++ b/hw/i386/acpi-build.h
> > @@ -5,6 +5,10 @@
> >
> > extern const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio;
> >
> > +/* PCI Hot-plug registers bases. See docs/spec/acpi_pci_hotplug.txt */
> > +#define ACPI_PCIHP_SEJ_BASE 0x8
> > +#define ACPI_PCIHP_BNMR_BASE 0x10
> > +
> > void acpi_setup(void);
> >
> > #endif
> > diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
> > index 28a53181cb..4d19571ed7 100644
> > --- a/include/hw/acpi/ich9.h
> > +++ b/include/hw/acpi/ich9.h
> > @@ -28,6 +28,8 @@
> > #include "hw/acpi/acpi_dev_interface.h"
> > #include "hw/acpi/tco.h"
> >
> > +#define ACPI_PCIHP_ADDR_ICH9 0x0cc4
> > +
> > typedef struct ICH9LPCPMRegs {
> > /*
> >  * In ich9 spec says that pm1_cnt register is 32bit width and
> > diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
> > index 02f4665767..ce49fb03b9 100644
> > --- a/include/hw/acpi/pcihp.h
> > +++ b/include/hw/acpi/pcihp.h
> > @@ -54,7 +54,8 @@ typedef struct AcpiPciHpState {
> > } AcpiPciHpState;
> >
> > void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root,
> > - MemoryRegion *address_space_io, bool bridges_enabled);
> > + MemoryRegion *address_space_io, bool bridges_enabled,
> > + uint16_t io_base);
> >
> > void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
> >DeviceState *dev, Error **errp);
> > diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
> > index ff23104aea..bb457bc279 100644
> > --- a/hw/acpi/pcihp.c
> > +++ b/hw/acpi/pcihp.c
> > @@ -38,7 +38,6 @@
> > #include "qom/qom-qobject.h"
> > #include "trace.h"
> >
> > -#define ACPI_PCIHP_ADDR 0xae00
> > #define ACPI_PCIHP_SIZE 0x0014
> > #define PCI_UP_BASE 0x
> > #define PCI_DOWN_BASE 0x0004
> > @@ -381,12 +380,13 @@ static const MemoryRegionOps acpi_pcihp_io_ops = {
> > };
> >
> > void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
> > - MemoryRegion *address_space_io, bool bridges_enabled)
> > + MemoryRegion *address_space_io, bool bridges_enabled,
> > + uint16_t io_base)
> > {
> > s->io_len = ACPI_PCIHP_SIZE;
> > -s->io_base = ACPI_PCIHP_ADDR;
> > +s->io_base = io_base;
>
> Maybe you want to remove ACPI_PCIHP_ADDR ?

It is removed (a bit higher in this patch).

> > -s->root= root_bus;
> > +s->root = root_bus;
> > s->legacy_piix = !bridges_enabled;
> >
> > memory_region_init_io(>io, owner, _pcihp_io_ops, s,
> > diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
> > index 832f8fba82..a505ab5bcf 100644
> > --- a/hw/acpi/piix4.c
> > +++ b/hw/acpi/piix4.c
> > @@ -50,6 +50,8 @@
> > #define GPE_BASE 0xafe0
> > #define GPE_LEN 4
> >
> > +#define ACPI_PCIHP_ADDR_PIIX4 0xae00
> > +
> > struct pci_status {
> > uint32_t up; /* deprecated, maintained for migration compatibility */
> > uint32_t down;
> > @@ -597,7 +599,7 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion

Re: [RFC PATCH v3 3/7] hw/pci/pcie: Do not initialize slot capability if acpihp is used

2020-09-24 Thread Julia Suvorova
On Thu, Sep 24, 2020 at 9:36 AM Michael S. Tsirkin  wrote:
>
> On Thu, Sep 24, 2020 at 09:00:09AM +0200, Julia Suvorova wrote:
> > Instead of changing the hot-plug type in _OSC register, do not
> > initialize the slot capability or set the 'Slot Implemented' flag.
> > This way guest will choose ACPI hot-plug if it is preferred and leave
> > the option to use SHPC with pcie-pci-bridge.
> >
> > Signed-off-by: Julia Suvorova 
> > ---
> >  hw/i386/acpi-build.h |  2 ++
> >  hw/i386/acpi-build.c |  2 +-
> >  hw/pci/pcie.c| 16 
> >  3 files changed, 19 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
> > index 487ec7710f..4c5bfb3d0b 100644
> > --- a/hw/i386/acpi-build.h
> > +++ b/hw/i386/acpi-build.h
> > @@ -11,4 +11,6 @@ extern const struct AcpiGenericAddress 
> > x86_nvdimm_acpi_dsmio;
> >
> >  void acpi_setup(void);
> >
> > +Object *object_resolve_type_unambiguous(const char *typename);
> > +
> >  #endif
> > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > index cf503b16af..b7811a8912 100644
> > --- a/hw/i386/acpi-build.c
> > +++ b/hw/i386/acpi-build.c
> > @@ -174,7 +174,7 @@ static void init_common_fadt_data(MachineState *ms, 
> > Object *o,
> >  *data = fadt;
> >  }
> >
> > -static Object *object_resolve_type_unambiguous(const char *typename)
> > +Object *object_resolve_type_unambiguous(const char *typename)
> >  {
> >  bool ambig;
> >  Object *o = object_resolve_path_type("", typename, );
> > diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
> > index 5b48bae0f6..c1a082e8b9 100644
> > --- a/hw/pci/pcie.c
> > +++ b/hw/pci/pcie.c
> > @@ -27,6 +27,8 @@
> >  #include "hw/pci/pci_bus.h"
> >  #include "hw/pci/pcie_regs.h"
> >  #include "hw/pci/pcie_port.h"
> > +#include "hw/i386/ich9.h"
> > +#include "hw/i386/acpi-build.h"
> >  #include "qemu/range.h"
> >
> >  //#define DEBUG_PCIE
>
>
> Not really happy with pcie.c getting an i386 dependency.
>
>
>
> > @@ -515,12 +517,26 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler 
> > *hotplug_dev,
> >  pcie_cap_slot_push_attention_button(hotplug_pdev);
> >  }
> >
> > +static bool acpi_pcihp_enabled(void)
> > +{
> > +Object *lpc = object_resolve_type_unambiguous(TYPE_ICH9_LPC_DEVICE);
> > +
> > +return lpc &&
> > +   object_property_get_bool(lpc, 
> > "acpi-pci-hotplug-with-bridge-support",
> > +NULL);
> > +
> > +}
> > +
>
> Why not just check the property unconditionally?

Ok.

> >  /* pci express slot for pci express root/downstream port
> > PCI express capability slot registers */
> >  void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s)
> >  {
> >  uint32_t pos = dev->exp.exp_cap;
> >
> > +if (acpi_pcihp_enabled()) {
> > +return;
> > +}
> > +
>
> I think I would rather not teach pcie about acpi. How about we
> change the polarity, name the property
> "pci-native-hotplug" or whatever makes sense.

I'd prefer not to change the property name since the common code in
hw/i386/acpi-build.c depends on it, but I can add a new one if it
makes any sense.

> >  pci_word_test_and_set_mask(dev->config + pos + PCI_EXP_FLAGS,
> > PCI_EXP_FLAGS_SLOT);
> >
> > --
> > 2.25.4
>




[RFC PATCH v3 7/7] bios-tables-test: Update golden binaries

2020-09-24 Thread Julia Suvorova
Add ACPI hot-plug registers to DSDT Q35 tables.
Changes in the tables:

+Scope (_SB.PCI0)
+{
+OperationRegion (PCST, SystemIO, 0x0CC4, 0x08)
+Field (PCST, DWordAcc, NoLock, WriteAsZeros)
+{
+PCIU,   32,
+PCID,   32
+}
+
+OperationRegion (SEJ, SystemIO, 0x0CCC, 0x04)
+Field (SEJ, DWordAcc, NoLock, WriteAsZeros)
+{
+B0EJ,   32
+}
+
+OperationRegion (BNMR, SystemIO, 0x0CD4, 0x04)
+Field (BNMR, DWordAcc, NoLock, WriteAsZeros)
+{
+BNUM,   32
+}
+
+Mutex (BLCK, 0x00)
+Method (PCEJ, 2, NotSerialized)
+{
+Acquire (BLCK, 0x)
+BNUM = Arg0
+B0EJ = (One << Arg1)
+Release (BLCK)
+Return (Zero)
+}
+}
+
...

 Scope (_GPE)
 {
 Name (_HID, "ACPI0006" /* GPE Block Device */)  // _HID: Hardware ID
+Method (_E01, 0, NotSerialized)  // _Exx: Edge-Triggered GPE, 
xx=0x00-0xFF
+{
+Acquire (\_SB.PCI0.BLCK, 0x)
+\_SB.PCI0.PCNT ()
+Release (\_SB.PCI0.BLCK)
+}
 }
...

+
+Device (PHPR)
+{
+Name (_HID, "PNP0A06" /* Generic Container Device */)  // _HID: 
Hardware ID
+Name (_UID, "PCI Hotplug resources")  // _UID: Unique ID
+Name (_STA, 0x0B)  // _STA: Status
+Name (_CRS, ResourceTemplate ()  // _CRS: Current Resource Settings
+{
+IO (Decode16,
+0x0CC4, // Range Minimum
+0x0CC4, // Range Maximum
+0x01,   // Alignment
+0x14,   // Length
+)
+})
+}
 }

And if there is a port in configuration:

 Device (S10)
 {
 Name (_ADR, 0x0002)  // _ADR: Address
+Name (BSEL, Zero)
+Device (S00)
+{
+Name (_SUN, Zero)  // _SUN: Slot User Number
+Name (_ADR, Zero)  // _ADR: Address
+Method (_EJ0, 1, NotSerialized)  // _EJx: Eject Device, 
x=0-9
+{
+PCEJ (BSEL, _SUN)
+}
+}
+
...

+
+Method (DVNT, 2, NotSerialized)
+{
+If ((Arg0 & One))
+{
+Notify (S00, Arg1)
+}
+
+If ((Arg0 & 0x02))
+{
+Notify (S08, Arg1)
+    }
+
...

Signed-off-by: Julia Suvorova 
---
 tests/qtest/bios-tables-test-allowed-diff.h |  10 --
 tests/data/acpi/q35/DSDT| Bin 7678 -> 7950 bytes
 tests/data/acpi/q35/DSDT.acpihmat   | Bin 9002 -> 9274 bytes
 tests/data/acpi/q35/DSDT.bridge | Bin 7695 -> 9865 bytes
 tests/data/acpi/q35/DSDT.cphp   | Bin 8141 -> 8413 bytes
 tests/data/acpi/q35/DSDT.dimmpxm| Bin 9331 -> 9603 bytes
 tests/data/acpi/q35/DSDT.ipmibt | Bin 7753 -> 8025 bytes
 tests/data/acpi/q35/DSDT.memhp  | Bin 9037 -> 9309 bytes
 tests/data/acpi/q35/DSDT.mmio64 | Bin 8808 -> 9080 bytes
 tests/data/acpi/q35/DSDT.numamem| Bin 7684 -> 7956 bytes
 tests/data/acpi/q35/DSDT.tis| Bin 8283 -> 8555 bytes
 11 files changed, 10 deletions(-)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index 84f56b14db..dfb8523c8b 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1,11 +1 @@
 /* List of comma-separated changed AML files to ignore */
-"tests/data/acpi/q35/DSDT",
-"tests/data/acpi/q35/DSDT.tis",
-"tests/data/acpi/q35/DSDT.bridge",
-"tests/data/acpi/q35/DSDT.mmio64",
-"tests/data/acpi/q35/DSDT.ipmibt",
-"tests/data/acpi/q35/DSDT.cphp",
-"tests/data/acpi/q35/DSDT.memhp",
-"tests/data/acpi/q35/DSDT.acpihmat",
-"tests/data/acpi/q35/DSDT.numamem",
-"tests/data/acpi/q35/DSDT.dimmpxm",
diff --git a/tests/data/acpi/q35/DSDT b/tests/data/acpi/q35/DSDT
index 
bba8884073a27427b88ac0d733c9c87330a59366..56e5b111f3239ea0af2cfb6dea962e3cd837da80
 100644
GIT binary patch
delta 329
zcmexo-Dk(;66_MfC(ppZ*twDGAXB}72ZvsKuv2`1v!_9HLx6K|2qX6q9xjgPMgb7V
z87LmA03=)#q8ox;z2X_U&+u@uL^pDSIL=N6u3kV1CqLgHM(!@uEG$uHDbA)3+2
z$Jv`fL^Z(K)r%=w8N~blzaRr7Sy0KC$>3zb>FO1&4iaCo`4m&6WRO2gynBEvN4$rp
z3$LSdfTw|hff<8{WxT6_Aw#rsj6O5Wtq`-21OlA>LZa1?1VAbTd_^}~$?!9JMK^h|
z1b74lK}-(t3ovj58q5(N3bY64I|YyYl7gJlbcLeS;{4L0R

delta 57
zcmeCP`)AGN66_N4PnLm!am

[RFC PATCH v3 6/7] hw/acpi/ich9: Set ACPI PCI hot-plug as default

2020-09-24 Thread Julia Suvorova
Signed-off-by: Julia Suvorova 
---
 hw/acpi/ich9.c | 2 +-
 hw/i386/pc.c   | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 987f23e388..c67c20de4e 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -425,7 +425,7 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 pm->disable_s3 = 0;
 pm->disable_s4 = 0;
 pm->s4_val = 2;
-pm->use_acpi_hotplug_bridge = false;
+pm->use_acpi_hotplug_bridge = true;
 
 object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
>pm_io_base, OBJ_PROP_FLAG_READ);
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index b55369357e..5de4475570 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -101,6 +101,7 @@ GlobalProperty pc_compat_5_1[] = {};
 const size_t pc_compat_5_1_len = G_N_ELEMENTS(pc_compat_5_1);
 
 GlobalProperty pc_compat_5_0[] = {
+{ "ICH9-LPC", "acpi-pci-hotplug-with-bridge-support", "off" },
 };
 const size_t pc_compat_5_0_len = G_N_ELEMENTS(pc_compat_5_0);
 
-- 
2.25.4




[RFC PATCH v3 3/7] hw/pci/pcie: Do not initialize slot capability if acpihp is used

2020-09-24 Thread Julia Suvorova
Instead of changing the hot-plug type in _OSC register, do not
initialize the slot capability or set the 'Slot Implemented' flag.
This way guest will choose ACPI hot-plug if it is preferred and leave
the option to use SHPC with pcie-pci-bridge.

Signed-off-by: Julia Suvorova 
---
 hw/i386/acpi-build.h |  2 ++
 hw/i386/acpi-build.c |  2 +-
 hw/pci/pcie.c| 16 
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
index 487ec7710f..4c5bfb3d0b 100644
--- a/hw/i386/acpi-build.h
+++ b/hw/i386/acpi-build.h
@@ -11,4 +11,6 @@ extern const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio;
 
 void acpi_setup(void);
 
+Object *object_resolve_type_unambiguous(const char *typename);
+
 #endif
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index cf503b16af..b7811a8912 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -174,7 +174,7 @@ static void init_common_fadt_data(MachineState *ms, Object 
*o,
 *data = fadt;
 }
 
-static Object *object_resolve_type_unambiguous(const char *typename)
+Object *object_resolve_type_unambiguous(const char *typename)
 {
 bool ambig;
 Object *o = object_resolve_path_type("", typename, );
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 5b48bae0f6..c1a082e8b9 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -27,6 +27,8 @@
 #include "hw/pci/pci_bus.h"
 #include "hw/pci/pcie_regs.h"
 #include "hw/pci/pcie_port.h"
+#include "hw/i386/ich9.h"
+#include "hw/i386/acpi-build.h"
 #include "qemu/range.h"
 
 //#define DEBUG_PCIE
@@ -515,12 +517,26 @@ void pcie_cap_slot_unplug_request_cb(HotplugHandler 
*hotplug_dev,
 pcie_cap_slot_push_attention_button(hotplug_pdev);
 }
 
+static bool acpi_pcihp_enabled(void)
+{
+Object *lpc = object_resolve_type_unambiguous(TYPE_ICH9_LPC_DEVICE);
+
+return lpc &&
+   object_property_get_bool(lpc, 
"acpi-pci-hotplug-with-bridge-support",
+NULL);
+
+}
+
 /* pci express slot for pci express root/downstream port
PCI express capability slot registers */
 void pcie_cap_slot_init(PCIDevice *dev, PCIESlot *s)
 {
 uint32_t pos = dev->exp.exp_cap;
 
+if (acpi_pcihp_enabled()) {
+return;
+}
+
 pci_word_test_and_set_mask(dev->config + pos + PCI_EXP_FLAGS,
PCI_EXP_FLAGS_SLOT);
 
-- 
2.25.4




[RFC PATCH v3 4/7] hw/acpi/ich9: Enable ACPI PCI hot-plug

2020-09-24 Thread Julia Suvorova
Add acpi_pcihp to ich9_pm as part of
'acpi-pci-hotplug-with-bridge-support' option. Set default to false.

Signed-off-by: Julia Suvorova 
---
 hw/i386/acpi-build.h   |  1 +
 include/hw/acpi/ich9.h |  3 ++
 hw/acpi/ich9.c | 67 ++
 hw/acpi/pcihp.c|  5 +++-
 hw/i386/acpi-build.c   |  2 +-
 5 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
index 4c5bfb3d0b..39f143830a 100644
--- a/hw/i386/acpi-build.h
+++ b/hw/i386/acpi-build.h
@@ -10,6 +10,7 @@ extern const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio;
 #define ACPI_PCIHP_BNMR_BASE 0x10
 
 void acpi_setup(void);
+Object *acpi_get_i386_pci_host(void);
 
 Object *object_resolve_type_unambiguous(const char *typename);
 
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 4d19571ed7..833e62fefe 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -24,6 +24,7 @@
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/cpu_hotplug.h"
 #include "hw/acpi/cpu.h"
+#include "hw/acpi/pcihp.h"
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/acpi_dev_interface.h"
 #include "hw/acpi/tco.h"
@@ -55,6 +56,8 @@ typedef struct ICH9LPCPMRegs {
 AcpiCpuHotplug gpe_cpu;
 CPUHotplugState cpuhp_state;
 
+bool use_acpi_hotplug_bridge;
+AcpiPciHpState acpi_pci_hotplug;
 MemHotplugState acpi_memory_hotplug;
 
 uint8_t disable_s3;
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 6a19070cec..987f23e388 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -218,6 +218,26 @@ static const VMStateDescription vmstate_cpuhp_state = {
 }
 };
 
+static bool vmstate_test_use_pcihp(void *opaque)
+{
+ICH9LPCPMRegs *s = opaque;
+
+return s->use_acpi_hotplug_bridge;
+}
+
+static const VMStateDescription vmstate_pcihp_state = {
+.name = "ich9_pm/pcihp",
+.version_id = 1,
+.minimum_version_id = 1,
+.needed = vmstate_test_use_pcihp,
+.fields  = (VMStateField[]) {
+VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug,
+ICH9LPCPMRegs,
+NULL),
+VMSTATE_END_OF_LIST()
+}
+};
+
 const VMStateDescription vmstate_ich9_pm = {
 .name = "ich9_pm",
 .version_id = 1,
@@ -239,6 +259,7 @@ const VMStateDescription vmstate_ich9_pm = {
 _memhp_state,
 _tco_io_state,
 _cpuhp_state,
+_pcihp_state,
 NULL
 }
 };
@@ -260,6 +281,7 @@ static void pm_reset(void *opaque)
 }
 pm->smi_en_wmask = ~0;
 
+acpi_pcihp_reset(>acpi_pci_hotplug, true);
 acpi_update_sci(>acpi_regs, pm->irq);
 }
 
@@ -298,6 +320,18 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 pm->enable_tco = true;
 acpi_pm_tco_init(>tco_regs, >io);
 
+if (pm->use_acpi_hotplug_bridge) {
+acpi_pcihp_init(OBJECT(lpc_pci),
+>acpi_pci_hotplug,
+pci_get_bus(lpc_pci),
+pci_address_space_io(lpc_pci),
+true,
+ACPI_PCIHP_ADDR_ICH9);
+
+qbus_set_hotplug_handler(BUS(pci_get_bus(lpc_pci)),
+ OBJECT(lpc_pci));
+}
+
 pm->irq = sci_irq;
 qemu_register_reset(pm_reset, pm);
 pm->powerdown_notifier.notify = pm_powerdown_req;
@@ -369,6 +403,20 @@ static void ich9_pm_set_enable_tco(Object *obj, bool 
value, Error **errp)
 s->pm.enable_tco = value;
 }
 
+static bool ich9_pm_get_acpi_pci_hotplug(Object *obj, Error **errp)
+{
+ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
+
+return s->pm.use_acpi_hotplug_bridge;
+}
+
+static void ich9_pm_set_acpi_pci_hotplug(Object *obj, bool value,
+   Error **errp)
+{
+ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
+
+s->pm.use_acpi_hotplug_bridge = value;
+}
 void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 {
 static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN;
@@ -377,6 +425,7 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 pm->disable_s3 = 0;
 pm->disable_s4 = 0;
 pm->s4_val = 2;
+pm->use_acpi_hotplug_bridge = false;
 
 object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
>pm_io_base, OBJ_PROP_FLAG_READ);
@@ -400,6 +449,9 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
 object_property_add_bool(obj, ACPI_PM_PROP_TCO_ENABLED,
  ich9_pm_get_enable_tco,
  ich9_pm_set_enable_tco);
+object_property_add_bool(obj, "acpi-pci-hotplug-with-bridge-support",
+ ich9_pm_get_acpi_pci_hotplug,
+ ich9_pm_set_acpi_pci_hotplug);
 }
 
 void ich9_pm_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *d

[RFC PATCH v3 2/7] hw/i386/acpi-build: Add ACPI PCI hot-plug methods to Q35

2020-09-24 Thread Julia Suvorova
Implement notifications and gpe to support q35 ACPI PCI hot-plug.
Use 0xcc4 - 0xcd7 range for 'acpi-pci-hotplug' io ports.

Signed-off-by: Julia Suvorova 
---
 hw/i386/acpi-build.h|  4 
 include/hw/acpi/ich9.h  |  2 ++
 include/hw/acpi/pcihp.h |  3 ++-
 hw/acpi/pcihp.c |  8 
 hw/acpi/piix4.c |  4 +++-
 hw/i386/acpi-build.c| 27 ---
 6 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
index 74df5fc612..487ec7710f 100644
--- a/hw/i386/acpi-build.h
+++ b/hw/i386/acpi-build.h
@@ -5,6 +5,10 @@
 
 extern const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio;
 
+/* PCI Hot-plug registers bases. See docs/spec/acpi_pci_hotplug.txt */
+#define ACPI_PCIHP_SEJ_BASE 0x8
+#define ACPI_PCIHP_BNMR_BASE 0x10
+
 void acpi_setup(void);
 
 #endif
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 28a53181cb..4d19571ed7 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -28,6 +28,8 @@
 #include "hw/acpi/acpi_dev_interface.h"
 #include "hw/acpi/tco.h"
 
+#define ACPI_PCIHP_ADDR_ICH9 0x0cc4
+
 typedef struct ICH9LPCPMRegs {
 /*
  * In ich9 spec says that pm1_cnt register is 32bit width and
diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
index 02f4665767..ce49fb03b9 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -54,7 +54,8 @@ typedef struct AcpiPciHpState {
 } AcpiPciHpState;
 
 void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root,
- MemoryRegion *address_space_io, bool bridges_enabled);
+ MemoryRegion *address_space_io, bool bridges_enabled,
+ uint16_t io_base);
 
 void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp);
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index ff23104aea..bb457bc279 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -38,7 +38,6 @@
 #include "qom/qom-qobject.h"
 #include "trace.h"
 
-#define ACPI_PCIHP_ADDR 0xae00
 #define ACPI_PCIHP_SIZE 0x0014
 #define PCI_UP_BASE 0x
 #define PCI_DOWN_BASE 0x0004
@@ -381,12 +380,13 @@ static const MemoryRegionOps acpi_pcihp_io_ops = {
 };
 
 void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
- MemoryRegion *address_space_io, bool bridges_enabled)
+ MemoryRegion *address_space_io, bool bridges_enabled,
+ uint16_t io_base)
 {
 s->io_len = ACPI_PCIHP_SIZE;
-s->io_base = ACPI_PCIHP_ADDR;
+s->io_base = io_base;
 
-s->root= root_bus;
+s->root = root_bus;
 s->legacy_piix = !bridges_enabled;
 
 memory_region_init_io(>io, owner, _pcihp_io_ops, s,
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 832f8fba82..a505ab5bcf 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -50,6 +50,8 @@
 #define GPE_BASE 0xafe0
 #define GPE_LEN 4
 
+#define ACPI_PCIHP_ADDR_PIIX4 0xae00
+
 struct pci_status {
 uint32_t up; /* deprecated, maintained for migration compatibility */
 uint32_t down;
@@ -597,7 +599,7 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
*parent,
 memory_region_add_subregion(parent, GPE_BASE, >io_gpe);
 
 acpi_pcihp_init(OBJECT(s), >acpi_pci_hotplug, bus, parent,
-s->use_acpi_hotplug_bridge);
+s->use_acpi_hotplug_bridge, ACPI_PCIHP_ADDR_PIIX4);
 
 s->cpu_hotplug_legacy = true;
 object_property_add_bool(OBJECT(s), "cpu-hotplug-legacy",
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 0e0535d2e3..cf503b16af 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -201,10 +201,6 @@ static void acpi_get_pm_info(MachineState *machine, 
AcpiPmInfo *pm)
 /* w2k requires FADT(rev1) or it won't boot, keep PC compatible */
 pm->fadt.rev = 1;
 pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE;
-pm->pcihp_io_base =
-object_property_get_uint(obj, ACPI_PCIHP_IO_BASE_PROP, NULL);
-pm->pcihp_io_len =
-object_property_get_uint(obj, ACPI_PCIHP_IO_LEN_PROP, NULL);
 }
 if (lpc) {
 struct AcpiGenericAddress r = { .space_id = AML_AS_SYSTEM_IO,
@@ -214,6 +210,10 @@ static void acpi_get_pm_info(MachineState *machine, 
AcpiPmInfo *pm)
 pm->fadt.flags |= 1 << ACPI_FADT_F_RESET_REG_SUP;
 pm->cpu_hp_io_base = ICH9_CPU_HOTPLUG_IO_BASE;
 }
+pm->pcihp_io_base =
+object_property_get_uint(obj, ACPI_PCIHP_IO_BASE_PROP, NULL);
+pm->pcihp_io_len =
+object_property_get_uint(obj, ACPI_PCIHP_IO_LEN_PROP, NULL);
 
 /* The above need not be conditional on machine type because the reset port
  * happens to be the same on PIIX (pc) and ICH9 (q35). */
@@ -472,7 +472,7 @@ static void build_append_pci_bus_devices(Aml *par

[RFC PATCH v3 1/7] hw/acpi/pcihp: Enhance acpi_pcihp_disable_root_bus() to support Q35

2020-09-24 Thread Julia Suvorova
PCI Express does not allow hot-plug on pcie.0. Check for Q35 in
acpi_pcihp_disable_root_bus() to be able to forbid hot-plug using the
'acpi-root-pci-hotplug' flag.

Signed-off-by: Julia Suvorova 
---
 hw/acpi/pcihp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 39b1f74442..ff23104aea 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -107,13 +107,14 @@ static void acpi_set_pci_info(void)
 static void acpi_pcihp_disable_root_bus(void)
 {
 static bool root_hp_disabled;
+Object *host = acpi_get_i386_pci_host();
 PCIBus *bus;
 
 if (root_hp_disabled) {
 return;
 }
 
-bus = find_i440fx();
+bus = PCI_HOST_BRIDGE(host)->bus;
 if (bus) {
 /* setting the hotplug handler to NULL makes the bus non-hotpluggable 
*/
 qbus_set_hotplug_handler(BUS(bus), NULL);
-- 
2.25.4




[RFC PATCH v3 5/7] bios-tables-test: Allow changes in DSDT ACPI tables

2020-09-24 Thread Julia Suvorova
All DSDT Q35 tables will be modified because ACPI hot-plug is enabled
by default.

Signed-off-by: Julia Suvorova 
---
 tests/qtest/bios-tables-test-allowed-diff.h | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/tests/qtest/bios-tables-test-allowed-diff.h 
b/tests/qtest/bios-tables-test-allowed-diff.h
index dfb8523c8b..84f56b14db 100644
--- a/tests/qtest/bios-tables-test-allowed-diff.h
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
@@ -1 +1,11 @@
 /* List of comma-separated changed AML files to ignore */
+"tests/data/acpi/q35/DSDT",
+"tests/data/acpi/q35/DSDT.tis",
+"tests/data/acpi/q35/DSDT.bridge",
+"tests/data/acpi/q35/DSDT.mmio64",
+"tests/data/acpi/q35/DSDT.ipmibt",
+"tests/data/acpi/q35/DSDT.cphp",
+"tests/data/acpi/q35/DSDT.memhp",
+"tests/data/acpi/q35/DSDT.acpihmat",
+"tests/data/acpi/q35/DSDT.numamem",
+"tests/data/acpi/q35/DSDT.dimmpxm",
-- 
2.25.4




[RFC PATCH v3 0/7] Use ACPI PCI hot-plug for Q35

2020-09-24 Thread Julia Suvorova
The patch set consists of two parts:
patches 1-4: introduce new feature
 'acpi-pci-hotplug-with-bridge-support' on Q35
patches 5-7: make the feature default along with changes in ACPI tables

This way maintainers can decide which way to choose without breaking
the patch set.

With the feature disabled Q35 falls back to the native hot-plug.

Pros
* no racy behavior during boot (see 110c477c2ed)
* eject is possible - according to PCIe spec, attention button
  press should lead to power off, and then the adapter should be
  removed manually. As there is no power down state exists in QEMU,
  we cannot distinguish between an eject and a power down
  request.
* no delay during deleting - after the actual power off software
  must wait at least 1 second before indicating about it. This case
  is quite important for users, it even has its own bug:
  https://bugzilla.redhat.com/show_bug.cgi?id=1594168
* no timer-based behavior - in addition to the previous example,
  the attention button has a 5-second waiting period, during which
  the operation can be canceled with a second press. While this
  looks fine for manual button control, automation will result in
  the need to queue or drop events, and the software receiving
  events in all sort of unspecified combinations of attention/power
  indicator states, which is racy and uppredictable.
* fixes:
* https://bugzilla.redhat.com/show_bug.cgi?id=1752465
* https://bugzilla.redhat.com/show_bug.cgi?id=1690256

Cons:
* lose per-port control over hot-plug (can be resolved)
* no access to possible features presented in slot capabilities
  (this is only surprise removal AFAIK)

v3:
* drop change of _OSC to allow SHPC on hotplugged bridges
* use 'acpi-root-pci-hotplug'
* add migration states [Igor]
* minor style changes

v2:
* new ioport range for acpiphp [Gerd]
* drop find_pci_host() [Igor]
* explain magic numbers in _OSC [Igor]
* drop build_q35_pci_hotplug() wrapper [Igor]

Julia Suvorova (7):
  hw/acpi/pcihp: Enhance acpi_pcihp_disable_root_bus() to support Q35
  hw/i386/acpi-build: Add ACPI PCI hot-plug methods to Q35
  hw/pci/pcie: Do not initialize slot capability if acpihp is used
  hw/acpi/ich9: Enable ACPI PCI hot-plug
  bios-tables-test: Allow changes in DSDT ACPI tables
  hw/acpi/ich9: Set ACPI PCI hot-plug as default
  bios-tables-test: Update golden binaries

 hw/i386/acpi-build.h  |   7 
 include/hw/acpi/ich9.h|   5 +++
 include/hw/acpi/pcihp.h   |   3 +-
 hw/acpi/ich9.c|  67 ++
 hw/acpi/pcihp.c   |  16 ---
 hw/acpi/piix4.c   |   4 +-
 hw/i386/acpi-build.c  |  31 --
 hw/i386/pc.c  |   1 +
 hw/pci/pcie.c |  16 +++
 tests/data/acpi/q35/DSDT  | Bin 7678 -> 7950 bytes
 tests/data/acpi/q35/DSDT.acpihmat | Bin 9002 -> 9274 bytes
 tests/data/acpi/q35/DSDT.bridge   | Bin 7695 -> 9865 bytes
 tests/data/acpi/q35/DSDT.cphp | Bin 8141 -> 8413 bytes
 tests/data/acpi/q35/DSDT.dimmpxm  | Bin 9331 -> 9603 bytes
 tests/data/acpi/q35/DSDT.ipmibt   | Bin 7753 -> 8025 bytes
 tests/data/acpi/q35/DSDT.memhp| Bin 9037 -> 9309 bytes
 tests/data/acpi/q35/DSDT.mmio64   | Bin 8808 -> 9080 bytes
 tests/data/acpi/q35/DSDT.numamem  | Bin 7684 -> 7956 bytes
 tests/data/acpi/q35/DSDT.tis  | Bin 8283 -> 8555 bytes
 19 files changed, 129 insertions(+), 21 deletions(-)

-- 
2.25.4




Re: [PATCH] hw/pci/pci: Fix slot check for plugged devices

2020-09-23 Thread Julia Suvorova
On Wed, Sep 23, 2020 at 5:03 PM Michael S. Tsirkin  wrote:
>
> On Wed, Sep 23, 2020 at 11:26:36AM +0200, Julia Suvorova wrote:
> > If devfn is assigned automatically, 'else' clauses will never be
> > executed. And if it does not matter for the reserved and available
> > devfn, because we have already checked it, the check for function0
> > needs to be done again.
> >
> > Signed-off-by: Julia Suvorova 
>
> This is just cosmetics right? I wouldn't describe this as
> a "fix" then - "simplify" would be clearer.

No, this is a bug fix. For example, if you had a root port with a
device on it already, and you do
'device_add new_device,bus=the_same_root_port', then it will miss the
last 'if' and will be added to slot 1.

> > ---
> >  hw/pci/pci.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> >
> > diff --git a/hw/pci/pci.c b/hw/pci/pci.c
> > index de0fae10ab..ae132b0b52 100644
> > --- a/hw/pci/pci.c
> > +++ b/hw/pci/pci.c
> > @@ -1034,8 +1034,9 @@ static PCIDevice *do_pci_register_device(PCIDevice 
> > *pci_dev,
> > PCI_SLOT(devfn), PCI_FUNC(devfn), name,
> > bus->devices[devfn]->name);
> >  return NULL;
> > -} else if (dev->hotplugged &&
> > -   pci_get_function_0(pci_dev)) {
> > +};
> > +
> > +if (dev->hotplugged && pci_get_function_0(pci_dev)) {
> >  error_setg(errp, "PCI: slot %d function 0 already ocuppied by %s,"
> > " new func %s cannot be exposed to guest.",
> > PCI_SLOT(pci_get_function_0(pci_dev)->devfn),
> > --
> > 2.25.4
>




[PATCH] hw/pci/pci: Fix slot check for plugged devices

2020-09-23 Thread Julia Suvorova
If devfn is assigned automatically, 'else' clauses will never be
executed. And if it does not matter for the reserved and available
devfn, because we have already checked it, the check for function0
needs to be done again.

Signed-off-by: Julia Suvorova 
---
 hw/pci/pci.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index de0fae10ab..ae132b0b52 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1034,8 +1034,9 @@ static PCIDevice *do_pci_register_device(PCIDevice 
*pci_dev,
PCI_SLOT(devfn), PCI_FUNC(devfn), name,
bus->devices[devfn]->name);
 return NULL;
-} else if (dev->hotplugged &&
-   pci_get_function_0(pci_dev)) {
+};
+
+if (dev->hotplugged && pci_get_function_0(pci_dev)) {
 error_setg(errp, "PCI: slot %d function 0 already ocuppied by %s,"
" new func %s cannot be exposed to guest.",
PCI_SLOT(pci_get_function_0(pci_dev)->devfn),
-- 
2.25.4




[PATCH] hw/i386/acpi-build: Explain bits in OSC method

2020-09-23 Thread Julia Suvorova
Provide a better explanation for the enabled bits in the _OSC control
field. Base it on the latest specification due to new bits 5 and 6.

Signed-off-by: Julia Suvorova 
---
 hw/i386/acpi-build.h | 11 +++
 hw/i386/acpi-build.c |  7 ++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
index 74df5fc612..bb5269d162 100644
--- a/hw/i386/acpi-build.h
+++ b/hw/i386/acpi-build.h
@@ -5,6 +5,17 @@
 
 extern const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio;
 
+/* PCI Firmware Specification 3.2, Table 4-5 */
+typedef enum {
+ACPI_OSC_NATIVE_HP_EN = 0,
+ACPI_OSC_SHPC_EN = 1,
+ACPI_OSC_PME_EN = 2,
+ACPI_OSC_AER_EN = 3,
+ACPI_OSC_PCIE_CAP_EN = 4,
+ACPI_OSC_LTR_EN = 5,
+ACPI_OSC_ALLONES_INVALID = 6,
+} AcpiOSCField;
+
 void acpi_setup(void);
 
 #endif
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 0e0535d2e3..b08f005a35 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1417,6 +1417,7 @@ static Aml *build_q35_osc_method(void)
 Aml *method;
 Aml *a_cwd1 = aml_name("CDW1");
 Aml *a_ctrl = aml_local(0);
+unsigned osc_ctrl;
 
 method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
 aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
@@ -1432,7 +1433,11 @@ static Aml *build_q35_osc_method(void)
  * Always allow native PME, AER (no dependencies)
  * Allow SHPC (PCI bridges can have SHPC controller)
  */
-aml_append(if_ctx, aml_and(a_ctrl, aml_int(0x1F), a_ctrl));
+osc_ctrl = BIT(ACPI_OSC_PME_EN) | BIT(ACPI_OSC_AER_EN) |
+   BIT(ACPI_OSC_PCIE_CAP_EN) | BIT(ACPI_OSC_NATIVE_HP_EN) |
+   BIT(ACPI_OSC_SHPC_EN);
+
+aml_append(if_ctx, aml_and(a_ctrl, aml_int(osc_ctrl), a_ctrl));
 
 if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1;
 /* Unknown revision */
-- 
2.25.4




Re: [RFC PATCH v2 3/4] hw/i386/acpi-build: Turn off support of PCIe native hot-plug and SHPC in _OSC

2020-09-17 Thread Julia Suvorova
On Thu, Sep 17, 2020 at 8:01 AM Igor Mammedov  wrote:
>
> On Wed, 16 Sep 2020 21:14:36 +0200
> Julia Suvorova  wrote:
>
> > On Wed, Sep 16, 2020 at 8:03 PM Julia Suvorova  wrote:
> > >
> > > On Fri, Aug 21, 2020 at 2:13 PM Igor Mammedov  wrote:
> > > >
> > > > On Tue, 18 Aug 2020 23:52:26 +0200
> > > > Julia Suvorova  wrote:
> > > >
> > > > > Other methods may be used if the system is capable of this and the 
> > > > > _OSC bit
> > > > > is set. Disable them explicitly to force ACPI PCI hot-plug use. The 
> > > > > older
> > > > > versions will still use PCIe native.
> > > > >
> > > > > Signed-off-by: Julia Suvorova 
> > > > > ---
> > > > >  hw/i386/acpi-build.h | 11 +++
> > > > >  hw/i386/acpi-build.c | 21 +++--
> > > > >  2 files changed, 26 insertions(+), 6 deletions(-)
> > > > >
> > > > > diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
> > > > > index 74df5fc612..6f94312c39 100644
> > > > > --- a/hw/i386/acpi-build.h
> > > > > +++ b/hw/i386/acpi-build.h
> > > > > @@ -5,6 +5,17 @@
> > > > >
> > > > >  extern const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio;
> > > > >
> > > > > +/* PCI Firmware Specification 3.2, Table 4-5 */
> > > > > +typedef enum {
> > > > > +ACPI_OSC_NATIVE_HP_EN = 0,
> > > > > +ACPI_OSC_SHPC_EN = 1,
> > > > > +ACPI_OSC_PME_EN = 2,
> > > > > +ACPI_OSC_AER_EN = 3,
> > > > > +ACPI_OSC_PCIE_CAP_EN = 4,
> > > > > +ACPI_OSC_LTR_EN = 5,
> > > > > +ACPI_OSC_ALLONES_INVALID = 6,
> > > > > +} AcpiOSCField;
> > > > > +
> > > > >  void acpi_setup(void);
> > > > >
> > > > >  #endif
> > > > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > > > index f3cd52bd06..c5f4802b8c 100644
> > > > > --- a/hw/i386/acpi-build.c
> > > > > +++ b/hw/i386/acpi-build.c
> > > > > @@ -1411,7 +1411,7 @@ static void build_i386_pci_hotplug(Aml *table, 
> > > > > uint64_t pcihp_addr)
> > > > >  aml_append(table, scope);
> > > > >  }
> > > > >
> > > > > -static Aml *build_q35_osc_method(void)
> > > > > +static Aml *build_q35_osc_method(AcpiPmInfo *pm)
> > > > >  {
> > > > >  Aml *if_ctx;
> > > > >  Aml *if_ctx2;
> > > > > @@ -1419,6 +1419,7 @@ static Aml *build_q35_osc_method(void)
> > > > >  Aml *method;
> > > > >  Aml *a_cwd1 = aml_name("CDW1");
> > > > >  Aml *a_ctrl = aml_local(0);
> > > > > +unsigned osc_ctrl;
> > > > >
> > > > >  method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
> > > > >  aml_append(method, aml_create_dword_field(aml_arg(3), 
> > > > > aml_int(0), "CDW1"));
> > > > > @@ -1430,11 +1431,19 @@ static Aml *build_q35_osc_method(void)
> > > > >
> > > > >  aml_append(if_ctx, aml_store(aml_name("CDW3"), a_ctrl));
> > > > >
> > > > > +/* Always allow native PME, AER (depend on PCIE Capability 
> > > > > Control) */
> > > > > +osc_ctrl = BIT(ACPI_OSC_PME_EN) | BIT(ACPI_OSC_AER_EN) |
> > > > > +   BIT(ACPI_OSC_PCIE_CAP_EN);
> > > > > +
> > > > >  /*
> > > > > - * Always allow native PME, AER (no dependencies)
> > > > > - * Allow SHPC (PCI bridges can have SHPC controller)
> > > > > + * Guests seem to generally prefer native hot-plug control.
> > > > > + * Enable it only when we do not use ACPI hot-plug.
> > > > >   */
> > > > > -aml_append(if_ctx, aml_and(a_ctrl, aml_int(0x1F), a_ctrl));
> > > > > +if (!pm->pcihp_bridge_en) {
> > > > > +osc_ctrl |= BIT(ACPI_OSC_NATIVE_HP_EN) | 
> > > > > BIT(ACPI_OSC_SHPC_EN);
> > > > > +}
> > > >
> > > > ACPI hotplug works only for coldplugged bridges, and native one is used
> > > > on hotplugged ones.
> > > > Wouldn't that break SHPC/Native hotplug on hotplugged PCI/PCI-E bridge?

Re: [RFC PATCH v2 4/4] hw/acpi/ich9: Enable ACPI PCI hot-plug

2020-09-16 Thread Julia Suvorova
On Fri, Aug 21, 2020 at 2:24 PM Igor Mammedov  wrote:
>
> On Tue, 18 Aug 2020 23:52:27 +0200
> Julia Suvorova  wrote:
>
> > Add acpi_pcihp to ich9_pm and use ACPI PCI hot-plug by default.
>
> I don't see anything related to migrating hotplug state within series,
>
> see VMSTATE_PCI_HOTPLUG for example.

Ok, will do.

>
> > Signed-off-by: Julia Suvorova 
> > ---
> > Note: New pc_compats are usually added shortly after release.
> >   I will switch to pc_compat_5_1 when it becomes available.
> >
> >  hw/i386/acpi-build.h   |  1 +
> >  include/hw/acpi/ich9.h |  3 +++
> >  hw/acpi/ich9.c | 45 ++
> >  hw/acpi/pcihp.c|  5 -
> >  hw/i386/acpi-build.c   |  2 +-
> >  hw/i386/pc.c   |  1 +
> >  6 files changed, 55 insertions(+), 2 deletions(-)
> >
> > diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
> > index 6f94312c39..f0bb080018 100644
> > --- a/hw/i386/acpi-build.h
> > +++ b/hw/i386/acpi-build.h
> > @@ -17,5 +17,6 @@ typedef enum {
> >  } AcpiOSCField;
> >
> >  void acpi_setup(void);
> > +Object *acpi_get_i386_pci_host(void);
> >
> >  #endif
> > diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
> > index 28a53181cb..9947085e9c 100644
> > --- a/include/hw/acpi/ich9.h
> > +++ b/include/hw/acpi/ich9.h
> > @@ -24,6 +24,7 @@
> >  #include "hw/acpi/acpi.h"
> >  #include "hw/acpi/cpu_hotplug.h"
> >  #include "hw/acpi/cpu.h"
> > +#include "hw/acpi/pcihp.h"
> >  #include "hw/acpi/memory_hotplug.h"
> >  #include "hw/acpi/acpi_dev_interface.h"
> >  #include "hw/acpi/tco.h"
> > @@ -53,6 +54,8 @@ typedef struct ICH9LPCPMRegs {
> >  AcpiCpuHotplug gpe_cpu;
> >  CPUHotplugState cpuhp_state;
> >
> > +bool use_acpi_hotplug_bridge;
> > +AcpiPciHpState acpi_pci_hotplug;
> >  MemHotplugState acpi_memory_hotplug;
> >
> >  uint8_t disable_s3;
> > diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> > index a2a1742aa6..fde86d12ae 100644
> > --- a/hw/acpi/ich9.c
> > +++ b/hw/acpi/ich9.c
> > @@ -265,6 +265,7 @@ static void pm_reset(void *opaque)
> >  }
> >  pm->smi_en_wmask = ~0;
> >
> > +acpi_pcihp_reset(>acpi_pci_hotplug);
> >  acpi_update_sci(>acpi_regs, pm->irq);
> >  }
> >
> > @@ -303,6 +304,17 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs 
> > *pm,
> >  pm->enable_tco = true;
> >  acpi_pm_tco_init(>tco_regs, >io);
> >
> > +if (pm->use_acpi_hotplug_bridge) {
> > +acpi_pcihp_init(OBJECT(lpc_pci),
> > +>acpi_pci_hotplug,
> > +pci_get_bus(lpc_pci),
> > +pci_address_space_io(lpc_pci),
> > +true, false);
> > +
> > +qbus_set_hotplug_handler(BUS(pci_get_bus(lpc_pci)),
> > + OBJECT(lpc_pci));
> > +}
> > +
> >  pm->irq = sci_irq;
> >  qemu_register_reset(pm_reset, pm);
> >  pm->powerdown_notifier.notify = pm_powerdown_req;
> > @@ -374,6 +386,20 @@ static void ich9_pm_set_enable_tco(Object *obj, bool 
> > value, Error **errp)
> >  s->pm.enable_tco = value;
> >  }
> >
> > +static bool ich9_pm_get_acpi_pci_hotplug(Object *obj, Error **errp)
> > +{
> > +ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
> > +
> > +return s->pm.use_acpi_hotplug_bridge;
> > +}
> > +
> > +static void ich9_pm_set_acpi_pci_hotplug(Object *obj, bool value,
> > +   Error **errp)
> > +{
> > +ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
> > +
> > +s->pm.use_acpi_hotplug_bridge = value;
> > +}
> >  void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm)
> >  {
> >  static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN;
> > @@ -382,6 +408,7 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs 
> > *pm)
> >  pm->disable_s3 = 0;
> >  pm->disable_s4 = 0;
> >  pm->s4_val = 2;
> > +pm->use_acpi_hotplug_bridge = true;
>
> I'd prefer default to be false, and managment turn it on when creating
> config for Windows.
>
> i.e. if users need it, they should enable it explicitly so overhead it 
> produces
> won't affect other configs.
>
> >  object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
&g

Re: [RFC PATCH v2 2/4] hw/i386/acpi-build: Add ACPI PCI hot-plug methods to q35

2020-09-16 Thread Julia Suvorova
On Wed, Aug 19, 2020 at 5:21 AM Philippe Mathieu-Daudé
 wrote:
>
> Hi Julia,
>
> On 8/18/20 11:52 PM, Julia Suvorova wrote:
> > Implement notifications and gpe to support q35 ACPI PCI hot-plug.
> > Use 0xcc4 - 0xcd7 range for 'acpi-pci-hotplug' io ports.
> >
> > Signed-off-by: Julia Suvorova 
> > ---
> >  include/hw/acpi/pcihp.h |  3 ++-
> >  hw/acpi/pcihp.c | 10 ++
> >  hw/acpi/piix4.c |  2 +-
> >  hw/i386/acpi-build.c| 25 ++---
> >  4 files changed, 23 insertions(+), 17 deletions(-)
> >
> > diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
> > index 8bc4a4c01d..1e9d246f57 100644
> > --- a/include/hw/acpi/pcihp.h
> > +++ b/include/hw/acpi/pcihp.h
> > @@ -54,7 +54,8 @@ typedef struct AcpiPciHpState {
> >  } AcpiPciHpState;
> >
> >  void acpi_pcihp_init(Object *owner, AcpiPciHpState *, PCIBus *root,
> > - MemoryRegion *address_space_io, bool bridges_enabled);
> > + MemoryRegion *address_space_io, bool bridges_enabled,
> > + bool is_piix4);
> >
> >  void acpi_pcihp_device_pre_plug_cb(HotplugHandler *hotplug_dev,
> > DeviceState *dev, Error **errp);
> > diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
> > index 9e31ab2da4..9a35ed6c83 100644
> > --- a/hw/acpi/pcihp.c
> > +++ b/hw/acpi/pcihp.c
> > @@ -38,7 +38,8 @@
> >  #include "qom/qom-qobject.h"
> >  #include "trace.h"
> >
> > -#define ACPI_PCIHP_ADDR 0xae00
> > +#define ACPI_PCIHP_ADDR_PIIX4 0xae00
> > +#define ACPI_PCIHP_ADDR_Q35 0x0cc4
> >  #define ACPI_PCIHP_SIZE 0x0014
> >  #define PCI_UP_BASE 0x
> >  #define PCI_DOWN_BASE 0x0004
> > @@ -359,12 +360,13 @@ static const MemoryRegionOps acpi_pcihp_io_ops = {
> >  };
> >
> >  void acpi_pcihp_init(Object *owner, AcpiPciHpState *s, PCIBus *root_bus,
> > - MemoryRegion *address_space_io, bool bridges_enabled)
> > + MemoryRegion *address_space_io, bool bridges_enabled,
> > + bool is_piix4)
>
> Instead of adding implementation knowledge to this generic function, can
> you instead pass it a 'io_base' argument (or 'pcihp_addr')?

Ok.

> >  {
> >  s->io_len = ACPI_PCIHP_SIZE;
> > -s->io_base = ACPI_PCIHP_ADDR;
> > +s->io_base = is_piix4 ? ACPI_PCIHP_ADDR_PIIX4 : ACPI_PCIHP_ADDR_Q35;
> >
> > -s->root= root_bus;
> > +s->root = root_bus;
> >  s->legacy_piix = !bridges_enabled;
> >
> >  memory_region_init_io(>io, owner, _pcihp_io_ops, s,
> > diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
> > index cdfa0e2998..1f27bfbd06 100644
> > --- a/hw/acpi/piix4.c
> > +++ b/hw/acpi/piix4.c
> > @@ -596,7 +596,7 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
> > *parent,
> >  memory_region_add_subregion(parent, GPE_BASE, >io_gpe);
> >
> >  acpi_pcihp_init(OBJECT(s), >acpi_pci_hotplug, bus, parent,
> > -s->use_acpi_hotplug_bridge);
> > +s->use_acpi_hotplug_bridge, true);
> >
> >  s->cpu_hotplug_legacy = true;
> >  object_property_add_bool(OBJECT(s), "cpu-hotplug-legacy",
> > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > index b7bc2a..f3cd52bd06 100644
> > --- a/hw/i386/acpi-build.c
> > +++ b/hw/i386/acpi-build.c
> > @@ -201,10 +201,6 @@ static void acpi_get_pm_info(MachineState *machine, 
> > AcpiPmInfo *pm)
> >  /* w2k requires FADT(rev1) or it won't boot, keep PC compatible */
> >  pm->fadt.rev = 1;
> >  pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE;
> > -pm->pcihp_io_base =
> > -object_property_get_uint(obj, ACPI_PCIHP_IO_BASE_PROP, NULL);
> > -pm->pcihp_io_len =
> > -object_property_get_uint(obj, ACPI_PCIHP_IO_LEN_PROP, NULL);
> >  }
> >  if (lpc) {
> >  struct AcpiGenericAddress r = { .space_id = AML_AS_SYSTEM_IO,
> > @@ -214,6 +210,10 @@ static void acpi_get_pm_info(MachineState *machine, 
> > AcpiPmInfo *pm)
> >  pm->fadt.flags |= 1 << ACPI_FADT_F_RESET_REG_SUP;
> >  pm->cpu_hp_io_base = ICH9_CPU_HOTPLUG_IO_BASE;
> >  }
> > +pm->pcihp_io_base =
> > +object_property_get_uint(obj, ACPI_PCIHP_IO_BASE_PROP, NULL);
> > +pm->pcihp_io_len =
> > +object_property_get_uint(obj, ACPI_PCIHP_IO_LEN

Re: [RFC PATCH v2 3/4] hw/i386/acpi-build: Turn off support of PCIe native hot-plug and SHPC in _OSC

2020-09-16 Thread Julia Suvorova
On Wed, Sep 16, 2020 at 8:03 PM Julia Suvorova  wrote:
>
> On Fri, Aug 21, 2020 at 2:13 PM Igor Mammedov  wrote:
> >
> > On Tue, 18 Aug 2020 23:52:26 +0200
> > Julia Suvorova  wrote:
> >
> > > Other methods may be used if the system is capable of this and the _OSC 
> > > bit
> > > is set. Disable them explicitly to force ACPI PCI hot-plug use. The older
> > > versions will still use PCIe native.
> > >
> > > Signed-off-by: Julia Suvorova 
> > > ---
> > >  hw/i386/acpi-build.h | 11 +++
> > >  hw/i386/acpi-build.c | 21 +++--
> > >  2 files changed, 26 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h
> > > index 74df5fc612..6f94312c39 100644
> > > --- a/hw/i386/acpi-build.h
> > > +++ b/hw/i386/acpi-build.h
> > > @@ -5,6 +5,17 @@
> > >
> > >  extern const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio;
> > >
> > > +/* PCI Firmware Specification 3.2, Table 4-5 */
> > > +typedef enum {
> > > +ACPI_OSC_NATIVE_HP_EN = 0,
> > > +ACPI_OSC_SHPC_EN = 1,
> > > +ACPI_OSC_PME_EN = 2,
> > > +ACPI_OSC_AER_EN = 3,
> > > +ACPI_OSC_PCIE_CAP_EN = 4,
> > > +ACPI_OSC_LTR_EN = 5,
> > > +ACPI_OSC_ALLONES_INVALID = 6,
> > > +} AcpiOSCField;
> > > +
> > >  void acpi_setup(void);
> > >
> > >  #endif
> > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > index f3cd52bd06..c5f4802b8c 100644
> > > --- a/hw/i386/acpi-build.c
> > > +++ b/hw/i386/acpi-build.c
> > > @@ -1411,7 +1411,7 @@ static void build_i386_pci_hotplug(Aml *table, 
> > > uint64_t pcihp_addr)
> > >  aml_append(table, scope);
> > >  }
> > >
> > > -static Aml *build_q35_osc_method(void)
> > > +static Aml *build_q35_osc_method(AcpiPmInfo *pm)
> > >  {
> > >  Aml *if_ctx;
> > >  Aml *if_ctx2;
> > > @@ -1419,6 +1419,7 @@ static Aml *build_q35_osc_method(void)
> > >  Aml *method;
> > >  Aml *a_cwd1 = aml_name("CDW1");
> > >  Aml *a_ctrl = aml_local(0);
> > > +unsigned osc_ctrl;
> > >
> > >  method = aml_method("_OSC", 4, AML_NOTSERIALIZED);
> > >  aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), 
> > > "CDW1"));
> > > @@ -1430,11 +1431,19 @@ static Aml *build_q35_osc_method(void)
> > >
> > >  aml_append(if_ctx, aml_store(aml_name("CDW3"), a_ctrl));
> > >
> > > +/* Always allow native PME, AER (depend on PCIE Capability Control) 
> > > */
> > > +osc_ctrl = BIT(ACPI_OSC_PME_EN) | BIT(ACPI_OSC_AER_EN) |
> > > +   BIT(ACPI_OSC_PCIE_CAP_EN);
> > > +
> > >  /*
> > > - * Always allow native PME, AER (no dependencies)
> > > - * Allow SHPC (PCI bridges can have SHPC controller)
> > > + * Guests seem to generally prefer native hot-plug control.
> > > + * Enable it only when we do not use ACPI hot-plug.
> > >   */
> > > -aml_append(if_ctx, aml_and(a_ctrl, aml_int(0x1F), a_ctrl));
> > > +if (!pm->pcihp_bridge_en) {
> > > +osc_ctrl |= BIT(ACPI_OSC_NATIVE_HP_EN) | BIT(ACPI_OSC_SHPC_EN);
> > > +}
> >
> > ACPI hotplug works only for coldplugged bridges, and native one is used
> > on hotplugged ones.
> > Wouldn't that break SHPC/Native hotplug on hotplugged PCI/PCI-E bridge?

Wait, what configuration are you talking about exactly?

> > > +aml_append(if_ctx, aml_and(a_ctrl, aml_int(osc_ctrl), a_ctrl));
> > >
> > >  if_ctx2 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1;
> > >  /* Unknown revision */
> > > @@ -1514,7 +1523,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
> > >  aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
> > >  aml_append(dev, aml_name_decl("_ADR", aml_int(0)));
> > >  aml_append(dev, aml_name_decl("_UID", aml_int(1)));
> > > -aml_append(dev, build_q35_osc_method());
> > > +aml_append(dev, build_q35_osc_method(pm));
> > >  aml_append(sb_scope, dev);
> > >  aml_append(dsdt, sb_scope);
> > >
> > > @@ -1590,7 +1599,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
> > >  if (pci_bus_is_express(bus)) {
> > >  aml_append(dev, aml_name_decl("_HID", 
> > > aml_eisaid("PNP0A08")));
> > >  aml_append(dev, aml_name_decl("_CID", 
> > > aml_eisaid("PNP0A03")));
> > > -aml_append(dev, build_q35_osc_method());
> > > +aml_append(dev, build_q35_osc_method(pm));
> > >  } else {
> > >  aml_append(dev, aml_name_decl("_HID", 
> > > aml_eisaid("PNP0A03")));
> > >  }
> >




  1   2   3   >