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
Subject: Re: [RFC PATCH 06/10] ARM: vGIC: move config from irq_rank to struct pending_irq
Date: Thu, 4 May 2017 17:55:37 +0100 [thread overview]
Message-ID: <23a47d67-7cee-8557-f10c-7ef52ad34fe8@arm.com> (raw)
In-Reply-To: <20170504153123.1204-7-andre.przywara@arm.com>
Hi Andre,
On 04/05/17 16:31, Andre Przywara wrote:
> Currently we store the interrupt type configuration (level or edge
> triggered) in the rank structure. Move this value into struct pending_irq.
> We just need one bit (edge or level), so use one of the status bits.
>
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> ---
> xen/arch/arm/vgic-v2.c | 29 ++++++++++-------------------
> xen/arch/arm/vgic-v3.c | 31 ++++++++++++-------------------
> xen/arch/arm/vgic.c | 39 ++++++++++++++++++++-------------------
> xen/include/asm-arm/vgic.h | 7 ++++++-
> 4 files changed, 48 insertions(+), 58 deletions(-)
>
> diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c
> index 5c59fb4..795173c 100644
> --- a/xen/arch/arm/vgic-v2.c
> +++ b/xen/arch/arm/vgic-v2.c
> @@ -278,20 +278,10 @@ static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info,
> goto read_reserved;
>
> case VRANGE32(GICD_ICFGR, GICD_ICFGRN):
> - {
> - uint32_t icfgr;
> -
> if ( dabt.size != DABT_WORD ) goto bad_width;
> - rank = vgic_rank_offset(v, 2, gicd_reg - GICD_ICFGR, DABT_WORD);
> - if ( rank == NULL) goto read_as_zero;
> - vgic_lock_rank(v, rank, flags);
> - icfgr = rank->icfg[REG_RANK_INDEX(2, gicd_reg - GICD_ICFGR, DABT_WORD)];
> - vgic_unlock_rank(v, rank, flags);
> -
> - *r = vgic_reg32_extract(icfgr, info);
> -
> + irq = (gicd_reg - GICD_ICFGR) * 4;
This would be nicer to have that handle directly in
gather_irq_info_config rather than open-coding everywhere. Also it
avoids this confusion of what irq actually meaning in this context.
I was also expecting some check on whether the interrupts is valid for
the vGIC.
> + *r = vgic_reg32_extract(gather_irq_info_config(v, irq), info);
> return 1;
> - }
>
> case VRANGE32(0xD00, 0xDFC):
> goto read_impl_defined;
> @@ -534,15 +524,16 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info,
> goto write_ignore_32;
>
> case VRANGE32(GICD_ICFGR2, GICD_ICFGRN): /* SPIs */
> + {
> + uint32_t icfgr;
> +
> if ( dabt.size != DABT_WORD ) goto bad_width;
> - rank = vgic_rank_offset(v, 2, gicd_reg - GICD_ICFGR, DABT_WORD);
> - if ( rank == NULL) goto write_ignore;
> - vgic_lock_rank(v, rank, flags);
> - vgic_reg32_update(&rank->icfg[REG_RANK_INDEX(2, gicd_reg - GICD_ICFGR,
> - DABT_WORD)],
> - r, info);
> - vgic_unlock_rank(v, rank, flags);
> + irq = (gicd_reg - GICD_ICFGR) * 4;
Ditto for the irq and the check.
> + icfgr = gather_irq_info_config(v, irq);
> + vgic_reg32_update(&icfgr, r, info);
> + scatter_irq_info_config(v, irq, icfgr);
> return 1;
> + }
>
> case VRANGE32(0xD00, 0xDFC):
> goto write_impl_defined;
> diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
> index 10db939..7989989 100644
> --- a/xen/arch/arm/vgic-v3.c
> +++ b/xen/arch/arm/vgic-v3.c
> @@ -521,20 +521,11 @@ static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v,
> return 1;
>
> case VRANGE32(GICD_ICFGR, GICD_ICFGRN):
> - {
> - uint32_t icfgr;
> -
> if ( dabt.size != DABT_WORD ) goto bad_width;
> - rank = vgic_rank_offset(v, 2, reg - GICD_ICFGR, DABT_WORD);
> - if ( rank == NULL ) goto read_as_zero;
> - vgic_lock_rank(v, rank, flags);
> - icfgr = rank->icfg[REG_RANK_INDEX(2, reg - GICD_ICFGR, DABT_WORD)];
> - vgic_unlock_rank(v, rank, flags);
> -
> - *r = vgic_reg32_extract(icfgr, info);
> -
> + irq = (reg - GICD_IPRIORITYR) * 4;
> + if ( irq >= v->domain->arch.vgic.nr_spis + 32 ) goto read_as_zero;
This should really be an helper.
> + *r = vgic_reg32_extract(gather_irq_info_config(v, irq), info);
> return 1;
> - }
>
> default:
> printk(XENLOG_G_ERR
> @@ -636,17 +627,19 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v,
> goto write_ignore_32;
>
> case VRANGE32(GICD_ICFGR + 4, GICD_ICFGRN): /* PPI + SPIs */
> + {
> + uint32_t icfgr;
> +
> /* ICFGR1 for PPI's, which is implementation defined
> if ICFGR1 is programmable or not. We chose to program */
> if ( dabt.size != DABT_WORD ) goto bad_width;
> - rank = vgic_rank_offset(v, 2, reg - GICD_ICFGR, DABT_WORD);
> - if ( rank == NULL ) goto write_ignore;
> - vgic_lock_rank(v, rank, flags);
> - vgic_reg32_update(&rank->icfg[REG_RANK_INDEX(2, reg - GICD_ICFGR,
> - DABT_WORD)],
> - r, info);
> - vgic_unlock_rank(v, rank, flags);
> + irq = (reg - GICD_ICFGR) * 4;
> + if ( irq >= v->domain->arch.vgic.nr_spis + 32 ) goto write_ignore;
> + icfgr = gather_irq_info_config(v, irq);
> + vgic_reg32_update(&icfgr, r, info);
> + scatter_irq_info_config(v, irq, icfgr);
> return 1;
> + }
>
> default:
> printk(XENLOG_G_ERR
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index 68eef47..02c1d12 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -235,6 +235,19 @@ static void set_priority(struct pending_irq *p, uint8_t prio)
> p->new_priority = prio;
> }
>
> +unsigned int extract_config(struct pending_irq *p)
Why this is exported? Also naming.
> +{
> + return test_bit(GIC_IRQ_GUEST_EDGE, &p->status) ? 2 : 0;
Please document 0, 2. Likely with a some define.
> +}
> +
> +static void set_config(struct pending_irq *p, unsigned int config)
Naming.
> +{
> + if ( config < 2 )
Ditto.
> + clear_bit(GIC_IRQ_GUEST_EDGE, &p->status);
> + else
> + set_bit(GIC_IRQ_GUEST_EDGE, &p->status);
> +}
> +
>
> #define DEFINE_GATHER_IRQ_INFO(name, get_val, shift) \
> uint32_t gather_irq_info_##name(struct vcpu *v, unsigned int irq) \
> @@ -267,6 +280,8 @@ void scatter_irq_info_##name(struct vcpu *v, unsigned int irq, \
> /* grep fodder: gather_irq_info_priority, scatter_irq_info_priority below */
> DEFINE_GATHER_IRQ_INFO(priority, extract_priority, 8)
> DEFINE_SCATTER_IRQ_INFO(priority, set_priority, 8)
> +DEFINE_GATHER_IRQ_INFO(config, extract_config, 2)
> +DEFINE_SCATTER_IRQ_INFO(config, set_config, 2)
>
> bool vgic_migrate_irq(struct vcpu *old, struct vcpu *new, unsigned int irq)
> {
> @@ -357,27 +372,11 @@ void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n)
> }
> }
>
> -#define VGIC_ICFG_MASK(intr) (1 << ((2 * ((intr) % 16)) + 1))
> -
> -/* The function should be called with the rank lock taken */
> -static inline unsigned int vgic_get_virq_type(struct vcpu *v, int n, int index)
> -{
> - struct vgic_irq_rank *r = vgic_get_rank(v, n);
> - uint32_t tr = r->icfg[index >> 4];
> -
> - ASSERT(spin_is_locked(&r->lock));
> -
> - if ( tr & VGIC_ICFG_MASK(index) )
> - return IRQ_TYPE_EDGE_RISING;
> - else
> - return IRQ_TYPE_LEVEL_HIGH;
> -}
> -
> void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
> {
> const unsigned long mask = r;
> struct pending_irq *p;
> - unsigned int irq;
> + unsigned int irq, int_type;
> unsigned long flags;
> int i = 0;
> struct vcpu *v_target;
> @@ -392,6 +391,8 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
> spin_lock(&p->lock);
>
> set_bit(GIC_IRQ_GUEST_ENABLED, &p->status);
> + int_type = test_bit(GIC_IRQ_GUEST_EDGE, &p->status) ?
> + IRQ_TYPE_EDGE_RISING : IRQ_TYPE_LEVEL_HIGH;
>
> if ( !list_empty(&p->inflight) && !test_bit(GIC_IRQ_GUEST_VISIBLE, &p->status) )
> gic_raise_guest_irq(v_target, p);
> @@ -399,15 +400,15 @@ void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
> spin_unlock_irqrestore(&v_target->arch.vgic.lock, flags);
> if ( p->desc != NULL )
> {
> - irq_set_affinity(p->desc, cpumask_of(v_target->processor));
> spin_lock_irqsave(&p->desc->lock, flags);
> + irq_set_affinity(p->desc, cpumask_of(v_target->processor));
> /*
> * The irq cannot be a PPI, we only support delivery of SPIs
> * to guests.
> */
> ASSERT(irq >= 32);
> if ( irq_type_set_by_domain(d) )
> - gic_set_irq_type(p->desc, vgic_get_virq_type(v, n, i));
> + gic_set_irq_type(p->desc, int_type);
> p->desc->handler->enable(p->desc);
> spin_unlock_irqrestore(&p->desc->lock, flags);
> }
> diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
> index 38a5e76..931a672 100644
> --- a/xen/include/asm-arm/vgic.h
> +++ b/xen/include/asm-arm/vgic.h
> @@ -60,12 +60,15 @@ struct pending_irq
> * vcpu while it is still inflight and on an GICH_LR register on the
> * old vcpu.
> *
> + * GIC_IRQ_GUEST_EDGE: the IRQ is an edge triggered interrupt.
Also, explain that by default the interrupt will be level.
> + *
> */
> #define GIC_IRQ_GUEST_QUEUED 0
> #define GIC_IRQ_GUEST_ACTIVE 1
> #define GIC_IRQ_GUEST_VISIBLE 2
> #define GIC_IRQ_GUEST_ENABLED 3
> #define GIC_IRQ_GUEST_MIGRATING 4
> +#define GIC_IRQ_GUEST_EDGE 5
> unsigned long status;
> struct irq_desc *desc; /* only set it the irq corresponds to a physical irq */
> unsigned int irq;
> @@ -102,7 +105,6 @@ struct vgic_irq_rank {
> uint8_t index;
>
> uint32_t ienable;
> - uint32_t icfg[2];
>
> /*
> * It's more convenient to store a target VCPU per vIRQ
> @@ -173,6 +175,9 @@ static inline int REG_RANK_NR(int b, uint32_t n)
> uint32_t gather_irq_info_priority(struct vcpu *v, unsigned int irq);
> void scatter_irq_info_priority(struct vcpu *v, unsigned int irq,
> unsigned int value);
> +uint32_t gather_irq_info_config(struct vcpu *v, unsigned int irq);
> +void scatter_irq_info_config(struct vcpu *v, unsigned int irq,
> + unsigned int value);
>
> #define VGIC_REG_MASK(size) ((~0UL) >> (BITS_PER_LONG - ((1 << (size)) * 8)))
>
>
Cheers,
--
Julien Grall
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
next prev parent reply other threads:[~2017-05-04 16:55 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-05-04 15:31 [RFC PATCH 00/10] ARM VGIC rework: remove rank, introduce per-IRQ lock Andre Przywara
2017-05-04 15:31 ` [RFC PATCH 01/10] ARM: vGIC: remove rank lock from IRQ routing functions Andre Przywara
2017-05-04 15:53 ` Julien Grall
2017-05-08 9:15 ` Andre Przywara
2017-05-08 14:26 ` Julien Grall
2017-05-08 21:53 ` Stefano Stabellini
2017-05-08 22:13 ` Julien Grall
2017-05-09 0:47 ` Stefano Stabellini
2017-05-09 15:24 ` Julien Grall
2017-05-04 15:31 ` [RFC PATCH 02/10] ARM: vGIC: rework gic_raise_*_irq() functions Andre Przywara
2017-05-04 15:31 ` [RFC PATCH 03/10] ARM: vGIC: introduce and initialize pending_irq lock Andre Przywara
2017-05-04 15:31 ` [RFC PATCH 04/10] ARM: vGIC: add struct pending_irq locking Andre Przywara
2017-05-04 16:21 ` Julien Grall
2017-05-05 9:02 ` Andre Przywara
2017-05-05 23:29 ` Stefano Stabellini
2017-05-06 6:41 ` Julien Grall
2017-05-05 23:42 ` Stefano Stabellini
2017-05-04 16:54 ` Julien Grall
2017-05-05 23:26 ` Stefano Stabellini
2017-05-04 15:31 ` [RFC PATCH 05/10] ARM: vGIC: move priority from irq_rank to struct pending_irq Andre Przywara
2017-05-04 16:39 ` Julien Grall
2017-05-04 16:47 ` Julien Grall
2017-05-04 15:31 ` [RFC PATCH 06/10] ARM: vGIC: move config " Andre Przywara
2017-05-04 16:55 ` Julien Grall [this message]
2017-05-04 15:31 ` [RFC PATCH 07/10] ARM: vGIC: move enable status " Andre Przywara
2017-05-04 15:31 ` [RFC PATCH 08/10] ARM: vGIC: move target vcpu " Andre Przywara
2017-05-04 17:20 ` Julien Grall
2017-05-04 15:31 ` [RFC PATCH 09/10] ARM: vGIC: introduce vgic_get/put_pending_irq Andre Przywara
2017-05-04 17:36 ` Julien Grall
2017-05-04 22:42 ` Stefano Stabellini
2017-05-04 15:31 ` [RFC PATCH 10/10] ARM: vGIC: remove struct irq_rank and support functions 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=23a47d67-7cee-8557-f10c-7ef52ad34fe8@arm.com \
--to=julien.grall@arm.com \
--cc=andre.przywara@arm.com \
--cc=sstabellini@kernel.org \
--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).