All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefano Stabellini <sstabellini@kernel.org>
To: Andre Przywara <andre.przywara@arm.com>
Cc: xen-devel@lists.xenproject.org,
	Julien Grall <julien.grall@arm.com>,
	Stefano Stabellini <sstabellini@kernel.org>,
	Vijay Kilari <vijay.kilari@gmail.com>
Subject: Re: [RFC PATCH v2 03/26] ARM: GICv3 ITS: allocate device and collection table
Date: Wed, 4 Jan 2017 13:47:35 -0800 (PST)	[thread overview]
Message-ID: <alpine.DEB.2.10.1701041313540.17742@sstabellini-ThinkPad-X260> (raw)
In-Reply-To: <20161222182446.18791-4-andre.przywara@arm.com>

On Thu, 22 Dec 2016, Andre Przywara wrote:
> Each ITS maps a pair of a DeviceID (usually the PCI b/d/f triplet) and
> an EventID (the MSI payload or interrupt ID) to a pair of LPI number
> and collection ID, which points to the target CPU.
> This mapping is stored in the device and collection tables, which software
> has to provide for the ITS to use.
> Allocate the required memory and hand it the ITS.
> The maximum number of devices is limited to a compile-time constant
> exposed in Kconfig.
> 
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> ---
>  xen/arch/arm/Kconfig          |   6 +++
>  xen/arch/arm/gic-its.c        | 114 ++++++++++++++++++++++++++++++++++++++++++
>  xen/arch/arm/gic-v3.c         |   5 ++
>  xen/include/asm-arm/bitops.h  |   1 +
>  xen/include/asm-arm/gic-its.h |  51 ++++++++++++++++++-
>  5 files changed, 176 insertions(+), 1 deletion(-)
> 
> diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig
> index a7d941c..a369305 100644
> --- a/xen/arch/arm/Kconfig
> +++ b/xen/arch/arm/Kconfig
> @@ -59,6 +59,12 @@ config MAX_HOST_LPI_BITS
>            This can be overriden on the command line with the max_lpi_bits
>            parameter.
>  
> +config MAX_ITS_PCI_BUSSES
> +        depends on HAS_ITS
> +        int "Number of PCI busses the ITS supports (4)"
> +        range 1 1024
> +        default "4"

Given that any kind of devices can be behind an ITS, including non-PCI
devices, I think it is best to call this MAX_PHYS_ITS_DEVICES.


>  endmenu
>  
>  menu "ARM errata workaround via the alternative framework"
> diff --git a/xen/arch/arm/gic-its.c b/xen/arch/arm/gic-its.c
> index 6c3a35d..f1540b2 100644
> --- a/xen/arch/arm/gic-its.c
> +++ b/xen/arch/arm/gic-its.c
> @@ -22,6 +22,7 @@
>  #include <xen/libfdt/libfdt.h>
>  #include <xen/sizes.h>
>  #include <asm/p2m.h>
> +#include <asm/io.h>
>  #include <asm/gic.h>
>  #include <asm/gic_v3_defs.h>
>  #include <asm/gic-its.h>
> @@ -37,6 +38,119 @@ static DEFINE_PER_CPU(void *, pending_table);
>  
>  #define MAX_PHYS_LPIS   (BIT_ULL(lpi_data.host_lpi_bits) - 8192)
>  
> +#define BASER_ATTR_MASK                                           \
> +        ((0x3UL << GITS_BASER_SHAREABILITY_SHIFT)               | \
> +         (0x7UL << GITS_BASER_OUTER_CACHEABILITY_SHIFT)         | \
> +         (0x7UL << GITS_BASER_INNER_CACHEABILITY_SHIFT))
> +#define BASER_RO_MASK   (GENMASK(58, 56) | GENMASK(52, 48))
> +
> +static uint64_t encode_phys_addr(paddr_t addr, int page_bits)
> +{
> +    uint64_t ret;
> +
> +    if ( page_bits < 16)
> +        return (uint64_t)addr & GENMASK(47, page_bits);
> +
> +    ret = addr & GENMASK(47, 16);
> +    return ret | (addr & GENMASK(51, 48)) >> (48 - 12);
> +}
> +
> +static int its_map_baser(void __iomem *basereg, uint64_t regc, int nr_items)
> +{
> +    uint64_t attr;
> +    int entry_size = ((regc >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0x1f) + 1;
> +    int pagesz;
> +    int order;
> +    void *buffer = NULL;
> +
> +    attr  = GIC_BASER_InnerShareable << GITS_BASER_SHAREABILITY_SHIFT;
> +    attr |= GIC_BASER_CACHE_SameAsInner << GITS_BASER_OUTER_CACHEABILITY_SHIFT;
> +    attr |= GIC_BASER_CACHE_RaWaWb << GITS_BASER_INNER_CACHEABILITY_SHIFT;
> +
> +    /*
> +     * Loop over the page sizes (4K, 16K, 64K) to find out what the host
> +     * supports.
> +     */
> +    for ( pagesz = 0; pagesz < 3; pagesz++ )
> +    {
> +        uint64_t reg;
> +        int nr_bytes;
> +
> +        nr_bytes = ROUNDUP(nr_items * entry_size, BIT(pagesz * 2 + 12));

12/PAGE_SHIFT


> +        order = get_order_from_bytes(nr_bytes);
> +
> +        if ( !buffer )
> +            buffer = alloc_xenheap_pages(order, 0);
> +        if ( !buffer )
> +            return -ENOMEM;
> +
> +        reg  = attr;
> +        reg |= (pagesz << GITS_BASER_PAGE_SIZE_SHIFT);
> +        reg |= nr_bytes >> (pagesz * 2 + 12);
> +        reg |= regc & BASER_RO_MASK;
> +        reg |= GITS_BASER_VALID;
> +        reg |= encode_phys_addr(virt_to_maddr(buffer), pagesz * 2 + 12);
> +
> +        writeq_relaxed(reg, basereg);
> +        regc = readl_relaxed(basereg);
> +
> +        /* The host didn't like our attributes, just use what it returned. */
> +        if ( (regc & BASER_ATTR_MASK) != attr )
> +            attr = regc & BASER_ATTR_MASK;
> +
> +        /* If the host accepted our page size, we are done. */
> +        if ( (reg & (3UL << GITS_BASER_PAGE_SIZE_SHIFT)) == pagesz )
> +            return 0;
> +
> +        /* Check whether our buffer is aligned to the next page size already. */
> +        if ( !(virt_to_maddr(buffer) & (BIT(pagesz * 2 + 12 + 2) - 1)) )
> +        {
> +            free_xenheap_pages(buffer, order);
> +            buffer = NULL;
> +        }

Regardless of alignment, should we always free buffer here, given that
we need to allocate the right size for the next attempt?


> +    }
> +
> +    if ( buffer )
> +        free_xenheap_pages(buffer, order);
> +
> +    return -EINVAL;
> +}
> +
> +int gicv3_its_init(struct host_its *hw_its)
> +{
> +    uint64_t reg;
> +    int i;
> + 
> +    hw_its->its_base = ioremap_nocache(hw_its->addr, hw_its->size);
> +    if ( !hw_its->its_base )
> +        return -ENOMEM;
> +
> +    for ( i = 0; i < GITS_BASER_NR_REGS; i++ )
> +    {
> +        void __iomem *basereg = hw_its->its_base + GITS_BASER0 + i * 8;
> +        int type;
> +
> +        reg = readq_relaxed(basereg);
> +        type = (reg & GITS_BASER_TYPE_MASK) >> GITS_BASER_TYPE_SHIFT;
> +        switch ( type )
> +        {
> +        case GITS_BASER_TYPE_NONE:
> +            continue;
> +        case GITS_BASER_TYPE_DEVICE:
> +            /* TODO: find some better way of limiting the number of devices */
> +            its_map_baser(basereg, reg, CONFIG_MAX_ITS_PCI_BUSSES * 256);
> +            break;
> +        case GITS_BASER_TYPE_COLLECTION:
> +            its_map_baser(basereg, reg, NR_CPUS);
> +            break;
> +        default:
> +            continue;
> +        }
> +    }
> +
> +    return 0;
> +}
> +
>  uint64_t gicv3_lpi_allocate_pendtable(void)
>  {
>      uint64_t reg, attr;
> diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
> index 1c6869d..8ca7da2 100644
> --- a/xen/arch/arm/gic-v3.c
> +++ b/xen/arch/arm/gic-v3.c
> @@ -29,6 +29,7 @@
>  #include <xen/irq.h>
>  #include <xen/iocap.h>
>  #include <xen/sched.h>
> +#include <xen/err.h>
>  #include <xen/errno.h>
>  #include <xen/delay.h>
>  #include <xen/device_tree.h>
> @@ -1564,6 +1565,7 @@ static int __init gicv3_init(void)
>  {
>      int res, i;
>      uint32_t reg;
> +    struct host_its *hw_its;
>  
>      if ( !cpu_has_gicv3 )
>      {
> @@ -1619,6 +1621,9 @@ static int __init gicv3_init(void)
>      res = gicv3_cpu_init();
>      gicv3_hyp_init();
>  
> +    list_for_each_entry(hw_its, &host_its_list, entry)
> +        gicv3_its_init(hw_its);
> +
>      spin_unlock(&gicv3.lock);
>  
>      return res;
> diff --git a/xen/include/asm-arm/bitops.h b/xen/include/asm-arm/bitops.h
> index c9adf79..4ccb444 100644
> --- a/xen/include/asm-arm/bitops.h
> +++ b/xen/include/asm-arm/bitops.h
> @@ -24,6 +24,7 @@
>  #define BIT(nr)                 (1UL << (nr))
>  #define BIT_MASK(nr)            (1UL << ((nr) % BITS_PER_WORD))
>  #define BIT_WORD(nr)            ((nr) / BITS_PER_WORD)
> +#define BIT_ULL(nr)             (1ULL << (nr))
>  #define BITS_PER_BYTE           8
>  #define BIT_ULL(nr)             (1ULL << (nr))
>  
> diff --git a/xen/include/asm-arm/gic-its.h b/xen/include/asm-arm/gic-its.h
> index a66b6be..26b0584 100644
> --- a/xen/include/asm-arm/gic-its.h
> +++ b/xen/include/asm-arm/gic-its.h
> @@ -18,6 +18,49 @@
>  #ifndef __ASM_ARM_ITS_H__
>  #define __ASM_ARM_ITS_H__
>  
> +#define LPI_OFFSET                      8192
> +
> +#define GITS_CTLR                       0x000
> +#define GITS_IIDR                       0x004
> +#define GITS_TYPER                      0x008
> +#define GITS_CBASER                     0x080
> +#define GITS_CWRITER                    0x088
> +#define GITS_CREADR                     0x090
> +#define GITS_BASER_NR_REGS              8
> +#define GITS_BASER0                     0x100
> +#define GITS_BASER1                     0x108
> +#define GITS_BASER2                     0x110
> +#define GITS_BASER3                     0x118
> +#define GITS_BASER4                     0x120
> +#define GITS_BASER5                     0x128
> +#define GITS_BASER6                     0x130
> +#define GITS_BASER7                     0x138
> +
> +/* Register bits */
> +#define GITS_CTLR_ENABLE                BIT_ULL(0)
> +#define GITS_IIDR_VALUE                 0x34c
> +
> +#define GITS_BASER_VALID                BIT_ULL(63)
> +#define GITS_BASER_INDIRECT             BIT_ULL(62)
> +#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_OUTER_CACHEABILITY_SHIFT        53
> +#define GITS_BASER_TYPE_NONE            0UL
> +#define GITS_BASER_TYPE_DEVICE          1UL
> +#define GITS_BASER_TYPE_VCPU            2UL
> +#define GITS_BASER_TYPE_CPU             3UL
> +#define GITS_BASER_TYPE_COLLECTION      4UL
> +#define GITS_BASER_TYPE_RESERVED5       5UL
> +#define GITS_BASER_TYPE_RESERVED6       6UL
> +#define GITS_BASER_TYPE_RESERVED7       7UL
> +#define GITS_BASER_ENTRY_SIZE_SHIFT     48
> +#define GITS_BASER_SHAREABILITY_SHIFT   10
> +#define GITS_BASER_PAGE_SIZE_SHIFT      8
> +#define GITS_BASER_RO_MASK              (GITS_BASER_TYPE_MASK | \
> +                                        (31UL << GITS_BASER_ENTRY_SIZE_SHIFT) |\
> +                                        GITS_BASER_INDIRECT)
> +
>  #ifndef __ASSEMBLY__
>  #include <xen/device_tree.h>
>  
> @@ -27,6 +70,7 @@ struct host_its {
>      const struct dt_device_node *dt_node;
>      paddr_t addr;
>      paddr_t size;
> +    void __iomem *its_base;
>  };
>  
>  extern struct list_head host_its_list;
> @@ -42,8 +86,9 @@ void gicv3_its_dt_init(const struct dt_device_node *node);
>  uint64_t gicv3_lpi_get_proptable(void);
>  uint64_t gicv3_lpi_allocate_pendtable(void);
>  
> -/* Initialize the host structures for LPIs. */
> +/* Initialize the host structures for LPIs and the host ITSes. */
>  int gicv3_lpi_init_host_lpis(unsigned int nr_lpis);
> +int gicv3_its_init(struct host_its *hw_its);
>  
>  #else
>  
> @@ -62,6 +107,10 @@ static inline int gicv3_lpi_init_host_lpis(unsigned int nr_lpis)
>  {
>      return 0;
>  }
> +static inline int gicv3_its_init(struct host_its *hw_its)
> +{
> +    return 0;
> +}
>  #endif /* CONFIG_HAS_ITS */
>  
>  #endif /* __ASSEMBLY__ */
> -- 
> 2.9.0
> 

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

  reply	other threads:[~2017-01-04 21:47 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-22 18:24 [RFC PATCH v2 00/26] arm64: Dom0 ITS emulation Andre Przywara
2016-12-22 18:24 ` [RFC PATCH v2 01/26] ARM: GICv3 ITS: parse and store ITS subnodes from hardware DT Andre Przywara
2016-12-22 18:24 ` [RFC PATCH v2 02/26] ARM: GICv3: allocate LPI pending and property table Andre Przywara
2017-01-04 21:09   ` Stefano Stabellini
2017-01-05 17:13     ` Andre Przywara
2017-01-05 17:52       ` Stefano Stabellini
2016-12-22 18:24 ` [RFC PATCH v2 03/26] ARM: GICv3 ITS: allocate device and collection table Andre Przywara
2017-01-04 21:47   ` Stefano Stabellini [this message]
2017-01-05 17:56     ` Andre Przywara
2017-01-20 11:12     ` Julien Grall
2017-01-20 11:27       ` Andre Przywara
2017-01-20 12:18         ` Julien Grall
2017-01-20 16:05           ` Andre Przywara
2017-01-20 18:14             ` Julien Grall
2016-12-22 18:24 ` [RFC PATCH v2 04/26] ARM: GICv3 ITS: map ITS command buffer Andre Przywara
2017-01-04 21:53   ` Stefano Stabellini
2016-12-22 18:24 ` [RFC PATCH v2 05/26] ARM: GICv3 ITS: introduce ITS command handling Andre Przywara
2017-01-04 22:08   ` Stefano Stabellini
2016-12-22 18:24 ` [RFC PATCH v2 06/26] ARM: GICv3 ITS: introduce device mapping Andre Przywara
2017-01-05  0:13   ` Stefano Stabellini
2017-01-13 12:31     ` Andre Przywara
2017-01-13 19:22       ` Stefano Stabellini
2017-01-13 12:31     ` Andre Przywara
2016-12-22 18:24 ` [RFC PATCH v2 07/26] ARM: GICv3 ITS: introduce host LPI array Andre Przywara
2017-01-05 18:56   ` Stefano Stabellini
2017-01-06 17:59     ` Andre Przywara
2017-01-06 20:20       ` Stefano Stabellini
2017-01-20 12:00         ` Julien Grall
2017-01-20 22:58           ` Stefano Stabellini
2016-12-22 18:24 ` [RFC PATCH v2 08/26] ARM: GICv3 ITS: map device and LPIs to the ITS on physdev_op hypercall Andre Przywara
2017-01-05 21:23   ` Stefano Stabellini
2016-12-22 18:24 ` [RFC PATCH v2 09/26] ARM: GICv3: introduce separate pending_irq structs for LPIs Andre Przywara
2017-01-05 21:36   ` Stefano Stabellini
2017-01-12 18:24     ` Andre Przywara
2017-01-12 19:15       ` Stefano Stabellini
2017-01-12 19:28         ` Andre Przywara
2016-12-22 18:24 ` [RFC PATCH v2 10/26] ARM: GICv3: forward pending LPIs to guests Andre Przywara
2017-01-05 22:10   ` Stefano Stabellini
2017-01-12 12:16     ` Andre Przywara
2017-01-12 18:57       ` Stefano Stabellini
2016-12-22 18:24 ` [RFC PATCH v2 11/26] ARM: GICv3: enable ITS and LPIs on the host Andre Przywara
2016-12-22 18:24 ` [RFC PATCH v2 12/26] ARM: vGICv3: handle virtual LPI pending and property tables Andre Przywara
2017-01-05 22:17   ` Stefano Stabellini
2016-12-22 18:24 ` [RFC PATCH v2 13/26] ARM: vGICv3: Handle disabled LPIs Andre Przywara
2017-01-05 22:28   ` [RFC PATCH v2 13/26] ARM: vGICv3: Handle disabled LPIso Stefano Stabellini
2016-12-22 18:24 ` [RFC PATCH v2 14/26] ARM: vGICv3: introduce basic ITS emulation bits Andre Przywara
2017-02-15  0:02   ` Stefano Stabellini
2016-12-22 18:24 ` [RFC PATCH v2 15/26] ARM: vITS: handle CLEAR command Andre Przywara
2016-12-22 18:24 ` [RFC PATCH v2 16/26] ARM: vITS: handle INT command Andre Przywara
2016-12-22 18:24 ` [RFC PATCH v2 17/26] ARM: vITS: handle MAPC command Andre Przywara
2016-12-22 18:24 ` [RFC PATCH v2 18/26] ARM: vITS: handle MAPD command Andre Przywara
2016-12-22 18:24 ` [RFC PATCH v2 19/26] ARM: vITS: handle MAPTI command Andre Przywara
2016-12-22 18:24 ` [RFC PATCH v2 20/26] ARM: vITS: handle MOVI command Andre Przywara
2016-12-22 18:24 ` [RFC PATCH v2 21/26] ARM: vITS: handle DISCARD command Andre Przywara
2016-12-22 18:24 ` [RFC PATCH v2 22/26] ARM: vITS: handle INV command Andre Przywara
2016-12-22 18:24 ` [RFC PATCH v2 23/26] ARM: vITS: handle INVALL command Andre Przywara
2017-01-05 22:50   ` Stefano Stabellini
2016-12-22 18:24 ` [RFC PATCH v2 24/26] ARM: vITS: create and initialize virtual ITSes for Dom0 Andre Przywara
2016-12-22 18:24 ` [RFC PATCH v2 25/26] ARM: vITS: create ITS subnodes for Dom0 DT Andre Przywara
2016-12-22 18:24 ` [RFC PATCH v2 26/26] ARM: vGIC: advertising LPI support Andre Przywara
2017-01-18  8:13 ` [RFC PATCH v2 00/26] arm64: Dom0 ITS emulation Vijay Kilari
2017-01-18  9:55   ` Julien Grall
2017-01-19 12:26 ` Vijay Kilari
2017-01-19 13:50   ` Andre Przywara
2017-01-19 14:32     ` Julien Grall
2017-01-19 14:45       ` Andre Przywara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.DEB.2.10.1701041313540.17742@sstabellini-ThinkPad-X260 \
    --to=sstabellini@kernel.org \
    --cc=andre.przywara@arm.com \
    --cc=julien.grall@arm.com \
    --cc=vijay.kilari@gmail.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.