Message ID | 1527736557-11084-2-git-send-email-zhaoshenglong@huawei.com |
---|---|
State | New |
Headers | show |
Series | Fix ARM KVM GICv3 get/put data shift bug | expand |
Hi, On 05/31/2018 05:15 AM, Shannon Zhao wrote: > While for_each_dist_irq_reg loop starts from GIC_INTERNAL, it forgot to > offset the date array and index. This will overlap the GICR registers > value and leave the last GIC_INTERNAL irq's registers out of update. > > Fixes: 367b9f527becdd20ddf116e17a3c0c2bbc486920 > Cc: qemu-stable@nongnu.org > Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Eric Auger <eric.auger@redhat.com> Thanks Eric > Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com> > --- > hw/intc/arm_gicv3_kvm.c | 18 ++++++++++++++++-- > 1 file changed, 16 insertions(+), 2 deletions(-) > > diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c > index 3536795..147e691 100644 > --- a/hw/intc/arm_gicv3_kvm.c > +++ b/hw/intc/arm_gicv3_kvm.c > @@ -135,7 +135,14 @@ static void kvm_dist_get_priority(GICv3State *s, uint32_t offset, uint8_t *bmp) > uint32_t reg, *field; > int irq; > > - field = (uint32_t *)bmp; > + /* For the KVM GICv3, affinity routing is always enabled, and the first 8 > + * GICD_IPRIORITYR<n> registers are always RAZ/WI. The corresponding > + * functionality is replaced by GICR_IPRIORITYR<n>. It doesn't need to > + * sync them. So it needs to skip the field of GIC_INTERNAL irqs in bmp and > + * offset. > + */ > + field = (uint32_t *)(bmp + GIC_INTERNAL); > + offset += (GIC_INTERNAL * 8) / 8; > for_each_dist_irq_reg(irq, s->num_irq, 8) { > kvm_gicd_access(s, offset, ®, false); > *field = reg; > @@ -149,7 +156,14 @@ static void kvm_dist_put_priority(GICv3State *s, uint32_t offset, uint8_t *bmp) > uint32_t reg, *field; > int irq; > > - field = (uint32_t *)bmp; > + /* For the KVM GICv3, affinity routing is always enabled, and the first 8 > + * GICD_IPRIORITYR<n> registers are always RAZ/WI. The corresponding > + * functionality is replaced by GICR_IPRIORITYR<n>. It doesn't need to > + * sync them. So it needs to skip the field of GIC_INTERNAL irqs in bmp and > + * offset. > + */ > + field = (uint32_t *)(bmp + GIC_INTERNAL); > + offset += (GIC_INTERNAL * 8) / 8; > for_each_dist_irq_reg(irq, s->num_irq, 8) { > reg = *field; > kvm_gicd_access(s, offset, ®, true); >
On 2018/5/31 19:01, Auger Eric wrote: > Hi, > > On 05/31/2018 05:15 AM, Shannon Zhao wrote: >> While for_each_dist_irq_reg loop starts from GIC_INTERNAL, it forgot to >> offset the date array and index. This will overlap the GICR registers >> value and leave the last GIC_INTERNAL irq's registers out of update. >> >> Fixes: 367b9f527becdd20ddf116e17a3c0c2bbc486920 >> Cc: qemu-stable@nongnu.org >> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> > Reviewed-by: Eric Auger <eric.auger@redhat.com> > Hi Peter, Looks like we missed picking up this patch. I didn't include this in v6 since you and Eric both reviewed it. Could you please pick it up? Thanks,
On 11 June 2018 at 09:32, Shannon Zhao <zhaoshenglong@huawei.com> wrote: > Hi Peter, > > Looks like we missed picking up this patch. I didn't include this in v6 > since you and Eric both reviewed it. > > Could you please pick it up? Oops; added to target-arm.next. (I generally forget entirely about vN of a patchset as soon as vN+1 appears on the list, so better not to drop patches from a set unless I've specifically said I've put them in target-arm.next or they're on the list as their own patchset.) thanks -- PMM
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c index 3536795..147e691 100644 --- a/hw/intc/arm_gicv3_kvm.c +++ b/hw/intc/arm_gicv3_kvm.c @@ -135,7 +135,14 @@ static void kvm_dist_get_priority(GICv3State *s, uint32_t offset, uint8_t *bmp) uint32_t reg, *field; int irq; - field = (uint32_t *)bmp; + /* For the KVM GICv3, affinity routing is always enabled, and the first 8 + * GICD_IPRIORITYR<n> registers are always RAZ/WI. The corresponding + * functionality is replaced by GICR_IPRIORITYR<n>. It doesn't need to + * sync them. So it needs to skip the field of GIC_INTERNAL irqs in bmp and + * offset. + */ + field = (uint32_t *)(bmp + GIC_INTERNAL); + offset += (GIC_INTERNAL * 8) / 8; for_each_dist_irq_reg(irq, s->num_irq, 8) { kvm_gicd_access(s, offset, ®, false); *field = reg; @@ -149,7 +156,14 @@ static void kvm_dist_put_priority(GICv3State *s, uint32_t offset, uint8_t *bmp) uint32_t reg, *field; int irq; - field = (uint32_t *)bmp; + /* For the KVM GICv3, affinity routing is always enabled, and the first 8 + * GICD_IPRIORITYR<n> registers are always RAZ/WI. The corresponding + * functionality is replaced by GICR_IPRIORITYR<n>. It doesn't need to + * sync them. So it needs to skip the field of GIC_INTERNAL irqs in bmp and + * offset. + */ + field = (uint32_t *)(bmp + GIC_INTERNAL); + offset += (GIC_INTERNAL * 8) / 8; for_each_dist_irq_reg(irq, s->num_irq, 8) { reg = *field; kvm_gicd_access(s, offset, ®, true);