|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [RFC PATCH 10/19] arm/its: Keep track of BASER regs
On Mon, Feb 2, 2026 at 6:14 PM Mykyta Poturai <Mykyta_Poturai@xxxxxxxx> wrote:
>
> Keep all the info about BASER regs in host_its structure to be able to easily
> access it later.
>
> Signed-off-by: Mykyta Poturai <mykyta_poturai@xxxxxxxx>
> ---
> xen/arch/arm/gic-v3-its.c | 36 +++++++++++++++++++++------
> xen/arch/arm/include/asm/gic_v3_its.h | 14 +++++++++++
> 2 files changed, 43 insertions(+), 7 deletions(-)
>
> diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c
> index c628959f42..2328595a85 100644
> --- a/xen/arch/arm/gic-v3-its.c
> +++ b/xen/arch/arm/gic-v3-its.c
> @@ -430,16 +430,32 @@ static void *its_map_cbaser(struct host_its *its)
> /* The ITS BASE registers work with page sizes of 4K, 16K or 64K. */
> #define BASER_PAGE_BITS(sz) ((sz) * 2 + 12)
>
> +struct its_baser *its_get_baser(struct host_its *hw_its, uint32_t type)
> +{
> + unsigned int i;
> +
> + for ( i = 0; i < GITS_BASER_NR_REGS; i++ )
> + {
> + if (GITS_BASER_TYPE(hw_its->tables[i].val) == type)
> + return &hw_its->tables[i];
> + }
> +
> + return NULL;
> +}
> +
> static int its_map_baser(void __iomem *basereg, uint64_t regc,
> - unsigned int nr_items)
> + unsigned int nr_items, struct its_baser *baser)
> {
> uint64_t attr, reg;
> unsigned int entry_size = GITS_BASER_ENTRY_SIZE(regc);
> - unsigned int pagesz = 2; /* try 64K pages first, then go down. */
> + unsigned int page_size[4] = {SZ_4K, SZ_16K, SZ_64K, SZ_64K};
> + unsigned int pagesz = 0; /* try 64K pages first, then go down. */
pagesz=0 looks like test leftover
> unsigned int table_size;
> unsigned int order;
> void *buffer;
> + uint32_t type;
>
> + type = GITS_BASER_TYPE(regc);
nit: unused
> attr = gicv3_its_get_shareability() << GITS_BASER_SHAREABILITY_SHIFT;
> attr |= GIC_BASER_CACHE_SameAsInner <<
> GITS_BASER_OUTER_CACHEABILITY_SHIFT;
> attr |= gicv3_its_get_cacheability() <<
> GITS_BASER_INNER_CACHEABILITY_SHIFT;
> @@ -479,6 +495,11 @@ retry:
> writeq_relaxed(reg, basereg);
> regc = readq_relaxed(basereg);
>
> + baser->val = regc;
> + baser->base = buffer;
> + baser->table_size = table_size;
> + baser->pagesz = page_size[pagesz];
> +
> /* The host didn't like our attributes, just use what it returned. */
> if ( (regc & BASER_ATTR_MASK) != attr )
> {
> @@ -490,7 +511,7 @@ retry:
> }
> attr = regc & BASER_ATTR_MASK;
> }
> - if ( (regc & GITS_BASER_INNER_CACHEABILITY_MASK) <= GIC_BASER_CACHE_nC )
> + if ( gicv3_its_get_cacheability() <= GIC_BASER_CACHE_nC )
> clean_and_invalidate_dcache_va_range(buffer, table_size);
>
> /* If the host accepted our page size, we are done. */
> @@ -568,26 +589,27 @@ static int gicv3_its_init_single_its(struct host_its
> *hw_its)
> {
> void __iomem *basereg = hw_its->its_base + GITS_BASER0 + i * 8;
> unsigned int type;
> + struct its_baser *baser = hw_its->tables + i;
>
> reg = readq_relaxed(basereg);
> - type = (reg & GITS_BASER_TYPE_MASK) >> GITS_BASER_TYPE_SHIFT;
> + type = GITS_BASER_TYPE(reg);
> switch ( type )
> {
> case GITS_BASER_TYPE_NONE:
> continue;
> case GITS_BASER_TYPE_DEVICE:
> - ret = its_map_baser(basereg, reg, BIT(hw_its->devid_bits, UL));
> + ret = its_map_baser(basereg, reg, BIT(hw_its->devid_bits, UL),
> baser);
> if ( ret )
> return ret;
> break;
> case GITS_BASER_TYPE_COLLECTION:
> - ret = its_map_baser(basereg, reg, num_possible_cpus());
> + ret = its_map_baser(basereg, reg, num_possible_cpus(), baser);
> if ( ret )
> return ret;
> break;
> /* In case this is a GICv4, provide a (dummy) vPE table as well. */
> case GITS_BASER_TYPE_VCPU:
> - ret = its_map_baser(basereg, reg, 1);
> + ret = its_map_baser(basereg, reg, 32, baser);
Since MAX_VPEID is introduced later in the series, could you use it here
instead of the hardcoded 32 (or reorder the patches so it’s available)?
Also, if the BASER ends up indirect, the L1 sizing should be recalculated
from MAX_VPEID.
Best regards,
Mykola
> if ( ret )
> return ret;
> break;
> diff --git a/xen/arch/arm/include/asm/gic_v3_its.h
> b/xen/arch/arm/include/asm/gic_v3_its.h
> index 973ca6acdd..bd2696f354 100644
> --- a/xen/arch/arm/include/asm/gic_v3_its.h
> +++ b/xen/arch/arm/include/asm/gic_v3_its.h
> @@ -64,6 +64,7 @@
> #define GITS_BASER_INNER_CACHEABILITY_SHIFT 59
> #define GITS_BASER_TYPE_SHIFT 56
> #define GITS_BASER_TYPE_MASK (7ULL << GITS_BASER_TYPE_SHIFT)
> +#define GITS_BASER_TYPE(reg) ((reg & GITS_BASER_TYPE_MASK) >>
> GITS_BASER_TYPE_SHIFT)
> #define GITS_BASER_OUTER_CACHEABILITY_SHIFT 53
> #define GITS_BASER_TYPE_NONE 0UL
> #define GITS_BASER_TYPE_DEVICE 1UL
> @@ -143,6 +144,17 @@ struct its_device {
> #endif
> };
>
> +/*
> + * The ITS_BASER structure - contains memory information, cached
> + * value of BASER register configuration.
> + */
> +struct its_baser {
> + void *base;
> + uint64_t val;
> + unsigned int table_size;
> + unsigned int pagesz;
> +};
> +
> /* data structure for each hardware ITS */
> struct host_its {
> struct list_head entry;
> @@ -156,6 +168,7 @@ struct host_its {
> spinlock_t cmd_lock;
> void *cmd_buf;
> unsigned int flags;
> + struct its_baser tables[GITS_BASER_NR_REGS];
> };
>
> /* Map a collection for this host CPU to each host ITS. */
> @@ -259,6 +272,7 @@ struct pending_irq *gicv3_assign_guest_event(struct
> domain *d,
> uint32_t virt_lpi);
> void gicv3_lpi_update_host_entry(uint32_t host_lpi, int domain_id,
> uint32_t virt_lpi);
> +struct its_baser *its_get_baser(struct host_its *hw_its, uint32_t type);
> void lpi_write_config(uint8_t *prop_table, uint32_t lpi, uint8_t clr,
> uint8_t set);
> int its_send_command(struct host_its *hw_its, const void *its_cmd);
> --
> 2.51.2
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |