[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [RFC Patch v4 6/8] hvmload: Add x2apic entry support in the MADT and SRAT build



From: Lan Tianyu <tianyu.lan@xxxxxxxxx>

This patch contains the following changes:
1. add x2apic entry support for ACPI MADT table according to
 ACPI spec 5.2.12.12 Processor Local x2APIC Structure.
2. add x2apic entry support for ACPI SRAT table according to
 ACPI spec 5.2.16.3 Processor Local x2APIC Affinity Structure.

Signed-off-by: Lan Tianyu <tianyu.lan@xxxxxxxxx>
Signed-off-by: Chao Gao <chao.gao@xxxxxxxxx>
---
v4:
 - also add x2apic entry in SRAT
---
 tools/libacpi/acpi2_0.h | 25 ++++++++++++++++++++--
 tools/libacpi/build.c   | 57 +++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 69 insertions(+), 13 deletions(-)

diff --git a/tools/libacpi/acpi2_0.h b/tools/libacpi/acpi2_0.h
index 6081417..7eb983d 100644
--- a/tools/libacpi/acpi2_0.h
+++ b/tools/libacpi/acpi2_0.h
@@ -322,6 +322,7 @@ struct acpi_20_waet {
 #define ACPI_IO_SAPIC                       0x06
 #define ACPI_PROCESSOR_LOCAL_SAPIC          0x07
 #define ACPI_PLATFORM_INTERRUPT_SOURCES     0x08
+#define ACPI_PROCESSOR_LOCAL_X2APIC         0x09
 
 /*
  * APIC Structure Definitions.
@@ -338,6 +339,15 @@ struct acpi_20_madt_lapic {
     uint32_t flags;
 };
 
+struct acpi_20_madt_x2apic {
+    uint8_t  type;
+    uint8_t  length;
+    uint16_t reserved;
+    uint32_t x2apic_id;
+    uint32_t flags;
+    uint32_t acpi_processor_uid;
+};
+
 /*
  * Local APIC Flags.  All other bits are reserved and must be 0.
  */
@@ -378,8 +388,9 @@ struct acpi_20_srat {
 /*
  * System Resource Affinity Table structure types.
  */
-#define ACPI_PROCESSOR_AFFINITY 0x0
-#define ACPI_MEMORY_AFFINITY    0x1
+#define ACPI_PROCESSOR_AFFINITY         0x0
+#define ACPI_MEMORY_AFFINITY            0x1
+#define ACPI_PROCESSOR_X2APIC_AFFINITY  0x2
 struct acpi_20_srat_processor {
     uint8_t type;
     uint8_t length;
@@ -391,6 +402,16 @@ struct acpi_20_srat_processor {
     uint32_t reserved;
 };
 
+struct acpi_20_srat_processor_x2apic {
+    uint8_t type;
+    uint8_t length;
+    uint16_t reserved;
+    uint32_t domain;
+    uint32_t x2apic_id;
+    uint32_t flags;
+    uint32_t reserved2[2];
+};
+
 /*
  * Local APIC Affinity Flags.  All other bits are reserved and must be 0.
  */
diff --git a/tools/libacpi/build.c b/tools/libacpi/build.c
index df0a67c..5cbf6a9 100644
--- a/tools/libacpi/build.c
+++ b/tools/libacpi/build.c
@@ -30,6 +30,11 @@
 
 #define align16(sz)        (((sz) + 15) & ~15)
 #define fixed_strcpy(d, s) strncpy((d), (s), sizeof(d))
+#define min(X, Y) ({                             \
+            const typeof (X) _x = (X);           \
+            const typeof (Y) _y = (Y);           \
+            (void) (&_x == &_y);                 \
+            (_x < _y) ? _x : _y; })
 
 extern struct acpi_20_rsdp Rsdp;
 extern struct acpi_20_rsdt Rsdt;
@@ -79,16 +84,19 @@ static struct acpi_20_madt *construct_madt(struct acpi_ctxt 
*ctxt,
     struct acpi_20_madt_intsrcovr *intsrcovr;
     struct acpi_20_madt_ioapic    *io_apic;
     struct acpi_20_madt_lapic     *lapic;
+    struct acpi_20_madt_x2apic    *x2apic;
     const struct hvm_info_table   *hvminfo = config->hvminfo;
-    int i, sz;
+    int i, sz, nr_apic;
 
     if ( config->lapic_id == NULL )
         return NULL;
 
+    nr_apic = min(hvminfo->nr_vcpus, MADT_MAX_LOCAL_APIC);
     sz  = sizeof(struct acpi_20_madt);
     sz += sizeof(struct acpi_20_madt_intsrcovr) * 16;
     sz += sizeof(struct acpi_20_madt_ioapic);
-    sz += sizeof(struct acpi_20_madt_lapic) * hvminfo->nr_vcpus;
+    sz += sizeof(struct acpi_20_madt_lapic) * nr_apic;
+    sz += sizeof(struct acpi_20_madt_x2apic) * (hvminfo->nr_vcpus - nr_apic);
 
     madt = ctxt->mem_ops.alloc(ctxt, sz, 16);
     if (!madt) return NULL;
@@ -149,7 +157,7 @@ static struct acpi_20_madt *construct_madt(struct acpi_ctxt 
*ctxt,
 
     info->nr_cpus = hvminfo->nr_vcpus;
     info->madt_lapic0_addr = ctxt->mem_ops.v2p(ctxt, lapic);
-    for ( i = 0; i < hvminfo->nr_vcpus; i++ )
+    for ( i = 0; i < nr_apic; i++ )
     {
         memset(lapic, 0, sizeof(*lapic));
         lapic->type    = ACPI_PROCESSOR_LOCAL_APIC;
@@ -157,12 +165,26 @@ static struct acpi_20_madt *construct_madt(struct 
acpi_ctxt *ctxt,
         /* Processor ID must match processor-object IDs in the DSDT. */
         lapic->acpi_processor_id = i;
         lapic->apic_id = config->lapic_id(i);
-        lapic->flags = (test_bit(i, hvminfo->vcpu_online)
-                        ? ACPI_LOCAL_APIC_ENABLED : 0);
+        lapic->flags = test_bit(i, hvminfo->vcpu_online)
+                           ? ACPI_LOCAL_APIC_ENABLED : 0;
         lapic++;
     }
 
-    madt->header.length = (unsigned char *)lapic - (unsigned char *)madt;
+    x2apic = (void *)lapic;
+    for ( ; i < hvminfo->nr_vcpus; i++ )
+    {
+        memset(x2apic, 0, sizeof(*x2apic));
+        x2apic->type    = ACPI_PROCESSOR_LOCAL_X2APIC;
+        x2apic->length  = sizeof(*x2apic);
+        /* Processor UID must match processor-object UIDs in the DSDT. */
+        x2apic->acpi_processor_uid = i;
+        x2apic->x2apic_id = config->lapic_id(i);
+        x2apic->flags =  test_bit(i, hvminfo->vcpu_online)
+                             ? ACPI_LOCAL_APIC_ENABLED : 0;
+        x2apic++;
+    }
+
+    madt->header.length = (unsigned char *)x2apic - (unsigned char *)madt;
     set_checksum(madt, offsetof(struct acpi_header, checksum),
                  madt->header.length);
     info->madt_csum_addr =
@@ -216,12 +238,14 @@ static struct acpi_20_srat *construct_srat(struct 
acpi_ctxt *ctxt,
 {
     struct acpi_20_srat *srat;
     struct acpi_20_srat_processor *processor;
+    struct acpi_20_srat_processor_x2apic *x2apic;
     struct acpi_20_srat_memory *memory;
-    unsigned int size;
+    unsigned int size, i, nr_apic;
     void *p;
-    unsigned int i;
 
-    size = sizeof(*srat) + sizeof(*processor) * config->hvminfo->nr_vcpus +
+    nr_apic = min(MADT_MAX_LOCAL_APIC, config->hvminfo->nr_vcpus);
+    size = sizeof(*srat) + sizeof(*processor) * nr_apic +
+           sizeof(*x2apic) * (config->hvminfo->nr_vcpus - nr_apic) +
            sizeof(*memory) * config->numa.nr_vmemranges;
 
     p = ctxt->mem_ops.alloc(ctxt, size, 16);
@@ -239,7 +263,7 @@ static struct acpi_20_srat *construct_srat(struct acpi_ctxt 
*ctxt,
     srat->table_revision      = ACPI_SRAT_TABLE_REVISION;
 
     processor = (struct acpi_20_srat_processor *)(srat + 1);
-    for ( i = 0; i < config->hvminfo->nr_vcpus; i++ )
+    for ( i = 0; i < nr_apic; i++ )
     {
         processor->type     = ACPI_PROCESSOR_AFFINITY;
         processor->length   = sizeof(*processor);
@@ -249,7 +273,18 @@ static struct acpi_20_srat *construct_srat(struct 
acpi_ctxt *ctxt,
         processor++;
     }
 
-    memory = (struct acpi_20_srat_memory *)processor;
+    x2apic = (struct acpi_20_srat_processor_x2apic *)processor;
+    for ( ; i < config->hvminfo->nr_vcpus; i++ )
+    {
+        x2apic->type       = ACPI_PROCESSOR_X2APIC_AFFINITY;
+        x2apic->length     = sizeof(*x2apic);
+        x2apic->domain     = config->numa.vcpu_to_vnode[i];
+        x2apic->x2apic_id  = config->lapic_id(i);
+        x2apic->flags      = ACPI_LOCAL_APIC_AFFIN_ENABLED;
+        x2apic++;
+    }
+
+    memory = (struct acpi_20_srat_memory *)x2apic;
     for ( i = 0; i < config->numa.nr_vmemranges; i++ )
     {
         memory->type          = ACPI_MEMORY_AFFINITY;
-- 
1.8.3.1


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.