diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index a0af3e9d73..fe07817013 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1902,6 +1902,17 @@ void build_socket_hierarchy(GArray *tbl, uint32_t parent, uint32_t id)
     build_append_int_noprefix(tbl, 0, 4);  /* Number of private resources */
 }
 
+void build_cluster_hierarchy(GArray *tbl, uint32_t parent, uint32_t id)
+{
+    build_append_byte(tbl, ACPI_PPTT_TYPE_PROCESSOR); /* Type 0 - processor */
+    build_append_byte(tbl, 20);           /* Length, no private resources */
+    build_append_int_noprefix(tbl, 0, 2);      /* Reserved */
+    build_append_int_noprefix(tbl, 0, 4);      /* Flags */
+    build_append_int_noprefix(tbl, parent, 4); /* Parent */
+    build_append_int_noprefix(tbl, id, 4);     /* ACPI processor ID */
+    build_append_int_noprefix(tbl, 0, 4); /* Number of private resources */
+}
+
 void build_processor_hierarchy(GArray *tbl, uint32_t flags,
                                uint32_t parent, uint32_t id)
 {
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 38d50ce66c..3b80518a90 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -442,6 +442,7 @@ build_pptt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
     int pptt_start = table_data->len;
     int uid = 0, cpus = 0, socket = 0;
     MachineState *ms = MACHINE(vms);
+    unsigned int smp_clusters = ms->smp.clusters;
     unsigned int smp_cores = ms->smp.cores;
     unsigned int smp_threads = ms->smp.threads;
 
@@ -449,29 +450,35 @@ build_pptt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
 
     for (socket = 0; cpus < ms->possible_cpus->len; socket++) {
         uint32_t socket_offset = table_data->len - pptt_start;
-        int core;
+        int cluster;
 
         build_socket_hierarchy(table_data, 0, socket);
 
-        for (core = 0; core < smp_cores; core++) {
-            uint32_t core_offset = table_data->len - pptt_start;
-            int thread;
-
-            if (smp_threads <= 1) {
-                build_processor_hierarchy(table_data,
-                                          ACPI_PPTT_ACPI_PROCESSOR_ID_VALID |
-                                          ACPI_PPTT_ACPI_LEAF_NODE,
-                                          socket_offset, uid++);
-             } else {
-                build_processor_hierarchy(table_data,
-                                          ACPI_PPTT_ACPI_PROCESSOR_ID_VALID,
-                                          socket_offset, core);
-                for (thread = 0; thread < smp_threads; thread++) {
-                    build_thread_hierarchy(table_data, core_offset, uid++);
+        for (cluster = 0; cluster < smp_clusters; cluster++) {
+            uint32_t cluster_offset = table_data->len - pptt_start;
+            int core;
+
+            build_cluster_hierarchy(table_data, socket_offset, cluster);
+
+            for (core = 0; core < smp_cores; core++) {
+                uint32_t core_offset = table_data->len - pptt_start;
+                int thread;
+
+                if (smp_threads <= 1) {
+                    build_processor_hierarchy(table_data,
+                                              ACPI_PPTT_ACPI_PROCESSOR_ID_VALID |
+                                              ACPI_PPTT_ACPI_LEAF_NODE,
+                                              cluster_offset, uid++);
+                } else {
+                    build_processor_hierarchy(table_data, 0, cluster_offset, core);
+
+                    for (thread = 0; thread < smp_threads; thread++) {
+                        build_thread_hierarchy(table_data, core_offset, uid++);
+                    }
                 }
-             }
+            }
         }
-        cpus += smp_cores * smp_threads;
+        cpus += smp_clusters * smp_cores * smp_threads;
     }
 
     build_header(linker, table_data,
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 7f0ca1a198..cb68535cf1 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -464,6 +464,8 @@ void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms,
 
 void build_socket_hierarchy(GArray *tbl, uint32_t parent, uint32_t id);
 
+void build_cluster_hierarchy(GArray *tbl, uint32_t parent, uint32_t id);
+
 void build_processor_hierarchy(GArray *tbl, uint32_t flags,
                                uint32_t parent, uint32_t id);
 
