]> git.hungrycats.org Git - linux/commitdiff
[ACPI] Check for overflow when parsing MADT entries
authorJes Sorensen <jes@wildopensource.com>
Tue, 27 Jan 2004 18:54:34 +0000 (13:54 -0500)
committerLen Brown <lenb@dhcppc3.>
Tue, 27 Jan 2004 18:54:34 +0000 (13:54 -0500)
from Jes Sorensen

arch/i386/kernel/acpi/boot.c
arch/ia64/kernel/acpi.c
arch/ia64/kernel/iosapic.c
arch/x86_64/kernel/acpi/boot.c
drivers/acpi/numa.c
drivers/acpi/tables.c
include/asm-ia64/iosapic.h
include/linux/acpi.h

index 8aac4a6b9606c959686532f07aff8e3f15c7bf7c..d14ddab92d8711dc0d37917bd7e501c498018134 100644 (file)
@@ -43,8 +43,8 @@
 int acpi_noirq __initdata = 0; /* skip ACPI IRQ initialization */
 int acpi_ht __initdata = 1;    /* enable HT */
 
-int acpi_lapic = 0;
-int acpi_ioapic = 0;
+int acpi_lapic;
+int acpi_ioapic;
 
 /* --------------------------------------------------------------------------
                               Boot-time Configuration
@@ -456,7 +456,7 @@ acpi_boot_init (void)
         * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
         */
 
-       result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr);
+       result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0);
        if (result < 0) {
                printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
                return result;
@@ -464,7 +464,8 @@ acpi_boot_init (void)
 
        mp_register_lapic_address(acpi_lapic_addr);
 
-       result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic);
+       result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic,
+                                      MAX_APICS);
        if (!result) { 
                printk(KERN_ERR PREFIX "No LAPIC entries present\n");
                /* TBD: Cleanup to allow fallback to MPS */
@@ -476,7 +477,7 @@ acpi_boot_init (void)
                return result;
        }
 
-       result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi);
+       result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0);
        if (result < 0) {
                printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
                /* TBD: Cleanup to allow fallback to MPS */
@@ -513,8 +514,8 @@ acpi_boot_init (void)
                return 1;
        }
 
-       result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic);
-       if (!result) { 
+       result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, MAX_IO_APICS);
+       if (!result) {
                printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
                return -ENODEV;
        }
@@ -526,14 +527,14 @@ acpi_boot_init (void)
        /* Build a default routing table for legacy (ISA) interrupts. */
        mp_config_acpi_legacy_irqs();
 
-       result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr);
+       result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS);
        if (result < 0) {
                printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
                /* TBD: Cleanup to allow fallback to MPS */
                return result;
        }
 
-       result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src);
+       result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, NR_IRQ_VECTORS);
        if (result < 0) {
                printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
                /* TBD: Cleanup to allow fallback to MPS */
index d757134a2175e2a100dbadf29fdbfeaf0b59e1aa..b3ceb1a018eb53ed5298cd3f0f4004666962504c 100644 (file)
@@ -189,8 +189,6 @@ acpi_parse_lsapic (acpi_table_entry_header *header)
 
        if (!lsapic->flags.enabled)
                printk(" disabled");
-       else if (available_cpus >= NR_CPUS)
-               printk(" ignored (increase NR_CPUS)");
        else {
                printk(" enabled");
 #ifdef CONFIG_SMP
@@ -393,12 +391,6 @@ acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma)
        size = ma->length_hi;
        size = (size << 32) | ma->length_lo;
 
-       if (num_memblks >= NR_MEMBLKS) {
-               printk(KERN_ERR "Too many mem chunks in SRAT. Ignoring %ld MBytes at %lx\n",
-                      size/(1024*1024), paddr);
-               return;
-       }
-
        /* Ignore disabled entries */
        if (!ma->flags.enabled)
                return;
@@ -550,29 +542,29 @@ acpi_boot_init (void)
 
        /* Local APIC */
 
-       if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr) < 0)
+       if (acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0) < 0)
                printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
 
-       if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic) < 1)
+       if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_parse_lsapic, NR_CPUS) < 1)
                printk(KERN_ERR PREFIX "Error parsing MADT - no LAPIC entries\n");
 
-       if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi) < 0)
+       if (acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0) < 0)
                printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
 
        /* I/O APIC */
 
-       if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC, acpi_parse_iosapic) < 1)
+       if (acpi_table_parse_madt(ACPI_MADT_IOSAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1)
                printk(KERN_ERR PREFIX "Error parsing MADT - no IOSAPIC entries\n");
 
        /* System-Level Interrupt Routing */
 
-       if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC, acpi_parse_plat_int_src) < 0)
+       if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC, acpi_parse_plat_int_src, ACPI_MAX_PLATFORM_INTERRUPTS) < 0)
                printk(KERN_ERR PREFIX "Error parsing platform interrupt source entry\n");
 
-       if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr) < 0)
+       if (acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, 0) < 0)
                printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
 
-       if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src) < 0)
+       if (acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src, 0) < 0)
                printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
   skip_madt:
 
index 9e30b08ba40e98ccde70415b5ac04c7480847fee..879f566dd1b15cd81b260257a690e72916e5169a 100644 (file)
@@ -114,7 +114,7 @@ static struct iosapic {
        char            *addr;          /* base address of IOSAPIC */
        unsigned int    gsi_base;       /* first GSI assigned to this IOSAPIC */
        unsigned short  num_rte;        /* number of RTE in this IOSAPIC */
-} iosapic_lists[256];
+} iosapic_lists[NR_IOSAPICS];
 
 static int num_iosapic;
 
index 33a40edea70b2d3343d04add402169c28625667a..d46c2d41b75924d41bfacafae48a72aa44a3ccb3 100644 (file)
@@ -51,8 +51,8 @@
 int acpi_noirq __initdata = 0; /* skip ACPI IRQ initialization */
 int acpi_ht __initdata = 1;    /* enable HT */
 
-int acpi_lapic = 0;
-int acpi_ioapic = 0;
+int acpi_lapic;
+int acpi_ioapic;
 
 /* --------------------------------------------------------------------------
                               Boot-time Configuration
@@ -439,7 +439,7 @@ acpi_boot_init (void)
         * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value).
         */
 
-       result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr);
+       result = acpi_table_parse_madt(ACPI_MADT_LAPIC_ADDR_OVR, acpi_parse_lapic_addr_ovr, 0);
        if (result < 0) {
                printk(KERN_ERR PREFIX "Error parsing LAPIC address override entry\n");
                return result;
@@ -447,7 +447,8 @@ acpi_boot_init (void)
 
        mp_register_lapic_address(acpi_lapic_addr);
 
-       result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic);
+       result = acpi_table_parse_madt(ACPI_MADT_LAPIC, acpi_parse_lapic,
+                                      MAX_APICS);
        if (!result) { 
                printk(KERN_ERR PREFIX "No LAPIC entries present\n");
                /* TBD: Cleanup to allow fallback to MPS */
@@ -459,7 +460,7 @@ acpi_boot_init (void)
                return result;
        }
 
-       result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi);
+       result = acpi_table_parse_madt(ACPI_MADT_LAPIC_NMI, acpi_parse_lapic_nmi, 0);
        if (result < 0) {
                printk(KERN_ERR PREFIX "Error parsing LAPIC NMI entry\n");
                /* TBD: Cleanup to allow fallback to MPS */
@@ -496,8 +497,8 @@ acpi_boot_init (void)
                return 1;
        }
 
-       result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic);
-       if (!result) { 
+       result = acpi_table_parse_madt(ACPI_MADT_IOAPIC, acpi_parse_ioapic, MAX_IO_APICS);
+       if (!result) {
                printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
                return -ENODEV;
        }
@@ -509,14 +510,15 @@ acpi_boot_init (void)
        /* Build a default routing table for legacy (ISA) interrupts. */
        mp_config_acpi_legacy_irqs();
 
-       result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr);
+       result = acpi_table_parse_madt(ACPI_MADT_INT_SRC_OVR, acpi_parse_int_src_ovr, NR_IRQ_VECTORS);
        if (result < 0) {
                printk(KERN_ERR PREFIX "Error parsing interrupt source overrides entry\n");
                /* TBD: Cleanup to allow fallback to MPS */
                return result;
        }
 
-       result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src);
+       result = acpi_table_parse_madt(ACPI_MADT_NMI_SRC, acpi_parse_nmi_src,
+                                      NR_IRQ_VECTORS);
        if (result < 0) {
                printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
                /* TBD: Cleanup to allow fallback to MPS */
index 62a484e4f6f81e2519b123bf7c46b36d40df4f46..ad63798aa6252b053074363da98e61f38f523d89 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/acpi.h>
 #include <acpi/acpi_bus.h>
 
-extern int __init acpi_table_parse_madt_family (enum acpi_table_id id, unsigned long madt_size, int entry_id, acpi_madt_entry_handler handler);
+extern int __init acpi_table_parse_madt_family (enum acpi_table_id id, unsigned long madt_size, int entry_id, acpi_madt_entry_handler handler, unsigned int max_entries);
 
 void __init
 acpi_table_print_srat_entry (
@@ -149,10 +149,11 @@ acpi_parse_srat (unsigned long phys_addr, unsigned long size)
 int __init
 acpi_table_parse_srat (
        enum acpi_srat_entry_id id,
-       acpi_madt_entry_handler handler)
+       acpi_madt_entry_handler handler,
+       unsigned int max_entries)
 {
        return acpi_table_parse_madt_family(ACPI_SRAT, sizeof(struct acpi_table_srat),
-                                           id, handler);
+                                           id, handler, max_entries);
 }
 
 
@@ -166,9 +167,11 @@ acpi_numa_init()
 
        if (result > 0) {
                result = acpi_table_parse_srat(ACPI_SRAT_PROCESSOR_AFFINITY,
-                                              acpi_parse_processor_affinity);
+                                              acpi_parse_processor_affinity,
+                                              NR_CPUS);
                result = acpi_table_parse_srat(ACPI_SRAT_MEMORY_AFFINITY,
-                                              acpi_parse_memory_affinity);
+                                              acpi_parse_memory_affinity,
+                                              NR_MEMBLKS);
        } else {
                /* FIXME */
                printk("Warning: acpi_table_parse(ACPI_SRAT) returned %d!\n",result);
index e997203d754b3a7ca4041064c85ab611c259e759..2583a0fcf2cef6b8bab928f22cadb0e8a1359618 100644 (file)
@@ -302,13 +302,14 @@ acpi_table_parse_madt_family (
        enum acpi_table_id      id,
        unsigned long           madt_size,
        int                     entry_id,
-       acpi_madt_entry_handler handler)
+       acpi_madt_entry_handler handler,
+       unsigned int            max_entries)
 {
        void                    *madt = NULL;
-       acpi_table_entry_header *entry = NULL;
-       unsigned long           count = 0;
-       unsigned long           madt_end = 0;
-       unsigned int                    i = 0;
+       acpi_table_entry_header *entry;
+       unsigned int            count = 0;
+       unsigned long           madt_end;
+       unsigned int            i;
 
        if (!handler)
                return -EINVAL;
@@ -342,13 +343,18 @@ acpi_table_parse_madt_family (
                ((unsigned long) madt + madt_size);
 
        while (((unsigned long) entry) < madt_end) {
-               if (entry->type == entry_id) {
-                       count++;
+               if (entry->type == entry_id &&
+                   (!max_entries || count++ < max_entries))
                        handler(entry);
-               }
+
                entry = (acpi_table_entry_header *)
                        ((unsigned long) entry + entry->length);
        }
+       if (max_entries && count > max_entries) {
+               printk(KERN_WARNING PREFIX "[%s:0x%02x] ignored %i entries of "
+                      "%i found\n", acpi_table_signatures[id], entry_id,
+                      count - max_entries, count);
+       }
 
        return count;
 }
@@ -357,10 +363,11 @@ acpi_table_parse_madt_family (
 int __init
 acpi_table_parse_madt (
        enum acpi_madt_entry_id id,
-       acpi_madt_entry_handler handler)
+       acpi_madt_entry_handler handler,
+       unsigned int max_entries)
 {
        return acpi_table_parse_madt_family(ACPI_APIC, sizeof(struct acpi_table_madt),
-                                           id, handler);
+                                           id, handler, max_entries);
 }
 
 
@@ -585,4 +592,3 @@ acpi_table_init (void)
 
        return 0;
 }
-
index 68fa169e7a5b52f26443a442a4230becbca22e03..ba8a35f418a285bd9cbb97dcfff3c3358356f35d 100644 (file)
@@ -52,6 +52,9 @@
 #ifndef __ASSEMBLY__
 
 #ifdef CONFIG_IOSAPIC
+
+#define NR_IOSAPICS                    256
+
 extern void __init iosapic_system_init (int pcat_compat);
 extern void __init iosapic_init (unsigned long address,
                                    unsigned int gsi_base);
index 8e4eba21e7ea7205f5b06beb92a819897fc5e202..f851b34903e34d8125441ebf630dd6e97bbbba60 100644 (file)
@@ -355,8 +355,8 @@ int acpi_numa_init (void);
 int acpi_table_init (void);
 int acpi_table_parse (enum acpi_table_id id, acpi_table_handler handler);
 int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header);
-int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler);
-int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler);
+int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries);
+int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries);
 void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr);
 void acpi_table_print_madt_entry (acpi_table_entry_header *madt);
 void acpi_table_print_srat_entry (acpi_table_entry_header *srat);