[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 4/8] xen/arm: vgic: Use dynamic memory allocation for vgic_rdist_region
The number of Re-distributor regions allowed for dom0 is hardcoded to a compile time macro MAX_RDIST_COUNT which is 4. On some systems, especially latest server chips might have more than 4 redistributors. Either we have to increase MAX_RDIST_COUNT to a bigger number or allocate memory based on number of redistributors that are found in MADT table. In the worst case scenario, the macro MAX_RDIST_COUNT should be equal to CONFIG_NR_CPUS in order to support per CPU Redistributors. Increasing MAX_RDIST_COUNT has side effect, it blows 'struct domain' size and hits BUILD_BUG_ON() in domain build code path. struct domain *alloc_domain_struct(void) { struct domain *d; BUILD_BUG_ON(sizeof(*d) > PAGE_SIZE); d = alloc_xenheap_pages(0, 0); if ( d == NULL ) return NULL; ... This patch uses the second approach to fix the BUILD_BUG(). Signed-off-by: Shanker Donthineni <shankerd@xxxxxxxxxxxxxx> --- xen/arch/arm/vgic-v2.c | 6 ++++++ xen/arch/arm/vgic-v3.c | 22 +++++++++++++++++++--- xen/arch/arm/vgic.c | 1 + xen/include/asm-arm/domain.h | 12 +++++++----- xen/include/asm-arm/vgic.h | 2 ++ 5 files changed, 35 insertions(+), 8 deletions(-) diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c index 9adb4a9..f5778e6 100644 --- a/xen/arch/arm/vgic-v2.c +++ b/xen/arch/arm/vgic-v2.c @@ -699,9 +699,15 @@ static int vgic_v2_domain_init(struct domain *d) return 0; } +static void vgic_v2_domain_free(struct domain *d) +{ + /* Nothing to be cleanup for this driver */ +} + static const struct vgic_ops vgic_v2_ops = { .vcpu_init = vgic_v2_vcpu_init, .domain_init = vgic_v2_domain_init, + .domain_free = vgic_v2_domain_free, .max_vcpus = 8, }; diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c index b37a7c0..e877e9e 100644 --- a/xen/arch/arm/vgic-v3.c +++ b/xen/arch/arm/vgic-v3.c @@ -1393,7 +1393,19 @@ static int vgic_v3_vcpu_init(struct vcpu *v) static int vgic_v3_domain_init(struct domain *d) { - int i; + struct vgic_rdist_region *rdist_regions; + int rdist_count, i; + + /* Allocate memory for Re-distributor regions */ + rdist_count = is_hardware_domain(d) ? vgic_v3_hw.nr_rdist_regions : + GUEST_GICV3_RDIST_REGIONS; + + rdist_regions = xzalloc_array(struct vgic_rdist_region, rdist_count); + if ( !rdist_regions ) + return -ENOMEM; + + d->arch.vgic.nr_regions = rdist_count; + d->arch.vgic.rdist_regions = rdist_regions; /* * Domain 0 gets the hardware address. @@ -1426,7 +1438,6 @@ static int vgic_v3_domain_init(struct domain *d) first_cpu += size / d->arch.vgic.rdist_stride; } - d->arch.vgic.nr_regions = vgic_v3_hw.nr_rdist_regions; } else { @@ -1435,7 +1446,6 @@ static int vgic_v3_domain_init(struct domain *d) /* XXX: Only one Re-distributor region mapped for the guest */ BUILD_BUG_ON(GUEST_GICV3_RDIST_REGIONS != 1); - d->arch.vgic.nr_regions = GUEST_GICV3_RDIST_REGIONS; d->arch.vgic.rdist_stride = GUEST_GICV3_RDIST_STRIDE; /* The first redistributor should contain enough space for all CPUs */ @@ -1467,9 +1477,15 @@ static int vgic_v3_domain_init(struct domain *d) return 0; } +static void vgic_v3_domain_free(struct domain *d) +{ + xfree(d->arch.vgic.rdist_regions); +} + static const struct vgic_ops v3_ops = { .vcpu_init = vgic_v3_vcpu_init, .domain_init = vgic_v3_domain_init, + .domain_free = vgic_v3_domain_free, .emulate_sysreg = vgic_v3_emulate_sysreg, /* * We use both AFF1 and AFF0 in (v)MPIDR. Thus, the max number of CPU diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c index 3e1c572..5df5f01 100644 --- a/xen/arch/arm/vgic.c +++ b/xen/arch/arm/vgic.c @@ -177,6 +177,7 @@ void domain_vgic_free(struct domain *d) } } + d->arch.vgic.handler->domain_free(d); xfree(d->arch.vgic.shared_irqs); xfree(d->arch.vgic.pending_irqs); xfree(d->arch.vgic.allocated_irqs); diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h index 370cdeb..9492727 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -40,6 +40,12 @@ struct vtimer { uint64_t cval; }; +struct vgic_rdist_region { + paddr_t base; /* Base address */ + paddr_t size; /* Size */ + unsigned int first_cpu; /* First CPU handled */ +}; + struct arch_domain { #ifdef CONFIG_ARM_64 @@ -103,11 +109,7 @@ struct arch_domain #ifdef CONFIG_HAS_GICV3 /* GIC V3 addressing */ /* List of contiguous occupied by the redistributors */ - struct vgic_rdist_region { - paddr_t base; /* Base address */ - paddr_t size; /* Size */ - unsigned int first_cpu; /* First CPU handled */ - } rdist_regions[MAX_RDIST_COUNT]; + struct vgic_rdist_region *rdist_regions; int nr_regions; /* Number of rdist regions */ uint32_t rdist_stride; /* Re-Distributor stride */ #endif diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h index a2fccc0..fbb763a 100644 --- a/xen/include/asm-arm/vgic.h +++ b/xen/include/asm-arm/vgic.h @@ -128,6 +128,8 @@ struct vgic_ops { int (*vcpu_init)(struct vcpu *v); /* Domain specific initialization of vGIC */ int (*domain_init)(struct domain *d); + /* Release resources that are allocated by domain_init */ + void (*domain_free)(struct domain *d); /* vGIC sysreg emulation */ int (*emulate_sysreg)(struct cpu_user_regs *regs, union hsr hsr); /* Maximum number of vCPU supported */ -- Qualcomm Technologies, Inc. on behalf of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |