@@ -1103,6 +1103,14 @@ void __weak kvm_arch_create_vm_debugfs(struct kvm *kvm)
11031103{
11041104}
11051105
1106+ /* Called only on cleanup and destruction paths when there are no users. */
1107+ static inline struct kvm_io_bus * kvm_get_bus_for_destruction (struct kvm * kvm ,
1108+ enum kvm_bus idx )
1109+ {
1110+ return rcu_dereference_protected (kvm -> buses [idx ],
1111+ !refcount_read (& kvm -> users_count ));
1112+ }
1113+
11061114static struct kvm * kvm_create_vm (unsigned long type , const char * fdname )
11071115{
11081116 struct kvm * kvm = kvm_arch_alloc_vm ();
@@ -1228,7 +1236,7 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
12281236out_err_no_arch_destroy_vm :
12291237 WARN_ON_ONCE (!refcount_dec_and_test (& kvm -> users_count ));
12301238 for (i = 0 ; i < KVM_NR_BUSES ; i ++ )
1231- kfree (kvm_get_bus (kvm , i ));
1239+ kfree (kvm_get_bus_for_destruction (kvm , i ));
12321240 kvm_free_irq_routing (kvm );
12331241out_err_no_irq_routing :
12341242 cleanup_srcu_struct (& kvm -> irq_srcu );
@@ -1276,7 +1284,7 @@ static void kvm_destroy_vm(struct kvm *kvm)
12761284
12771285 kvm_free_irq_routing (kvm );
12781286 for (i = 0 ; i < KVM_NR_BUSES ; i ++ ) {
1279- struct kvm_io_bus * bus = kvm_get_bus (kvm , i );
1287+ struct kvm_io_bus * bus = kvm_get_bus_for_destruction (kvm , i );
12801288
12811289 if (bus )
12821290 kvm_io_bus_destroy (bus );
@@ -1312,6 +1320,7 @@ static void kvm_destroy_vm(struct kvm *kvm)
13121320 kvm_free_memslots (kvm , & kvm -> __memslots [i ][1 ]);
13131321 }
13141322 cleanup_srcu_struct (& kvm -> irq_srcu );
1323+ srcu_barrier (& kvm -> srcu );
13151324 cleanup_srcu_struct (& kvm -> srcu );
13161325#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
13171326 xa_destroy (& kvm -> mem_attr_array );
@@ -5843,6 +5852,18 @@ static int __kvm_io_bus_write(struct kvm_vcpu *vcpu, struct kvm_io_bus *bus,
58435852 return - EOPNOTSUPP ;
58445853}
58455854
5855+ static struct kvm_io_bus * kvm_get_bus_srcu (struct kvm * kvm , enum kvm_bus idx )
5856+ {
5857+ /*
5858+ * Ensure that any updates to kvm_buses[] observed by the previous vCPU
5859+ * machine instruction are also visible to the vCPU machine instruction
5860+ * that triggered this call.
5861+ */
5862+ smp_mb__after_srcu_read_lock ();
5863+
5864+ return srcu_dereference (kvm -> buses [idx ], & kvm -> srcu );
5865+ }
5866+
58465867int kvm_io_bus_write (struct kvm_vcpu * vcpu , enum kvm_bus bus_idx , gpa_t addr ,
58475868 int len , const void * val )
58485869{
@@ -5855,7 +5876,7 @@ int kvm_io_bus_write(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr,
58555876 .len = len ,
58565877 };
58575878
5858- bus = srcu_dereference (vcpu -> kvm -> buses [ bus_idx ], & vcpu -> kvm -> srcu );
5879+ bus = kvm_get_bus_srcu (vcpu -> kvm , bus_idx );
58595880 if (!bus )
58605881 return - ENOMEM ;
58615882 r = __kvm_io_bus_write (vcpu , bus , & range , val );
@@ -5874,7 +5895,7 @@ int kvm_io_bus_write_cookie(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx,
58745895 .len = len ,
58755896 };
58765897
5877- bus = srcu_dereference (vcpu -> kvm -> buses [ bus_idx ], & vcpu -> kvm -> srcu );
5898+ bus = kvm_get_bus_srcu (vcpu -> kvm , bus_idx );
58785899 if (!bus )
58795900 return - ENOMEM ;
58805901
@@ -5924,14 +5945,21 @@ int kvm_io_bus_read(struct kvm_vcpu *vcpu, enum kvm_bus bus_idx, gpa_t addr,
59245945 .len = len ,
59255946 };
59265947
5927- bus = srcu_dereference (vcpu -> kvm -> buses [ bus_idx ], & vcpu -> kvm -> srcu );
5948+ bus = kvm_get_bus_srcu (vcpu -> kvm , bus_idx );
59285949 if (!bus )
59295950 return - ENOMEM ;
59305951 r = __kvm_io_bus_read (vcpu , bus , & range , val );
59315952 return r < 0 ? r : 0 ;
59325953}
59335954EXPORT_SYMBOL_GPL (kvm_io_bus_read );
59345955
5956+ static void __free_bus (struct rcu_head * rcu )
5957+ {
5958+ struct kvm_io_bus * bus = container_of (rcu , struct kvm_io_bus , rcu );
5959+
5960+ kfree (bus );
5961+ }
5962+
59355963int kvm_io_bus_register_dev (struct kvm * kvm , enum kvm_bus bus_idx , gpa_t addr ,
59365964 int len , struct kvm_io_device * dev )
59375965{
@@ -5970,8 +5998,7 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
59705998 memcpy (new_bus -> range + i + 1 , bus -> range + i ,
59715999 (bus -> dev_count - i ) * sizeof (struct kvm_io_range ));
59726000 rcu_assign_pointer (kvm -> buses [bus_idx ], new_bus );
5973- synchronize_srcu_expedited (& kvm -> srcu );
5974- kfree (bus );
6001+ call_srcu (& kvm -> srcu , & bus -> rcu , __free_bus );
59756002
59766003 return 0 ;
59776004}
@@ -6033,7 +6060,7 @@ struct kvm_io_device *kvm_io_bus_get_dev(struct kvm *kvm, enum kvm_bus bus_idx,
60336060
60346061 srcu_idx = srcu_read_lock (& kvm -> srcu );
60356062
6036- bus = srcu_dereference (kvm -> buses [ bus_idx ], & kvm -> srcu );
6063+ bus = kvm_get_bus_srcu (kvm , bus_idx );
60376064 if (!bus )
60386065 goto out_unlock ;
60396066
0 commit comments