@@ -4332,7 +4332,7 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
43324332void kvm_io_bus_unregister_dev (struct kvm * kvm , enum kvm_bus bus_idx ,
43334333 struct kvm_io_device * dev )
43344334{
4335- int i ;
4335+ int i , j ;
43364336 struct kvm_io_bus * new_bus , * bus ;
43374337
43384338 bus = kvm_get_bus (kvm , bus_idx );
@@ -4349,17 +4349,20 @@ void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
43494349
43504350 new_bus = kmalloc (struct_size (bus , range , bus -> dev_count - 1 ),
43514351 GFP_KERNEL_ACCOUNT );
4352- if (!new_bus ) {
4352+ if (new_bus ) {
4353+ memcpy (new_bus , bus , sizeof (* bus ) + i * sizeof (struct kvm_io_range ));
4354+ new_bus -> dev_count -- ;
4355+ memcpy (new_bus -> range + i , bus -> range + i + 1 ,
4356+ (new_bus -> dev_count - i ) * sizeof (struct kvm_io_range ));
4357+ } else {
43534358 pr_err ("kvm: failed to shrink bus, removing it completely\n" );
4354- goto broken ;
4359+ for (j = 0 ; j < bus -> dev_count ; j ++ ) {
4360+ if (j == i )
4361+ continue ;
4362+ kvm_iodevice_destructor (bus -> range [j ].dev );
4363+ }
43554364 }
43564365
4357- memcpy (new_bus , bus , sizeof (* bus ) + i * sizeof (struct kvm_io_range ));
4358- new_bus -> dev_count -- ;
4359- memcpy (new_bus -> range + i , bus -> range + i + 1 ,
4360- (new_bus -> dev_count - i ) * sizeof (struct kvm_io_range ));
4361-
4362- broken :
43634366 rcu_assign_pointer (kvm -> buses [bus_idx ], new_bus );
43644367 synchronize_srcu_expedited (& kvm -> srcu );
43654368 kfree (bus );
0 commit comments