aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2019-03-19 08:47:11 -0400
committerMarc Zyngier <marc.zyngier@arm.com>2019-03-19 13:56:56 -0400
commita6ecfb11bf37743c1ac49b266595582b107b61d4 (patch)
treefc59b321a1e01e5e99c087f7bf304364d90110c9 /virt/kvm
parentca71228b42a96908eca7658861eafacd227856c9 (diff)
KVM: arm/arm64: vgic-its: Take the srcu lock when writing to guest memory
When halting a guest, QEMU flushes the virtual ITS caches, which amounts to writing to the various tables that the guest has allocated. When doing this, we fail to take the srcu lock, and the kernel shouts loudly if running a lockdep kernel: [ 69.680416] ============================= [ 69.680819] WARNING: suspicious RCU usage [ 69.681526] 5.1.0-rc1-00008-g600025238f51-dirty #18 Not tainted [ 69.682096] ----------------------------- [ 69.682501] ./include/linux/kvm_host.h:605 suspicious rcu_dereference_check() usage! [ 69.683225] [ 69.683225] other info that might help us debug this: [ 69.683225] [ 69.683975] [ 69.683975] rcu_scheduler_active = 2, debug_locks = 1 [ 69.684598] 6 locks held by qemu-system-aar/4097: [ 69.685059] #0: 0000000034196013 (&kvm->lock){+.+.}, at: vgic_its_set_attr+0x244/0x3a0 [ 69.686087] #1: 00000000f2ed935e (&its->its_lock){+.+.}, at: vgic_its_set_attr+0x250/0x3a0 [ 69.686919] #2: 000000005e71ea54 (&vcpu->mutex){+.+.}, at: lock_all_vcpus+0x64/0xd0 [ 69.687698] #3: 00000000c17e548d (&vcpu->mutex){+.+.}, at: lock_all_vcpus+0x64/0xd0 [ 69.688475] #4: 00000000ba386017 (&vcpu->mutex){+.+.}, at: lock_all_vcpus+0x64/0xd0 [ 69.689978] #5: 00000000c2c3c335 (&vcpu->mutex){+.+.}, at: lock_all_vcpus+0x64/0xd0 [ 69.690729] [ 69.690729] stack backtrace: [ 69.691151] CPU: 2 PID: 4097 Comm: qemu-system-aar Not tainted 5.1.0-rc1-00008-g600025238f51-dirty #18 [ 69.691984] Hardware name: rockchip evb_rk3399/evb_rk3399, BIOS 2019.04-rc3-00124-g2feec69fb1 03/15/2019 [ 69.692831] Call trace: [ 69.694072] lockdep_rcu_suspicious+0xcc/0x110 [ 69.694490] gfn_to_memslot+0x174/0x190 [ 69.694853] kvm_write_guest+0x50/0xb0 [ 69.695209] vgic_its_save_tables_v0+0x248/0x330 [ 69.695639] vgic_its_set_attr+0x298/0x3a0 [ 69.696024] kvm_device_ioctl_attr+0x9c/0xd8 [ 69.696424] kvm_device_ioctl+0x8c/0xf8 [ 69.696788] do_vfs_ioctl+0xc8/0x960 [ 69.697128] ksys_ioctl+0x8c/0xa0 [ 69.697445] __arm64_sys_ioctl+0x28/0x38 [ 69.697817] el0_svc_common+0xd8/0x138 [ 69.698173] el0_svc_handler+0x38/0x78 [ 69.698528] el0_svc+0x8/0xc The fix is to obviously take the srcu lock, just like we do on the read side of things since bf308242ab98. One wonders why this wasn't fixed at the same time, but hey... Fixes: bf308242ab98 ("KVM: arm/arm64: VGIC/ITS: protect kvm_read_guest() calls with SRCU lock") Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'virt/kvm')
-rw-r--r--virt/kvm/arm/vgic/vgic-its.c8
-rw-r--r--virt/kvm/arm/vgic/vgic-v3.c4
2 files changed, 6 insertions, 6 deletions
diff --git a/virt/kvm/arm/vgic/vgic-its.c b/virt/kvm/arm/vgic/vgic-its.c
index ab3f47745d9c..c41e11fd841c 100644
--- a/virt/kvm/arm/vgic/vgic-its.c
+++ b/virt/kvm/arm/vgic/vgic-its.c
@@ -1919,7 +1919,7 @@ static int vgic_its_save_ite(struct vgic_its *its, struct its_device *dev,
1919 ((u64)ite->irq->intid << KVM_ITS_ITE_PINTID_SHIFT) | 1919 ((u64)ite->irq->intid << KVM_ITS_ITE_PINTID_SHIFT) |
1920 ite->collection->collection_id; 1920 ite->collection->collection_id;
1921 val = cpu_to_le64(val); 1921 val = cpu_to_le64(val);
1922 return kvm_write_guest(kvm, gpa, &val, ite_esz); 1922 return kvm_write_guest_lock(kvm, gpa, &val, ite_esz);
1923} 1923}
1924 1924
1925/** 1925/**
@@ -2066,7 +2066,7 @@ static int vgic_its_save_dte(struct vgic_its *its, struct its_device *dev,
2066 (itt_addr_field << KVM_ITS_DTE_ITTADDR_SHIFT) | 2066 (itt_addr_field << KVM_ITS_DTE_ITTADDR_SHIFT) |
2067 (dev->num_eventid_bits - 1)); 2067 (dev->num_eventid_bits - 1));
2068 val = cpu_to_le64(val); 2068 val = cpu_to_le64(val);
2069 return kvm_write_guest(kvm, ptr, &val, dte_esz); 2069 return kvm_write_guest_lock(kvm, ptr, &val, dte_esz);
2070} 2070}
2071 2071
2072/** 2072/**
@@ -2246,7 +2246,7 @@ static int vgic_its_save_cte(struct vgic_its *its,
2246 ((u64)collection->target_addr << KVM_ITS_CTE_RDBASE_SHIFT) | 2246 ((u64)collection->target_addr << KVM_ITS_CTE_RDBASE_SHIFT) |
2247 collection->collection_id); 2247 collection->collection_id);
2248 val = cpu_to_le64(val); 2248 val = cpu_to_le64(val);
2249 return kvm_write_guest(its->dev->kvm, gpa, &val, esz); 2249 return kvm_write_guest_lock(its->dev->kvm, gpa, &val, esz);
2250} 2250}
2251 2251
2252static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa, int esz) 2252static int vgic_its_restore_cte(struct vgic_its *its, gpa_t gpa, int esz)
@@ -2317,7 +2317,7 @@ static int vgic_its_save_collection_table(struct vgic_its *its)
2317 */ 2317 */
2318 val = 0; 2318 val = 0;
2319 BUG_ON(cte_esz > sizeof(val)); 2319 BUG_ON(cte_esz > sizeof(val));
2320 ret = kvm_write_guest(its->dev->kvm, gpa, &val, cte_esz); 2320 ret = kvm_write_guest_lock(its->dev->kvm, gpa, &val, cte_esz);
2321 return ret; 2321 return ret;
2322} 2322}
2323 2323
diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
index 408a78eb6a97..9f87e58dbd4a 100644
--- a/virt/kvm/arm/vgic/vgic-v3.c
+++ b/virt/kvm/arm/vgic/vgic-v3.c
@@ -358,7 +358,7 @@ retry:
358 if (status) { 358 if (status) {
359 /* clear consumed data */ 359 /* clear consumed data */
360 val &= ~(1 << bit_nr); 360 val &= ~(1 << bit_nr);
361 ret = kvm_write_guest(kvm, ptr, &val, 1); 361 ret = kvm_write_guest_lock(kvm, ptr, &val, 1);
362 if (ret) 362 if (ret)
363 return ret; 363 return ret;
364 } 364 }
@@ -409,7 +409,7 @@ int vgic_v3_save_pending_tables(struct kvm *kvm)
409 else 409 else
410 val &= ~(1 << bit_nr); 410 val &= ~(1 << bit_nr);
411 411
412 ret = kvm_write_guest(kvm, ptr, &val, 1); 412 ret = kvm_write_guest_lock(kvm, ptr, &val, 1);
413 if (ret) 413 if (ret)
414 return ret; 414 return ret;
415 } 415 }