From: Salil Mehta <salil.me...@huawei.com>

This change emits AML in DSDT to support vCPU deferred online-capability on
arm/virt. It wires the CPU OSPM coordination paths so that CPUs which are
administratively disabled at boot can be brought online later under policy,
providing hotplug-like functionality without claiming full hotplug support.

The AML connects the CPUS scan method to a GED handler so QEMU and the
guest OSPM can coordinate CPU add/remove while the VM is running (e.g.
device-check, eject-request, _EJ0, CPU scan, _OST status reporting).

It also fixes an ACPI namespace load error:
  AE_NOT_FOUND resolving \_SB.GED.PSCN
Error excerpt:
[    0.070518] ACPI BIOS Error (bug): Object does not exist: GED_
[    0.071457] ACPI BIOS Error (bug): Could not resolve symbol [\_SB.GED.PSCN],
[    0.073084] ACPI Error: AE_NOT_FOUND, During name lookup/catalog

Root cause was build order and naming: the PSCN handler must be created
under \_SB.GED using a short ACPI 'NameSeg', and referenced elsewhere by its
fully qualified path. The GED device (and PSCN) are now defined before the CPUS
AML, preventing the early lookup failure.

Notes:
  * CPU enumeration remains from MADT (GICC). CPU0 is Enabled; other CPUs
    may be Disabled but Online-Capable.
  * Policy (which CPUs start disabled, later enabled) is administrative
    and not decided by OSPM.

Tested: boot with EDK2/ACPI; no AE_NOT_FOUND for \_SB.GED.PSCN; generic CPU
devices register; sysfs topology group warnings do not occur.

           DSDT.dsl (Not Working)                                               
     DSDT.dsl (Working)
           ---------------------                                                
     ------------------

DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPC    ", 0x00000001)        
DefinitionBlock ("", "DSDT", 2, "BOCHS ", "BXPC    ", 0x00000001)
{                                                                        {
    Scope (\_SB)                                                             
Scope (\_SB)
    {                                                                        {
        Scope (_SB)                                                             
 Device (\_SB.GED)
        {                                                                       
 {
            Device (\_SB.CPUR)                                                  
     Name (_HID, "ACPI0013"
            {                                                                   
     Name (_UID, "GED")
            [...]                                                               
     Name (_CRS, ResourceTemplate ()
            Device (\_SB.CPUS)                                                  
     [...]
            {                                                                   
     Method (_EVT, 1, Serialized)
                Name (_HID, "ACPI0010")                                         
     {
                Name (_CID, EisaId ("PNP0A05"))                                 
         Local0 = ESEL /* \_SB_.GED_.ESEL */
                Method (CTFY, 2, NotSerialized)                                 
         If (((Local0 & 0x02) == 0x02))
                {                                                               
         {
            [...]                                                               
              Notify (PWRB, 0x80)
                Method (CSTA, 1, Serialized)                                    
         }
                {
            [...]                                                               
         If (((Local0 & 0x08) == 0x08))
                Method (CEJ0, 1, Serialized)                                    
         {
                {                                                               
             \_SB.GED.PSCN ()
            [...]                                                               
         }
                Method (CSCN, 0, Serialized)                                    
     }
                {                                                               
 }
            [...]
                Method (COST, 4, Serialized)                                    
 Scope (_SB)
                {                                                               
 {
            [...]                                                               
     Device (\_SB.CPUR)
                Device (C000)                                                   
     {
                {                                                               
          [...]
            [...]                                                               
     Device (\_SB.CPUS)
                Device (C001)                                                   
     {
                {                                                               
          Name (_HID, "ACPI0010")
            [...]                                                               
          Name (_CID, EisaId ("PNP0A05"))
                Device (C002)                                                   
          Method (CTFY, 2, NotSerialized)
                {                                                               
          {
            [...]                                                               
     [...]
                Device (C003)                                                   
          Method (CSTA, 1, Serialized)
                {                                                               
          {
            [...]                                                               
     [...]
                Device (C004)                                                   
          Method (CEJ0, 1, Serialized)
                {                                                               
          {
            [...]                                                               
     [...]
                Device (C005)                                                   
          Method (CSCN, 0, Serialized)
                {                                                               
          {
            }                                                                   
     [...]
        }                                                                       
          Method (COST, 4, Serialized)
                                                                                
          {
        Method (\_SB.GED.PSCN, 0, NotSerialized)                                
     [...]
        {                                                                       
          Device (C000)
            \_SB.CPUS.CSCN ()                                                   
          {
        }                                                                       
     [...]
                                                                                
          Device (C001)
        Device (COM0)                                                           
          {
        {                                                                       
     [...]
            [...]                                                               
          Device (C002)
                                                                                
          {
        Device (\_SB.GED)                                                       
     [...]
        {                                                                       
          Device (C003)
            Name (_HID, "ACPI0013")                                             
          {
            Name (_UID, "GED")                                                  
     [...]
            Name (_CRS, ResourceTemplate ()                                     
          Device (C004)
            {                                                                   
          {
            [...]                                                               
     [...]
            OperationRegion (EREG, SystemMemory, 0x09080000, 0x04)              
          Device (C005)
            Field (EREG, DWordAcc, NoLock, WriteAsZeros)                        
          {
            {                                                                   
      }
            [...]                                                               
  }

            Method (_EVT, 1, Serialized)                                        
  Method (\_SB.GED.PSCN, 0, NotSerialized)
            {                                                                   
  {
                Local0 = ESEL                                                   
      \_SB.CPUS.CSCN ()
                If (((Local0 & 0x02) == 0x02))                                  
  }
                {
                    Notify (PWRB, 0x80)                                         
  Device (COM0)
                }                                                               
  {
                                                                                
      [...]
                If (((Local0 & 0x08) == 0x08))                               }
                {                                                        }
                    \_SB.GED.PSCN ()
                }
            }
        }

        Device (PWRB)
        {
            [...]
    }
}

Signed-off-by: Salil Mehta <salil.me...@huawei.com>
---
 hw/arm/virt-acpi-build.c | 35 +++++++++++++++++++++++++----------
 1 file changed, 25 insertions(+), 10 deletions(-)

diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 7c24dd6369..5e5acb3026 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -931,6 +931,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
     VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
     Aml *scope, *dsdt;
     MachineState *ms = MACHINE(vms);
+    MachineClass *mc = MACHINE_GET_CLASS(ms);
     const MemMapEntry *memmap = vms->memmap;
     const int *irqmap = vms->irqmap;
     AcpiTable table = { .sig = "DSDT", .rev = 2, .oem_id = vms->oem_id,
@@ -946,7 +947,30 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
      * the RTC ACPI device at all when using UEFI.
      */
     scope = aml_scope("\\_SB");
-    acpi_dsdt_add_cpus(scope, vms);
+    if (vms->acpi_dev) {
+        build_ged_aml(scope, "\\_SB."GED_DEVICE,
+                      HOTPLUG_HANDLER(vms->acpi_dev),
+                      irqmap[VIRT_ACPI_GED] + ARM_SPI_BASE, AML_SYSTEM_MEMORY,
+                      memmap[VIRT_ACPI_GED].base);
+    } else {
+        acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
+                           (irqmap[VIRT_GPIO] + ARM_SPI_BASE));
+    }
+
+    /*
+     * If the machine supports bringing administratively disabled vCPUs
+     * deferred-online under policy, build AML to coordinate the addition and
+     * removal of CPUs gracefully with the OSPM while the VM is running. This
+     * includes events such as device-check, eject-request, ejection (_EJ0),
+     * CPU scan, _OST status reporting, etc.
+     */
+    if (vms->acpi_dev && mc->has_online_capable_cpus) {
+        acpi_build_cpus_aml(scope, memmap[VIRT_ACPI_CPUPS].base, "\\_SB",
+                            AML_GED_EVT_CPUPS_SCAN_METHOD);
+    } else {
+        acpi_dsdt_add_cpus(scope, vms);
+    }
+
     acpi_dsdt_add_uart(scope, &memmap[VIRT_UART0],
                        (irqmap[VIRT_UART0] + ARM_SPI_BASE), 0);
     if (vms->second_ns_uart_present) {
@@ -961,15 +985,6 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 
VirtMachineState *vms)
                          (irqmap[VIRT_MMIO] + ARM_SPI_BASE),
                          0, NUM_VIRTIO_TRANSPORTS);
     acpi_dsdt_add_pci(scope, memmap, irqmap[VIRT_PCIE] + ARM_SPI_BASE, vms);
-    if (vms->acpi_dev) {
-        build_ged_aml(scope, "\\_SB."GED_DEVICE,
-                      HOTPLUG_HANDLER(vms->acpi_dev),
-                      irqmap[VIRT_ACPI_GED] + ARM_SPI_BASE, AML_SYSTEM_MEMORY,
-                      memmap[VIRT_ACPI_GED].base);
-    } else {
-        acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
-                           (irqmap[VIRT_GPIO] + ARM_SPI_BASE));
-    }
 
     if (vms->acpi_dev) {
         uint32_t event = object_property_get_uint(OBJECT(vms->acpi_dev),
-- 
2.34.1


Reply via email to