[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] xen/arm: vgic: Use dynamic memory allocation for vgic_rdist_region
commit 611c1befab88e2bdca34fcf167256d7eb47a6325 Author: Shanker Donthineni <shankerd@xxxxxxxxxxxxxx> AuthorDate: Mon Jun 27 15:33:37 2016 -0500 Commit: Stefano Stabellini <sstabellini@xxxxxxxxxx> CommitDate: Thu Jul 14 15:14:19 2016 +0100 xen/arm: vgic: Use dynamic memory allocation for vgic_rdist_region The number of Redistributor regions allowed for dom0 is hardcoded to a define MAX_RDIST_COUNT which is 4. Some systems, especially latest server chips, may have more than 4 redistributors. Either we have to increase MAX_RDIST_COUNT to a bigger number or allocate memory based on the 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 a 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> Reviewed-by: Julien Grall <julien.grall@xxxxxxx> Acked-by: Stefano Stabellini <sstabellini@xxxxxxxxxx> --- xen/arch/arm/vgic-v2.c | 6 ++++++ xen/arch/arm/vgic-v3.c | 27 ++++++++++++++++++++++++--- xen/arch/arm/vgic.c | 1 + xen/include/asm-arm/domain.h | 2 +- xen/include/asm-arm/vgic.h | 2 ++ 5 files changed, 34 insertions(+), 4 deletions(-) diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c index cbe61cf..6a5e67b 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..be9a9a3 100644 --- a/xen/arch/arm/vgic-v3.c +++ b/xen/arch/arm/vgic-v3.c @@ -1391,9 +1391,26 @@ static int vgic_v3_vcpu_init(struct vcpu *v) return 0; } +static inline unsigned int vgic_v3_rdist_count(struct domain *d) +{ + return is_hardware_domain(d) ? vgic_v3_hw.nr_rdist_regions : + GUEST_GICV3_RDIST_REGIONS; +} + 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 = vgic_v3_rdist_count(d); + + 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 +1443,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 +1451,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 +1482,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 413ff16..5b9d9b6 100644 --- a/xen/arch/arm/vgic.c +++ b/xen/arch/arm/vgic.c @@ -179,6 +179,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 979f7de..4e9d8bf 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -107,7 +107,7 @@ struct arch_domain paddr_t base; /* Base address */ paddr_t size; /* Size */ unsigned int first_cpu; /* First CPU handled */ - } rdist_regions[MAX_RDIST_COUNT]; + } *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..c3cc4f6 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 were 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 */ -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |