[PATCH 4.16 017/110] KVM: arm/arm64: VGIC/ITS save/restore: protect kvm_read_guest() calls

From: Greg Kroah-Hartman
Date: Mon May 21 2018 - 16:57:30 EST


4.16-stable review patch. If anyone has any objections, please let me know.

------------------

From: Andre Przywara <andre.przywara@xxxxxxx>

commit 711702b57cc3c50b84bd648de0f1ca0a378805be upstream.

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@xxxxxxxxxxxxxxx> # 4.12+
Reported-by: Jan Glauber <jan.glauber@xxxxxxxxxxxxxxxxxx>
Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx>
Acked-by: Christoffer Dall <christoffer.dall@xxxxxxx>
Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
virt/kvm/arm/vgic/vgic-its.c | 4 ++--
virt/kvm/arm/vgic/vgic-v3.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)

--- a/virt/kvm/arm/vgic/vgic-its.c
+++ b/virt/kvm/arm/vgic/vgic-its.c
@@ -1896,7 +1896,7 @@ static int scan_its_table(struct vgic_it
int next_offset;
size_t byte_offset;

- ret = kvm_read_guest(kvm, gpa, entry, esz);
+ ret = kvm_read_guest_lock(kvm, gpa, entry, esz);
if (ret)
return ret;

@@ -2266,7 +2266,7 @@ static int vgic_its_restore_cte(struct v
int ret;

BUG_ON(esz > sizeof(val));
- ret = kvm_read_guest(kvm, gpa, &val, esz);
+ ret = kvm_read_guest_lock(kvm, gpa, &val, esz);
if (ret)
return ret;
val = le64_to_cpu(val);
--- a/virt/kvm/arm/vgic/vgic-v3.c
+++ b/virt/kvm/arm/vgic/vgic-v3.c
@@ -329,7 +329,7 @@ retry:
bit_nr = irq->intid % BITS_PER_BYTE;
ptr = pendbase + byte_offset;

- ret = kvm_read_guest(kvm, ptr, &val, 1);
+ ret = kvm_read_guest_lock(kvm, ptr, &val, 1);
if (ret)
return ret;

@@ -382,7 +382,7 @@ int vgic_v3_save_pending_tables(struct k
ptr = pendbase + 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)
return ret;
last_byte_offset = byte_offset;