xen-devel.lists.xenproject.org archive mirror
 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,
	Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com>,
	Vijay Kilari <vijay.kilari@gmail.com>,
	Shanker Donthineni <shankerd@codeaurora.org>
Subject: Re: [PATCH v9 03/28] ARM: GIC: Add checks for NULL pointer pending_irq's
Date: Fri, 12 May 2017 15:19:22 +0100	[thread overview]
Message-ID: <dcb34f96-31b2-3b14-ea2e-43f58c58ccd4@arm.com> (raw)
In-Reply-To: <20170511175340.8448-4-andre.przywara@arm.com>

Hi Andre,

On 11/05/17 18:53, Andre Przywara wrote:
> For LPIs the struct pending_irq's are dynamically allocated and the
> pointers will be stored in a radix tree. Since an LPI can be "unmapped"
> at any time, teach the VGIC how to deal with irq_to_pending() returning
> a NULL pointer.
> We just do nothing in this case or clean up the LR if the virtual LPI
> number was still in an LR.
>
> Those are all call sites for irq_to_pending(), as per:
> "git grep irq_to_pending", and their evaluations:
> (PROTECTED means: added NULL check and bailing out)
>
>     xen/arch/arm/gic.c:
> gic_route_irq_to_guest(): only called for SPIs, added ASSERT()
> gic_remove_irq_from_guest(): only called for SPIs, added ASSERT()
> gic_remove_from_queues(): PROTECTED, called within VCPU VGIC lock
> gic_raise_inflight_irq(): PROTECTED, called under VCPU VGIC lock
> gic_raise_guest_irq(): PROTECTED, called under VCPU VGIC lock
> gic_update_one_lr(): PROTECTED, called under VCPU VGIC lock

Even they are protected, an ASSERT would be useful.

>
>     xen/arch/arm/vgic.c:
> vgic_migrate_irq(): not called for LPIs (virtual IRQs), added ASSERT()
> arch_move_irqs(): not iterating over LPIs, added ASSERT()
> vgic_disable_irqs(): not called for LPIs, added ASSERT()
> vgic_enable_irqs(): not called for LPIs, added ASSERT()
> vgic_vcpu_inject_irq(): PROTECTED, moved under VCPU VGIC lock
>
>     xen/include/asm-arm/event.h:
> local_events_need_delivery_nomask(): only called for a PPI, added ASSERT()
>
>     xen/include/asm-arm/vgic.h:
> (prototype)
>
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> ---
>  xen/arch/arm/gic.c          | 34 ++++++++++++++++++++++++++++++----
>  xen/arch/arm/vgic.c         | 24 ++++++++++++++++++++++++
>  xen/include/asm-arm/event.h |  3 +++
>  3 files changed, 57 insertions(+), 4 deletions(-)
>
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index dcb1783..46bb306 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -148,6 +148,7 @@ int gic_route_irq_to_guest(struct domain *d, unsigned int virq,
>      /* Caller has already checked that the IRQ is an SPI */
>      ASSERT(virq >= 32);
>      ASSERT(virq < vgic_num_irqs(d));
> +    ASSERT(!is_lpi(virq));
>
>      vgic_lock_rank(v_target, rank, flags);
>
> @@ -184,6 +185,7 @@ int gic_remove_irq_from_guest(struct domain *d, unsigned int virq,
>      ASSERT(spin_is_locked(&desc->lock));
>      ASSERT(test_bit(_IRQ_GUEST, &desc->status));
>      ASSERT(p->desc == desc);
> +    ASSERT(!is_lpi(virq));
>
>      vgic_lock_rank(v_target, rank, flags);
>
> @@ -408,9 +410,13 @@ void gic_remove_from_queues(struct vcpu *v, unsigned int virtual_irq)
>      spin_lock_irqsave(&v->arch.vgic.lock, flags);
>
>      p = irq_to_pending(v, virtual_irq);
> -
> -    if ( !list_empty(&p->lr_queue) )
> +    /*
> +     * If an LPIs has been removed meanwhile, it has been cleaned up
> +     * already, so nothing to remove here.
> +     */
> +    if ( likely(p) && !list_empty(&p->lr_queue) )
>          list_del_init(&p->lr_queue);
> +
>      spin_unlock_irqrestore(&v->arch.vgic.lock, flags);
>  }
>
> @@ -418,6 +424,10 @@ void gic_raise_inflight_irq(struct vcpu *v, unsigned int virtual_irq)
>  {
>      struct pending_irq *n = irq_to_pending(v, virtual_irq);
>
> +    /* If an LPI has been removed meanwhile, there is nothing left to raise. */
> +    if ( unlikely(!n) )
> +        return;
> +
>      ASSERT(spin_is_locked(&v->arch.vgic.lock));
>
>      if ( list_empty(&n->lr_queue) )
> @@ -437,20 +447,25 @@ void gic_raise_guest_irq(struct vcpu *v, unsigned int virtual_irq,
>  {
>      int i;
>      unsigned int nr_lrs = gic_hw_ops->info->nr_lrs;
> +    struct pending_irq *p = irq_to_pending(v, virtual_irq);
>
>      ASSERT(spin_is_locked(&v->arch.vgic.lock));
>
> +    if ( unlikely(!p) )
> +        /* An unmapped LPI does not need to be raised. */
> +        return;
> +
>      if ( v == current && list_empty(&v->arch.vgic.lr_pending) )
>      {
>          i = find_first_zero_bit(&this_cpu(lr_mask), nr_lrs);
>          if (i < nr_lrs) {
>              set_bit(i, &this_cpu(lr_mask));
> -            gic_set_lr(i, irq_to_pending(v, virtual_irq), GICH_LR_PENDING);
> +            gic_set_lr(i, p, GICH_LR_PENDING);
>              return;
>          }
>      }
>
> -    gic_add_to_lr_pending(v, irq_to_pending(v, virtual_irq));
> +    gic_add_to_lr_pending(v, p);
>  }
>
>  static void gic_update_one_lr(struct vcpu *v, int i)
> @@ -465,6 +480,17 @@ static void gic_update_one_lr(struct vcpu *v, int i)
>      gic_hw_ops->read_lr(i, &lr_val);
>      irq = lr_val.virq;
>      p = irq_to_pending(v, irq);
> +    /* An LPI might have been unmapped, in which case we just clean up here. */
> +    if ( unlikely(!p) )
> +    {
> +        ASSERT(is_lpi(irq));
> +
> +        gic_hw_ops->clear_lr(i);
> +        clear_bit(i, &this_cpu(lr_mask));
> +
> +        return;
> +    }
> +
>      if ( lr_val.state & GICH_LR_ACTIVE )
>      {
>          set_bit(GIC_IRQ_GUEST_ACTIVE, &p->status);
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index d30f324..8a5d93b 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -242,6 +242,9 @@ bool vgic_migrate_irq(struct vcpu *old, struct vcpu *new, unsigned int irq)
>      unsigned long flags;
>      struct pending_irq *p = irq_to_pending(old, irq);
>
> +    /* This will never be called for an LPI, as we don't migrate them. */
> +    ASSERT(!is_lpi(irq));
> +
>      /* nothing to do for virtual interrupts */
>      if ( p->desc == NULL )
>          return true;
> @@ -291,6 +294,9 @@ void arch_move_irqs(struct vcpu *v)
>      struct vcpu *v_target;
>      int i;
>
> +    /* We don't migrate LPIs at the moment. */
> +    ASSERT(!is_lpi(vgic_num_irqs(d) - 1));
> +
>      for ( i = 32; i < vgic_num_irqs(d); i++ )
>      {
>          v_target = vgic_get_target_vcpu(v, i);
> @@ -310,6 +316,9 @@ void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n)
>      int i = 0;
>      struct vcpu *v_target;
>
> +    /* LPIs will never be disabled via this function. */
> +    ASSERT(!is_lpi(32 * n + 31));
> +
>      while ( (i = find_next_bit(&mask, 32, i)) < 32 ) {
>          irq = i + (32 * n);
>          v_target = vgic_get_target_vcpu(v, irq);
> @@ -352,6 +361,9 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
>      struct vcpu *v_target;
>      struct domain *d = v->domain;
>
> +    /* LPIs will never be enabled via this function. */
> +    ASSERT(!is_lpi(32 * n + 31));
> +
>      while ( (i = find_next_bit(&mask, 32, i)) < 32 ) {
>          irq = i + (32 * n);
>          v_target = vgic_get_target_vcpu(v, irq);
> @@ -432,6 +444,12 @@ bool vgic_to_sgi(struct vcpu *v, register_t sgir, enum gic_sgi_mode irqmode,
>      return true;
>  }
>
> +/*
> + * Returns the pointer to the struct pending_irq belonging to the given
> + * interrupt.
> + * This can return NULL if called for an LPI which has been unmapped
> + * meanwhile.
> + */
>  struct pending_irq *irq_to_pending(struct vcpu *v, unsigned int irq)
>  {
>      struct pending_irq *n;
> @@ -475,6 +493,12 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int virq)
>      spin_lock_irqsave(&v->arch.vgic.lock, flags);
>
>      n = irq_to_pending(v, virq);
> +    /* If an LPI has been removed, there is nothing to inject here. */
> +    if ( unlikely(!n) )
> +    {
> +        spin_unlock_irqrestore(&v->arch.vgic.lock, flags);
> +        return;
> +    }
>
>      /* vcpu offline */
>      if ( test_bit(_VPF_down, &v->pause_flags) )
> diff --git a/xen/include/asm-arm/event.h b/xen/include/asm-arm/event.h
> index 5330dfe..caefa50 100644
> --- a/xen/include/asm-arm/event.h
> +++ b/xen/include/asm-arm/event.h
> @@ -19,6 +19,9 @@ static inline int local_events_need_delivery_nomask(void)
>      struct pending_irq *p = irq_to_pending(current,
>                                             current->domain->arch.evtchn_irq);
>
> +    /* Does not work for LPIs. */
> +    ASSERT(!is_lpi(current->domain->arch.evtchn_irq));
> +
>      /* XXX: if the first interrupt has already been delivered, we should
>       * check whether any other interrupts with priority higher than the
>       * one in GICV_IAR are in the lr_pending queue or in the LR
>

Cheers,

-- 
Julien Grall

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

  reply	other threads:[~2017-05-12 14:19 UTC|newest]

Thread overview: 108+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-11 17:53 [PATCH v9 00/28] arm64: Dom0 ITS emulation Andre Przywara
2017-05-11 17:53 ` [PATCH v9 01/28] ARM: GICv3: setup number of LPI bits for a GICv3 guest Andre Przywara
2017-05-11 18:34   ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 02/28] ARM: VGIC: move irq_to_pending() calls under the VGIC VCPU lock Andre Przywara
2017-05-20  0:34   ` Stefano Stabellini
2017-05-11 17:53 ` [PATCH v9 03/28] ARM: GIC: Add checks for NULL pointer pending_irq's Andre Przywara
2017-05-12 14:19   ` Julien Grall [this message]
2017-05-22 16:49     ` Andre Przywara
2017-05-22 17:15       ` Julien Grall
2017-05-25 16:14         ` Andre Przywara
2017-05-20  1:25   ` Stefano Stabellini
2017-05-11 17:53 ` [PATCH v9 04/28] ARM: GICv3: introduce separate pending_irq structs for LPIs Andre Przywara
2017-05-12 14:22   ` Julien Grall
2017-05-22 21:52   ` Stefano Stabellini
2017-05-11 17:53 ` [PATCH v9 05/28] ARM: GICv3: forward pending LPIs to guests Andre Przywara
2017-05-12 14:55   ` Julien Grall
2017-05-22 22:03   ` Stefano Stabellini
2017-05-25 16:42     ` Andre Przywara
2017-05-11 17:53 ` [PATCH v9 06/28] ARM: GICv3: enable ITS and LPIs on the host Andre Przywara
2017-05-11 17:53 ` [PATCH v9 07/28] ARM: vGICv3: handle virtual LPI pending and property tables Andre Przywara
2017-05-12 15:23   ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 08/28] ARM: introduce vgic_access_guest_memory() Andre Przywara
2017-05-12 15:30   ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 09/28] ARM: vGICv3: re-use vgic_reg64_check_access Andre Przywara
2017-05-11 17:53 ` [PATCH v9 10/28] ARM: GIC: export and extend vgic_init_pending_irq() Andre Przywara
2017-05-16 12:26   ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 11/28] ARM: VGIC: add vcpu_id to struct pending_irq Andre Przywara
2017-05-16 12:31   ` Julien Grall
2017-05-22 22:15     ` Stefano Stabellini
2017-05-23  9:49       ` Andre Przywara
2017-05-11 17:53 ` [PATCH v9 12/28] ARM: vGIC: advertise LPI support Andre Przywara
2017-05-16 13:03   ` Julien Grall
2017-05-22 22:19     ` Stefano Stabellini
2017-05-23 10:49       ` Julien Grall
2017-05-23 17:47         ` Stefano Stabellini
2017-05-24 10:10           ` Julien Grall
2017-05-25 18:02           ` Andre Przywara
2017-05-25 18:49             ` Stefano Stabellini
2017-05-25 20:07               ` Julien Grall
2017-05-25 21:05                 ` Stefano Stabellini
2017-05-26 10:19                   ` Julien Grall
2017-05-26 17:12                     ` Andre Przywara
2017-05-23 17:23     ` Andre Przywara
2017-05-11 17:53 ` [PATCH v9 13/28] ARM: vITS: add command handling stub and MMIO emulation Andre Przywara
2017-05-16 15:24   ` Julien Grall
2017-05-17 16:16   ` Julien Grall
2017-05-22 22:32   ` Stefano Stabellini
2017-05-23 10:54     ` Julien Grall
2017-05-23 17:43       ` Stefano Stabellini
2017-05-11 17:53 ` [PATCH v9 14/28] ARM: vITS: introduce translation table walks Andre Przywara
2017-05-16 15:57   ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 15/28] ARM: vITS: provide access to struct pending_irq Andre Przywara
2017-05-17 15:35   ` Julien Grall
2017-05-22 16:50     ` Andre Przywara
2017-05-22 17:19       ` Julien Grall
2017-05-26  9:10         ` Andre Przywara
2017-05-26 10:00           ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 16/28] ARM: vITS: handle INT command Andre Przywara
2017-05-17 16:17   ` Julien Grall
2017-05-23 17:24     ` Andre Przywara
2017-05-11 17:53 ` [PATCH v9 17/28] ARM: vITS: handle MAPC command Andre Przywara
2017-05-17 17:22   ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 18/28] ARM: vITS: handle CLEAR command Andre Przywara
2017-05-17 17:45   ` Julien Grall
2017-05-23 17:24     ` Andre Przywara
2017-05-24  9:04       ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 19/28] ARM: vITS: handle MAPD command Andre Przywara
2017-05-17 18:07   ` Julien Grall
2017-05-24  9:10     ` Andre Przywara
2017-05-24  9:56       ` Julien Grall
2017-05-24 13:09         ` Andre Przywara
2017-05-25 18:55           ` Stefano Stabellini
2017-05-25 20:17             ` Julien Grall
2017-05-25 20:44               ` Stefano Stabellini
2017-05-26  8:16                 ` Andre Przywara
2017-05-11 17:53 ` [PATCH v9 20/28] ARM: GICv3: handle unmapped LPIs Andre Przywara
2017-05-17 18:37   ` Julien Grall
2017-05-20  1:25   ` Stefano Stabellini
2017-05-22 23:48     ` Stefano Stabellini
2017-05-23 11:10       ` Julien Grall
2017-05-23 18:23         ` Stefano Stabellini
2017-05-24  9:47           ` Julien Grall
2017-05-24 17:49             ` Stefano Stabellini
2017-05-23 14:41     ` Andre Przywara
2017-05-11 17:53 ` [PATCH v9 21/28] ARM: vITS: handle MAPTI command Andre Przywara
2017-05-18 14:04   ` Julien Grall
2017-05-22 23:39   ` Stefano Stabellini
2017-05-23 10:01     ` Andre Przywara
2017-05-23 17:44       ` Stefano Stabellini
2017-05-11 17:53 ` [PATCH v9 22/28] ARM: vITS: handle MOVI command Andre Przywara
2017-05-18 14:17   ` Julien Grall
2017-05-23  0:28   ` Stefano Stabellini
2017-05-11 17:53 ` [PATCH v9 23/28] ARM: vITS: handle DISCARD command Andre Przywara
2017-05-18 14:23   ` Julien Grall
2017-05-22 16:50     ` Andre Przywara
2017-05-22 17:20       ` Julien Grall
2017-05-23  9:40         ` Andre Przywara
2017-05-11 17:53 ` [PATCH v9 24/28] ARM: vITS: handle INV command Andre Przywara
2017-05-23  0:01   ` Stefano Stabellini
2017-05-11 17:53 ` [PATCH v9 25/28] ARM: vITS: handle INVALL command Andre Przywara
2017-06-02 17:24   ` Julien Grall
2017-06-02 17:25     ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 26/28] ARM: vITS: increase mmio_count for each ITS Andre Przywara
2017-05-18 14:34   ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 27/28] ARM: vITS: create and initialize virtual ITSes for Dom0 Andre Przywara
2017-05-18 14:41   ` Julien Grall
2017-05-11 17:53 ` [PATCH v9 28/28] ARM: vITS: create ITS subnodes for Dom0 DT Andre Przywara
2017-05-11 18:31 ` [PATCH v9 00/28] 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=dcb34f96-31b2-3b14-ea2e-43f58c58ccd4@arm.com \
    --to=julien.grall@arm.com \
    --cc=Vijaya.Kumar@caviumnetworks.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).