File tree Expand file tree Collapse file tree 1 file changed +26
-1
lines changed Expand file tree Collapse file tree 1 file changed +26
-1
lines changed Original file line number Diff line number Diff line change @@ -84,15 +84,40 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
84
84
!kvm_vgic_global_state .can_emulate_gicv2 )
85
85
return - ENODEV ;
86
86
87
- /* Must be held to avoid race with vCPU creation */
87
+ /*
88
+ * Ensure mutual exclusion with vCPU creation and any vCPU ioctls by:
89
+ *
90
+ * - Holding kvm->lock to prevent KVM_CREATE_VCPU from reaching
91
+ * kvm_arch_vcpu_precreate() and ensuring created_vcpus is stable.
92
+ * This alone is insufficient, as kvm_vm_ioctl_create_vcpu() drops
93
+ * the kvm->lock before completing the vCPU creation.
94
+ */
88
95
lockdep_assert_held (& kvm -> lock );
89
96
97
+ /*
98
+ * - Acquiring the vCPU mutex for every *online* vCPU to prevent
99
+ * concurrent vCPU ioctls for vCPUs already visible to userspace.
100
+ */
90
101
ret = - EBUSY ;
91
102
if (!lock_all_vcpus (kvm ))
92
103
return ret ;
93
104
105
+ /*
106
+ * - Taking the config_lock which protects VGIC data structures such
107
+ * as the per-vCPU arrays of private IRQs (SGIs, PPIs).
108
+ */
94
109
mutex_lock (& kvm -> arch .config_lock );
95
110
111
+ /*
112
+ * - Bailing on the entire thing if a vCPU is in the middle of creation,
113
+ * dropped the kvm->lock, but hasn't reached kvm_arch_vcpu_create().
114
+ *
115
+ * The whole combination of this guarantees that no vCPU can get into
116
+ * KVM with a VGIC configuration inconsistent with the VM's VGIC.
117
+ */
118
+ if (kvm -> created_vcpus != atomic_read (& kvm -> online_vcpus ))
119
+ goto out_unlock ;
120
+
96
121
if (irqchip_in_kernel (kvm )) {
97
122
ret = - EEXIST ;
98
123
goto out_unlock ;
You can’t perform that action at this time.
0 commit comments