From: Christoffer Dall <christoffer.dall@linaro.org> To: kvmarm@lists.cs.columbia.edu, linux-arm-kernel@lists.infradead.org Cc: Marc Zyngier <marc.zyngier@arm.com>, kvm@vger.kernel.org Subject: [PULL 04/12] KVM: arm64: vgic-its: Make updates to propbaser/pendbaser atomic Date: Wed, 17 Aug 2016 21:38:51 +0200 [thread overview] Message-ID: <20160817193859.15726-5-christoffer.dall@linaro.org> (raw) In-Reply-To: <20160817193859.15726-1-christoffer.dall@linaro.org> There are two problems with the current implementation of the MMIO handlers for the propbaser and pendbaser: First, the write to the value itself is not guaranteed to be an atomic 64-bit write so two concurrent writes to the structure field could be intermixed. Second, because we do a read-modify-update operation without any synchronization, if we have two 32-bit accesses to separate parts of the register, we can loose one of them. By using the atomic cmpxchg64 we should cover both issues above. Reviewed-by: Andre Przywara <andre.przywara@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org> --- virt/kvm/arm/vgic/vgic-mmio-v3.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c index ff668e0..90d8181 100644 --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c @@ -306,16 +306,19 @@ static void vgic_mmio_write_propbase(struct kvm_vcpu *vcpu, { struct vgic_dist *dist = &vcpu->kvm->arch.vgic; struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; - u64 propbaser = dist->propbaser; + u64 old_propbaser, propbaser; /* Storing a value with LPIs already enabled is undefined */ if (vgic_cpu->lpis_enabled) return; - propbaser = update_64bit_reg(propbaser, addr & 4, len, val); - propbaser = vgic_sanitise_propbaser(propbaser); - - dist->propbaser = propbaser; + do { + old_propbaser = dist->propbaser; + propbaser = old_propbaser; + propbaser = update_64bit_reg(propbaser, addr & 4, len, val); + propbaser = vgic_sanitise_propbaser(propbaser); + } while (cmpxchg64(&dist->propbaser, old_propbaser, + propbaser) != old_propbaser); } static unsigned long vgic_mmio_read_pendbase(struct kvm_vcpu *vcpu, @@ -331,16 +334,19 @@ static void vgic_mmio_write_pendbase(struct kvm_vcpu *vcpu, unsigned long val) { struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; - u64 pendbaser = vgic_cpu->pendbaser; + u64 old_pendbaser, pendbaser; /* Storing a value with LPIs already enabled is undefined */ if (vgic_cpu->lpis_enabled) return; - pendbaser = update_64bit_reg(pendbaser, addr & 4, len, val); - pendbaser = vgic_sanitise_pendbaser(pendbaser); - - vgic_cpu->pendbaser = pendbaser; + do { + old_pendbaser = vgic_cpu->pendbaser; + pendbaser = old_pendbaser; + pendbaser = update_64bit_reg(pendbaser, addr & 4, len, val); + pendbaser = vgic_sanitise_pendbaser(pendbaser); + } while (cmpxchg64(&vgic_cpu->pendbaser, old_pendbaser, + pendbaser) != old_pendbaser); } /* -- 2.9.0
WARNING: multiple messages have this Message-ID (diff)
From: christoffer.dall@linaro.org (Christoffer Dall) To: linux-arm-kernel@lists.infradead.org Subject: [PULL 04/12] KVM: arm64: vgic-its: Make updates to propbaser/pendbaser atomic Date: Wed, 17 Aug 2016 21:38:51 +0200 [thread overview] Message-ID: <20160817193859.15726-5-christoffer.dall@linaro.org> (raw) In-Reply-To: <20160817193859.15726-1-christoffer.dall@linaro.org> There are two problems with the current implementation of the MMIO handlers for the propbaser and pendbaser: First, the write to the value itself is not guaranteed to be an atomic 64-bit write so two concurrent writes to the structure field could be intermixed. Second, because we do a read-modify-update operation without any synchronization, if we have two 32-bit accesses to separate parts of the register, we can loose one of them. By using the atomic cmpxchg64 we should cover both issues above. Reviewed-by: Andre Przywara <andre.przywara@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org> --- virt/kvm/arm/vgic/vgic-mmio-v3.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c index ff668e0..90d8181 100644 --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c @@ -306,16 +306,19 @@ static void vgic_mmio_write_propbase(struct kvm_vcpu *vcpu, { struct vgic_dist *dist = &vcpu->kvm->arch.vgic; struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; - u64 propbaser = dist->propbaser; + u64 old_propbaser, propbaser; /* Storing a value with LPIs already enabled is undefined */ if (vgic_cpu->lpis_enabled) return; - propbaser = update_64bit_reg(propbaser, addr & 4, len, val); - propbaser = vgic_sanitise_propbaser(propbaser); - - dist->propbaser = propbaser; + do { + old_propbaser = dist->propbaser; + propbaser = old_propbaser; + propbaser = update_64bit_reg(propbaser, addr & 4, len, val); + propbaser = vgic_sanitise_propbaser(propbaser); + } while (cmpxchg64(&dist->propbaser, old_propbaser, + propbaser) != old_propbaser); } static unsigned long vgic_mmio_read_pendbase(struct kvm_vcpu *vcpu, @@ -331,16 +334,19 @@ static void vgic_mmio_write_pendbase(struct kvm_vcpu *vcpu, unsigned long val) { struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; - u64 pendbaser = vgic_cpu->pendbaser; + u64 old_pendbaser, pendbaser; /* Storing a value with LPIs already enabled is undefined */ if (vgic_cpu->lpis_enabled) return; - pendbaser = update_64bit_reg(pendbaser, addr & 4, len, val); - pendbaser = vgic_sanitise_pendbaser(pendbaser); - - vgic_cpu->pendbaser = pendbaser; + do { + old_pendbaser = vgic_cpu->pendbaser; + pendbaser = old_pendbaser; + pendbaser = update_64bit_reg(pendbaser, addr & 4, len, val); + pendbaser = vgic_sanitise_pendbaser(pendbaser); + } while (cmpxchg64(&vgic_cpu->pendbaser, old_pendbaser, + pendbaser) != old_pendbaser); } /* -- 2.9.0
next prev parent reply other threads:[~2016-08-17 19:38 UTC|newest] Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-08-17 19:38 [PULL 00/12] KVM/ARM Fixes for v4.8-rc3 Christoffer Dall 2016-08-17 19:38 ` Christoffer Dall 2016-08-17 19:38 ` [PULL 01/12] KVM: arm64: ITS: return 1 on successful MSI injection Christoffer Dall 2016-08-17 19:38 ` Christoffer Dall 2016-08-17 19:38 ` [PULL 02/12] KVM: arm64: vgic-its: Handle errors from vgic_add_lpi Christoffer Dall 2016-08-17 19:38 ` Christoffer Dall 2016-08-17 19:38 ` [PULL 03/12] KVM: arm64: vgic-its: Plug race in vgic_put_irq Christoffer Dall 2016-08-17 19:38 ` Christoffer Dall 2016-08-17 19:38 ` Christoffer Dall [this message] 2016-08-17 19:38 ` [PULL 04/12] KVM: arm64: vgic-its: Make updates to propbaser/pendbaser atomic Christoffer Dall 2016-08-17 19:38 ` [PULL 05/12] KVM: arm64: ITS: move ITS registration into first VCPU run Christoffer Dall 2016-08-17 19:38 ` Christoffer Dall 2016-08-17 19:38 ` [PULL 06/12] KVM: arm64: check for ITS device on MSI injection Christoffer Dall 2016-08-17 19:38 ` Christoffer Dall 2016-08-17 19:38 ` [PULL 07/12] KVM: arm64: ITS: avoid re-mapping LPIs Christoffer Dall 2016-08-17 19:38 ` Christoffer Dall 2016-08-17 19:38 ` [PULL 08/12] KVM: arm/arm64: Change misleading use of is_error_pfn Christoffer Dall 2016-08-17 19:38 ` Christoffer Dall 2016-08-17 19:38 ` [PULL 09/12] arm64: Document workaround for Cortex-A72 erratum #853709 Christoffer Dall 2016-08-17 19:38 ` Christoffer Dall 2016-08-17 19:38 ` [PULL 10/12] KVM: arm/arm64: timer: Workaround misconfigured timer interrupt Christoffer Dall 2016-08-17 19:38 ` Christoffer Dall 2016-08-17 19:38 ` [PULL 11/12] arm64: KVM: remove misleading comment on pmu status Christoffer Dall 2016-08-17 19:38 ` Christoffer Dall 2016-08-17 19:38 ` [PULL 12/12] arm64: KVM: report configured SRE value to 32-bit world Christoffer Dall 2016-08-17 19:38 ` Christoffer Dall 2016-08-18 10:19 ` [PULL 00/12] KVM/ARM Fixes for v4.8-rc3 Paolo Bonzini 2016-08-18 10:19 ` Paolo Bonzini
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=20160817193859.15726-5-christoffer.dall@linaro.org \ --to=christoffer.dall@linaro.org \ --cc=kvm@vger.kernel.org \ --cc=kvmarm@lists.cs.columbia.edu \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=marc.zyngier@arm.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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.