]> xenbits.xensource.com Git - people/julieng/linux-arm.git/commitdiff
irqchip, gicv3-its: Add range check for number of allocated pages
authorRobert Richter <rrichter@cavium.com>
Mon, 27 Apr 2015 15:27:50 +0000 (17:27 +0200)
committerJulien Grall <julien.grall@citrix.com>
Mon, 28 Sep 2015 11:05:06 +0000 (12:05 +0100)
The number of pages for the its table may exceed the maximum of 256.
Adding a range check and limitting the number to its maximum.

Based on a patch from Tirumalesh Chalamarla <tchalamarla@cavium.com>.

Signed-off-by: Tirumalesh Chalamarla <tchalamarla@cavium.com>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Robert Richter <rrichter@cavium.com>
Signed-off-by: Vadim Lomovtsev <Vadim.Lomovtsev@caviumnetworks.com>
drivers/irqchip/irq-gic-v3-its.c
include/linux/irqchip/arm-gic-v3.h

index c00e2db351ba5aec327ebb1e98085b25b9b4d056..7c79ba6e9813da352c07954ea2e964f7ad26d521 100644 (file)
@@ -845,6 +845,7 @@ static int its_alloc_tables(struct its_node *its)
                u64 entry_size = GITS_BASER_ENTRY_SIZE(val);
                int order = get_order(psz);
                int alloc_size;
+               int alloc_pages;
                u64 tmp;
                void *base;
 
@@ -879,6 +880,14 @@ static int its_alloc_tables(struct its_node *its)
                }
 
                alloc_size = (1 << order) * PAGE_SIZE;
+               alloc_pages = (alloc_size / psz);
+               if (alloc_pages > GITS_BASER_PAGES_MAX) {
+                       alloc_pages = GITS_BASER_PAGES_MAX;
+                       order = get_order(GITS_BASER_PAGES_MAX * psz);
+                       pr_warn("%s: Device Table too large, reduce its page order to %u (%u pages)\n",
+                               its->msi_chip.of_node->full_name, order, alloc_pages);
+               }
+
                base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
                if (!base) {
                        err = -ENOMEM;
@@ -907,7 +916,7 @@ retry_baser:
                        break;
                }
 
-               val |= (alloc_size / psz) - 1;
+               val |= alloc_pages - 1;
 
                writeq_relaxed(val, its->base + GITS_BASER + i * 8);
                tmp = readq_relaxed(its->base + GITS_BASER + i * 8);
index ffbc034c88104d251c3891f4513c12a62818c5dd..f28da189c4aa0ee52a5259e23f9f75aa45cb5253 100644 (file)
 #define GITS_BASER_PAGE_SIZE_16K       (1UL << GITS_BASER_PAGE_SIZE_SHIFT)
 #define GITS_BASER_PAGE_SIZE_64K       (2UL << GITS_BASER_PAGE_SIZE_SHIFT)
 #define GITS_BASER_PAGE_SIZE_MASK      (3UL << GITS_BASER_PAGE_SIZE_SHIFT)
+#define GITS_BASER_PAGES_MAX           256
 
 #define GITS_BASER_TYPE_NONE           0
 #define GITS_BASER_TYPE_DEVICE         1