Commit 59112e9
KVM: arm64: vgic: Fix a circular locking issue
Lockdep reports a circular lock dependency between the srcu and the
config_lock:
[ 262.179917] -> #1 (&kvm->srcu){.+.+}-{0:0}:
[ 262.182010] __synchronize_srcu+0xb0/0x224
[ 262.183422] synchronize_srcu_expedited+0x24/0x34
[ 262.184554] kvm_io_bus_register_dev+0x324/0x50c
[ 262.185650] vgic_register_redist_iodev+0x254/0x398
[ 262.186740] vgic_v3_set_redist_base+0x3b0/0x724
[ 262.188087] kvm_vgic_addr+0x364/0x600
[ 262.189189] vgic_set_common_attr+0x90/0x544
[ 262.190278] vgic_v3_set_attr+0x74/0x9c
[ 262.191432] kvm_device_ioctl+0x2a0/0x4e4
[ 262.192515] __arm64_sys_ioctl+0x7ac/0x1ba8
[ 262.193612] invoke_syscall.constprop.0+0x70/0x1e0
[ 262.195006] do_el0_svc+0xe4/0x2d4
[ 262.195929] el0_svc+0x44/0x8c
[ 262.196917] el0t_64_sync_handler+0xf4/0x120
[ 262.198238] el0t_64_sync+0x190/0x194
[ 262.199224]
[ 262.199224] -> #0 (&kvm->arch.config_lock){+.+.}-{3:3}:
[ 262.201094] __lock_acquire+0x2b70/0x626c
[ 262.202245] lock_acquire+0x454/0x778
[ 262.203132] __mutex_lock+0x190/0x8b4
[ 262.204023] mutex_lock_nested+0x24/0x30
[ 262.205100] vgic_mmio_write_v3_misc+0x5c/0x2a0
[ 262.206178] dispatch_mmio_write+0xd8/0x258
[ 262.207498] __kvm_io_bus_write+0x1e0/0x350
[ 262.208582] kvm_io_bus_write+0xe0/0x1cc
[ 262.209653] io_mem_abort+0x2ac/0x6d8
[ 262.210569] kvm_handle_guest_abort+0x9b8/0x1f88
[ 262.211937] handle_exit+0xc4/0x39c
[ 262.212971] kvm_arch_vcpu_ioctl_run+0x90c/0x1c04
[ 262.214154] kvm_vcpu_ioctl+0x450/0x12f8
[ 262.215233] __arm64_sys_ioctl+0x7ac/0x1ba8
[ 262.216402] invoke_syscall.constprop.0+0x70/0x1e0
[ 262.217774] do_el0_svc+0xe4/0x2d4
[ 262.218758] el0_svc+0x44/0x8c
[ 262.219941] el0t_64_sync_handler+0xf4/0x120
[ 262.221110] el0t_64_sync+0x190/0x194
Note that the current report, which can be triggered by the vgic_irq
kselftest, is a triple chain that includes slots_lock, but after
inverting the slots_lock/config_lock dependency, the actual problem
reported above remains.
In several places, the vgic code calls kvm_io_bus_register_dev(), which
synchronizes the srcu, while holding config_lock (#1). And the MMIO
handler takes the config_lock while holding the srcu read lock (#0).
Break dependency #1, by registering the distributor and redistributors
without holding config_lock. The ITS also uses kvm_io_bus_register_dev()
but already relies on slots_lock to serialize calls.
The distributor iodev is created on the first KVM_RUN call. Multiple
threads will race for vgic initialization, and only the first one will
see !vgic_ready() under the lock. To serialize those threads, rely on
slots_lock rather than config_lock.
Redistributors are created earlier, through KVM_DEV_ARM_VGIC_GRP_ADDR
ioctls and vCPU creation. Similarly, serialize the iodev creation with
slots_lock, and the rest with config_lock.
Fixes: f003277 ("KVM: arm64: Use config_lock to protect vgic state")
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Reviewed-by: Oliver Upton <oliver.upton@linux.dev>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230518100914.2837292-2-jean-philippe@linaro.org1 parent c3a62df commit 59112e9
File tree
6 files changed
+51
-37
lines changed- arch/arm64/kvm/vgic
6 files changed
+51
-37
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
235 | 235 | | |
236 | 236 | | |
237 | 237 | | |
238 | | - | |
| 238 | + | |
239 | 239 | | |
240 | | - | |
| 240 | + | |
241 | 241 | | |
242 | 242 | | |
243 | 243 | | |
| |||
446 | 446 | | |
447 | 447 | | |
448 | 448 | | |
| 449 | + | |
449 | 450 | | |
450 | 451 | | |
451 | 452 | | |
452 | 453 | | |
453 | 454 | | |
| 455 | + | |
454 | 456 | | |
455 | 457 | | |
456 | 458 | | |
| |||
463 | 465 | | |
464 | 466 | | |
465 | 467 | | |
466 | | - | |
| 468 | + | |
467 | 469 | | |
468 | | - | |
469 | | - | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
470 | 484 | | |
471 | 485 | | |
472 | 486 | | |
| 487 | + | |
473 | 488 | | |
474 | 489 | | |
475 | 490 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
102 | 102 | | |
103 | 103 | | |
104 | 104 | | |
105 | | - | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
106 | 110 | | |
107 | 111 | | |
108 | 112 | | |
| |||
182 | 186 | | |
183 | 187 | | |
184 | 188 | | |
| 189 | + | |
185 | 190 | | |
186 | 191 | | |
187 | 192 | | |
188 | 193 | | |
189 | 194 | | |
190 | 195 | | |
191 | 196 | | |
| 197 | + | |
192 | 198 | | |
193 | 199 | | |
194 | | - | |
| 200 | + | |
195 | 201 | | |
196 | 202 | | |
197 | 203 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
769 | 769 | | |
770 | 770 | | |
771 | 771 | | |
772 | | - | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
773 | 776 | | |
774 | 777 | | |
775 | | - | |
| 778 | + | |
776 | 779 | | |
777 | 780 | | |
778 | 781 | | |
| |||
782 | 785 | | |
783 | 786 | | |
784 | 787 | | |
785 | | - | |
| 788 | + | |
786 | 789 | | |
787 | | - | |
788 | | - | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
789 | 794 | | |
790 | 795 | | |
791 | 796 | | |
| |||
799 | 804 | | |
800 | 805 | | |
801 | 806 | | |
802 | | - | |
| 807 | + | |
| 808 | + | |
803 | 809 | | |
804 | 810 | | |
805 | | - | |
806 | | - | |
807 | 811 | | |
808 | 812 | | |
809 | 813 | | |
| 814 | + | |
810 | 815 | | |
811 | 816 | | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
812 | 821 | | |
813 | 822 | | |
814 | 823 | | |
| |||
834 | 843 | | |
835 | 844 | | |
836 | 845 | | |
837 | | - | |
838 | 846 | | |
839 | 847 | | |
840 | 848 | | |
841 | 849 | | |
842 | | - | |
843 | 850 | | |
844 | 851 | | |
845 | 852 | | |
| |||
938 | 945 | | |
939 | 946 | | |
940 | 947 | | |
| 948 | + | |
941 | 949 | | |
| 950 | + | |
942 | 951 | | |
943 | 952 | | |
944 | 953 | | |
| |||
950 | 959 | | |
951 | 960 | | |
952 | 961 | | |
| 962 | + | |
953 | 963 | | |
954 | 964 | | |
| 965 | + | |
955 | 966 | | |
956 | 967 | | |
957 | 968 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1096 | 1096 | | |
1097 | 1097 | | |
1098 | 1098 | | |
1099 | | - | |
1100 | 1099 | | |
1101 | 1100 | | |
1102 | 1101 | | |
| |||
1114 | 1113 | | |
1115 | 1114 | | |
1116 | 1115 | | |
1117 | | - | |
1118 | | - | |
1119 | | - | |
1120 | | - | |
1121 | | - | |
1122 | | - | |
| 1116 | + | |
| 1117 | + | |
1123 | 1118 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
312 | 312 | | |
313 | 313 | | |
314 | 314 | | |
315 | | - | |
316 | | - | |
317 | | - | |
318 | | - | |
319 | | - | |
320 | | - | |
321 | 315 | | |
322 | 316 | | |
323 | 317 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
539 | 539 | | |
540 | 540 | | |
541 | 541 | | |
542 | | - | |
543 | 542 | | |
544 | 543 | | |
545 | 544 | | |
| |||
569 | 568 | | |
570 | 569 | | |
571 | 570 | | |
572 | | - | |
573 | | - | |
574 | | - | |
575 | | - | |
576 | | - | |
577 | | - | |
578 | 571 | | |
579 | 572 | | |
580 | 573 | | |
| |||
0 commit comments