:p
atchew
Login
From: Mykola Kvach <mykola_kvach@epam.com> GITS_BASER_INNER_CACHEABILITY_MASK and GICR_PROPBASER_INNER_CACHEABILITY_MASK are shifted masks. Comparing the masked but unshifted values against GIC_BASER_CACHE_nC, which is an unshifted enum value, leads to incorrect detection of non-cacheable GITS_CBASER command queue, GITS_BASER tables, and GICR_PROPBASER mappings. Use MASK_EXTR() to decode these cacheability fields before comparing against GIC_BASER_CACHE_nC, so the backing memory is flushed when required. Fixes: 8ed8d21373be ("ARM: GICv3 ITS: map ITS command buffer") Fixes: 05238012b86d ("ARM: GICv3 ITS: allocate device and collection table") Fixes: c9b939863c89 ("ARM: GICv3: allocate LPI pending and property table") Signed-off-by: Mykyta Poturai <mykyta_poturai@epam.com> Signed-off-by: Mykola Kvach <mykola_kvach@epam.com> --- Changes in v2: - use MASK_EXTR() instead of open-coding the BASER field shift - fix the analogous PROPBASER cacheability comparison in gicv3_lpi_set_proptable() - fix the CBASER command queue cacheability check as well --- xen/arch/arm/gic-v3-its.c | 6 ++++-- xen/arch/arm/gic-v3-lpi.c | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/gic-v3-its.c +++ b/xen/arch/arm/gic-v3-its.c @@ -XXX,XX +XXX,XX @@ static void *its_map_cbaser(struct host_its *its) * If the command queue memory is mapped as uncached, we need to flush * it on every access. */ - if ( !(reg & GITS_BASER_INNER_CACHEABILITY_MASK) ) + if ( MASK_EXTR(reg, GITS_BASER_INNER_CACHEABILITY_MASK) <= + GIC_BASER_CACHE_nC ) { its->flags |= HOST_ITS_FLUSH_CMD_QUEUE; printk(XENLOG_WARNING "using non-cacheable ITS command queue\n"); @@ -XXX,XX +XXX,XX @@ retry: } attr = regc & BASER_ATTR_MASK; } - if ( (regc & GITS_BASER_INNER_CACHEABILITY_MASK) <= GIC_BASER_CACHE_nC ) + if ( MASK_EXTR(regc, GITS_BASER_INNER_CACHEABILITY_MASK) <= + GIC_BASER_CACHE_nC ) clean_and_invalidate_dcache_va_range(buffer, table_size); /* If the host accepted our page size, we are done. */ diff --git a/xen/arch/arm/gic-v3-lpi.c b/xen/arch/arm/gic-v3-lpi.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/gic-v3-lpi.c +++ b/xen/arch/arm/gic-v3-lpi.c @@ -XXX,XX +XXX,XX @@ static int gicv3_lpi_set_proptable(void __iomem * rdist_base) } /* Remember that we have to flush the property table if non-cacheable. */ - if ( (reg & GICR_PROPBASER_INNER_CACHEABILITY_MASK) <= GIC_BASER_CACHE_nC ) + if ( MASK_EXTR(reg, GICR_PROPBASER_INNER_CACHEABILITY_MASK) <= + GIC_BASER_CACHE_nC ) { lpi_data.flags |= LPI_PROPTABLE_NEEDS_FLUSHING; /* Update the redistributors knowledge about the attributes. */ -- 2.43.0
From: Mykola Kvach <mykola_kvach@epam.com> GITS_BASER_INNER_CACHEABILITY_MASK and GICR_PROPBASER_INNER_CACHEABILITY_MASK are shifted masks. Comparing the masked but unshifted values against GIC_BASER_CACHE_nC, which is an unshifted enum value, leads to incorrect detection of non-cacheable GITS_BASER tables and GICR_PROPBASER mappings. Use MASK_EXTR() to decode these cacheability fields before comparing against GIC_BASER_CACHE_nC, so the backing memory is flushed when required. Fixes: 05238012b86d ("ARM: GICv3 ITS: allocate device and collection table") Fixes: c9b939863c89 ("ARM: GICv3: allocate LPI pending and property table") Signed-off-by: Mykyta Poturai <mykyta_poturai@epam.com> Signed-off-by: Mykola Kvach <mykola_kvach@epam.com> --- Changes in v3: - drop CBASER command queue hunk (separate functional change, not the same shifted-mask bug) Changes in v2: - use MASK_EXTR() instead of open-coding the BASER field shift - fix the analogous PROPBASER cacheability comparison in gicv3_lpi_set_proptable() - fix the CBASER command queue cacheability check as well --- xen/arch/arm/gic-v3-its.c | 3 ++- xen/arch/arm/gic-v3-lpi.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/gic-v3-its.c +++ b/xen/arch/arm/gic-v3-its.c @@ -XXX,XX +XXX,XX @@ retry: } attr = regc & BASER_ATTR_MASK; } - if ( (regc & GITS_BASER_INNER_CACHEABILITY_MASK) <= GIC_BASER_CACHE_nC ) + if ( MASK_EXTR(regc, GITS_BASER_INNER_CACHEABILITY_MASK) <= + GIC_BASER_CACHE_nC ) clean_and_invalidate_dcache_va_range(buffer, table_size); /* If the host accepted our page size, we are done. */ diff --git a/xen/arch/arm/gic-v3-lpi.c b/xen/arch/arm/gic-v3-lpi.c index XXXXXXX..XXXXXXX 100644 --- a/xen/arch/arm/gic-v3-lpi.c +++ b/xen/arch/arm/gic-v3-lpi.c @@ -XXX,XX +XXX,XX @@ static int gicv3_lpi_set_proptable(void __iomem * rdist_base) } /* Remember that we have to flush the property table if non-cacheable. */ - if ( (reg & GICR_PROPBASER_INNER_CACHEABILITY_MASK) <= GIC_BASER_CACHE_nC ) + if ( MASK_EXTR(reg, GICR_PROPBASER_INNER_CACHEABILITY_MASK) <= + GIC_BASER_CACHE_nC ) { lpi_data.flags |= LPI_PROPTABLE_NEEDS_FLUSHING; /* Update the redistributors knowledge about the attributes. */ -- 2.43.0