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 06/26] ARM: GICv3 ITS: introduce device mapping
Date: Wed, 4 Jan 2017 16:13:01 -0800 (PST)	[thread overview]
Message-ID: <alpine.DEB.2.10.1701041436220.16169@sstabellini-ThinkPad-X260> (raw)
In-Reply-To: <20161222182446.18791-7-andre.przywara@arm.com>

On Thu, 22 Dec 2016, Andre Przywara wrote:
> The ITS uses device IDs to map LPIs to a device. Dom0 will later use
> those IDs, which we directly pass on to the host.
> For this we have to map each device that Dom0 may request to a host
> ITS device with the same identifier.
> Allocate the respective memory and enter each device into a list to
> later be able to iterate over it or to easily teardown guests.
> 
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> ---
>  xen/arch/arm/gic-its.c        | 118 ++++++++++++++++++++++++++++++++++++++++++
>  xen/arch/arm/vgic.c           |   3 ++
>  xen/include/asm-arm/domain.h  |   2 +
>  xen/include/asm-arm/gic-its.h |  22 ++++++++
>  4 files changed, 145 insertions(+)
> 
> diff --git a/xen/arch/arm/gic-its.c b/xen/arch/arm/gic-its.c
> index d0f5fd1..e157c6b 100644
> --- a/xen/arch/arm/gic-its.c
> +++ b/xen/arch/arm/gic-its.c
> @@ -21,6 +21,7 @@
>  #include <xen/err.h>
>  #include <xen/device_tree.h>
>  #include <xen/libfdt/libfdt.h>
> +#include <xen/sched.h>
>  #include <xen/sizes.h>
>  #include <asm/p2m.h>
>  #include <asm/io.h>
> @@ -108,6 +109,21 @@ static int its_send_cmd_mapc(struct host_its *its, int collection_id, int cpu)
>      return its_send_command(its, cmd);
>  }
>  
> +static int its_send_cmd_mapd(struct host_its *its, uint32_t deviceid,
> +                             int size, uint64_t itt_addr, bool valid)
> +{
> +    uint64_t cmd[4];
> +
> +    cmd[0] = GITS_CMD_MAPD | ((uint64_t)deviceid << 32);
> +    cmd[1] = size & GENMASK(4, 0);
> +    cmd[2] = itt_addr & GENMASK(51, 8);
> +    if ( valid )
> +        cmd[2] |= BIT_ULL(63);
> +    cmd[3] = 0x00;
> +
> +    return its_send_command(its, cmd);
> +}
> +
>  /* Set up the (1:1) collection mapping for the given host CPU. */
>  void gicv3_its_setup_collection(int cpu)
>  {
> @@ -237,6 +253,7 @@ int gicv3_its_init(struct host_its *hw_its)
>  
>      reg = readq_relaxed(hw_its->its_base + GITS_TYPER);
>      hw_its->pta = !!(reg & GITS_TYPER_PTA);
> +    hw_its->itte_size = ((reg >> 4) & 0xf) + 1;

Please #define all numbers


>      for ( i = 0; i < GITS_BASER_NR_REGS; i++ )
>      {
> @@ -358,6 +375,107 @@ int gicv3_lpi_init_host_lpis(unsigned int hw_lpi_bits)
>      return 0;
>  }
>  
> +static void remove_mapped_guest_device(struct its_devices *dev)
> +{
> +    if ( dev->hw_its )
> +        its_send_cmd_mapd(dev->hw_its, dev->host_devid, 0, 0, false);
> +
> +    xfree(dev->itt_addr);
> +    xfree(dev);
> +}
> +
> +int gicv3_its_map_device(struct domain *d, int host_devid, int guest_devid,
> +                         int bits, bool valid)
> +{
> +    void *itt_addr = NULL;
> +    struct its_devices *dev, *temp;
> +    struct host_its *hw_its;
> +    int ret;
> +
> +    /* check for already existing mappings */
> +    spin_lock(&d->arch.vgic.its_devices_lock);
> +    list_for_each_entry_safe(dev, temp, &d->arch.vgic.its_devices, entry)
> +    {
> +        if ( dev->guest_devid != guest_devid )
> +            continue;
> +
> +        if ( !valid )
> +            list_del(&dev->entry);
> +
> +        spin_unlock(&d->arch.vgic.its_devices_lock);
> +
> +        if ( valid )
> +            return -EBUSY;
> +
> +        remove_mapped_guest_device(dev);
> +
> +        return 0;
> +    }
> +    spin_unlock(&d->arch.vgic.its_devices_lock);

Compared to the previous version, now the list is per-domain, which is
better for DomUs, but not for Dom0. In the case of Dom0 the number of
iterations will be the same.

I suggest we move to a different data structure, such as an hashtable or
an rbtree. If devids were guaranteed to be dense, then we could store
struct its_devices pointers in an array and direct access them, but I
don't think they are?

If devids are sparse, using a per-domain structure could be a good idea,
but we still need to prevent a device from being assigned to two domains
simultaneously. Is there a check to avoid that?


> +    if ( !valid )
> +        return -ENOENT;
> +
> +    /* TODO: Work out the correct hardware ITS to use here.
> +     * Maybe a per-platform function: devid -> ITS?
> +     * Or parsing the DT to find the msi_parent?
> +     * Or get Dom0 to give us this information?
> +     * For now just use the first ITS.
> +     */
> +    hw_its = list_first_entry(&host_its_list, struct host_its, entry);
> +
> +    itt_addr = _xmalloc(BIT(bits) * hw_its->itte_size, 256);
> +    if ( !itt_addr )
> +        return -ENOMEM;
> +
> +    dev = xmalloc(struct its_devices);
> +    if ( !dev )
> +    {
> +        xfree(itt_addr);
> +        return -ENOMEM;
> +    }
> +
> +    ret = its_send_cmd_mapd(hw_its, host_devid, bits - 1,
> +                            virt_to_maddr(itt_addr), true);
> +    if (ret) {
> +        xfree(itt_addr);
> +        xfree(dev);
> +        return ret;
> +    }
> +
> +    dev->itt_addr = itt_addr;
> +    dev->hw_its = hw_its;
> +    dev->guest_devid = guest_devid;
> +    dev->host_devid = host_devid;
> +    dev->eventids = BIT(bits);
> +
> +    spin_lock(&d->arch.vgic.its_devices_lock);
> +    list_add_tail(&dev->entry, &d->arch.vgic.its_devices);
> +    spin_unlock(&d->arch.vgic.its_devices_lock);
> +
> +    return 0;
> +}
> +
> +/* Removing any connections a domain had to any ITS in the system. */
> +int its_remove_domain(struct domain *d)
> +{
> +    struct its_devices *dev, *temp;
> +
> +retry:
> +
> +    spin_lock(&d->arch.vgic.its_devices_lock);
> +    list_for_each_entry_safe(dev, temp, &d->arch.vgic.its_devices, entry)
> +    {
> +        list_del(&dev->entry);
> +        spin_unlock(&d->arch.vgic.its_devices_lock);
> +
> +        remove_mapped_guest_device(dev);
> +        goto retry;
> +    }
> +
> +    return 0;
> +}
> +
>  /* Scan the DT for any ITS nodes and create a list of host ITSes out of it. */
>  void gicv3_its_dt_init(const struct dt_device_node *node)
>  {
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index 364d5f0..de77aaa 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -156,6 +156,9 @@ int domain_vgic_init(struct domain *d, unsigned int nr_spis)
>      for ( i = 0; i < NR_GIC_SGI; i++ )
>          set_bit(i, d->arch.vgic.allocated_irqs);
>  
> +    spin_lock_init(&d->arch.vgic.its_devices_lock);
> +    INIT_LIST_HEAD(&d->arch.vgic.its_devices);
> +
>      return 0;
>  }
>  
> diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
> index 2d6fbb1..8ccc32a 100644
> --- a/xen/include/asm-arm/domain.h
> +++ b/xen/include/asm-arm/domain.h
> @@ -109,6 +109,8 @@ struct arch_domain
>          } *rdist_regions;
>          int nr_regions;                     /* Number of rdist regions */
>          uint32_t rdist_stride;              /* Re-Distributor stride */
> +        struct list_head its_devices;       /* devices mapped to an ITS */
> +        spinlock_t its_devices_lock;        /* protects the its_devices list */
>  #endif
>      } vgic;
>  
> diff --git a/xen/include/asm-arm/gic-its.h b/xen/include/asm-arm/gic-its.h
> index 68e5f63..525a29d 100644
> --- a/xen/include/asm-arm/gic-its.h
> +++ b/xen/include/asm-arm/gic-its.h
> @@ -93,9 +93,19 @@ struct host_its {
>      void __iomem *its_base;
>      spinlock_t cmd_lock;
>      void *cmd_buf;
> +    int itte_size;
>      bool pta;
>  };
>  
> +struct its_devices {
> +    struct list_head entry;
> +    struct host_its *hw_its;
> +    void *itt_addr;
> +    uint32_t guest_devid;
> +    uint32_t host_devid;
> +    uint32_t eventids;
> +};
> +
>  extern struct list_head host_its_list;
>  
>  #ifdef CONFIG_HAS_ITS
> @@ -119,6 +129,13 @@ void gicv3_set_redist_addr(paddr_t address, int redist_id);
>  /* Map a collection for this host CPU to each host ITS. */
>  void gicv3_its_setup_collection(int cpu);
>  
> +/* Map a device on the host by allocating an ITT on the host (ITS).
> + * "bits" specifies how many events (interrupts) this device will need.
> + * Setting "valid" to false deallocates the device.
> + */
> +int gicv3_its_map_device(struct domain *d, int host_devid, int guest_devid,
> +                         int bits, bool valid);
> +
>  #else
>  
>  static inline void gicv3_its_dt_init(const struct dt_device_node *node)
> @@ -146,6 +163,11 @@ static inline void gicv3_set_redist_addr(paddr_t address, int redist_id)
>  static inline void gicv3_its_setup_collection(int cpu)
>  {
>  }
> +static inline int gicv3_its_map_device(struct domain *d, int host_devid,
> +                         int guest_devid, int bits, bool valid)
> +{
> +    return -ENODEV;
> +}
>  
>  #endif /* CONFIG_HAS_ITS */
>  
> -- 
> 2.9.0
> 

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

  reply	other threads:[~2017-01-05  0:13 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
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 [this message]
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.1701041436220.16169@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.