All of lore.kernel.org
 help / color / mirror / Atom feed
From: Julien Grall <julien.grall@arm.com>
To: Andre Przywara <andre.przywara@arm.com>,
	Stefano Stabellini <sstabellini@kernel.org>
Cc: xen-devel@lists.xenproject.org,
	Shanker Donthineni <shankerd@codeaurora.org>,
	Vijay Kilari <vijay.kilari@gmail.com>
Subject: Re: [PATCH v5 18/30] ARM: vITS: introduce translation table walks
Date: Thu, 6 Apr 2017 23:41:37 +0100	[thread overview]
Message-ID: <1ff2cbdb-757e-2bbe-2f71-4c3970cfffd5@arm.com> (raw)
In-Reply-To: <1491434362-30310-19-git-send-email-andre.przywara@arm.com>

Hi Andre,

On 04/06/2017 12:19 AM, Andre Przywara wrote:
> The ITS stores the target (v)CPU and the (virtual) LPI number in tables.
> Introduce functions to walk those tables and translate an device ID -
> event ID pair into a pair of virtual LPI and vCPU.
> We map those tables on demand - which is cheap on arm64. Also we take
> care of the locking on the way, since we can't easily protect those ITTs
> from being altered by the guest.
>
> To allow compiling without warnings, we declare two functions as
> non-static for the moment, which two later patches will fix.
>
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> ---
>  xen/arch/arm/gic.c         |   2 +
>  xen/arch/arm/vgic-v3-its.c | 179 +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 181 insertions(+)
>
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index a56be34..5000b0d 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -491,6 +491,8 @@ static void gic_update_one_lr(struct vcpu *v, int i)
>      {
>          gic_hw_ops->clear_lr(i);
>          clear_bit(i, &this_cpu(lr_mask));
> +        if ( is_lpi(irq) )
> +            clear_bit(GIC_IRQ_GUEST_LPI_PENDING, &p->status);

I am struggling to understand why this change is introduced in this 
patch. This does not look related to the translation table.

>
>          if ( p->desc != NULL )
>              clear_bit(_IRQ_INPROGRESS, &p->desc->status);
> diff --git a/xen/arch/arm/vgic-v3-its.c b/xen/arch/arm/vgic-v3-its.c
> index f6bf1ee..a145666 100644
> --- a/xen/arch/arm/vgic-v3-its.c
> +++ b/xen/arch/arm/vgic-v3-its.c
> @@ -67,6 +67,8 @@ struct vits_itte
>      uint16_t pad;
>  };
>
> +#define UNMAPPED_COLLECTION      ((uint16_t)~0)
> +
>  void vgic_v3_its_init_domain(struct domain *d)
>  {
>      spin_lock_init(&d->arch.vgic.its_devices_lock);
> @@ -78,6 +80,183 @@ void vgic_v3_its_free_domain(struct domain *d)
>      ASSERT(RB_EMPTY_ROOT(&d->arch.vgic.its_devices));
>  }
>
> +/*
> + * The physical address is encoded slightly differently depending on
> + * the used page size: the highest four bits are stored in the lowest
> + * four bits of the field for 64K pages.
> + */
> +static paddr_t get_baser_phys_addr(uint64_t reg)
> +{
> +    if ( reg & BIT(9) )
> +        return (reg & GENMASK_ULL(47, 16)) |
> +                ((reg & GENMASK_ULL(15, 12)) << 36);
> +    else
> +        return reg & GENMASK_ULL(47, 12);
> +}
> +
> +/* Must be called with the ITS lock held. */
> +static struct vcpu *get_vcpu_from_collection(struct virt_its *its,
> +                                             uint16_t collid)
> +{
> +    paddr_t addr = get_baser_phys_addr(its->baser_coll);
> +    uint16_t vcpu_id;
> +    int ret;
> +
> +    ASSERT(spin_is_locked(&its->its_lock));
> +
> +    if ( collid >= its->max_collections )
> +        return NULL;
> +
> +    ret = vgic_access_guest_memory(its->d, addr + collid * sizeof(uint16_t),
> +                                   &vcpu_id, sizeof(vcpu_id), false);
> +    if ( ret )
> +        return NULL;
> +
> +    if ( vcpu_id == UNMAPPED_COLLECTION || vcpu_id >= its->d->max_vcpus )
> +        return NULL;
> +
> +    return its->d->vcpu[vcpu_id];
> +}
> +
> +/*
> + * Our device table encodings:
> + * Contains the guest physical address of the Interrupt Translation Table in
> + * bits [51:8], and the size of it is encoded as the number of bits minus one
> + * in the lowest 8 bits of the word.
> + */
> +#define DEV_TABLE_ITT_ADDR(x) ((x) & GENMASK_ULL(51, 8))
> +#define DEV_TABLE_ITT_SIZE(x) (BIT(((x) & GENMASK_ULL(7, 0)) + 1))
> +#define DEV_TABLE_ENTRY(addr, bits)                     \
> +        (((addr) & GENMASK_ULL(51, 8)) | (((bits) - 1) & GENMASK_ULL(7, 0)))
> +
> +/*
> + * Lookup the address of the Interrupt Translation Table associated with
> + * a device ID and return the address of the ITTE belonging to the event ID
> + * (which is an index into that table).

You likely want a TODO support two-level table here.

> + */
> +static paddr_t its_get_itte_address(struct virt_its *its,
> +                                    uint32_t devid, uint32_t evid)
> +{
> +    paddr_t addr = get_baser_phys_addr(its->baser_dev);
> +    uint64_t itt;
> +
> +    if ( devid >= its->max_devices )
> +        return INVALID_PADDR;
> +
> +    if ( vgic_access_guest_memory(its->d, addr + devid * sizeof(uint64_t),
> +                                  &itt, sizeof(itt), false) )
> +        return INVALID_PADDR;
> +
> +    if ( evid >= DEV_TABLE_ITT_SIZE(itt) ||
> +         DEV_TABLE_ITT_ADDR(itt) == INVALID_PADDR )
> +        return INVALID_PADDR;
> +
> +    return DEV_TABLE_ITT_ADDR(itt) + evid * sizeof(struct vits_itte);
> +}
> +
> +/*
> + * Queries the collection and device tables to get the vCPU and virtual
> + * LPI number for a given guest event. This first accesses the guest memory
> + * to resolve the address of the ITTE, then reads the ITTE entry at this
> + * address and puts the result in vcpu_ptr and vlpi_ptr.
> + * Requires the ITS lock to be held.
> + */
> +static bool read_itte_locked(struct virt_its *its, uint32_t devid,
> +                             uint32_t evid, struct vcpu **vcpu_ptr,
> +                             uint32_t *vlpi_ptr)
> +{
> +    paddr_t addr;
> +    struct vits_itte itte;
> +    struct vcpu *vcpu;
> +
> +    ASSERT(spin_is_locked(&its->its_lock));
> +
> +    addr = its_get_itte_address(its, devid, evid);
> +    if ( addr == INVALID_PADDR )
> +        return false;
> +
> +    if ( vgic_access_guest_memory(its->d, addr, &itte, sizeof(itte), false) )
> +        return false;
> +
> +    vcpu = get_vcpu_from_collection(its, itte.collection);
> +    if ( !vcpu )
> +        return false;
> +
> +    *vcpu_ptr = vcpu;
> +    *vlpi_ptr = itte.vlpi;
> +    return true;
> +}
> +
> +/*
> + * This function takes care of the locking by taking the its_lock itself, so
> + * a caller shall not hold this. Before returning, the lock is dropped again.
> + */
> +bool read_itte(struct virt_its *its, uint32_t devid, uint32_t evid,
> +               struct vcpu **vcpu_ptr, uint32_t *vlpi_ptr)
> +{
> +    bool ret;
> +
> +    spin_lock(&its->its_lock);
> +    ret = read_itte_locked(its, devid, evid, vcpu_ptr, vlpi_ptr);
> +    spin_unlock(&its->its_lock);
> +
> +    return ret;
> +}
> +
> +/*
> + * Queries the collection and device tables to translate the device ID and
> + * event ID and find the appropriate ITTE. The given collection ID and the
> + * virtual LPI number are then stored into that entry.
> + * If vcpu_ptr is provided, returns the VCPU belonging to that collection.
> + * Requires the ITS lock to be held.
> + */
> +static bool write_itte_locked(struct virt_its *its, uint32_t devid,
> +                              uint32_t evid, uint32_t collid, uint32_t vlpi,
> +                              struct vcpu **vcpu_ptr)
> +{
> +    paddr_t addr;
> +    struct vits_itte itte;
> +
> +    ASSERT(spin_is_locked(&its->its_lock));
> +
> +    if ( collid >= its->max_collections )
> +        return false;
> +
> +    if ( vlpi >= its->d->arch.vgic.nr_lpis )
> +        return false;
> +
> +    addr = its_get_itte_address(its, devid, evid);
> +    if ( addr == INVALID_PADDR )
> +        return false;
> +
> +    itte.collection = collid;
> +    itte.vlpi = vlpi;
> +
> +    if ( vgic_access_guest_memory(its->d, addr, &itte, sizeof(itte), true) )
> +        return false;
> +
> +    if ( vcpu_ptr )
> +        *vcpu_ptr = get_vcpu_from_collection(its, collid);
> +
> +    return true;
> +}
> +
> +/*
> + * This function takes care of the locking by taking the its_lock itself, so
> + * a caller shall not hold this. Before returning, the lock is dropped again.
> + */
> +bool write_itte(struct virt_its *its, uint32_t devid, uint32_t evid,
> +                uint32_t collid, uint32_t vlpi, struct vcpu **vcpu_ptr)
> +{
> +    bool ret;
> +
> +    spin_lock(&its->its_lock);
> +    ret = write_itte_locked(its, devid, evid, collid, vlpi, vcpu_ptr);
> +    spin_unlock(&its->its_lock);
> +
> +    return ret;
> +}
> +
>  /**************************************
>   * Functions that handle ITS commands *
>   **************************************/
>

-- 
Julien Grall

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

  reply	other threads:[~2017-04-06 22:41 UTC|newest]

Thread overview: 122+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-05 23:18 [PATCH v5 00/30] arm64: Dom0 ITS emulation Andre Przywara
2017-04-05 23:18 ` [PATCH v5 01/30] bitops: add GENMASK_ULL Andre Przywara
2017-04-05 23:25   ` Stefano Stabellini
2017-04-06  8:45     ` Julien Grall
2017-04-06  9:15       ` Jan Beulich
2017-04-06  9:55         ` Andre Przywara
2017-04-05 23:18 ` [PATCH v5 02/30] bitops: add BIT_ULL variant Andre Przywara
2017-04-05 23:26   ` Stefano Stabellini
2017-04-05 23:18 ` [PATCH v5 03/30] ARM: GICv3 ITS: parse and store ITS subnodes from hardware DT Andre Przywara
2017-04-05 23:26   ` Stefano Stabellini
2017-04-06 12:39     ` Julien Grall
2017-04-06 14:56       ` Andre Przywara
2017-04-06 15:02         ` Julien Grall
2017-04-06 18:55     ` Andre Przywara
2017-04-05 23:18 ` [PATCH v5 04/30] ARM: GICv3 ITS: initialize host ITS Andre Przywara
2017-04-05 23:27   ` Stefano Stabellini
2017-04-06 12:41   ` Julien Grall
2017-04-05 23:18 ` [PATCH v5 05/30] ARM: GICv3: allocate LPI pending and property table Andre Przywara
2017-04-05 23:30   ` Stefano Stabellini
2017-04-06 12:58   ` Julien Grall
2017-04-06 14:37     ` Andre Przywara
2017-04-06 14:37       ` Julien Grall
2017-04-05 23:18 ` [PATCH v5 06/30] ARM: GICv3 ITS: allocate device and collection table Andre Przywara
2017-04-06 14:44   ` Julien Grall
2017-04-06 15:49     ` Andre Przywara
2017-04-06 22:19   ` Julien Grall
2017-04-06 22:25     ` André Przywara
2017-04-05 23:18 ` [PATCH v5 07/30] ARM: GICv3 ITS: map ITS command buffer Andre Przywara
2017-04-06 14:49   ` Julien Grall
2017-04-05 23:19 ` [PATCH v5 08/30] ARM: GICv3 ITS: introduce ITS command handling Andre Przywara
2017-04-05 23:33   ` Stefano Stabellini
2017-04-06 14:55   ` Julien Grall
2017-04-05 23:19 ` [PATCH v5 09/30] ARM: GICv3 ITS: introduce host LPI array Andre Przywara
2017-04-05 23:37   ` Stefano Stabellini
2017-04-06 10:31     ` Andre Przywara
2017-04-06 11:18       ` Julien Grall
2017-04-05 23:19 ` [PATCH v5 10/30] ARM: vGICv3: introduce ITS emulation stub Andre Przywara
2017-04-06 15:17   ` Julien Grall
2017-04-07 14:31   ` Julien Grall
2017-04-05 23:19 ` [PATCH v5 11/30] ARM: GICv3 ITS: introduce device mapping Andre Przywara
2017-04-05 23:41   ` Stefano Stabellini
2017-04-06 11:15     ` Julien Grall
2017-04-06 16:42       ` Stefano Stabellini
2017-04-06 17:12         ` Julien Grall
2017-04-06 15:34   ` Julien Grall
2017-04-06 16:10     ` Andre Przywara
2017-04-06 18:00       ` Julien Grall
2017-04-07 14:46   ` Julien Grall
2017-04-05 23:19 ` [PATCH v5 12/30] ARM: GICv3: introduce separate pending_irq structs for LPIs Andre Przywara
2017-04-06 15:59   ` Julien Grall
2017-04-05 23:19 ` [PATCH v5 13/30] ARM: GICv3: forward pending LPIs to guests Andre Przywara
2017-04-05 23:45   ` Stefano Stabellini
2017-04-06 17:42     ` Andre Przywara
2017-04-06 18:47       ` Stefano Stabellini
2017-04-06 19:13         ` Julien Grall
2017-04-06 19:47           ` Stefano Stabellini
2017-04-06 19:54             ` Julien Grall
2017-04-06 20:29               ` Stefano Stabellini
2017-04-06 18:10   ` Julien Grall
2017-04-05 23:19 ` [PATCH v5 14/30] ARM: GICv3: enable ITS and LPIs on the host Andre Przywara
2017-04-05 23:19 ` [PATCH v5 15/30] ARM: vGICv3: handle virtual LPI pending and property tables Andre Przywara
2017-04-05 23:55   ` Stefano Stabellini
2017-04-06 11:21     ` Julien Grall
2017-04-06 11:25     ` Andre Przywara
2017-04-06 11:24       ` Julien Grall
2017-04-06 11:28         ` Andre Przywara
2017-04-06 20:33   ` Julien Grall
2017-04-05 23:19 ` [PATCH v5 16/30] ARM: vGICv3: handle disabled LPIs Andre Przywara
2017-04-05 23:58   ` Stefano Stabellini
2017-04-06 19:09     ` Andre Przywara
2017-04-06 20:43       ` Stefano Stabellini
2017-04-06 21:20   ` Julien Grall
2017-04-05 23:19 ` [PATCH v5 17/30] ARM: vITS: add command handling stub and MMIO emulation Andre Przywara
2017-04-06  0:21   ` Stefano Stabellini
2017-04-06  8:55     ` Andre Przywara
2017-04-06 21:43   ` Julien Grall
2017-04-06 22:22     ` André Przywara
2017-04-06 22:34       ` Julien Grall
2017-04-06 22:25   ` Julien Grall
2017-04-06 22:39   ` Julien Grall
2017-04-05 23:19 ` [PATCH v5 18/30] ARM: vITS: introduce translation table walks Andre Przywara
2017-04-06 22:41   ` Julien Grall [this message]
2017-04-05 23:19 ` [PATCH v5 19/30] ARM: vITS: handle CLEAR command Andre Przywara
2017-04-06  0:31   ` Stefano Stabellini
2017-04-05 23:19 ` [PATCH v5 20/30] ARM: vITS: handle INT command Andre Przywara
2017-04-05 23:19 ` [PATCH v5 21/30] ARM: vITS: handle MAPC command Andre Przywara
2017-04-05 23:19 ` [PATCH v5 22/30] ARM: vITS: handle MAPD command Andre Przywara
2017-04-06  0:39   ` Stefano Stabellini
2017-04-07 12:41   ` Julien Grall
2017-04-05 23:19 ` [PATCH v5 23/30] ARM: vITS: handle MAPTI command Andre Przywara
2017-04-06  0:45   ` Stefano Stabellini
2017-04-11 16:15     ` Andre Przywara
2017-04-07 12:53   ` Julien Grall
2017-04-07 13:07   ` Julien Grall
2017-04-07 13:12     ` Andre Przywara
2017-04-05 23:19 ` [PATCH v5 24/30] ARM: vITS: handle MOVI command Andre Przywara
2017-04-06  0:47   ` Stefano Stabellini
2017-04-06 10:07     ` Andre Przywara
2017-04-06 17:56       ` Stefano Stabellini
2017-04-07 12:55   ` Julien Grall
2017-04-05 23:19 ` [PATCH v5 25/30] ARM: vITS: handle DISCARD command Andre Przywara
2017-04-06  0:48   ` Stefano Stabellini
2017-04-07 13:03   ` Julien Grall
2017-04-05 23:19 ` [PATCH v5 26/30] ARM: vITS: handle INV command Andre Przywara
2017-04-06  0:56   ` Stefano Stabellini
2017-04-07 13:23   ` Julien Grall
2017-04-05 23:19 ` [PATCH v5 27/30] ARM: vITS: handle INVALL command Andre Przywara
2017-04-05 23:19 ` [PATCH v5 28/30] ARM: vITS: create and initialize virtual ITSes for Dom0 Andre Przywara
2017-04-07 13:38   ` Julien Grall
2017-04-05 23:19 ` [PATCH v5 29/30] ARM: vITS: create ITS subnodes for Dom0 DT Andre Przywara
2017-04-07 13:41   ` Julien Grall
2017-04-07 13:46     ` Andre Przywara
2017-04-07 13:45       ` Julien Grall
2017-04-07 13:47         ` Julien Grall
2017-04-07 13:49           ` Andre Przywara
2017-04-05 23:19 ` [PATCH v5 30/30] ARM: vGIC: advertise LPI support Andre Przywara
2017-04-06  1:04   ` Stefano Stabellini
2017-04-06 10:21     ` Andre Przywara
2017-04-06 11:42       ` Julien Grall
2017-04-06 22:54         ` André Przywara
2017-04-07 13:43   ` Julien Grall
2017-04-06 12:31 ` [PATCH v5 00/30] arm64: Dom0 ITS emulation Julien Grall

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=1ff2cbdb-757e-2bbe-2f71-4c3970cfffd5@arm.com \
    --to=julien.grall@arm.com \
    --cc=andre.przywara@arm.com \
    --cc=shankerd@codeaurora.org \
    --cc=sstabellini@kernel.org \
    --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.