xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
To: xen-devel@lists.xensource.com
Cc: julien.grall@citrix.com, Ian.Campbell@citrix.com,
	JBeulich@suse.com,
	Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Subject: [PATCH v4 4/4] xen/arm: physical irq follow virtual irq
Date: Fri, 6 Jun 2014 18:48:28 +0100	[thread overview]
Message-ID: <1402076908-26740-4-git-send-email-stefano.stabellini@eu.citrix.com> (raw)
In-Reply-To: <alpine.DEB.2.02.1406061801080.2526@kaball.uk.xensource.com>

Migrate physical irqs to the same physical cpu that is running the vcpu
expected to receive the irqs. That is done when enabling irqs, when the
guest writes to GICD_ITARGETSR and when Xen migrates a vcpu to a
different pcpu.

Introduce a new hook in common code to call the vgic irq migration code
as evtchn_move_pirqs only deals with event channels at the moment.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
CC: JBeulich@suse.com
---
 xen/arch/arm/gic.c         |   18 ++++++++++++++++--
 xen/arch/arm/vgic.c        |   31 +++++++++++++++++++++++++++++++
 xen/common/event_channel.c |    4 ++++
 xen/include/asm-arm/gic.h  |    1 +
 4 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 6f24b14..43bef21 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -192,9 +192,23 @@ static void gic_guest_irq_end(struct irq_desc *desc)
     /* Deactivation happens in maintenance interrupt / via GICV */
 }
 
-static void gic_irq_set_affinity(struct irq_desc *desc, const cpumask_t *mask)
+static void gic_irq_set_affinity(struct irq_desc *desc, const cpumask_t *cpu_mask)
 {
-    BUG();
+    volatile unsigned char *bytereg;
+    unsigned int mask;
+
+    if ( desc == NULL || cpumask_empty(cpu_mask) )
+        return;
+
+    spin_lock(&gic.lock);
+
+    mask = gic_cpu_mask(cpu_mask);
+
+    /* Set target CPU mask (RAZ/WI on uniprocessor) */
+    bytereg = (unsigned char *) (GICD + GICD_ITARGETSR);
+    bytereg[desc->irq] = mask;
+
+    spin_unlock(&gic.lock);
 }
 
 /* XXX different for level vs edge */
diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
index 54d3676..a90d9cb 100644
--- a/xen/arch/arm/vgic.c
+++ b/xen/arch/arm/vgic.c
@@ -408,6 +408,32 @@ struct vcpu *vgic_get_target_vcpu(struct vcpu *v, unsigned int irq)
     return v_target;
 }
 
+void vgic_move_irqs(struct vcpu *v)
+{
+    const cpumask_t *cpu_mask = cpumask_of(v->processor);
+    struct domain *d = v->domain;
+    struct pending_irq *p;
+    int i, j, k;
+
+    for ( i = 0; i < DOMAIN_NR_RANKS(d); i++ )
+    {
+        for ( j = 0 ; j < 8 ; j++ )
+        {
+            for ( k = 0; k < 4; k++ )
+            {
+                uint8_t target = byte_read(d->arch.vgic.shared_irqs[i].itargets[j], 0, k);
+                target = find_next_bit((const unsigned long *) &target, 8, 0);
+                if ( target == v->vcpu_id )
+                {
+                    p = irq_to_pending(v, 32 * (i + 1) + (j * 4) + k);
+                    if ( p->desc != NULL )
+                        p->desc->handler->set_affinity(p->desc, cpu_mask);
+                }
+            }
+        }
+    }
+}
+
 static void vgic_disable_irqs(struct vcpu *v, uint32_t r, int n)
 {
     const unsigned long mask = r;
@@ -463,6 +489,7 @@ static void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
         }
         if ( p->desc != NULL )
         {
+            p->desc->handler->set_affinity(p->desc, cpumask_of(v_target->processor));
             spin_lock_irqsave(&p->desc->lock, flags);
             p->desc->handler->enable(p->desc);
             spin_unlock_irqrestore(&p->desc->lock, flags);
@@ -649,6 +676,7 @@ static int vgic_distr_mmio_write(struct vcpu *v, mmio_info_t *info)
         {
             unsigned int irq, target, old_target;
             struct vcpu *v_target, *v_old;
+            struct pending_irq *p;
 
             target = i % 8;
 
@@ -657,6 +685,9 @@ static int vgic_distr_mmio_write(struct vcpu *v, mmio_info_t *info)
             old_target = byte_read(rank->itargets[REG_RANK_INDEX(8, gicd_reg - GICD_ITARGETSR)], 0, i/8);
             v_old = v->domain->vcpu[old_target];
             vgic_migrate_irq(v_old, v_target, irq);
+            p = irq_to_pending(v_target, irq);
+            if ( p->desc != NULL )
+                p->desc->handler->set_affinity(p->desc, cpumask_of(v_target->processor));
             i += 8 - target;
         }
         if ( dabt.size == 2 )
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index 6853842..226321d 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -1319,6 +1319,10 @@ void evtchn_move_pirqs(struct vcpu *v)
     unsigned int port;
     struct evtchn *chn;
 
+#ifdef CONFIG_ARM
+	vgic_move_irqs(v);
+#endif
+
     spin_lock(&d->event_lock);
     for ( port = v->pirq_evtchn_head; port; port = chn->u.pirq.next_port )
     {
diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index bd40628..8f457dd 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -228,6 +228,7 @@ int gic_irq_xlate(const u32 *intspec, unsigned int intsize,
 void gic_clear_lrs(struct vcpu *v);
 
 struct vcpu *vgic_get_target_vcpu(struct vcpu *v, unsigned int irq);
+void vgic_move_irqs(struct vcpu *v);
 
 #endif /* __ASSEMBLY__ */
 #endif
-- 
1.7.10.4

  parent reply	other threads:[~2014-06-06 17:48 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-06 17:47 [PATCH v4 0/4] vgic emulation and GICD_ITARGETSR Stefano Stabellini
2014-06-06 17:48 ` [PATCH v4 1/4] xen/arm: observe itargets setting in vgic_enable_irqs and vgic_disable_irqs Stefano Stabellini
2014-06-07 14:33   ` Julien Grall
2014-06-09 10:47     ` Stefano Stabellini
2014-06-09 11:37       ` Julien Grall
2014-06-09 12:04         ` Stefano Stabellini
2014-06-09 12:32           ` Julien Grall
2014-06-09 17:21             ` Stefano Stabellini
2014-06-10 11:44   ` Ian Campbell
2014-06-11 11:54     ` Stefano Stabellini
2014-06-06 17:48 ` [PATCH v4 2/4] xen/arm: inflight irqs during migration Stefano Stabellini
2014-06-10 12:12   ` Ian Campbell
2014-06-11 14:15     ` Stefano Stabellini
2014-06-11 14:28       ` Julien Grall
2014-06-11 14:49         ` Stefano Stabellini
2014-06-11 15:16           ` Julien Grall
2014-06-11 15:55             ` Stefano Stabellini
2014-06-06 17:48 ` [PATCH v4 3/4] xen/arm: support irq delivery to vcpu > 0 Stefano Stabellini
2014-06-10 12:16   ` Ian Campbell
2014-06-10 12:56     ` Julien Grall
2014-06-11 14:22     ` Stefano Stabellini
2014-06-06 17:48 ` Stefano Stabellini [this message]
2014-06-10 12:27   ` [PATCH v4 4/4] xen/arm: physical irq follow virtual irq Ian Campbell
2014-06-11 14:47     ` Stefano Stabellini
2014-06-11 15:14       ` Ian Campbell

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=1402076908-26740-4-git-send-email-stefano.stabellini@eu.citrix.com \
    --to=stefano.stabellini@eu.citrix.com \
    --cc=Ian.Campbell@citrix.com \
    --cc=JBeulich@suse.com \
    --cc=julien.grall@citrix.com \
    --cc=xen-devel@lists.xensource.com \
    /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).