From 4ba9f75107ac7d2c46c41d9f6516faff91bd2a5a Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Fri, 8 May 2020 15:51:13 -0700 Subject: [PATCH] xen/arm: if is_domain_direct_mapped use native addresses for GICv3 Today we use native addresses to map the GICv3 for Dom0 and fixed addresses for DomUs. This patch changes the behavior so that native addresses are used for any domain that is_domain_direct_mapped. Update the rdist accessor too. Signed-off-by: Stefano Stabellini --- Changes in v2: - no #ifdef - modify accessor - use hw layout for direct mapped guests --- xen/arch/arm/domain_build.c | 30 ++++++++++++++++++++++-------- xen/arch/arm/vgic-v3.c | 10 +++++----- xen/include/asm-arm/vgic.h | 6 +++--- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index cea13389e2..eb73e33958 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -1697,10 +1697,11 @@ static int __init make_gicv3_domU_node(struct kernel_info *kinfo) { void *fdt = kinfo->fdt; int res = 0; - __be32 reg[(GUEST_ROOT_ADDRESS_CELLS + GUEST_ROOT_SIZE_CELLS) * 2]; + __be32 *reg; __be32 *cells; struct domain *d = kinfo->d; char buf[38]; + unsigned int i, len = 0; snprintf(buf, sizeof(buf), "interrupt-controller@%"PRIx64, vgic_dist_base(&d->arch.vgic)); @@ -1724,27 +1725,40 @@ static int __init make_gicv3_domU_node(struct kernel_info *kinfo) if ( res ) return res; + len = (GUEST_ROOT_ADDRESS_CELLS + GUEST_ROOT_SIZE_CELLS) * + (vgic_rdist_nr(&d->arch.vgic) + 1) * sizeof(__be32); + reg = xmalloc_bytes(len); + if ( reg == NULL ) + return -ENOMEM; + cells = ®[0]; dt_child_set_range(&cells, GUEST_ROOT_ADDRESS_CELLS, GUEST_ROOT_SIZE_CELLS, vgic_dist_base(&d->arch.vgic), GUEST_GICV3_GICD_SIZE); - dt_child_set_range(&cells, GUEST_ROOT_ADDRESS_CELLS, GUEST_ROOT_SIZE_CELLS, - vgic_rdist_base(&d->arch.vgic, 0), - vgic_rdist_size(&d->arch.vgic, 0)); + for ( i = 0; + i < vgic_rdist_nr(&d->arch.vgic); + i++, cells += (GUEST_ROOT_ADDRESS_CELLS + GUEST_ROOT_SIZE_CELLS) ) + { + dt_child_set_range(&cells, GUEST_ROOT_ADDRESS_CELLS, GUEST_ROOT_SIZE_CELLS, + vgic_rdist_base(&d->arch.vgic, i), + vgic_rdist_size(&d->arch.vgic, i)); + } - res = fdt_property(fdt, "reg", reg, sizeof(reg)); + res = fdt_property(fdt, "reg", reg, len); if (res) - return res; + goto out; res = fdt_property_cell(fdt, "linux,phandle", kinfo->phandle_gic); if (res) - return res; + goto out; res = fdt_property_cell(fdt, "phandle", kinfo->phandle_gic); if (res) - return res; + goto out; res = fdt_end_node(fdt); +out: + xfree(reg); return res; } diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c index 4e60ba15cc..85e6a6dcc3 100644 --- a/xen/arch/arm/vgic-v3.c +++ b/xen/arch/arm/vgic-v3.c @@ -1651,8 +1651,8 @@ static inline unsigned int vgic_v3_max_rdist_count(struct domain *d) * However DomU get a constructed memory map, so we can go with * the architected single redistributor region. */ - return is_hardware_domain(d) ? vgic_v3_hw.nr_rdist_regions : - GUEST_GICV3_RDIST_REGIONS; + return is_domain_direct_mapped(d) ? vgic_v3_hw.nr_rdist_regions : + GUEST_GICV3_RDIST_REGIONS; } static int vgic_v3_domain_init(struct domain *d) @@ -1674,10 +1674,10 @@ static int vgic_v3_domain_init(struct domain *d) radix_tree_init(&d->arch.vgic.pend_lpi_tree); /* - * Domain 0 gets the hardware address. - * Guests get the virtual platform layout. + * Direct mapped domains (including Dom0) gets the hardware address. + * Other guests get the virtual platform layout. */ - if ( is_hardware_domain(d) ) + if ( is_domain_direct_mapped(d) ) { unsigned int first_cpu = 0; diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h index 82bf206b1b..5755cb4cba 100644 --- a/xen/include/asm-arm/vgic.h +++ b/xen/include/asm-arm/vgic.h @@ -291,17 +291,17 @@ static inline paddr_t vgic_dist_base(struct vgic_dist *vgic) #ifdef CONFIG_GICV3 static inline unsigned int vgic_rdist_nr(struct vgic_dist *vgic) { - return GUEST_GICV3_RDIST_REGIONS; + return vgic->nr_regions; } static inline paddr_t vgic_rdist_base(struct vgic_dist *vgic, unsigned int i) { - return GUEST_GICV3_GICR0_BASE; + return vgic->rdist_regions[i].base; } static inline paddr_t vgic_rdist_size(struct vgic_dist *vgic, unsigned int i) { - return GUEST_GICV3_GICR0_SIZE; + return vgic->rdist_regions[i].size; } #endif -- 2.39.5