[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] xen/arm: vgic-v3: Clean the emulation of IROUTER
On Mon, May 25, 2015 at 09:44:20PM +0100, Julien Grall wrote: > The read emulation of the register IROUTER contains lots of uncessary > code as irouter is already valid and doesn't need any processing before > setting the value in a register. > > Also take the opportunity to factorize the code to find a vCPU from the > affinity in a single place. It will be easier to change the way to do it > later. > > Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx> > Cc: Chen Baozi <cbz@xxxxxxxxxx> Acked-by: Chen Baozi <baozich@xxxxxxxxx> > --- > xen/arch/arm/vgic-v3.c | 100 > ++++++++++++++++++------------------------------- > 1 file changed, 36 insertions(+), 64 deletions(-) > > diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c > index 45a46c3..4af5a84 100644 > --- a/xen/arch/arm/vgic-v3.c > +++ b/xen/arch/arm/vgic-v3.c > @@ -50,42 +50,36 @@ > */ > #define VGICD_CTLR_DEFAULT (GICD_CTLR_ARE_NS) > > -static struct vcpu *vgic_v3_irouter_to_vcpu(struct vcpu *v, uint64_t irouter) > +static struct vcpu *vgic_v3_irouter_to_vcpu(struct domain *d, uint64_t > irouter) > { > - irouter &= ~(GICD_IROUTER_SPI_MODE_ANY); > - irouter = irouter & MPIDR_AFF0_MASK; > - > - return v->domain->vcpu[irouter]; > -} > + unsigned int vcpu_id; > > -static uint64_t vgic_v3_vcpu_to_irouter(struct vcpu *v, > - unsigned int vcpu_id) > -{ > - uint64_t irq_affinity; > - struct vcpu *v_target; > + /* > + * When the Interrupt Route Mode is set, the IRQ targets any vCPUs. > + * For simplicity, the IRQ is always routed to vCPU0. > + */ > + if ( irouter & GICD_IROUTER_SPI_MODE_ANY ) > + return d->vcpu[0]; > > - v_target = v->domain->vcpu[vcpu_id]; > - irq_affinity = (MPIDR_AFFINITY_LEVEL(v_target->arch.vmpidr, 3) << 32 | > - MPIDR_AFFINITY_LEVEL(v_target->arch.vmpidr, 2) << 16 | > - MPIDR_AFFINITY_LEVEL(v_target->arch.vmpidr, 1) << 8 | > - MPIDR_AFFINITY_LEVEL(v_target->arch.vmpidr, 0)); > + vcpu_id = irouter & MPIDR_AFF0_MASK; > + if ( vcpu_id >= d->max_vcpus ) > + return NULL; > > - return irq_affinity; > + return d->vcpu[vcpu_id]; > } > > static struct vcpu *vgic_v3_get_target_vcpu(struct vcpu *v, unsigned int irq) > { > - uint64_t target; > + struct vcpu *v_target; > struct vgic_irq_rank *rank = vgic_rank_irq(v, irq); > > ASSERT(spin_is_locked(&rank->lock)); > > - target = rank->v3.irouter[irq % 32]; > - target &= ~(GICD_IROUTER_SPI_MODE_ANY); > - target &= MPIDR_AFF0_MASK; > - ASSERT(target >= 0 && target < v->domain->max_vcpus); > + v_target = vgic_v3_irouter_to_vcpu(v->domain, rank->v3.irouter[irq % > 32]); > > - return v->domain->vcpu[target]; > + ASSERT(v_target != NULL); > + > + return v_target; > } > > static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info, > @@ -670,8 +664,6 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, > mmio_info_t *info) > register_t *r = select_user_reg(regs, dabt.reg); > struct vgic_irq_rank *rank; > unsigned long flags; > - uint64_t irouter; > - unsigned int vcpu_id; > int gicd_reg = (int)(info->gpa - v->domain->arch.vgic.dbase); > > perfc_incr(vgicd_reads); > @@ -742,17 +734,8 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, > mmio_info_t *info) > DABT_DOUBLE_WORD); > if ( rank == NULL ) goto read_as_zero; > vgic_lock_rank(v, rank, flags); > - irouter = rank->v3.irouter[REG_RANK_INDEX(64, > - (gicd_reg - GICD_IROUTER), > DABT_DOUBLE_WORD)]; > - /* XXX: bit[31] stores IRQ mode. Just return */ > - if ( irouter & GICD_IROUTER_SPI_MODE_ANY ) > - { > - *r = GICD_IROUTER_SPI_MODE_ANY; > - vgic_unlock_rank(v, rank, flags); > - return 1; > - } > - vcpu_id = irouter; > - *r = vgic_v3_vcpu_to_irouter(v, vcpu_id); > + *r = rank->v3.irouter[REG_RANK_INDEX(64, > + (gicd_reg - GICD_IROUTER), DABT_DOUBLE_WORD)]; > vgic_unlock_rank(v, rank, flags); > return 1; > case GICD_NSACR ... GICD_NSACRN: > @@ -838,7 +821,7 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, > mmio_info_t *info) > register_t *r = select_user_reg(regs, dabt.reg); > struct vgic_irq_rank *rank; > unsigned long flags; > - uint64_t new_irouter, new_target, old_target; > + uint64_t new_irouter, old_irouter; > struct vcpu *old_vcpu, *new_vcpu; > int gicd_reg = (int)(info->gpa - v->domain->arch.vgic.dbase); > > @@ -910,40 +893,29 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, > mmio_info_t *info) > new_irouter = *r; > vgic_lock_rank(v, rank, flags); > > - old_target = rank->v3.irouter[REG_RANK_INDEX(64, > - (gicd_reg - GICD_IROUTER), DABT_DOUBLE_WORD)]; > - old_target &= ~(GICD_IROUTER_SPI_MODE_ANY); > - if ( new_irouter & GICD_IROUTER_SPI_MODE_ANY ) > + old_irouter = rank->v3.irouter[REG_RANK_INDEX(64, > + (gicd_reg - GICD_IROUTER), > + DABT_DOUBLE_WORD)]; > + old_vcpu = vgic_v3_irouter_to_vcpu(v->domain, old_irouter); > + new_vcpu = vgic_v3_irouter_to_vcpu(v->domain, new_irouter); > + > + if ( !new_vcpu ) > { > + printk(XENLOG_G_DEBUG > + "%pv: vGICD: wrong irouter at offset %#08x val > %#"PRIregister, > + v, gicd_reg, *r); > + vgic_unlock_rank(v, rank, flags); > /* > - * IRQ routing mode set. Route any one processor in the entire > - * system. We chose vcpu 0 and set IRQ mode bit[31] in irouter. > + * TODO: Don't inject a fault to the guest when the MPIDR is > + * not valid. From the spec, the interrupt should be > + * ignored. > */ > - new_target = 0; > - new_vcpu = v->domain->vcpu[0]; > - new_irouter = GICD_IROUTER_SPI_MODE_ANY; > - } > - else > - { > - new_target = new_irouter & MPIDR_AFF0_MASK; > - if ( new_target >= v->domain->max_vcpus ) > - { > - printk(XENLOG_G_DEBUG > - "%pv: vGICD: wrong irouter at offset %#08x\n val > 0x%lx vcpu %x", > - v, gicd_reg, new_target, v->domain->max_vcpus); > - vgic_unlock_rank(v, rank, flags); > - return 0; > - } > - new_vcpu = vgic_v3_irouter_to_vcpu(v, new_irouter); > + return 0; > } > - > rank->v3.irouter[REG_RANK_INDEX(64, (gicd_reg - GICD_IROUTER), > DABT_DOUBLE_WORD)] = new_irouter; > - if ( old_target != new_target ) > - { > - old_vcpu = v->domain->vcpu[old_target]; > + if ( old_vcpu != new_vcpu ) > vgic_migrate_irq(old_vcpu, new_vcpu, (gicd_reg - > GICD_IROUTER)/8); > - } > vgic_unlock_rank(v, rank, flags); > return 1; > case GICD_NSACR ... GICD_NSACRN: > -- > 2.1.4 > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@xxxxxxxxxxxxx > http://lists.xen.org/xen-devel _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |