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

[Xen-changelog] [xen master] hvmloader: limit CPUs exposed to guests



commit 08754333892407f415045c05659783baeb8fc5d4
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Fri Jun 17 16:51:22 2016 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Fri Jun 17 16:51:22 2016 +0200

    hvmloader: limit CPUs exposed to guests
    
    Various Linux versions allocate (partial) per-CPU data for all of them,
    as there is no indication in MADT whether they're hotpluggable. That's
    a little wasteful in terms of resource consumption especially for
    - guests with not overly much memory assigned,
    - 32-bit guests not having overly much address space available.
    Therefore limit what we put into MADT to the "maxvcpus" value, and make
    sure AML doesn't touch memory addresses corresponding to CPUs beyond
    that value (we can't reasonably make the respective processor objects
    disappear).
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>
    Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 tools/firmware/hvmloader/acpi/build.c   | 14 +++++---------
 tools/firmware/hvmloader/acpi/dsdt.asl  |  3 ++-
 tools/firmware/hvmloader/acpi/mk_dsdt.c | 19 ++++++++++++++++---
 3 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/tools/firmware/hvmloader/acpi/build.c 
b/tools/firmware/hvmloader/acpi/build.c
index 503648c..1f7103e 100644
--- a/tools/firmware/hvmloader/acpi/build.c
+++ b/tools/firmware/hvmloader/acpi/build.c
@@ -48,6 +48,7 @@ struct acpi_info {
     uint8_t  com2_present:1;    /* 0[1] - System has COM2? */
     uint8_t  lpt1_present:1;    /* 0[2] - System has LPT1? */
     uint8_t  hpet_present:1;    /* 0[3] - System has HPET? */
+    uint16_t nr_cpus;           /* 2    - Number of CPUs */
     uint32_t pci_min, pci_len;  /* 4, 8 - PCI I/O hole boundaries */
     uint32_t madt_csum_addr;    /* 12   - Address of MADT checksum */
     uint32_t madt_lapic0_addr;  /* 16   - Address of first MADT LAPIC struct */
@@ -55,9 +56,6 @@ struct acpi_info {
     uint64_t pci_hi_min, pci_hi_len; /* 24, 32 - PCI I/O hole boundaries */
 };
 
-/* Number of processor objects in the chosen DSDT. */
-static unsigned int nr_processor_objects;
-
 static void set_checksum(
     void *table, uint32_t checksum_offset, uint32_t length)
 {
@@ -89,7 +87,7 @@ static struct acpi_20_madt *construct_madt(struct acpi_info 
*info)
     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) * nr_processor_objects;
+    sz += sizeof(struct acpi_20_madt_lapic) * hvm_info->nr_vcpus;
 
     madt = mem_alloc(sz, 16);
     if (!madt) return NULL;
@@ -142,8 +140,9 @@ static struct acpi_20_madt *construct_madt(struct acpi_info 
*info)
     io_apic->ioapic_addr = IOAPIC_BASE_ADDRESS;
 
     lapic = (struct acpi_20_madt_lapic *)(io_apic + 1);
+    info->nr_cpus = hvm_info->nr_vcpus;
     info->madt_lapic0_addr = (uint32_t)lapic;
-    for ( i = 0; i < nr_processor_objects; i++ )
+    for ( i = 0; i < hvm_info->nr_vcpus; i++ )
     {
         memset(lapic, 0, sizeof(*lapic));
         lapic->type    = ACPI_PROCESSOR_LOCAL_APIC;
@@ -151,8 +150,7 @@ static struct acpi_20_madt *construct_madt(struct acpi_info 
*info)
         /* Processor ID must match processor-object IDs in the DSDT. */
         lapic->acpi_processor_id = i;
         lapic->apic_id = LAPIC_ID(i);
-        lapic->flags = ((i < hvm_info->nr_vcpus) &&
-                        test_bit(i, hvm_info->vcpu_online)
+        lapic->flags = (test_bit(i, hvm_info->vcpu_online)
                         ? ACPI_LOCAL_APIC_ENABLED : 0);
         lapic++;
     }
@@ -534,14 +532,12 @@ void acpi_build_tables(struct acpi_config *config, 
unsigned int physical)
         dsdt = mem_alloc(config->dsdt_15cpu_len, 16);
         if (!dsdt) goto oom;
         memcpy(dsdt, config->dsdt_15cpu, config->dsdt_15cpu_len);
-        nr_processor_objects = 15;
     }
     else
     {
         dsdt = mem_alloc(config->dsdt_anycpu_len, 16);
         if (!dsdt) goto oom;
         memcpy(dsdt, config->dsdt_anycpu, config->dsdt_anycpu_len);
-        nr_processor_objects = HVM_MAX_VCPUS;
     }
 
     /*
diff --git a/tools/firmware/hvmloader/acpi/dsdt.asl 
b/tools/firmware/hvmloader/acpi/dsdt.asl
index e266dc2..bd65823 100644
--- a/tools/firmware/hvmloader/acpi/dsdt.asl
+++ b/tools/firmware/hvmloader/acpi/dsdt.asl
@@ -50,7 +50,8 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, "Xen", "HVM", 0)
            UAR2, 1,
            LTP1, 1,
            HPET, 1,
-           Offset(4),
+           Offset(2),
+           NCPU, 16,
            PMIN, 32,
            PLEN, 32,
            MSUA, 32, /* MADT checksum address */
diff --git a/tools/firmware/hvmloader/acpi/mk_dsdt.c 
b/tools/firmware/hvmloader/acpi/mk_dsdt.c
index b567b38..b2ade89 100644
--- a/tools/firmware/hvmloader/acpi/mk_dsdt.c
+++ b/tools/firmware/hvmloader/acpi/mk_dsdt.c
@@ -150,6 +150,14 @@ int main(int argc, char **argv)
     indent(); printf("MSU, 8\n");
     pop_block();
 
+    /* Processor object helpers. */
+    push_block("Method", "PMAT, 2");
+    push_block("If", "LLess(Arg0, NCPU)");
+    stmt("Return", "ToBuffer(Arg1)");
+    pop_block();
+    stmt("Return", "Buffer() {0, 8, 0xff, 0xff, 0, 0, 0, 0}");
+    pop_block();
+
     /* Define processor objects and control methods. */
     for ( cpu = 0; cpu < max_cpus; cpu++)
     {
@@ -171,17 +179,22 @@ int main(int argc, char **argv)
         pop_block();
 
         push_block("Method", "_MAT, 0");
-        stmt("Return", "ToBuffer(MAT)");
+        if ( cpu )
+            stmt("Return", "PMAT (%d, MAT)", cpu);
+        else
+            stmt("Return", "ToBuffer(MAT)");
         pop_block();
 
         push_block("Method", "_STA");
+        if ( cpu )
+            push_block("If", "LLess(%d, \\_SB.NCPU)", cpu);
         push_block("If", "FLG");
         stmt("Return", "0xF");
         pop_block();
-        push_block("Else", NULL);
+        if ( cpu )
+            pop_block();
         stmt("Return", "0x0");
         pop_block();
-        pop_block();
 
         push_block("Method", "_EJ0, 1, NotSerialized");
         stmt("Sleep", "0xC8");
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

 


Rackspace

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