KVM: arm/arm64: VGIC/ITS save/restore: protect kvm_read_guest() calls

kvm_read_guest() will eventually look up in kvm_memslots(), which requires
either to hold the kvm->slots_lock or to be inside a kvm->srcu critical
section.
In contrast to x86 and s390 we don't take the SRCU lock on every guest
exit, so we have to do it individually for each kvm_read_guest() call.
Use the newly introduced wrapper for that.

Cc: Stable <stable@vger.kernel.org> # 4.12+
Reported-by: Jan Glauber <jan.glauber@caviumnetworks.com>
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Acked-by: Christoffer Dall <christoffer.dall@arm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Andre Przywara 2018-05-11 15:20:15 +01:00 committed by Paolo Bonzini
parent bf308242ab
commit 711702b57c
2 changed files with 4 additions and 4 deletions

View File

@ -1897,7 +1897,7 @@ static int scan_its_table(struct vgic_its *its, gpa_t base, int size, int esz,
int next_offset; int next_offset;
size_t byte_offset; size_t byte_offset;
ret = kvm_read_guest(kvm, gpa, entry, esz); ret = kvm_read_guest_lock(kvm, gpa, entry, esz);
if (ret) if (ret)
return ret; return ret;
@ -2267,7 +2267,7 @@ static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa, int esz)
int ret; int ret;
BUG_ON(esz > sizeof(val)); BUG_ON(esz > sizeof(val));
ret = kvm_read_guest(kvm, gpa, &val, esz); ret = kvm_read_guest_lock(kvm, gpa, &val, esz);
if (ret) if (ret)
return ret; return ret;
val = le64_to_cpu(val); val = le64_to_cpu(val);

View File

@ -344,7 +344,7 @@ retry:
bit_nr = irq->intid % BITS_PER_BYTE; bit_nr = irq->intid % BITS_PER_BYTE;
ptr = pendbase + byte_offset; ptr = pendbase + byte_offset;
ret = kvm_read_guest(kvm, ptr, &val, 1); ret = kvm_read_guest_lock(kvm, ptr, &val, 1);
if (ret) if (ret)
return ret; return ret;
@ -397,7 +397,7 @@ int vgic_v3_save_pending_tables(struct kvm *kvm)
ptr = pendbase + byte_offset; ptr = pendbase + byte_offset;
if (byte_offset != last_byte_offset) { if (byte_offset != last_byte_offset) {
ret = kvm_read_guest(kvm, ptr, &val, 1); ret = kvm_read_guest_lock(kvm, ptr, &val, 1);
if (ret) if (ret)
return ret; return ret;
last_byte_offset = byte_offset; last_byte_offset = byte_offset;