Commit 32bd44dc authored by Shanker Donthineni's avatar Shanker Donthineni Committed by Marc Zyngier

irqchip/gic-v3-its: Fix the incorrect parsing of VCPU table size

The VCPU table consists of vPE entries, and its size provides the number
of VPEs supported by GICv4 hardware. Unfortunately the maximum size of
the VPE table is not discoverable like Device table. All VLPI commands
limits the number of bits to 16 to hold VPEID, which is index into VCPU
table. Don't apply DEVID bits for VCPU table instead assume maximum bits
to 16.

ITS log messages on QDF2400 without fix:
  allocated 524288 Devices (indirect, esz 8, psz 64K, shr 1)
  allocated 8192 Interrupt Collections (flat, esz 8, psz 64K, shr 1)
  Virtual CPUs Table too large, reduce ids 32->26
  Virtual CPUs too large, reduce ITS pages 8192->256
  allocated 2097152 Virtual CPUs (flat, esz 8, psz 64K, shr 1)

ITS log messages on QDF2400 with fix:
  allocated 524288 Devices (indirect, esz 8, psz 64K, shr 1)
  allocated 8192 Interrupt Collections (flat, esz 8, psz 64K, shr 1)
  allocated 65536 Virtual CPUs (flat, esz 8, psz 64K, shr 1)
Signed-off-by: default avatarShanker Donthineni <shankerd@codeaurora.org>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent c427a475
...@@ -107,6 +107,10 @@ struct its_node { ...@@ -107,6 +107,10 @@ struct its_node {
#define ITS_ITT_ALIGN SZ_256 #define ITS_ITT_ALIGN SZ_256
/* The maximum number of VPEID bits supported by VLPI commands */
#define ITS_MAX_VPEID_BITS (16)
#define ITS_MAX_VPEID (1 << (ITS_MAX_VPEID_BITS))
/* Convert page order to size in bytes */ /* Convert page order to size in bytes */
#define PAGE_ORDER_TO_SIZE(o) (PAGE_SIZE << (o)) #define PAGE_ORDER_TO_SIZE(o) (PAGE_SIZE << (o))
...@@ -1582,13 +1586,12 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, ...@@ -1582,13 +1586,12 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
static bool its_parse_indirect_baser(struct its_node *its, static bool its_parse_indirect_baser(struct its_node *its,
struct its_baser *baser, struct its_baser *baser,
u32 psz, u32 *order) u32 psz, u32 *order, u32 ids)
{ {
u64 tmp = its_read_baser(its, baser); u64 tmp = its_read_baser(its, baser);
u64 type = GITS_BASER_TYPE(tmp); u64 type = GITS_BASER_TYPE(tmp);
u64 esz = GITS_BASER_ENTRY_SIZE(tmp); u64 esz = GITS_BASER_ENTRY_SIZE(tmp);
u64 val = GITS_BASER_InnerShareable | GITS_BASER_RaWaWb; u64 val = GITS_BASER_InnerShareable | GITS_BASER_RaWaWb;
u32 ids = its->device_ids;
u32 new_order = *order; u32 new_order = *order;
bool indirect = false; bool indirect = false;
...@@ -1680,9 +1683,13 @@ static int its_alloc_tables(struct its_node *its) ...@@ -1680,9 +1683,13 @@ static int its_alloc_tables(struct its_node *its)
continue; continue;
case GITS_BASER_TYPE_DEVICE: case GITS_BASER_TYPE_DEVICE:
indirect = its_parse_indirect_baser(its, baser,
psz, &order,
its->device_ids);
case GITS_BASER_TYPE_VCPU: case GITS_BASER_TYPE_VCPU:
indirect = its_parse_indirect_baser(its, baser, indirect = its_parse_indirect_baser(its, baser,
psz, &order); psz, &order,
ITS_MAX_VPEID_BITS);
break; break;
} }
...@@ -2551,7 +2558,7 @@ static struct irq_chip its_vpe_irq_chip = { ...@@ -2551,7 +2558,7 @@ static struct irq_chip its_vpe_irq_chip = {
static int its_vpe_id_alloc(void) static int its_vpe_id_alloc(void)
{ {
return ida_simple_get(&its_vpeid_ida, 0, 1 << 16, GFP_KERNEL); return ida_simple_get(&its_vpeid_ida, 0, ITS_MAX_VPEID, GFP_KERNEL);
} }
static void its_vpe_id_free(u16 id) static void its_vpe_id_free(u16 id)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment