[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen stable-4.7] vgic: refuse irq migration when one is already in progress
commit f1f2df22bf477c7fad56cbbb0e495a6e4b5d21ef Author: Stefano Stabellini <sstabellini@xxxxxxxxxx> AuthorDate: Wed Apr 5 13:28:43 2017 -0700 Commit: Stefano Stabellini <sstabellini@xxxxxxxxxx> CommitDate: Mon Jun 12 14:04:51 2017 -0700 vgic: refuse irq migration when one is already in progress When an irq migration is already in progress, but not yet completed (GIC_IRQ_GUEST_MIGRATING is set), refuse any other irq migration requests for the same irq. This patch implements this approach by returning success or failure from vgic_migrate_irq, and avoiding irq target changes on failure. It prints a warning in case the irq migration fails. It also moves the clear_bit of GIC_IRQ_GUEST_MIGRATING to after the physical irq affinity has been changed so that all operations regarding irq migration are completed. Signed-off-by: Stefano Stabellini <sstabellini@xxxxxxxxxx> Reviewed-by: Julien Grall <julien.grall@xxxxxxx> master-commit-id: 91ef7364933037b6a8d825405a1c809a72e6152f --- xen/arch/arm/gic.c | 3 ++- xen/arch/arm/vgic-v2.c | 7 +++---- xen/arch/arm/vgic-v3.c | 7 ++++--- xen/arch/arm/vgic.c | 14 +++++++++----- xen/include/asm-arm/vgic.h | 2 +- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index db07614..8e044e3 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -494,10 +494,11 @@ static void gic_update_one_lr(struct vcpu *v, int i) * accesses to inflight. */ smp_wmb(); - if ( test_and_clear_bit(GIC_IRQ_GUEST_MIGRATING, &p->status) ) + if ( test_bit(GIC_IRQ_GUEST_MIGRATING, &p->status) ) { struct vcpu *v_target = vgic_get_target_vcpu(v, irq); irq_set_affinity(p->desc, cpumask_of(v_target->processor)); + clear_bit(GIC_IRQ_GUEST_MIGRATING, &p->status); } } } diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c index 38916a0..ec99490 100644 --- a/xen/arch/arm/vgic-v2.c +++ b/xen/arch/arm/vgic-v2.c @@ -157,12 +157,11 @@ static void vgic_store_itargetsr(struct domain *d, struct vgic_irq_rank *rank, /* Only migrate the vIRQ if the target vCPU has changed */ if ( new_target != old_target ) { - vgic_migrate_irq(d->vcpu[old_target], + if ( vgic_migrate_irq(d->vcpu[old_target], d->vcpu[new_target], - virq); + virq) ) + write_atomic(&rank->vcpu[offset], new_target); } - - write_atomic(&rank->vcpu[offset], new_target); } } diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c index dac0e4a..1203fb0 100644 --- a/xen/arch/arm/vgic-v3.c +++ b/xen/arch/arm/vgic-v3.c @@ -151,9 +151,10 @@ static void vgic_store_irouter(struct domain *d, struct vgic_irq_rank *rank, /* Only migrate the IRQ if the target vCPU has changed */ if ( new_vcpu != old_vcpu ) - vgic_migrate_irq(old_vcpu, new_vcpu, virq); - - write_atomic(&rank->vcpu[offset], new_vcpu->vcpu_id); + { + if ( vgic_migrate_irq(old_vcpu, new_vcpu, virq) ) + write_atomic(&rank->vcpu[offset], new_vcpu->vcpu_id); + } } static inline bool vgic_reg64_check_access(struct hsr_dabt dabt) diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c index 07902c1..c34eb9f 100644 --- a/xen/arch/arm/vgic.c +++ b/xen/arch/arm/vgic.c @@ -234,18 +234,21 @@ static int vgic_get_virq_priority(struct vcpu *v, unsigned int virq) return priority; } -void vgic_migrate_irq(struct vcpu *old, struct vcpu *new, unsigned int irq) +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); /* nothing to do for virtual interrupts */ if ( p->desc == NULL ) - return; + return true; /* migration already in progress, no need to do anything */ if ( test_bit(GIC_IRQ_GUEST_MIGRATING, &p->status) ) - return; + { + gprintk(XENLOG_WARNING, "irq %u migration failed: requested while in progress\n", irq); + return false; + } perfc_incr(vgic_irq_migrates); @@ -255,7 +258,7 @@ void vgic_migrate_irq(struct vcpu *old, struct vcpu *new, unsigned int irq) { irq_set_affinity(p->desc, cpumask_of(new->processor)); spin_unlock_irqrestore(&old->arch.vgic.lock, flags); - return; + return true; } /* If the IRQ is still lr_pending, re-inject it to the new vcpu */ if ( !list_empty(&p->lr_queue) ) @@ -266,7 +269,7 @@ void vgic_migrate_irq(struct vcpu *old, struct vcpu *new, unsigned int irq) irq_set_affinity(p->desc, cpumask_of(new->processor)); spin_unlock_irqrestore(&old->arch.vgic.lock, flags); vgic_vcpu_inject_irq(new, irq); - return; + return true; } /* if the IRQ is in a GICH_LR register, set GIC_IRQ_GUEST_MIGRATING * and wait for the EOI */ @@ -274,6 +277,7 @@ void vgic_migrate_irq(struct vcpu *old, struct vcpu *new, unsigned int irq) set_bit(GIC_IRQ_GUEST_MIGRATING, &p->status); spin_unlock_irqrestore(&old->arch.vgic.lock, flags); + return true; } void arch_move_irqs(struct vcpu *v) diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h index 98932e7..6f3f245 100644 --- a/xen/include/asm-arm/vgic.h +++ b/xen/include/asm-arm/vgic.h @@ -311,7 +311,7 @@ extern int vcpu_vgic_free(struct vcpu *v); extern int vgic_to_sgi(struct vcpu *v, register_t sgir, enum gic_sgi_mode irqmode, int virq, const struct sgi_target *target); -extern void vgic_migrate_irq(struct vcpu *old, struct vcpu *new, unsigned int irq); +extern bool vgic_migrate_irq(struct vcpu *old, struct vcpu *new, unsigned int irq); /* Reserve a specific guest vIRQ */ extern bool_t vgic_reserve_virq(struct domain *d, unsigned int virq); -- generated by git-patchbot for /home/xen/git/xen.git#stable-4.7 _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |