|
@@ -822,6 +822,7 @@ static int its_alloc_tables(const char *node_name, 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;
|
|
|
|
|
@@ -856,6 +857,14 @@ static int its_alloc_tables(const char *node_name, 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",
|
|
|
+ node_name, order, alloc_pages);
|
|
|
+ }
|
|
|
+
|
|
|
base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order);
|
|
|
if (!base) {
|
|
|
err = -ENOMEM;
|
|
@@ -884,7 +893,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);
|