Message ID | 20180315203050.19791-32-andre.przywara@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | New VGIC(-v2) implementation | expand |
Hi Andre, On 03/15/2018 08:30 PM, Andre Przywara wrote: > Triggering an IPI via this register is v2 specific, so the > implementation lives entirely in vgic-mmio-v2.c. > > This is based on Linux commit 55cc01fb9004, written by Andre Przywara. > > Signed-off-by: Andre Przywara <andre.przywara@linaro.org> > --- > Changelog v1 ... v2: > - remove stray rebase artefact > > xen/arch/arm/vgic/vgic-mmio-v2.c | 45 +++++++++++++++++++++++++++++++++++++++- > 1 file changed, 44 insertions(+), 1 deletion(-) > > diff --git a/xen/arch/arm/vgic/vgic-mmio-v2.c b/xen/arch/arm/vgic/vgic-mmio-v2.c > index b333de9ed7..7e17cdc2ad 100644 > --- a/xen/arch/arm/vgic/vgic-mmio-v2.c > +++ b/xen/arch/arm/vgic/vgic-mmio-v2.c > @@ -81,6 +81,49 @@ static void vgic_mmio_write_v2_misc(struct vcpu *vcpu, > } > } > > +static void vgic_mmio_write_sgir(struct vcpu *source_vcpu, > + paddr_t addr, unsigned int len, > + unsigned long val) > +{ > + struct domain *d = source_vcpu->domain; > + unsigned int nr_vcpus = d->max_vcpus; > + unsigned int intid = val & GICD_SGI_INTID_MASK; > + unsigned long targets = (val & GICD_SGI_TARGET_MASK) >> > + GICD_SGI_TARGET_SHIFT; > + unsigned int vcpu_id; > + > + switch ( val & GICD_SGI_TARGET_LIST_MASK ) > + { > + case GICD_SGI_TARGET_LIST: /* as specified by targets */ > + targets &= GENMASK(nr_vcpus, 0); /* limit to existing VCPUs */ Shouldn't it be 'nr_vcpus - 1'? > + break; > + case GICD_SGI_TARGET_OTHERS: > + targets = GENMASK(nr_vcpus, 0); /* all, ... */ > + targets &= ~(1U << source_vcpu->vcpu_id); /* but self */ > + break; > + case GICD_SGI_TARGET_SELF: /* this very vCPU only */ > + targets = (1U << source_vcpu->vcpu_id); > + break; > + case 0x3: /* reserved */ > + return; > + } Cheers,
Hi, On 19/03/18 09:47, Julien Grall wrote: > Hi Andre, > > On 03/15/2018 08:30 PM, Andre Przywara wrote: >> Triggering an IPI via this register is v2 specific, so the >> implementation lives entirely in vgic-mmio-v2.c. >> >> This is based on Linux commit 55cc01fb9004, written by Andre Przywara. >> >> Signed-off-by: Andre Przywara <andre.przywara@linaro.org> >> --- >> Changelog v1 ... v2: >> - remove stray rebase artefact >> >> xen/arch/arm/vgic/vgic-mmio-v2.c | 45 >> +++++++++++++++++++++++++++++++++++++++- >> 1 file changed, 44 insertions(+), 1 deletion(-) >> >> diff --git a/xen/arch/arm/vgic/vgic-mmio-v2.c >> b/xen/arch/arm/vgic/vgic-mmio-v2.c >> index b333de9ed7..7e17cdc2ad 100644 >> --- a/xen/arch/arm/vgic/vgic-mmio-v2.c >> +++ b/xen/arch/arm/vgic/vgic-mmio-v2.c >> @@ -81,6 +81,49 @@ static void vgic_mmio_write_v2_misc(struct vcpu *vcpu, >> } >> } >> +static void vgic_mmio_write_sgir(struct vcpu *source_vcpu, >> + paddr_t addr, unsigned int len, >> + unsigned long val) >> +{ >> + struct domain *d = source_vcpu->domain; >> + unsigned int nr_vcpus = d->max_vcpus; >> + unsigned int intid = val & GICD_SGI_INTID_MASK; >> + unsigned long targets = (val & GICD_SGI_TARGET_MASK) >> >> + GICD_SGI_TARGET_SHIFT; >> + unsigned int vcpu_id; >> + >> + switch ( val & GICD_SGI_TARGET_LIST_MASK ) >> + { >> + case GICD_SGI_TARGET_LIST: /* as specified by >> targets */ >> + targets &= GENMASK(nr_vcpus, 0); /* limit to >> existing VCPUs */ > > Shouldn't it be 'nr_vcpus - 1'? D'oh! Indeed looks like it. Thanks for catching this! Cheers, Andre. >> + break; >> + case GICD_SGI_TARGET_OTHERS: >> + targets = GENMASK(nr_vcpus, 0); /* all, ... */ >> + targets &= ~(1U << source_vcpu->vcpu_id); /* but self */ >> + break; >> + case GICD_SGI_TARGET_SELF: /* this very vCPU >> only */ >> + targets = (1U << source_vcpu->vcpu_id); >> + break; >> + case 0x3: /* reserved */ >> + return; >> + } > > Cheers, >
diff --git a/xen/arch/arm/vgic/vgic-mmio-v2.c b/xen/arch/arm/vgic/vgic-mmio-v2.c index b333de9ed7..7e17cdc2ad 100644 --- a/xen/arch/arm/vgic/vgic-mmio-v2.c +++ b/xen/arch/arm/vgic/vgic-mmio-v2.c @@ -81,6 +81,49 @@ static void vgic_mmio_write_v2_misc(struct vcpu *vcpu, } } +static void vgic_mmio_write_sgir(struct vcpu *source_vcpu, + paddr_t addr, unsigned int len, + unsigned long val) +{ + struct domain *d = source_vcpu->domain; + unsigned int nr_vcpus = d->max_vcpus; + unsigned int intid = val & GICD_SGI_INTID_MASK; + unsigned long targets = (val & GICD_SGI_TARGET_MASK) >> + GICD_SGI_TARGET_SHIFT; + unsigned int vcpu_id; + + switch ( val & GICD_SGI_TARGET_LIST_MASK ) + { + case GICD_SGI_TARGET_LIST: /* as specified by targets */ + targets &= GENMASK(nr_vcpus, 0); /* limit to existing VCPUs */ + break; + case GICD_SGI_TARGET_OTHERS: + targets = GENMASK(nr_vcpus, 0); /* all, ... */ + targets &= ~(1U << source_vcpu->vcpu_id); /* but self */ + break; + case GICD_SGI_TARGET_SELF: /* this very vCPU only */ + targets = (1U << source_vcpu->vcpu_id); + break; + case 0x3: /* reserved */ + return; + } + + for_each_set_bit( vcpu_id, &targets, 8 ) + { + struct vcpu *vcpu = d->vcpu[vcpu_id]; + struct vgic_irq *irq = vgic_get_irq(d, vcpu, intid); + unsigned long flags; + + spin_lock_irqsave(&irq->irq_lock, flags); + + irq->pending_latch = true; + irq->source |= 1U << source_vcpu->vcpu_id; + + vgic_queue_irq_unlock(d, irq, flags); + vgic_put_irq(d, irq); + } +} + static unsigned long vgic_mmio_read_target(struct vcpu *vcpu, paddr_t addr, unsigned int len) { @@ -173,7 +216,7 @@ static const struct vgic_register_region vgic_v2_dist_registers[] = { vgic_mmio_read_config, vgic_mmio_write_config, 2, VGIC_ACCESS_32bit), REGISTER_DESC_WITH_LENGTH(GICD_SGIR, - vgic_mmio_read_raz, vgic_mmio_write_wi, 4, + vgic_mmio_read_raz, vgic_mmio_write_sgir, 4, VGIC_ACCESS_32bit), REGISTER_DESC_WITH_LENGTH(GICD_CPENDSGIR, vgic_mmio_read_raz, vgic_mmio_write_wi, 16,
Triggering an IPI via this register is v2 specific, so the implementation lives entirely in vgic-mmio-v2.c. This is based on Linux commit 55cc01fb9004, written by Andre Przywara. Signed-off-by: Andre Przywara <andre.przywara@linaro.org> --- Changelog v1 ... v2: - remove stray rebase artefact xen/arch/arm/vgic/vgic-mmio-v2.c | 45 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-)