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
next prev 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).